10static const char *
const TAG =
"display";
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;
25 if (x1 == x2 && y1 == y2)
45 int x1 = (start_radius * cos(angle * M_PI / 180)) +
x;
46 int y1 = (start_radius * sin(angle * M_PI / 180)) +
y;
47 int x2 = (stop_radius * cos(angle * M_PI / 180)) +
x;
48 int y2 = (stop_radius * sin(angle * M_PI / 180)) +
y;
51 this->
line(x1, y1, x2, y2, color);
55 ColorBitness bitness,
bool big_endian,
int x_offset,
int y_offset,
int x_pad) {
56 size_t line_stride = x_offset + w + x_pad;
58 for (
int y = 0;
y !=
h;
y++) {
59 size_t source_idx = (y_offset +
y) * line_stride + x_offset;
60 size_t source_idx_mod;
61 for (
int x = 0;
x != w;
x++, source_idx++) {
64 color_value = ptr[source_idx];
67 source_idx_mod = source_idx * 2;
69 color_value = (ptr[source_idx_mod] << 8) + ptr[source_idx_mod + 1];
71 color_value = ptr[source_idx_mod] + (ptr[source_idx_mod + 1] << 8);
75 source_idx_mod = source_idx * 3;
77 color_value = (ptr[source_idx_mod + 0] << 16) + (ptr[source_idx_mod + 1] << 8) + ptr[source_idx_mod + 2];
79 color_value = ptr[source_idx_mod + 0] + (ptr[source_idx_mod + 1] << 8) + (ptr[source_idx_mod + 2] << 16);
90 for (
int i =
x; i <
x + width; i++)
96 for (
int i =
y; i <
y + height; i++)
109 for (
int i = y1; i < y1 + height; i++) {
117 int err = 2 - 2 * radius;
128 if (-dx == dy && e2 <= dx) {
139 int dx = -int32_t(radius);
141 int err = 2 - 2 * radius;
149 int hline_width = 2 * (-dx) + 1;
150 this->
horizontal_line(center_x + dx, center_y + dy, hline_width, color);
151 this->
horizontal_line(center_x + dx, center_y - dy, hline_width, color);
155 if (-dx == dy && e2 <= dx) {
166 int rmax = radius1 > radius2 ? radius1 : radius2;
167 int rmin = radius1 < radius2 ? radius1 : radius2;
168 int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin);
169 int dymax = 0, dymin = 0;
170 int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
174 this->
draw_pixel_at(center_x - dxmax, center_y + dymax, color);
175 this->
draw_pixel_at(center_x + dxmax, center_y + dymax, color);
176 this->
draw_pixel_at(center_x - dxmin, center_y + dymin, color);
177 this->
draw_pixel_at(center_x + dxmin, center_y + dymin, color);
178 this->
draw_pixel_at(center_x + dxmax, center_y - dymax, color);
179 this->
draw_pixel_at(center_x - dxmax, center_y - dymax, color);
180 this->
draw_pixel_at(center_x + dxmin, center_y - dymin, color);
181 this->
draw_pixel_at(center_x - dxmin, center_y - dymin, color);
184 int hline_width = -(dxmax - dxmin) + 1;
185 this->
horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
186 this->
horizontal_line(center_x - dxmin, center_y + dymax, hline_width, color);
187 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
188 this->
horizontal_line(center_x - dxmin, center_y - dymax, hline_width, color);
191 int hline_width = 2 * (-dxmax) + 1;
192 this->
horizontal_line(center_x + dxmax, center_y + dymax, hline_width, color);
193 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
198 errmax += ++dymax * 2 + 1;
199 if (-dxmax == dymax && e2max <= dxmax) {
204 errmax += ++dxmax * 2 + 1;
207 while (dymin < dymax && dymin < rmin) {
210 errmin += ++dymin * 2 + 1;
211 if (-dxmin == dymin && e2min <= dxmin) {
216 errmin += ++dxmin * 2 + 1;
219 }
while (dxmax <= 0);
223 int rmax = radius1 > radius2 ? radius1 : radius2;
224 int rmin = radius1 < radius2 ? radius1 : radius2;
225 int dxmax = -int32_t(rmax), dxmin = -int32_t(rmin), upd_dxmax, upd_dxmin;
226 int dymax = 0, dymin = 0;
227 int errmax = 2 - 2 * rmax, errmin = 2 - 2 * rmin;
229 progress = std::max(0, std::min(progress, 100));
230 int draw_progress = progress > 50 ? (100 - progress) : progress;
231 float tan_a = (progress == 50) ? 65535 : tan(
float(draw_progress) * M_PI / 100);
235 this->
draw_pixel_at(center_x + dxmax, center_y - dymax, color);
236 this->
draw_pixel_at(center_x - dxmax, center_y - dymax, color);
239 int lhline_width = -(dxmax - dxmin) + 1;
240 if (progress >= 50) {
241 if (
float(dymax) <
float(-dxmax) * tan_a) {
242 upd_dxmax = ceil(
float(dymax) / tan_a);
246 this->
horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color);
248 this->
horizontal_line(center_x - dxmin, center_y, lhline_width, color);
249 if (upd_dxmax > -dxmin) {
251 int rhline_width = (upd_dxmax + dxmin) + 1;
253 rhline_width > lhline_width ? lhline_width : rhline_width, color);
256 if (
float(dymin) >
float(-dxmin) * tan_a) {
257 upd_dxmin = ceil(
float(dymin) / tan_a);
261 lhline_width = -(dxmax + upd_dxmin) + 1;
263 this->
horizontal_line(center_x - dxmin, center_y, lhline_width, color);
264 if (lhline_width > 0)
265 this->
horizontal_line(center_x + dxmax, center_y - dymax, lhline_width, color);
269 int hline_width = 2 * (-dxmax) + 1;
270 if (progress >= 50) {
271 if (dymax <
float(-dxmax) * tan_a) {
272 upd_dxmax = ceil(
float(dymax) / tan_a);
273 hline_width = -dxmax + upd_dxmax + 1;
276 if (dymax <
float(-dxmax) * tan_a) {
277 upd_dxmax = ceil(
float(dymax) / tan_a);
278 hline_width = -dxmax - upd_dxmax + 1;
284 this->
horizontal_line(center_x + dxmax, center_y - dymax, hline_width, color);
288 errmax += ++dymax * 2 + 1;
289 if (-dxmax == dymax && e2max <= dxmax) {
294 errmax += ++dxmax * 2 + 1;
296 while (dymin <= dymax && dymin <= rmin && dxmin <= 0) {
297 this->
draw_pixel_at(center_x + dxmin, center_y - dymin, color);
298 this->
draw_pixel_at(center_x - dxmin, center_y - dymin, color);
301 errmin += ++dymin * 2 + 1;
302 if (-dxmin == dymin && e2min <= dxmin) {
307 errmin += ++dxmin * 2 + 1;
310 }
while (dxmax <= 0);
314 this->
line(x1, y1, x2, y2, color);
315 this->
line(x1, y1, x3, y3, color);
316 this->
line(x2, y2, x3, y3, color);
321 int x_temp = *x1, y_temp = *y1;
322 *x1 = *x2, *y1 = *y2;
323 *x2 = x_temp, *y2 = y_temp;
326 int x_temp = *x1, y_temp = *y1;
327 *x1 = *x3, *y1 = *y3;
328 *x3 = x_temp, *y3 = y_temp;
331 int x_temp = *x2, y_temp = *y2;
332 *x2 = *x3, *y2 = *y3;
333 *x3 = x_temp, *y3 = y_temp;
341 int s1_current_x = x1;
342 int s1_current_y = y1;
343 bool s1_axis_swap =
false;
344 int s1_dx = abs(x2 - x1);
345 int s1_dy = abs(y2 - y1);
346 int s1_sign_x = ((x2 - x1) >= 0) ? 1 : -1;
347 int s1_sign_y = ((y2 - y1) >= 0) ? 1 : -1;
355 int s1_error = 2 * s1_dy - s1_dx;
358 int s2_current_x = x1;
359 int s2_current_y = y1;
360 bool s2_axis_swap =
false;
361 int s2_dx = abs(x3 - x1);
362 int s2_dy = abs(y3 - y1);
363 int s2_sign_x = ((x3 - x1) >= 0) ? 1 : -1;
364 int s2_sign_y = ((y3 - y1) >= 0) ? 1 : -1;
372 int s2_error = 2 * s2_dy - s2_dx;
375 for (
int i = 0; i <= s1_dx; i++) {
376 if (s1_current_x <= s2_current_x) {
377 this->
horizontal_line(s1_current_x, s1_current_y, s2_current_x - s1_current_x + 1, color);
379 this->
horizontal_line(s2_current_x, s2_current_y, s1_current_x - s2_current_x + 1, color);
384 while (s1_error >= 0) {
386 s1_current_x += s1_sign_x;
388 s1_current_y += s1_sign_y;
390 s1_error = s1_error - 2 * s1_dx;
393 s1_current_y += s1_sign_y;
395 s1_current_x += s1_sign_x;
397 s1_error = s1_error + 2 * s1_dy;
401 while (s2_current_y != s1_current_y) {
402 while (s2_error >= 0) {
404 s2_current_x += s2_sign_x;
406 s2_current_y += s2_sign_y;
408 s2_error = s2_error - 2 * s2_dx;
411 s2_current_y += s2_sign_y;
413 s2_current_x += s2_sign_x;
415 s2_error = s2_error + 2 * s2_dy;
427 }
else if (y1 == y2) {
432 int x_temp = (int) (x1 + ((
float) (y2 - y1) / (
float) (y3 - y1)) * (x3 - x1)), y_temp = y2;
440 float rotation_degrees) {
447 float rotation_radians = rotation_degrees * std::numbers::pi / 180;
453 rotation_radians -= (variation ==
VARIATION_FLAT_TOP) ? std::numbers::pi / edges : 0.0;
455 float vertex_angle = ((float) vertex_id) / edges * 2 * std::numbers::pi + rotation_radians;
456 *vertex_x = (int) round(cos(vertex_angle) * radius) + center_x;
457 *vertex_y = (int) round(sin(vertex_angle) * radius) + center_y;
464 int previous_vertex_x, previous_vertex_y;
465 for (
int current_vertex_id = 0; current_vertex_id <= edges; current_vertex_id++) {
466 int current_vertex_x, current_vertex_y;
468 variation, rotation_degrees);
469 if (current_vertex_id > 0) {
472 this->
filled_triangle(x,
y, previous_vertex_x, previous_vertex_y, current_vertex_x, current_vertex_y, color);
474 this->
line(previous_vertex_x, previous_vertex_y, current_vertex_x, current_vertex_y, color);
477 previous_vertex_x = current_vertex_x;
478 previous_vertex_y = current_vertex_y;
493 float rotation_degrees,
Color color) {
507 int x_start, y_start;
509 this->
get_text_bounds(x,
y, text, font, align, &x_start, &y_start, &width, &height);
510 font->
print(x_start, y_start,
this, color, text, background);
516 int ret = vsnprintf(buffer,
sizeof(buffer), format, arg);
518 this->
print(x,
y, font, color, align, buffer, background);
553 image->
draw(
x,
y,
this, color_on, color_off);
563 qr_code->
draw(
this,
x,
y, color_on, scale);
567#ifdef USE_GRAPHICAL_DISPLAY_MENU
569 Rect rect(
x,
y, width, height);
570 menu->draw(
this, &rect);
575 int *width,
int *height) {
576 int x_offset, baseline;
577 font->
measure(text, width, &x_offset, &baseline, height);
579 auto x_align =
TextAlign(
int(align) & 0x18);
580 auto y_align =
TextAlign(
int(align) & 0x07);
584 *x1 =
x - *width - x_offset;
587 *x1 =
x - (*width + x_offset) / 2;
604 *y1 =
y - (*height) / 2;
629 this->
vprintf_(x,
y, font, color, background, align, format, arg);
664 for (
auto *page : pages)
665 page->set_parent(
this);
667 for (uint32_t i = 0; i < pages.size() - 1; i++) {
668 pages[i]->set_next(pages[i + 1]);
669 pages[i + 1]->set_prev(pages[i]);
671 pages[0]->set_prev(pages[pages.size() - 1]);
672 pages[pages.size() - 1]->set_next(pages[0]);
694 }
else if (this->
page_ !=
nullptr) {
703 if ((this->
from_ ==
nullptr || this->
from_ == from) && (this->
to_ ==
nullptr || this->
to_ == to))
710 size_t ret = time.
strftime(buffer,
sizeof(buffer), format);
712 this->
print(x,
y, font, color, align, buffer, background);
741 ESP_LOGE(TAG,
"clear: Clipping is not set.");
749 ESP_LOGE(TAG,
"add: Clipping is not set.");
757 ESP_LOGE(TAG,
"add: Clipping is not set.");
782 min_x = std::max(
x, 0);
790 min_x = std::max(min_x, (
int) rect.x);
791 max_x = std::min(max_x, (
int) rect.x2());
794 return min_x < max_x;
798 min_y = std::max(
y, 0);
806 min_y = std::max(min_y, (
int) rect.y);
807 max_y = std::min(max_y, (
int) rect.y2());
810 return min_y < max_y;
813constexpr uint8_t TESTCARD_FONT[3][8]
PROGMEM = {{0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00},
814 {0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00},
815 {0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00}};
821 image_w = std::min(w - 20, 310);
822 image_h = std::min(
h - 20, 255);
823 int shift_x = (w - image_w) / 2;
824 int shift_y = (
h - image_h) / 2;
825 int line_w = (image_w - 6) / 6;
826 int image_c = image_w / 2;
828 Color r(255, 0, 0), g(0, 255, 0), b(0, 0, 255);
830 for (
auto i = 0; i != image_h; i++) {
831 int c = esp_scale(i, image_h);
832 this->
horizontal_line(shift_x + 0, shift_y + i, line_w, r.fade_to_white(c));
833 this->
horizontal_line(shift_x + line_w, shift_y + i, line_w, r.fade_to_black(c));
835 this->
horizontal_line(shift_x + image_c - line_w, shift_y + i, line_w, g.fade_to_white(c));
836 this->
horizontal_line(shift_x + image_c, shift_y + i, line_w, g.fade_to_black(c));
838 this->
horizontal_line(shift_x + image_w - (line_w * 2), shift_y + i, line_w, b.fade_to_white(c));
839 this->
horizontal_line(shift_x + image_w - line_w, shift_y + i, line_w, b.fade_to_black(c));
842 this->
rectangle(shift_x, shift_y, image_w, image_h,
Color(127, 127, 0));
844 uint16_t shift_r = shift_x + line_w - (8 * 3);
845 uint16_t shift_g = shift_x + image_c - (8 * 3);
846 uint16_t shift_b = shift_x + image_w - line_w - (8 * 3);
847 shift_y =
h / 2 - (8 * 3);
848 for (
auto i = 0; i < 8; i++) {
852 for (
auto k = 0; k < 8; k++) {
853 if ((ftr & (1 << k)) != 0) {
856 if ((ftg & (1 << k)) != 0) {
859 if ((ftb & (1 << k)) != 0) {
877 if (this->
next_ ==
nullptr) {
878 ESP_LOGE(TAG,
"no next page");
885 if (this->
prev_ ==
nullptr) {
886 ESP_LOGE(TAG,
"no previous page");
900 return LOG_STR(
"TOP_LEFT");
902 return LOG_STR(
"TOP_CENTER");
904 return LOG_STR(
"TOP_RIGHT");
906 return LOG_STR(
"CENTER_LEFT");
908 return LOG_STR(
"CENTER");
910 return LOG_STR(
"CENTER_RIGHT");
912 return LOG_STR(
"BASELINE_LEFT");
914 return LOG_STR(
"BASELINE_CENTER");
916 return LOG_STR(
"BASELINE_RIGHT");
918 return LOG_STR(
"BOTTOM_LEFT");
920 return LOG_STR(
"BOTTOM_CENTER");
922 return LOG_STR(
"BOTTOM_RIGHT");
924 return LOG_STR(
"UNKNOWN");
void trigger(const Ts &...x)
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.
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
Providing packet encoding functions for exchanging data with a remote host.
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.