ESPHome  2022.6.2
display_buffer.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include "esphome/core/defines.h"
6 #include "display_color_utils.h"
7 #include <cstdarg>
8 
9 #ifdef USE_TIME
11 #endif
12 
13 #ifdef USE_GRAPH
15 #endif
16 
17 #ifdef USE_QR_CODE
19 #endif
20 
21 namespace esphome {
22 namespace display {
23 
48 enum class TextAlign {
49  TOP = 0x00,
50  CENTER_VERTICAL = 0x01,
51  BASELINE = 0x02,
52  BOTTOM = 0x04,
53 
54  LEFT = 0x00,
55  CENTER_HORIZONTAL = 0x08,
56  RIGHT = 0x10,
57 
58  TOP_LEFT = TOP | LEFT,
60  TOP_RIGHT = TOP | RIGHT,
61 
65 
69 
73 };
74 
76 extern const Color COLOR_OFF;
78 extern const Color COLOR_ON;
79 
80 enum ImageType {
86 };
87 
92 };
93 
99 };
100 
101 class Font;
102 class Image;
103 class DisplayBuffer;
104 class DisplayPage;
106 
107 using display_writer_t = std::function<void(DisplayBuffer &)>;
108 
109 #define LOG_DISPLAY(prefix, type, obj) \
110  if ((obj) != nullptr) { \
111  ESP_LOGCONFIG(TAG, prefix type); \
112  ESP_LOGCONFIG(TAG, "%s Rotations: %d °", prefix, (obj)->rotation_); \
113  ESP_LOGCONFIG(TAG, "%s Dimensions: %dpx x %dpx", prefix, (obj)->get_width(), (obj)->get_height()); \
114  }
115 
117  public:
119  virtual void fill(Color color);
121  void clear();
122 
124  int get_width();
126  int get_height();
128  void draw_pixel_at(int x, int y, Color color = COLOR_ON);
129 
131  void line(int x1, int y1, int x2, int y2, Color color = COLOR_ON);
132 
134  void horizontal_line(int x, int y, int width, Color color = COLOR_ON);
135 
137  void vertical_line(int x, int y, int height, Color color = COLOR_ON);
138 
141  void rectangle(int x1, int y1, int width, int height, Color color = COLOR_ON);
142 
144  void filled_rectangle(int x1, int y1, int width, int height, Color color = COLOR_ON);
145 
147  void circle(int center_x, int center_xy, int radius, Color color = COLOR_ON);
148 
150  void filled_circle(int center_x, int center_y, int radius, Color color = COLOR_ON);
151 
161  void print(int x, int y, Font *font, Color color, TextAlign align, const char *text);
162 
171  void print(int x, int y, Font *font, Color color, const char *text);
172 
181  void print(int x, int y, Font *font, TextAlign align, const char *text);
182 
190  void print(int x, int y, Font *font, const char *text);
191 
202  void printf(int x, int y, Font *font, Color color, TextAlign align, const char *format, ...)
203  __attribute__((format(printf, 7, 8)));
204 
214  void printf(int x, int y, Font *font, Color color, const char *format, ...) __attribute__((format(printf, 6, 7)));
215 
225  void printf(int x, int y, Font *font, TextAlign align, const char *format, ...) __attribute__((format(printf, 6, 7)));
226 
235  void printf(int x, int y, Font *font, const char *format, ...) __attribute__((format(printf, 5, 6)));
236 
237 #ifdef USE_TIME
238 
248  void strftime(int x, int y, Font *font, Color color, TextAlign align, const char *format, time::ESPTime time)
249  __attribute__((format(strftime, 7, 0)));
250 
260  void strftime(int x, int y, Font *font, Color color, const char *format, time::ESPTime time)
261  __attribute__((format(strftime, 6, 0)));
262 
272  void strftime(int x, int y, Font *font, TextAlign align, const char *format, time::ESPTime time)
273  __attribute__((format(strftime, 6, 0)));
274 
283  void strftime(int x, int y, Font *font, const char *format, time::ESPTime time)
284  __attribute__((format(strftime, 5, 0)));
285 #endif
286 
295  void image(int x, int y, Image *image, Color color_on = COLOR_ON, Color color_off = COLOR_OFF);
296 
297 #ifdef USE_GRAPH
298 
305  void graph(int x, int y, graph::Graph *graph, Color color_on = COLOR_ON);
306 
318  void legend(int x, int y, graph::Graph *graph, Color color_on = COLOR_ON);
319 #endif // USE_GRAPH
320 
321 #ifdef USE_QR_CODE
322 
329  void qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on = COLOR_ON, int scale = 1);
330 #endif
331 
344  void get_text_bounds(int x, int y, const char *text, Font *font, TextAlign align, int *x1, int *y1, int *width,
345  int *height);
346 
348  void set_writer(display_writer_t &&writer);
349 
350  void show_page(DisplayPage *page);
351  void show_next_page();
352  void show_prev_page();
353 
354  void set_pages(std::vector<DisplayPage *> pages);
355 
356  const DisplayPage *get_active_page() const { return this->page_; }
357 
358  void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t) { this->on_page_change_triggers_.push_back(t); }
359 
361  void set_rotation(DisplayRotation rotation);
362 
363  // Internal method to set display auto clearing.
364  void set_auto_clear(bool auto_clear_enabled) { this->auto_clear_enabled_ = auto_clear_enabled; }
365 
366  virtual int get_height_internal() = 0;
367  virtual int get_width_internal() = 0;
368  DisplayRotation get_rotation() const { return this->rotation_; }
369 
373  virtual DisplayType get_display_type() = 0;
374 
375  protected:
376  void vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg);
377 
378  virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
379 
380  void init_internal_(uint32_t buffer_length);
381 
382  void do_update_();
383 
384  uint8_t *buffer_{nullptr};
387  DisplayPage *page_{nullptr};
388  DisplayPage *previous_page_{nullptr};
389  std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
390  bool auto_clear_enabled_{true};
391 };
392 
393 class DisplayPage {
394  public:
396  void show();
397  void show_next();
398  void show_prev();
399  void set_parent(DisplayBuffer *parent);
400  void set_prev(DisplayPage *prev);
401  void set_next(DisplayPage *next);
402  const display_writer_t &get_writer() const;
403 
404  protected:
407  DisplayPage *prev_{nullptr};
408  DisplayPage *next_{nullptr};
409 };
410 
411 struct GlyphData {
412  const char *a_char;
413  const uint8_t *data;
414  int offset_x;
415  int offset_y;
416  int width;
417  int height;
418 };
419 
420 class Glyph {
421  public:
422  Glyph(const GlyphData *data) : glyph_data_(data) {}
423 
424  bool get_pixel(int x, int y) const;
425 
426  const char *get_char() const;
427 
428  bool compare_to(const char *str) const;
429 
430  int match_length(const char *str) const;
431 
432  void scan_area(int *x1, int *y1, int *width, int *height) const;
433 
434  protected:
435  friend Font;
437 
439 };
440 
441 class Font {
442  public:
449  Font(const GlyphData *data, int data_nr, int baseline, int bottom);
450 
451  int match_next_glyph(const char *str, int *match_length);
452 
453  void measure(const char *str, int *width, int *x_offset, int *baseline, int *height);
454 
455  const std::vector<Glyph> &get_glyphs() const;
456 
457  protected:
458  std::vector<Glyph> glyphs_;
460  int bottom_;
461 };
462 
463 class Image {
464  public:
465  Image(const uint8_t *data_start, int width, int height, ImageType type);
466  virtual bool get_pixel(int x, int y) const;
467  virtual Color get_color_pixel(int x, int y) const;
468  virtual Color get_rgb565_pixel(int x, int y) const;
469  virtual Color get_grayscale_pixel(int x, int y) const;
470  int get_width() const;
471  int get_height() const;
472  ImageType get_type() const;
473 
474  protected:
475  int width_;
476  int height_;
478  const uint8_t *data_start_;
479 };
480 
481 class Animation : public Image {
482  public:
483  Animation(const uint8_t *data_start, int width, int height, uint32_t animation_frame_count, ImageType type);
484  bool get_pixel(int x, int y) const override;
485  Color get_color_pixel(int x, int y) const override;
486  Color get_rgb565_pixel(int x, int y) const override;
487  Color get_grayscale_pixel(int x, int y) const override;
488 
489  int get_animation_frame_count() const;
490  int get_current_frame() const;
491  void next_frame();
492  void prev_frame();
493 
494  protected:
497 };
498 
499 template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
500  public:
502 
503  void play(Ts... x) override {
504  auto *page = this->page_.value(x...);
505  if (page != nullptr) {
506  page->show();
507  }
508  }
509 };
510 
511 template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...> {
512  public:
513  DisplayPageShowNextAction(DisplayBuffer *buffer) : buffer_(buffer) {}
514 
515  void play(Ts... x) override { this->buffer_->show_next_page(); }
516 
518 };
519 
520 template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...> {
521  public:
522  DisplayPageShowPrevAction(DisplayBuffer *buffer) : buffer_(buffer) {}
523 
524  void play(Ts... x) override { this->buffer_->show_prev_page(); }
525 
527 };
528 
529 template<typename... Ts> class DisplayIsDisplayingPageCondition : public Condition<Ts...> {
530  public:
531  DisplayIsDisplayingPageCondition(DisplayBuffer *parent) : parent_(parent) {}
532 
533  void set_page(DisplayPage *page) { this->page_ = page; }
534  bool check(Ts... x) override { return this->parent_->get_active_page() == this->page_; }
535 
536  protected:
539 };
540 
541 class DisplayOnPageChangeTrigger : public Trigger<DisplayPage *, DisplayPage *> {
542  public:
544  void process(DisplayPage *from, DisplayPage *to);
545  void set_from(DisplayPage *p) { this->from_ = p; }
546  void set_to(DisplayPage *p) { this->to_ = p; }
547 
548  protected:
549  DisplayPage *from_{nullptr};
550  DisplayPage *to_{nullptr};
551 };
552 
553 } // namespace display
554 } // namespace esphome
void set_auto_clear(bool auto_clear_enabled)
DisplayPageShowPrevAction(DisplayBuffer *buffer)
const Color COLOR_OFF(0, 0, 0, 0)
Turn the pixel OFF.
DisplayRotation get_rotation() const
const uint8_t * data_start_
Glyph(const GlyphData *data)
DisplayPageShowNextAction(DisplayBuffer *buffer)
TextAlign
TextAlign is used to tell the display class how to position a piece of text.
A more user-friendly version of struct tm from time.h.
Base class for all automation conditions.
Definition: automation.h:74
const DisplayPage * get_active_page() const
uint8_t type
std::vector< Glyph > glyphs_
std::vector< DisplayOnPageChangeTrigger * > on_page_change_triggers_
enum esphome::EntityCategory __attribute__
const Color COLOR_ON(255, 255, 255, 255)
Turn the pixel ON.
TEMPLATABLE_VALUE(DisplayPage *, page) void play(Ts... x) override
Definition: a4988.cpp:4
const GlyphData * glyph_data_
std::function< void(DisplayBuffer &)> display_writer_t
void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t)