9static const char *
const TAG =
"display";
18 const int32_t dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
19 const int32_t dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
20 int32_t err = dx + dy;
24 if (x1 == x2 && y1 == y2)
44 int x1 = (start_radius * cos(angle * M_PI / 180)) +
x;
45 int y1 = (start_radius * sin(angle * M_PI / 180)) +
y;
46 int x2 = (stop_radius * cos(angle * M_PI / 180)) +
x;
47 int y2 = (stop_radius * sin(angle * M_PI / 180)) +
y;
50 this->
line(x1, y1, x2, y2, color);
54 ColorBitness bitness,
bool big_endian,
int x_offset,
int y_offset,
int x_pad) {
55 size_t line_stride = x_offset + w + x_pad;
57 for (
int y = 0;
y !=
h;
y++) {
58 size_t source_idx = (y_offset +
y) * line_stride + x_offset;
59 size_t source_idx_mod;
60 for (
int x = 0;
x != w;
x++, source_idx++) {
63 color_value = ptr[source_idx];
66 source_idx_mod = source_idx * 2;
68 color_value = (ptr[source_idx_mod] << 8) + ptr[source_idx_mod + 1];
70 color_value = ptr[source_idx_mod] + (ptr[source_idx_mod + 1] << 8);
74 source_idx_mod = source_idx * 3;
76 color_value = (ptr[source_idx_mod + 0] << 16) + (ptr[source_idx_mod + 1] << 8) + ptr[source_idx_mod + 2];
78 color_value = ptr[source_idx_mod + 0] + (ptr[source_idx_mod + 1] << 8) + (ptr[source_idx_mod + 2] << 16);
89 for (
int i =
x; i <
x + width; i++)
95 for (
int i =
y; i <
y + height; i++)
108 for (
int i = y1; i < y1 + height; i++) {
116 int err = 2 - 2 * radius;
127 if (-dx == dy && e2 <= dx) {
138 int dx = -int32_t(radius);
140 int err = 2 - 2 * radius;
148 int hline_width = 2 * (-dx) + 1;
149 this->
horizontal_line(center_x + dx, center_y + dy, hline_width, color);
150 this->
horizontal_line(center_x + dx, center_y - dy, hline_width, color);
154 if (-dx == dy && e2 <= dx) {
165 int rmax = radius1 > radius2 ? radius1 : radius2;
166 int rmin = radius1 < radius2 ? radius1 : radius2;
167 int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin);
168 int dymax = 0, dymin = 0;
169 int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
173 this->
draw_pixel_at(center_x - dxmax, center_y + dymax, color);
174 this->
draw_pixel_at(center_x + dxmax, center_y + dymax, color);
175 this->
draw_pixel_at(center_x - dxmin, center_y + dymin, color);
176 this->
draw_pixel_at(center_x + dxmin, center_y + dymin, color);
177 this->
draw_pixel_at(center_x + dxmax, center_y - dymax, color);
178 this->
draw_pixel_at(center_x - dxmax, center_y - dymax, color);
179 this->
draw_pixel_at(center_x + dxmin, center_y - dymin, color);
180 this->
draw_pixel_at(center_x - dxmin, center_y - dymin, color);
183 int hline_width = -(dxmax - dxmin) + 1;
184 this->
horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
185 this->
horizontal_line(center_x - dxmin, center_y + dymax, hline_width, color);
186 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
187 this->
horizontal_line(center_x - dxmin, center_y - dymax, hline_width, color);
190 int hline_width = 2 * (-dxmax) + 1;
191 this->
horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
192 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
197 errmax += ++dymax * 2 + 1;
198 if (-dxmax == dymax && e2max <= dxmax) {
203 errmax += ++dxmax * 2 + 1;
206 while (dymin < dymax && dymin < rmin) {
209 errmin += ++dymin * 2 + 1;
210 if (-dxmin == dymin && e2min <= dxmin) {
215 errmin += ++dxmin * 2 + 1;
218 }
while (dxmax <= 0);
222 int rmax = radius1 > radius2 ? radius1 : radius2;
223 int rmin = radius1 < radius2 ? radius1 : radius2;
224 int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin), upd_dxmax, upd_dxmin;
225 int dymax = 0, dymin = 0;
226 int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
228 progress = std::max(0, std::min(progress, 100));
229 int draw_progress = progress > 50 ? (100 - progress) : progress;
230 float tan_a = (progress == 50) ? 65535 : tan(
float(draw_progress) * M_PI / 100);
234 this->
draw_pixel_at(center_x + dxmax, center_y - dymax, color);
235 this->
draw_pixel_at(center_x - dxmax, center_y - dymax, color);
238 int lhline_width = -(dxmax - dxmin) + 1;
239 if (progress >= 50) {
240 if (
float(dymax) <
float(-dxmax) * tan_a) {
241 upd_dxmax = ceil(
float(dymax) / tan_a);
245 this->
horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color);
247 this->
horizontal_line(center_x - dxmin, center_y, lhline_width, color);
248 if (upd_dxmax > -dxmin) {
250 int rhline_width = (upd_dxmax + dxmin) + 1;
252 rhline_width > lhline_width ? lhline_width : rhline_width, color);
255 if (
float(dymin) >
float(-dxmin) * tan_a) {
256 upd_dxmin = ceil(
float(dymin) / tan_a);
260 lhline_width = -(dxmax + upd_dxmin) + 1;
262 this->
horizontal_line(center_x - dxmin, center_y, lhline_width, color);
263 if (lhline_width > 0)
264 this->
horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color);
268 int hline_width = 2 * (-dxmax) + 1;
269 if (progress >= 50) {
270 if (dymax <
float(-dxmax) * tan_a) {
271 upd_dxmax = ceil(
float(dymax) / tan_a);
272 hline_width = -dxmax + upd_dxmax + 1;
275 if (dymax <
float(-dxmax) * tan_a) {
276 upd_dxmax = ceil(
float(dymax) / tan_a);
277 hline_width = -dxmax - upd_dxmax + 1;
283 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
287 errmax += ++dymax * 2 + 1;
288 if (-dxmax == dymax && e2max <= dxmax) {
293 errmax += ++dxmax * 2 + 1;
295 while (dymin <= dymax && dymin <= rmin && dxmin <= 0) {
296 this->
draw_pixel_at(center_x + dxmin, center_y - dymin, color);
297 this->
draw_pixel_at(center_x - dxmin, center_y - dymin, color);
300 errmin += ++dymin * 2 + 1;
301 if (-dxmin == dymin && e2min <= dxmin) {
306 errmin += ++dxmin * 2 + 1;
309 }
while (dxmax <= 0);
313 this->
line(x1, y1, x2, y2, color);
314 this->
line(x1, y1, x3, y3, color);
315 this->
line(x2, y2, x3, y3, color);
320 int x_temp = *x1, y_temp = *y1;
321 *x1 = *x2, *y1 = *y2;
322 *x2 = x_temp, *y2 = y_temp;
325 int x_temp = *x1, y_temp = *y1;
326 *x1 = *x3, *y1 = *y3;
327 *x3 = x_temp, *y3 = y_temp;
330 int x_temp = *x2, y_temp = *y2;
331 *x2 = *x3, *y2 = *y3;
332 *x3 = x_temp, *y3 = y_temp;
340 int s1_current_x = x1;
341 int s1_current_y = y1;
342 bool s1_axis_swap =
false;
343 int s1_dx = abs(x2 - x1);
344 int s1_dy = abs(y2 - y1);
345 int s1_sign_x = ((x2 - x1) >= 0) ? 1 : -1;
346 int s1_sign_y = ((y2 - y1) >= 0) ? 1 : -1;
354 int s1_error = 2 * s1_dy - s1_dx;
357 int s2_current_x = x1;
358 int s2_current_y = y1;
359 bool s2_axis_swap =
false;
360 int s2_dx = abs(x3 - x1);
361 int s2_dy = abs(y3 - y1);
362 int s2_sign_x = ((x3 - x1) >= 0) ? 1 : -1;
363 int s2_sign_y = ((y3 - y1) >= 0) ? 1 : -1;
371 int s2_error = 2 * s2_dy - s2_dx;
374 for (
int i = 0; i <= s1_dx; i++) {
375 if (s1_current_x <= s2_current_x) {
376 this->
horizontal_line(s1_current_x, s1_current_y, s2_current_x - s1_current_x + 1, color);
378 this->
horizontal_line(s2_current_x, s2_current_y, s1_current_x - s2_current_x + 1, color);
383 while (s1_error >= 0) {
385 s1_current_x += s1_sign_x;
387 s1_current_y += s1_sign_y;
389 s1_error = s1_error - 2 * s1_dx;
392 s1_current_y += s1_sign_y;
394 s1_current_x += s1_sign_x;
396 s1_error = s1_error + 2 * s1_dy;
400 while (s2_current_y != s1_current_y) {
401 while (s2_error >= 0) {
403 s2_current_x += s2_sign_x;
405 s2_current_y += s2_sign_y;
407 s2_error = s2_error - 2 * s2_dx;
410 s2_current_y += s2_sign_y;
412 s2_current_x += s2_sign_x;
414 s2_error = s2_error + 2 * s2_dy;
426 }
else if (y1 == y2) {
431 int x_temp = (int) (x1 + ((
float) (y2 - y1) / (
float) (y3 - y1)) * (x3 - x1)), y_temp = y2;
439 float rotation_degrees) {
446 float rotation_radians = rotation_degrees * std::numbers::pi / 180;
452 rotation_radians -= (variation ==
VARIATION_FLAT_TOP) ? std::numbers::pi / edges : 0.0;
454 float vertex_angle = ((float) vertex_id) / edges * 2 * std::numbers::pi + rotation_radians;
455 *vertex_x = (int) round(cos(vertex_angle) * radius) + center_x;
456 *vertex_y = (int) round(sin(vertex_angle) * radius) + center_y;
463 int previous_vertex_x, previous_vertex_y;
464 for (
int current_vertex_id = 0; current_vertex_id <= edges; current_vertex_id++) {
465 int current_vertex_x, current_vertex_y;
467 variation, rotation_degrees);
468 if (current_vertex_id > 0) {
471 this->
filled_triangle(x,
y, previous_vertex_x, previous_vertex_y, current_vertex_x, current_vertex_y, color);
473 this->
line(previous_vertex_x, previous_vertex_y, current_vertex_x, current_vertex_y, color);
476 previous_vertex_x = current_vertex_x;
477 previous_vertex_y = current_vertex_y;
492 float rotation_degrees,
Color color) {
506 int x_start, y_start;
508 this->
get_text_bounds(x,
y, text, font, align, &x_start, &y_start, &width, &height);
509 font->
print(x_start, y_start,
this, color, text, background);
515 int ret = vsnprintf(buffer,
sizeof(buffer),
format, arg);
517 this->
print(x,
y, font, color, align, buffer, background);
552 image->
draw(
x,
y,
this, color_on, color_off);
562 qr_code->
draw(
this,
x,
y, color_on, scale);
566#ifdef USE_GRAPHICAL_DISPLAY_MENU
568 Rect rect(
x,
y, width, height);
569 menu->draw(
this, &rect);
574 int *width,
int *height) {
575 int x_offset, baseline;
576 font->
measure(text, width, &x_offset, &baseline, height);
578 auto x_align =
TextAlign(
int(align) & 0x18);
579 auto y_align =
TextAlign(
int(align) & 0x07);
583 *x1 =
x - *width - x_offset;
586 *x1 =
x - (*width + x_offset) / 2;
603 *y1 =
y - (*height) / 2;
666 for (
auto *page : pages)
667 page->set_parent(
this);
669 for (
uint32_t i = 0; i < pages.size() - 1; i++) {
670 pages[i]->set_next(pages[i + 1]);
671 pages[i + 1]->set_prev(pages[i]);
673 pages[0]->set_prev(pages[pages.size() - 1]);
674 pages[pages.size() - 1]->set_next(pages[0]);
696 }
else if (this->
page_ !=
nullptr) {
705 if ((this->
from_ ==
nullptr || this->
from_ == from) && (this->
to_ ==
nullptr || this->
to_ == to))
714 this->
print(x,
y, font, color, align, buffer, background);
743 ESP_LOGE(TAG,
"clear: Clipping is not set.");
751 ESP_LOGE(TAG,
"add: Clipping is not set.");
759 ESP_LOGE(TAG,
"add: Clipping is not set.");
784 min_x = std::max(
x, 0);
792 min_x = std::max(min_x, (
int) rect.x);
793 max_x = std::min(max_x, (
int) rect.x2());
796 return min_x < max_x;
800 min_y = std::max(
y, 0);
808 min_y = std::max(min_y, (
int) rect.y);
809 max_y = std::min(max_y, (
int) rect.y2());
812 return min_y < max_y;
815constexpr uint8_t TESTCARD_FONT[3][8]
PROGMEM = {{0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00},
816 {0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00},
817 {0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00}};
823 image_w = std::min(w - 20, 310);
824 image_h = std::min(
h - 20, 255);
825 int shift_x = (w - image_w) / 2;
826 int shift_y = (
h - image_h) / 2;
827 int line_w = (image_w - 6) / 6;
828 int image_c = image_w / 2;
830 Color r(255, 0, 0), g(0, 255, 0), b(0, 0, 255);
832 for (
auto i = 0; i != image_h; i++) {
833 int c = esp_scale(i, image_h);
834 this->
horizontal_line(shift_x + 0, shift_y + i, line_w, r.fade_to_white(c));
835 this->
horizontal_line(shift_x + line_w, shift_y + i, line_w, r.fade_to_black(c));
837 this->
horizontal_line(shift_x + image_c - line_w, shift_y + i, line_w, g.fade_to_white(c));
838 this->
horizontal_line(shift_x + image_c, shift_y + i, line_w, g.fade_to_black(c));
840 this->
horizontal_line(shift_x + image_w - (line_w * 2), shift_y + i, line_w, b.fade_to_white(c));
841 this->
horizontal_line(shift_x + image_w - line_w, shift_y + i, line_w, b.fade_to_black(c));
844 this->
rectangle(shift_x, shift_y, image_w, image_h,
Color(127, 127, 0));
846 uint16_t shift_r = shift_x + line_w - (8 * 3);
847 uint16_t shift_g = shift_x + image_c - (8 * 3);
848 uint16_t shift_b = shift_x + image_w - line_w - (8 * 3);
849 shift_y =
h / 2 - (8 * 3);
850 for (
auto i = 0; i < 8; i++) {
854 for (
auto k = 0; k < 8; k++) {
855 if ((ftr & (1 << k)) != 0) {
858 if ((ftg & (1 << k)) != 0) {
861 if ((ftb & (1 << k)) != 0) {
879 if (this->
next_ ==
nullptr) {
880 ESP_LOGE(TAG,
"no next page");
887 if (this->
prev_ ==
nullptr) {
888 ESP_LOGE(TAG,
"no previous page");
902 return LOG_STR(
"TOP_LEFT");
904 return LOG_STR(
"TOP_CENTER");
906 return LOG_STR(
"TOP_RIGHT");
908 return LOG_STR(
"CENTER_LEFT");
910 return LOG_STR(
"CENTER");
912 return LOG_STR(
"CENTER_RIGHT");
914 return LOG_STR(
"BASELINE_LEFT");
916 return LOG_STR(
"BASELINE_CENTER");
918 return LOG_STR(
"BASELINE_RIGHT");
920 return LOG_STR(
"BOTTOM_LEFT");
922 return LOG_STR(
"BOTTOM_CENTER");
924 return LOG_STR(
"BOTTOM_RIGHT");
926 return LOG_STR(
"UNKNOWN");
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
virtual void measure(const char *str, int *width, int *x_offset, int *baseline, int *height)=0
virtual void print(int x, int y, Display *display, Color color, const char *text, Color background)=0
virtual int get_height() const =0
virtual int get_width() const =0
virtual void draw(int x, int y, Display *display, Color color_on, Color color_off)=0
static Color to_color(uint32_t colorcode, ColorOrder color_order, ColorBitness color_bitness=ColorBitness::COLOR_BITNESS_888, bool right_bit_aligned=true)
void show_page(DisplayPage *page)
bool clip(int x, int y)
Check if pixel is within region of display.
void get_regular_polygon_vertex(int vertex_id, int *vertex_x, int *vertex_y, int center_x, int center_y, int radius, int edges, RegularPolygonVariation variation=VARIATION_POINTY_TOP, float rotation_degrees=ROTATION_0_DEGREES)
Get the specified vertex (x,y) coordinates for the regular polygon inscribed in the circle centered o...
virtual void clear()
Clear the entire screen by filling it with OFF pixels.
void end_clipping()
Reset the invalidation region.
void start_clipping(Rect rect)
Set the clipping rectangle for further drawing.
void set_pages(std::vector< DisplayPage * > pages)
void vprintf_(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format, va_list arg)
virtual int get_height()
Get the calculated height of the display in pixels with rotation applied.
virtual void fill(Color color)
Fill the entire screen with the given color.
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.
void sort_triangle_points_by_y_(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3)
virtual int get_width()
Get the calculated width of the display in pixels with rotation applied.
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...
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.
void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text, Color background=COLOR_OFF)
Print text with the anchor point at [x,y] with font.
virtual void set_rotation(DisplayRotation rotation)
Internal method to set the display rotation with.
void filled_regular_polygon(int x, int y, int radius, int edges, RegularPolygonVariation variation=VARIATION_POINTY_TOP, float rotation_degrees=ROTATION_0_DEGREES, Color color=COLOR_ON)
Fill a regular polygon inscribed in the circle centered on [x,y] with the given radius and color.
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.
bool clamp_x_(int x, int w, int &min_x, int &max_x)
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.
bool clamp_y_(int y, int h, int &min_y, int &max_y)
void filled_gauge(int center_x, int center_y, int radius1, int radius2, int progress, Color color=COLOR_ON)
Fill a half-ring "gauge" centered around [center_x,center_y] between two circles with the radius1 and...
virtual DisplayType get_display_type()=0
Get the type of display that the buffer corresponds to.
void void 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.
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.
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+...
DisplayPage * previous_page_
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.
void void void void void void strftime(int x, int y, BaseFont *font, Color color, Color background, 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,...
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,...
void printf(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,...) __attribute__((format(printf
Evaluate the printf-format format and print the result with the anchor point at [x,...
void set_writer(display_writer_t &&writer)
Internal method to set the display writer lambda.
void draw_pixel_at(int x, int y)
Set a single pixel at the specified coordinates to default color.
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.
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.
Rect get_clipping() const
Get the current the clipping rectangle.
void filled_ring(int center_x, int center_y, int radius1, int radius2, Color color=COLOR_ON)
Fill a ring centered around [center_x,center_y] between two circles with the radius1 and radius2 with...
void extend_clipping(Rect rect)
Add a rectangular region to the invalidation region.
void menu(int x, int y, graphical_display_menu::GraphicalDisplayMenu *menu, int width, int height)
void line_at_angle(int x, int y, int angle, int length, Color color=COLOR_ON)
Draw a straight line at the given angle based on the origin [x, y] for a specified length with the gi...
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.
DisplayRotation rotation_
std::vector< DisplayOnPageChangeTrigger * > on_page_change_triggers_
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's buffer.
void regular_polygon(int x, int y, int radius, int edges, RegularPolygonVariation variation=VARIATION_POINTY_TOP, float rotation_degrees=ROTATION_0_DEGREES, Color color=COLOR_ON, RegularPolygonDrawing drawing=DRAWING_OUTLINE)
Draw the outline of a regular polygon inscribed in the circle centered on [x,y] with the given radius...
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.
void shrink_clipping(Rect rect)
substract a rectangular region to the invalidation region
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,...
std::vector< Rect > clipping_rectangle_
void process(DisplayPage *from, DisplayPage *to)
void set_next(DisplayPage *next)
const display_writer_t & get_writer() const
void set_parent(Display *parent)
DisplayPage(display_writer_t writer)
void set_prev(DisplayPage *prev)
void draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color)
void draw_legend(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color)
void draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset, Color color, int scale)
constexpr uint8_t TESTCARD_FONT[3][8] PROGMEM
constexpr Color COLOR_ON(255, 255, 255, 255)
Turn the pixel ON.
constexpr Color COLOR_OFF(0, 0, 0, 0)
Turn the pixel OFF.
const LogString * text_align_to_string(TextAlign textalign)
ImageAlign
ImageAlign is used to tell the display class how to position a image.
const float ROTATION_270_DEGREES
TextAlign
TextAlign is used to tell the display class how to position a piece of text.
const float ROTATION_0_DEGREES
const char int const __FlashStringHelper * format
size_t size_t const char va_start(args, fmt)
uint8_t progmem_read_byte(const uint8_t *addr)
A more user-friendly version of struct tm from time.h.
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.