ESPHome  2024.2.1
display.cpp
Go to the documentation of this file.
1 #include "display.h"
2 
3 #include <utility>
4 
5 #include "esphome/core/log.h"
6 
7 namespace esphome {
8 namespace display {
9 
10 static const char *const TAG = "display";
11 
12 const Color COLOR_OFF(0, 0, 0, 0);
13 const Color COLOR_ON(255, 255, 255, 255);
14 
15 void Display::fill(Color color) { this->filled_rectangle(0, 0, this->get_width(), this->get_height(), color); }
16 void Display::clear() { this->fill(COLOR_OFF); }
17 void Display::set_rotation(DisplayRotation rotation) { this->rotation_ = rotation; }
18 void HOT Display::line(int x1, int y1, int x2, int y2, Color color) {
19  const int32_t dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
20  const int32_t dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
21  int32_t err = dx + dy;
22 
23  while (true) {
24  this->draw_pixel_at(x1, y1, color);
25  if (x1 == x2 && y1 == y2)
26  break;
27  int32_t e2 = 2 * err;
28  if (e2 >= dy) {
29  err += dy;
30  x1 += sx;
31  }
32  if (e2 <= dx) {
33  err += dx;
34  y1 += sy;
35  }
36  }
37 }
38 
39 void Display::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order,
40  ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) {
41  size_t line_stride = x_offset + w + x_pad; // length of each source line in pixels
42  uint32_t color_value;
43  for (int y = 0; y != h; y++) {
44  size_t source_idx = (y_offset + y) * line_stride + x_offset;
45  size_t source_idx_mod;
46  for (int x = 0; x != w; x++, source_idx++) {
47  switch (bitness) {
48  default:
49  color_value = ptr[source_idx];
50  break;
51  case COLOR_BITNESS_565:
52  source_idx_mod = source_idx * 2;
53  if (big_endian) {
54  color_value = (ptr[source_idx_mod] << 8) + ptr[source_idx_mod + 1];
55  } else {
56  color_value = ptr[source_idx_mod] + (ptr[source_idx_mod + 1] << 8);
57  }
58  break;
59  case COLOR_BITNESS_888:
60  source_idx_mod = source_idx * 3;
61  if (big_endian) {
62  color_value = (ptr[source_idx_mod + 0] << 16) + (ptr[source_idx_mod + 1] << 8) + ptr[source_idx_mod + 2];
63  } else {
64  color_value = ptr[source_idx_mod + 0] + (ptr[source_idx_mod + 1] << 8) + (ptr[source_idx_mod + 2] << 16);
65  }
66  break;
67  }
68  this->draw_pixel_at(x + x_start, y + y_start, ColorUtil::to_color(color_value, order, bitness));
69  }
70  }
71 }
72 
73 void HOT Display::horizontal_line(int x, int y, int width, Color color) {
74  // Future: Could be made more efficient by manipulating buffer directly in certain rotations.
75  for (int i = x; i < x + width; i++)
76  this->draw_pixel_at(i, y, color);
77 }
78 void HOT Display::vertical_line(int x, int y, int height, Color color) {
79  // Future: Could be made more efficient by manipulating buffer directly in certain rotations.
80  for (int i = y; i < y + height; i++)
81  this->draw_pixel_at(x, i, color);
82 }
83 void Display::rectangle(int x1, int y1, int width, int height, Color color) {
84  this->horizontal_line(x1, y1, width, color);
85  this->horizontal_line(x1, y1 + height - 1, width, color);
86  this->vertical_line(x1, y1, height, color);
87  this->vertical_line(x1 + width - 1, y1, height, color);
88 }
89 void Display::filled_rectangle(int x1, int y1, int width, int height, Color color) {
90  // Future: Use vertical_line and horizontal_line methods depending on rotation to reduce memory accesses.
91  for (int i = y1; i < y1 + height; i++) {
92  this->horizontal_line(x1, i, width, color);
93  }
94 }
95 void HOT Display::circle(int center_x, int center_xy, int radius, Color color) {
96  int dx = -radius;
97  int dy = 0;
98  int err = 2 - 2 * radius;
99  int e2;
100 
101  do {
102  this->draw_pixel_at(center_x - dx, center_xy + dy, color);
103  this->draw_pixel_at(center_x + dx, center_xy + dy, color);
104  this->draw_pixel_at(center_x + dx, center_xy - dy, color);
105  this->draw_pixel_at(center_x - dx, center_xy - dy, color);
106  e2 = err;
107  if (e2 < dy) {
108  err += ++dy * 2 + 1;
109  if (-dx == dy && e2 <= dx) {
110  e2 = 0;
111  }
112  }
113  if (e2 > dx) {
114  err += ++dx * 2 + 1;
115  }
116  } while (dx <= 0);
117 }
118 void Display::filled_circle(int center_x, int center_y, int radius, Color color) {
119  int dx = -int32_t(radius);
120  int dy = 0;
121  int err = 2 - 2 * radius;
122  int e2;
123 
124  do {
125  this->draw_pixel_at(center_x - dx, center_y + dy, color);
126  this->draw_pixel_at(center_x + dx, center_y + dy, color);
127  this->draw_pixel_at(center_x + dx, center_y - dy, color);
128  this->draw_pixel_at(center_x - dx, center_y - dy, color);
129  int hline_width = 2 * (-dx) + 1;
130  this->horizontal_line(center_x + dx, center_y + dy, hline_width, color);
131  this->horizontal_line(center_x + dx, center_y - dy, hline_width, color);
132  e2 = err;
133  if (e2 < dy) {
134  err += ++dy * 2 + 1;
135  if (-dx == dy && e2 <= dx) {
136  e2 = 0;
137  }
138  }
139  if (e2 > dx) {
140  err += ++dx * 2 + 1;
141  }
142  } while (dx <= 0);
143 }
144 void HOT Display::triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color) {
145  this->line(x1, y1, x2, y2, color);
146  this->line(x1, y1, x3, y3, color);
147  this->line(x2, y2, x3, y3, color);
148 }
149 void Display::sort_triangle_points_by_y_(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3) {
150  if (*y1 > *y2) {
151  int x_temp = *x1, y_temp = *y1;
152  *x1 = *x2, *y1 = *y2;
153  *x2 = x_temp, *y2 = y_temp;
154  }
155  if (*y1 > *y3) {
156  int x_temp = *x1, y_temp = *y1;
157  *x1 = *x3, *y1 = *y3;
158  *x3 = x_temp, *y3 = y_temp;
159  }
160  if (*y2 > *y3) {
161  int x_temp = *x2, y_temp = *y2;
162  *x2 = *x3, *y2 = *y3;
163  *x3 = x_temp, *y3 = y_temp;
164  }
165 }
166 void Display::filled_flat_side_triangle_(int x1, int y1, int x2, int y2, int x3, int y3, Color color) {
167  // y2 must be equal to y3 (same horizontal line)
168 
169  // Initialize Bresenham's algorithm for side 1
170  int s1_current_x = x1;
171  int s1_current_y = y1;
172  bool s1_axis_swap = false;
173  int s1_dx = abs(x2 - x1);
174  int s1_dy = abs(y2 - y1);
175  int s1_sign_x = ((x2 - x1) >= 0) ? 1 : -1;
176  int s1_sign_y = ((y2 - y1) >= 0) ? 1 : -1;
177  if (s1_dy > s1_dx) { // swap values
178  int tmp = s1_dx;
179  s1_dx = s1_dy;
180  s1_dy = tmp;
181  s1_axis_swap = true;
182  }
183  int s1_error = 2 * s1_dy - s1_dx;
184 
185  // Initialize Bresenham's algorithm for side 2
186  int s2_current_x = x1;
187  int s2_current_y = y1;
188  bool s2_axis_swap = false;
189  int s2_dx = abs(x3 - x1);
190  int s2_dy = abs(y3 - y1);
191  int s2_sign_x = ((x3 - x1) >= 0) ? 1 : -1;
192  int s2_sign_y = ((y3 - y1) >= 0) ? 1 : -1;
193  if (s2_dy > s2_dx) { // swap values
194  int tmp = s2_dx;
195  s2_dx = s2_dy;
196  s2_dy = tmp;
197  s2_axis_swap = true;
198  }
199  int s2_error = 2 * s2_dy - s2_dx;
200 
201  // Iterate on side 1 and allow side 2 to be processed to match the advance of the y-axis.
202  for (int i = 0; i <= s1_dx; i++) {
203  if (s1_current_x <= s2_current_x) {
204  this->horizontal_line(s1_current_x, s1_current_y, s2_current_x - s1_current_x + 1, color);
205  } else {
206  this->horizontal_line(s2_current_x, s2_current_y, s1_current_x - s2_current_x + 1, color);
207  }
208 
209  // Bresenham's #1
210  // Side 1 s1_current_x and s1_current_y calculation
211  while (s1_error >= 0) {
212  if (s1_axis_swap) {
213  s1_current_x += s1_sign_x;
214  } else {
215  s1_current_y += s1_sign_y;
216  }
217  s1_error = s1_error - 2 * s1_dx;
218  }
219  if (s1_axis_swap) {
220  s1_current_y += s1_sign_y;
221  } else {
222  s1_current_x += s1_sign_x;
223  }
224  s1_error = s1_error + 2 * s1_dy;
225 
226  // Bresenham's #2
227  // Side 2 s2_current_x and s2_current_y calculation
228  while (s2_current_y != s1_current_y) {
229  while (s2_error >= 0) {
230  if (s2_axis_swap) {
231  s2_current_x += s2_sign_x;
232  } else {
233  s2_current_y += s2_sign_y;
234  }
235  s2_error = s2_error - 2 * s2_dx;
236  }
237  if (s2_axis_swap) {
238  s2_current_y += s2_sign_y;
239  } else {
240  s2_current_x += s2_sign_x;
241  }
242  s2_error = s2_error + 2 * s2_dy;
243  }
244  }
245 }
246 void Display::filled_triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color) {
247  // Sort the three points by y-coordinate ascending, so [x1,y1] is the topmost point
248  this->sort_triangle_points_by_y_(&x1, &y1, &x2, &y2, &x3, &y3);
249 
250  if (y2 == y3) { // Check for special case of a bottom-flat triangle
251  this->filled_flat_side_triangle_(x1, y1, x2, y2, x3, y3, color);
252  } else if (y1 == y2) { // Check for special case of a top-flat triangle
253  this->filled_flat_side_triangle_(x3, y3, x1, y1, x2, y2, color);
254  } else { // General case: split the no-flat-side triangle in a top-flat triangle and bottom-flat triangle
255  int x_temp = (int) (x1 + ((float) (y2 - y1) / (float) (y3 - y1)) * (x3 - x1)), y_temp = y2;
256  this->filled_flat_side_triangle_(x1, y1, x2, y2, x_temp, y_temp, color);
257  this->filled_flat_side_triangle_(x3, y3, x2, y2, x_temp, y_temp, color);
258  }
259 }
260 
261 void Display::print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text) {
262  int x_start, y_start;
263  int width, height;
264  this->get_text_bounds(x, y, text, font, align, &x_start, &y_start, &width, &height);
265  font->print(x_start, y_start, this, color, text);
266 }
267 void Display::vprintf_(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, va_list arg) {
268  char buffer[256];
269  int ret = vsnprintf(buffer, sizeof(buffer), format, arg);
270  if (ret > 0)
271  this->print(x, y, font, color, align, buffer);
272 }
273 
274 void Display::image(int x, int y, BaseImage *image, Color color_on, Color color_off) {
275  this->image(x, y, image, ImageAlign::TOP_LEFT, color_on, color_off);
276 }
277 
278 void Display::image(int x, int y, BaseImage *image, ImageAlign align, Color color_on, Color color_off) {
279  auto x_align = ImageAlign(int(align) & (int(ImageAlign::HORIZONTAL_ALIGNMENT)));
280  auto y_align = ImageAlign(int(align) & (int(ImageAlign::VERTICAL_ALIGNMENT)));
281 
282  switch (x_align) {
283  case ImageAlign::RIGHT:
284  x -= image->get_width();
285  break;
287  x -= image->get_width() / 2;
288  break;
289  case ImageAlign::LEFT:
290  default:
291  break;
292  }
293 
294  switch (y_align) {
295  case ImageAlign::BOTTOM:
296  y -= image->get_height();
297  break;
299  y -= image->get_height() / 2;
300  break;
301  case ImageAlign::TOP:
302  default:
303  break;
304  }
305 
306  image->draw(x, y, this, color_on, color_off);
307 }
308 
309 #ifdef USE_GRAPH
310 void Display::graph(int x, int y, graph::Graph *graph, Color color_on) { graph->draw(this, x, y, color_on); }
311 void Display::legend(int x, int y, graph::Graph *graph, Color color_on) { graph->draw_legend(this, x, y, color_on); }
312 #endif // USE_GRAPH
313 
314 #ifdef USE_QR_CODE
315 void Display::qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on, int scale) {
316  qr_code->draw(this, x, y, color_on, scale);
317 }
318 #endif // USE_QR_CODE
319 
320 #ifdef USE_GRAPHICAL_DISPLAY_MENU
321 void Display::menu(int x, int y, graphical_display_menu::GraphicalDisplayMenu *menu, int width, int height) {
322  Rect rect(x, y, width, height);
323  menu->draw(this, &rect);
324 }
325 #endif // USE_GRAPHICAL_DISPLAY_MENU
326 
327 void Display::get_text_bounds(int x, int y, const char *text, BaseFont *font, TextAlign align, int *x1, int *y1,
328  int *width, int *height) {
329  int x_offset, baseline;
330  font->measure(text, width, &x_offset, &baseline, height);
331 
332  auto x_align = TextAlign(int(align) & 0x18);
333  auto y_align = TextAlign(int(align) & 0x07);
334 
335  switch (x_align) {
336  case TextAlign::RIGHT:
337  *x1 = x - *width;
338  break;
340  *x1 = x - (*width) / 2;
341  break;
342  case TextAlign::LEFT:
343  default:
344  // LEFT
345  *x1 = x;
346  break;
347  }
348 
349  switch (y_align) {
350  case TextAlign::BOTTOM:
351  *y1 = y - *height;
352  break;
353  case TextAlign::BASELINE:
354  *y1 = y - baseline;
355  break;
357  *y1 = y - (*height) / 2;
358  break;
359  case TextAlign::TOP:
360  default:
361  *y1 = y;
362  break;
363  }
364 }
365 void Display::print(int x, int y, BaseFont *font, Color color, const char *text) {
366  this->print(x, y, font, color, TextAlign::TOP_LEFT, text);
367 }
368 void Display::print(int x, int y, BaseFont *font, TextAlign align, const char *text) {
369  this->print(x, y, font, COLOR_ON, align, text);
370 }
371 void Display::print(int x, int y, BaseFont *font, const char *text) {
372  this->print(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, text);
373 }
374 void Display::printf(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ...) {
375  va_list arg;
376  va_start(arg, format);
377  this->vprintf_(x, y, font, color, align, format, arg);
378  va_end(arg);
379 }
380 void Display::printf(int x, int y, BaseFont *font, Color color, const char *format, ...) {
381  va_list arg;
382  va_start(arg, format);
383  this->vprintf_(x, y, font, color, TextAlign::TOP_LEFT, format, arg);
384  va_end(arg);
385 }
386 void Display::printf(int x, int y, BaseFont *font, TextAlign align, const char *format, ...) {
387  va_list arg;
388  va_start(arg, format);
389  this->vprintf_(x, y, font, COLOR_ON, align, format, arg);
390  va_end(arg);
391 }
392 void Display::printf(int x, int y, BaseFont *font, const char *format, ...) {
393  va_list arg;
394  va_start(arg, format);
395  this->vprintf_(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, arg);
396  va_end(arg);
397 }
398 void Display::set_writer(display_writer_t &&writer) { this->writer_ = writer; }
399 void Display::set_pages(std::vector<DisplayPage *> pages) {
400  for (auto *page : pages)
401  page->set_parent(this);
402 
403  for (uint32_t i = 0; i < pages.size() - 1; i++) {
404  pages[i]->set_next(pages[i + 1]);
405  pages[i + 1]->set_prev(pages[i]);
406  }
407  pages[0]->set_prev(pages[pages.size() - 1]);
408  pages[pages.size() - 1]->set_next(pages[0]);
409  this->show_page(pages[0]);
410 }
412  this->previous_page_ = this->page_;
413  this->page_ = page;
414  if (this->previous_page_ != this->page_) {
415  for (auto *t : on_page_change_triggers_)
416  t->process(this->previous_page_, this->page_);
417  }
418 }
422  if (this->auto_clear_enabled_) {
423  this->clear();
424  }
425  if (this->page_ != nullptr) {
426  this->page_->get_writer()(*this);
427  } else if (this->writer_.has_value()) {
428  (*this->writer_)(*this);
429  }
430  this->clear_clipping_();
431 }
433  if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
434  this->trigger(from, to);
435 }
436 void Display::strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time) {
437  char buffer[64];
438  size_t ret = time.strftime(buffer, sizeof(buffer), format);
439  if (ret > 0)
440  this->print(x, y, font, color, align, buffer);
441 }
442 void Display::strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time) {
443  this->strftime(x, y, font, color, TextAlign::TOP_LEFT, format, time);
444 }
445 void Display::strftime(int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time) {
446  this->strftime(x, y, font, COLOR_ON, align, format, time);
447 }
448 void Display::strftime(int x, int y, BaseFont *font, const char *format, ESPTime time) {
449  this->strftime(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, time);
450 }
451 
453  if (!this->clipping_rectangle_.empty()) {
454  Rect r = this->clipping_rectangle_.back();
455  rect.shrink(r);
456  }
457  this->clipping_rectangle_.push_back(rect);
458 }
460  if (this->clipping_rectangle_.empty()) {
461  ESP_LOGE(TAG, "clear: Clipping is not set.");
462  } else {
463  this->clipping_rectangle_.pop_back();
464  }
465 }
467  if (this->clipping_rectangle_.empty()) {
468  ESP_LOGE(TAG, "add: Clipping is not set.");
469  } else {
470  this->clipping_rectangle_.back().extend(add_rect);
471  }
472 }
474  if (this->clipping_rectangle_.empty()) {
475  ESP_LOGE(TAG, "add: Clipping is not set.");
476  } else {
477  this->clipping_rectangle_.back().shrink(add_rect);
478  }
479 }
481  if (this->clipping_rectangle_.empty()) {
482  return Rect();
483  } else {
484  return this->clipping_rectangle_.back();
485  }
486 }
488 bool Display::clip(int x, int y) {
489  if (x < 0 || x >= this->get_width() || y < 0 || y >= this->get_height())
490  return false;
491  if (!this->get_clipping().inside(x, y))
492  return false;
493  return true;
494 }
495 bool Display::clamp_x_(int x, int w, int &min_x, int &max_x) {
496  min_x = std::max(x, 0);
497  max_x = std::min(x + w, this->get_width());
498 
499  if (!this->clipping_rectangle_.empty()) {
500  const auto &rect = this->clipping_rectangle_.back();
501  if (!rect.is_set())
502  return false;
503 
504  min_x = std::max(min_x, (int) rect.x);
505  max_x = std::min(max_x, (int) rect.x2());
506  }
507 
508  return min_x < max_x;
509 }
510 bool Display::clamp_y_(int y, int h, int &min_y, int &max_y) {
511  min_y = std::max(y, 0);
512  max_y = std::min(y + h, this->get_height());
513 
514  if (!this->clipping_rectangle_.empty()) {
515  const auto &rect = this->clipping_rectangle_.back();
516  if (!rect.is_set())
517  return false;
518 
519  min_y = std::max(min_y, (int) rect.y);
520  max_y = std::min(max_y, (int) rect.y2());
521  }
522 
523  return min_y < max_y;
524 }
525 
527 void DisplayPage::show() { this->parent_->show_page(this); }
528 void DisplayPage::show_next() { this->next_->show(); }
529 void DisplayPage::show_prev() { this->prev_->show(); }
530 void DisplayPage::set_parent(Display *parent) { this->parent_ = parent; }
531 void DisplayPage::set_prev(DisplayPage *prev) { this->prev_ = prev; }
532 void DisplayPage::set_next(DisplayPage *next) { this->next_ = next; }
533 const display_writer_t &DisplayPage::get_writer() const { return this->writer_; }
534 
535 } // namespace display
536 } // namespace esphome
void circle(int center_x, int center_xy, int radius, Color color=COLOR_ON)
Draw the outline of a circle centered around [center_x,center_y] with the radius radius with the give...
Definition: display.cpp:95
void horizontal_line(int x, int y, int width, Color color=COLOR_ON)
Draw a horizontal line from the point [x,y] to [x+width,y] with the given color.
Definition: display.cpp:73
optional< display_writer_t > writer_
Definition: display.h:551
std::vector< DisplayOnPageChangeTrigger * > on_page_change_triggers_
Definition: display.h:554
void set_pages(std::vector< DisplayPage *> pages)
Definition: display.cpp:399
bool clamp_x_(int x, int w, int &min_x, int &max_x)
Definition: display.cpp:495
void sort_triangle_points_by_y_(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3)
Definition: display.cpp:149
size_t strftime(char *buffer, size_t buffer_len, const char *format)
Convert this ESPTime struct to a null-terminated c string buffer as specified by the format argument...
Definition: time.cpp:15
void get_text_bounds(int x, int y, const char *text, BaseFont *font, TextAlign align, int *x1, int *y1, int *width, int *height)
Get the text bounds of the given string.
Definition: display.cpp:327
void set_next(DisplayPage *next)
Definition: display.cpp:532
void set_parent(Display *parent)
Definition: display.cpp:530
uint16_t x
Definition: tt21100.cpp:17
void filled_flat_side_triangle_(int x1, int y1, int x2, int y2, int x3, int y3, Color color)
This method fills a triangle using only integer variables by using a modified bresenham algorithm...
Definition: display.cpp:166
A more user-friendly version of struct tm from time.h.
Definition: time.h:13
void set_rotation(DisplayRotation rotation)
Internal method to set the display rotation with.
Definition: display.cpp:17
const Color COLOR_OFF(0, 0, 0, 0)
Turn the pixel OFF.
Definition: display.h:154
void extend_clipping(Rect rect)
Add a rectangular region to the invalidation region.
Definition: display.cpp:466
STL namespace.
void shrink_clipping(Rect rect)
substract a rectangular region to the invalidation region
Definition: display.cpp:473
void filled_circle(int center_x, int center_y, int radius, Color color=COLOR_ON)
Fill a circle centered around [center_x,center_y] with the radius radius with the given color...
Definition: display.cpp:118
void triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color=COLOR_ON)
Draw the outline of a triangle contained between the points [x1,y1], [x2,y2] and [x3,y3] with the given color.
Definition: display.cpp:144
void filled_rectangle(int x1, int y1, int width, int height, Color color=COLOR_ON)
Fill a rectangle with the top left point at [x1,y1] and the bottom right point at [x1+width...
Definition: display.cpp:89
void printf(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format,...) __attribute__((format(printf
Evaluate the printf-format format and print the result with the anchor point at [x,y] with font.
Definition: display.cpp:374
virtual int get_width()=0
Get the width of the image in pixels with rotation applied.
bool has_value() const
Definition: optional.h:87
virtual void fill(Color color)
Fill the entire screen with the given color.
Definition: display.cpp:15
DisplayPage(display_writer_t writer)
Definition: display.cpp:526
Rect get_clipping() const
Get the current the clipping rectangle.
Definition: display.cpp:480
void qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on=COLOR_ON, int scale=1)
Draw the qr_code with the top-left corner at [x,y] to the screen.
Definition: display.cpp:315
bool clamp_y_(int y, int h, int &min_y, int &max_y)
Definition: display.cpp:510
virtual void draw(int x, int y, Display *display, Color color_on, Color color_off)=0
uint16_t y
Definition: tt21100.cpp:18
const display_writer_t & get_writer() const
Definition: display.cpp:533
void filled_triangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color=COLOR_ON)
Fill a triangle contained between the points [x1,y1], [x2,y2] and [x3,y3] with the given color...
Definition: display.cpp:246
void rectangle(int x1, int y1, int width, int height, Color color=COLOR_ON)
Draw the outline of a rectangle with the top left point at [x1,y1] and the bottom right point at [x1+...
Definition: display.cpp:83
TextAlign
TextAlign is used to tell the display class how to position a piece of text.
Definition: display.h:52
DisplayPage * page_
Definition: display.h:552
std::function< void(Display &)> display_writer_t
Definition: display.h:144
void process(DisplayPage *from, DisplayPage *to)
Definition: display.cpp:432
void start_clipping(Rect rect)
Set the clipping rectangle for further drawing.
Definition: display.cpp:452
ImageAlign
ImageAlign is used to tell the display class how to position a image.
Definition: display.h:102
void clear()
Clear the entire screen by filling it with OFF pixels.
Definition: display.cpp:16
void draw_legend(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color)
Definition: graph.cpp:331
void line(int x1, int y1, int x2, int y2, Color color=COLOR_ON)
Draw a straight line from the point [x1,y1] to [x2,y2] with the given color.
Definition: display.cpp:18
void legend(int x, int y, graph::Graph *graph, Color color_on=COLOR_ON)
Draw the legend for graph with the top-left corner at [x,y] to the screen.
Definition: display.cpp:311
void menu(int x, int y, graphical_display_menu::GraphicalDisplayMenu *menu, int width, int height)
Definition: display.cpp:321
void draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale)
Definition: qr_code.cpp:36
display_writer_t writer_
Definition: display.h:572
DisplayRotation rotation_
Definition: display.h:550
void end_clipping()
Reset the invalidation region.
Definition: display.cpp:459
DisplayPage * previous_page_
Definition: display.h:553
void vertical_line(int x, int y, int height, Color color=COLOR_ON)
Draw a vertical line from the point [x,y] to [x,y+width] with the given color.
Definition: display.cpp:78
const Color COLOR_ON(255, 255, 255, 255)
Turn the pixel ON.
Definition: display.h:156
void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text)
Print text with the anchor point at [x,y] with font.
Definition: display.cpp:261
void vprintf_(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, va_list arg)
Definition: display.cpp:267
uint8_t h
Definition: bl0939.h:21
virtual int get_width() const =0
bool clip(int x, int y)
Check if pixel is within region of display.
Definition: display.cpp:488
void void void void void strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time) __attribute__((format(strftime
Evaluate the strftime-format format and print the result with the anchor point at [x...
Definition: display.cpp:436
virtual void print(int x, int y, Display *display, Color color, const char *text)=0
void draw_pixel_at(int x, int y)
Set a single pixel at the specified coordinates to default color.
Definition: display.h:184
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
static Color to_color(uint32_t colorcode, ColorOrder color_order, ColorBitness color_bitness=ColorBitness::COLOR_BITNESS_888, bool right_bit_aligned=true)
void draw(display::Display *display, const display::Rect *bounds)
void draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color)
Definition: graph.cpp:59
virtual void measure(const char *str, int *width, int *x_offset, int *baseline, int *height)=0
std::vector< Rect > clipping_rectangle_
Definition: display.h:556
void set_writer(display_writer_t &&writer)
Internal method to set the display writer lambda.
Definition: display.cpp:398
void graph(int x, int y, graph::Graph *graph, Color color_on=COLOR_ON)
Draw the graph with the top-left corner at [x,y] to the screen.
Definition: display.cpp:310
void shrink(Rect rect)
Definition: rect.cpp:42
void void void void void void void void void image(int x, int y, BaseImage *image, Color color_on=COLOR_ON, Color color_off=COLOR_OFF)
Draw the image with the top-left corner at [x,y] to the screen.
Definition: display.cpp:274
void show_page(DisplayPage *page)
Definition: display.cpp:411
virtual void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order, ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad)
Given an array of pixels encoded in the nominated format, draw these into the display&#39;s buffer...
Definition: display.cpp:39
void set_prev(DisplayPage *prev)
Definition: display.cpp:531
virtual int get_height() const =0
virtual int get_height()=0
Get the height of the image in pixels with rotation applied.