modm API documentation
graphic_display.hpp
1 /*
2  * Copyright (c) 2009-2010, Martin Rosekeit
3  * Copyright (c) 2009-2011, 2013, Fabian Greif
4  * Copyright (c) 2011, 2013, Thorsten Lajewski
5  * Copyright (c) 2012-2014, 2016, Niklas Hauser
6  * Copyright (c) 2013, Hans Schily
7  * Copyright (c) 2014, Daniel Krebs
8  * Copyright (c) 2015, Niclas Rohrer
9  * Copyright (c) 2021, Thomas Sommer
10  *
11  * This file is part of the modm project.
12  *
13  * This Source Code Form is subject to the terms of the Mozilla Public
14  * License, v. 2.0. If a copy of the MPL was not distributed with this
15  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
16  */
17 // ----------------------------------------------------------------------------
18 
19 #ifndef MODM_GRAPHIC_DISPLAY_HPP
20 #define MODM_GRAPHIC_DISPLAY_HPP
21 
22 #include <modm/architecture/interface/accessor.hpp>
23 #include <modm/io/iodevice.hpp>
24 #include <modm/io/iostream.hpp>
25 #include <modm/math/geometry.hpp>
26 
27 #include <modm/ui/color.hpp>
28 #include "font.hpp"
29 
30 namespace modm
31 {
32 
33 /// @ingroup modm_ui_display
34 namespace glcd
35 {
36 
37 /// @ingroup modm_ui_display
38 using Point = Vector<int16_t, 2>;
39 
40 enum Orientation : uint8_t
41 {
42  Landscape0,
43  Portrait90,
44  Landscape180,
45  Portrait270,
46 };
47 
48 } // namespace glcd
49 
50 /**
51  * Base class for graphical displays.
52  *
53  * \ingroup modm_ui_display
54  */
55 
56 /*
57  *
58  * Text mode:
59  * - left adjusted (default)
60  * - right adjusted
61  * - centered
62  *
63  * All modes relative to the current viewport. This would make
64  * drawing a menu system easier.
65  */
66 class GraphicDisplay : public IOStream
67 {
68 public:
69  friend class VirtualGraphicDisplay;
70 
72 
73  virtual ~GraphicDisplay() {}
74 
75  /**
76  * Number of pixel in horizontal direction.
77  */
78  virtual uint16_t
79  getWidth() const = 0;
80 
81  /**
82  * Number of pixel in vertical direction.
83  */
84  virtual uint16_t
85  getHeight() const = 0;
86 
87  // TODO Requires all inherited drivers work with resumable functions
88  // virtual modm::ResumableResult<bool>
89  // setOrientation() = 0;
90 
91  /**
92  * Buffer-array size of first dimension
93  */
94  virtual std::size_t
95  getBufferWidth() const = 0;
96 
97  /**
98  * Buffer-array size of second dimension
99  */
100  virtual std::size_t
101  getBufferHeight() const = 0;
102 
103  /**
104  * Set a pixel to foregroundColor
105  *
106  * \param x x-position
107  * \param y y-position
108  */
109  virtual void
110  setPixel(int16_t x, int16_t y) = 0;
111 
112  /**
113  * Set a pixel to foregroundColor
114  *
115  * \param p point
116  */
117  inline void
119  {
120  this->setPixel(p.x, p.y);
121  }
122 
123  /**
124  * Set a pixel to backgroundColor
125  *
126  * \param x x-position
127  * \param y y-position
128  */
129  virtual void
130  clearPixel(int16_t x, int16_t y) = 0;
131 
132  /**
133  * Set a pixel to backgroundColor
134  *
135  * \param p point
136  */
137  inline void
139  {
140  this->setPixel(p.x, p.y);
141  }
142 
143  /**
144  * Set whole screen to backgroundColor
145  */
146  virtual void
147  clear() = 0;
148 
149  /**
150  * Transfer the content of the RAM buffer to the real display.
151  */
152  virtual void
153  update() = 0;
154 
155  // TODO Requires all inherited drivers work with resumable functions
156  // modm::ResumableResult<bool>
157  // writeDisplay();
158 
159  // TODO Set a clipping area
160  // Everything drawn outside this area will be discarded.
161  // inline void
162  // setClippingWindow(glcd::Point start, glcd::Point end);
163 
164  /**
165  * Draw a line.
166  *
167  * Uses the faster drawHorizontalLine() or drawVerticalLine() if
168  * possible, otherwise the line is rastered with the Bresenham line
169  * algorithm.
170  *
171  * \param start first point
172  * \param end second point
173  */
174  inline void
176  {
177  this->drawLine(start.x, start.y, end.x, end.y);
178  }
179 
180  /**
181  * Draw a line
182  *
183  * \param x1 Start x-position
184  * \param y1 Start y-position
185  * \param x2 End x-position
186  * \param y3 End y-position
187  */
188  void
189  drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2);
190 
191  /**
192  * Draw a rectangle.
193  *
194  * \param start Upper left corner
195  * \param width Width of rectangle
196  * \param height Height of rectangle
197  */
198  void
199  drawRectangle(glcd::Point start, uint16_t width, uint16_t height);
200 
201  /**
202  * Draw a rectangle.
203  *
204  * \param x Upper left corner x-position
205  * \param y Upper left corner y-position
206  * \param width Width of rectangle
207  * \param height Height of rectangle
208  */
209  inline void
210  drawRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height)
211  {
212  drawRectangle(glcd::Point(x, y), width, height);
213  }
214 
215  /**
216  * Draw a filled rectangle.
217  *
218  * \param start Upper left corner
219  * \param width Width of rectangle
220  * \param height Height of rectangle
221  */
222  void
223  fillRectangle(glcd::Point start, uint16_t width, uint16_t height);
224 
225  /**
226  * Draw a rectangle.
227  *
228  * \param x Upper left corner x-position
229  * \param y Upper left corner y-position
230  * \param width Width of rectangle
231  * \param height Height of rectangle
232  */
233  inline void
234  fillRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height)
235  {
236  fillRectangle(glcd::Point(x, y), width, height);
237  }
238 
239  /**
240  * Draw a rectangle with rounded corners
241  *
242  * \param start Upper left corner
243  * \param width Width of rectangle
244  * \param height Height of rectangle
245  * \param radius Rounding radius
246  */
247  void
248  drawRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, uint16_t radius);
249 
250  /**
251  * Draw a filled rectangle with rounded corners
252  *
253  * \param start Upper left corner
254  * \param width Width of rectangle
255  * \param height Height of rectangle
256  * \param radius Rounding radius
257  */
258  // TODO Not yet implemented
259  // void
260  // fillRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, uint16_t radius);
261 
262  /**
263  * Draw a circle
264  *
265  * Uses the midpoint circle algorithm.
266  *
267  * \param center Center of the circle
268  * \param radius Radius of the circle
269  */
270  void
271  drawCircle(glcd::Point center, uint16_t radius);
272 
273  /**
274  * Draw a filled circle.
275  *
276  * \param center Center of the circle
277  * \param radius Radius of the circle
278  */
279  virtual void
280  fillCircle(glcd::Point center, uint16_t radius);
281 
282  /**
283  * Draw an ellipse.
284  *
285  * Uses a variation of the midpoint algorithm. May be improved through
286  * simplification of the used formula.
287  *
288  * \param center Center of the ellipse
289  * \param rx Radius in x-direction
290  * \param ry Radius in y-direction
291  */
292  void
293  drawEllipse(glcd::Point center, int16_t rx, int16_t ry);
294 
295  /**
296  * Draw an image.
297  *
298  * The first byte in the image data specifies the with, the second
299  * byte the height. Afterwards the actual image data.
300  *
301  * \param start Upper left corner
302  * \param image Image data in Flash
303  *
304  * \see drawImage()
305  */
306  void
308 
309  /**
310  * Draw an image.
311  *
312  * \param start Upper left corner
313  * \param width Image width
314  * \param height Image height
315  * \param data Image data in Flash without any size information.
316  */
317  virtual void
318  drawImageRaw(glcd::Point start, uint16_t width, uint16_t height,
320 
321  /**
322  * Set the cursor for text drawing.
323  *
324  * \param position Cursor position
325  */
326  inline void
328  {
329  this->cursor = position;
330  }
331 
332  /**
333  * Set the cursor for text drawing.
334  *
335  * \param x Cursor x-position
336  * \param y Cursor y-position
337  */
338  inline void
339  setCursor(int16_t x, int16_t y)
340  {
341  this->cursor = glcd::Point(x, y);
342  }
343 
344  /**
345  * Set the cursor x-position for text drawing.
346  *
347  * \param x Cursor x-position
348  */
349  inline void
350  setCursorX(int16_t x)
351  {
352  this->cursor.x = x;
353  }
354 
355  /**
356  * Set the cursor y-position for text drawing.
357  *
358  * \param y Cursor y-position
359  */
360  inline void
361  setCursorY(int16_t y)
362  {
363  this->cursor.y = y;
364  }
365 
366  inline glcd::Point
367  getCursor() const
368  {
369  return this->cursor;
370  }
371 
372  /**
373  * Set a new font.
374  *
375  * Default font is modm::font::FixedWidth5x8.
376  *
377  * \param newFont Active font
378  * \see modm::font
379  */
380  inline void
381  setFont(const uint8_t *newFont)
382  {
383  this->font = modm::accessor::asFlash(newFont);
384  }
385 
386  inline void
388  {
389  this->font = *font;
390  }
391 
392  /**
393  * Get the height of a character.
394  */
395  uint8_t
396  getFontHeight() const;
397 
398  static uint8_t
400 
401  /**
402  * Get the width of (null terminated) string.
403  */
404  uint16_t
405  getStringWidth(const char *s) const;
406 
407  static uint16_t
408  getStringWidth(const char *s, const modm::accessor::Flash<uint8_t> *font);
409 
410  /**
411  * Write a single character.
412  */
413  void
414  write(char c);
415 
416 protected:
417  /// helper method for drawCircle() and drawEllipse()
418  void
419  drawCircle4(glcd::Point center, int16_t x, int16_t y);
420 
421  virtual void
422  drawHorizontalLine(glcd::Point start, uint16_t length);
423 
424  virtual void
425  drawVerticalLine(glcd::Point start, uint16_t length);
426 
427 protected:
428  // Interface class for the IOStream
429  class Writer : public IODevice
430  {
431  public:
432  Writer(GraphicDisplay *parent) : parent(parent) {}
433 
434  /// Draw a single character
435  virtual void
436  write(char c);
437 
438  using IODevice::write;
439 
440  // unused
441  virtual void
442  flush();
443 
444  // unused, returns always `false`
445  virtual bool
446  read(char &c);
447 
448  private:
449  GraphicDisplay *parent;
450  };
451 
452 protected:
453  Writer writer;
455  glcd::Point cursor;
456 };
457 } // namespace modm
458 
459 #endif // MODM_GRAPHIC_DISPLAY_HPP
virtual bool read(char &c)
Read a single character.
Definition: graphic_display_text.cpp:131
virtual void write(char c)
Draw a single character.
Definition: graphic_display_text.cpp:120
void drawCircle4(glcd::Point center, int16_t x, int16_t y)
helper method for drawCircle() and drawEllipse()
Definition: graphic_display.cpp:192
uint8_t getFontHeight() const
Definition: graphic_display_text.cpp:18
void setCursorY(int16_t y)
Definition: graphic_display.hpp:361
void setCursorX(int16_t x)
Definition: graphic_display.hpp:350
void setCursor(int16_t x, int16_t y)
Definition: graphic_display.hpp:339
void setCursor(glcd::Point position)
Definition: graphic_display.hpp:327
Definition: graphic_display.hpp:429
Definition: sab/interface_test.cpp:73
virtual void drawImageRaw(glcd::Point start, uint16_t width, uint16_t height, modm::accessor::Flash< uint8_t > data)
Definition: graphic_display.cpp:270
void drawImage(glcd::Point start, modm::accessor::Flash< uint8_t > image)
Definition: graphic_display.cpp:261
void drawEllipse(glcd::Point center, int16_t rx, int16_t ry)
Definition: graphic_display.cpp:204
void drawCircle(glcd::Point center, uint16_t radius)
Definition: graphic_display.cpp:164
Definition: modm/src/modm/io/iodevice.hpp:26
void drawRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, uint16_t radius)
Definition: graphic_display.cpp:122
void fillRectangle(glcd::Point start, uint16_t width, uint16_t height)
Definition: graphic_display_fill.cpp:19
void drawRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height)
Definition: graphic_display.hpp:210
void drawRectangle(glcd::Point start, uint16_t width, uint16_t height)
Definition: graphic_display.cpp:110
virtual void clear() = 0
void clearPixel(glcd::Point p)
Definition: graphic_display.hpp:138
virtual void write(char c) = 0
Write a single character.
modm_always_inline::modm::accessor::Flash< T > asFlash(const T *ptr)
Definition: accessor_flash.hpp:179
virtual void clearPixel(int16_t x, int16_t y) = 0
virtual void fillCircle(glcd::Point center, uint16_t radius)
Definition: graphic_display_fill.cpp:28
void drawLine(glcd::Point start, glcd::Point end)
Definition: graphic_display.hpp:175
void setPixel(glcd::Point p)
Definition: graphic_display.hpp:118
void write(char c)
Definition: graphic_display_text.cpp:63
virtual void setPixel(int16_t x, int16_t y) = 0
void fillRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height)
Definition: graphic_display.hpp:234
virtual std::size_t getBufferWidth() const = 0
virtual void update() = 0
virtual uint16_t getHeight() const = 0
virtual uint16_t getWidth() const = 0
Definition: virtual_graphic_display.hpp:24
uint16_t getStringWidth(const char *s) const
Definition: graphic_display_text.cpp:34
Definition: iostream.hpp:39
void setFont(const uint8_t *newFont)
Definition: graphic_display.hpp:381
virtual std::size_t getBufferHeight() const = 0
Definition: graphic_display.hpp:66