mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 17:05:21 +01:00
display: add BaseFont
and introduce Font::draw
methods (#4963)
This commit is contained in:
parent
5a8e93ed0a
commit
8c9d63f48f
7 changed files with 106 additions and 100 deletions
|
@ -7,10 +7,6 @@
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#include "animation.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -256,54 +252,14 @@ void DisplayBuffer::filled_circle(int center_x, int center_y, int radius, Color
|
||||||
} while (dx <= 0);
|
} while (dx <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayBuffer::print(int x, int y, Font *font, Color color, TextAlign align, const char *text) {
|
void DisplayBuffer::print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text) {
|
||||||
int x_start, y_start;
|
int x_start, y_start;
|
||||||
int width, height;
|
int width, height;
|
||||||
this->get_text_bounds(x, y, text, font, align, &x_start, &y_start, &width, &height);
|
this->get_text_bounds(x, y, text, font, align, &x_start, &y_start, &width, &height);
|
||||||
|
font->print(x_start, y_start, this, color, text);
|
||||||
int i = 0;
|
|
||||||
int x_at = x_start;
|
|
||||||
while (text[i] != '\0') {
|
|
||||||
int match_length;
|
|
||||||
int glyph_n = font->match_next_glyph(text + i, &match_length);
|
|
||||||
if (glyph_n < 0) {
|
|
||||||
// Unknown char, skip
|
|
||||||
ESP_LOGW(TAG, "Encountered character without representation in font: '%c'", text[i]);
|
|
||||||
if (!font->get_glyphs().empty()) {
|
|
||||||
uint8_t glyph_width = font->get_glyphs()[0].glyph_data_->width;
|
|
||||||
for (int glyph_x = 0; glyph_x < glyph_width; glyph_x++) {
|
|
||||||
for (int glyph_y = 0; glyph_y < height; glyph_y++)
|
|
||||||
this->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
|
|
||||||
}
|
|
||||||
x_at += glyph_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Glyph &glyph = font->get_glyphs()[glyph_n];
|
|
||||||
int scan_x1, scan_y1, scan_width, scan_height;
|
|
||||||
glyph.scan_area(&scan_x1, &scan_y1, &scan_width, &scan_height);
|
|
||||||
|
|
||||||
{
|
|
||||||
const int glyph_x_max = scan_x1 + scan_width;
|
|
||||||
const int glyph_y_max = scan_y1 + scan_height;
|
|
||||||
for (int glyph_x = scan_x1; glyph_x < glyph_x_max; glyph_x++) {
|
|
||||||
for (int glyph_y = scan_y1; glyph_y < glyph_y_max; glyph_y++) {
|
|
||||||
if (glyph.get_pixel(glyph_x, glyph_y)) {
|
|
||||||
this->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x_at += glyph.glyph_data_->width + glyph.glyph_data_->offset_x;
|
|
||||||
|
|
||||||
i += match_length;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void DisplayBuffer::vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg) {
|
void DisplayBuffer::vprintf_(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format,
|
||||||
|
va_list arg) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int ret = vsnprintf(buffer, sizeof(buffer), format, arg);
|
int ret = vsnprintf(buffer, sizeof(buffer), format, arg);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
|
@ -358,7 +314,7 @@ void DisplayBuffer::qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_
|
||||||
}
|
}
|
||||||
#endif // USE_QR_CODE
|
#endif // USE_QR_CODE
|
||||||
|
|
||||||
void DisplayBuffer::get_text_bounds(int x, int y, const char *text, Font *font, TextAlign align, int *x1, int *y1,
|
void DisplayBuffer::get_text_bounds(int x, int y, const char *text, BaseFont *font, TextAlign align, int *x1, int *y1,
|
||||||
int *width, int *height) {
|
int *width, int *height) {
|
||||||
int x_offset, baseline;
|
int x_offset, baseline;
|
||||||
font->measure(text, width, &x_offset, &baseline, height);
|
font->measure(text, width, &x_offset, &baseline, height);
|
||||||
|
@ -396,34 +352,34 @@ void DisplayBuffer::get_text_bounds(int x, int y, const char *text, Font *font,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void DisplayBuffer::print(int x, int y, Font *font, Color color, const char *text) {
|
void DisplayBuffer::print(int x, int y, BaseFont *font, Color color, const char *text) {
|
||||||
this->print(x, y, font, color, TextAlign::TOP_LEFT, text);
|
this->print(x, y, font, color, TextAlign::TOP_LEFT, text);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::print(int x, int y, Font *font, TextAlign align, const char *text) {
|
void DisplayBuffer::print(int x, int y, BaseFont *font, TextAlign align, const char *text) {
|
||||||
this->print(x, y, font, COLOR_ON, align, text);
|
this->print(x, y, font, COLOR_ON, align, text);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::print(int x, int y, Font *font, const char *text) {
|
void DisplayBuffer::print(int x, int y, BaseFont *font, const char *text) {
|
||||||
this->print(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, text);
|
this->print(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, text);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::printf(int x, int y, Font *font, Color color, TextAlign align, const char *format, ...) {
|
void DisplayBuffer::printf(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ...) {
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
this->vprintf_(x, y, font, color, align, format, arg);
|
this->vprintf_(x, y, font, color, align, format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::printf(int x, int y, Font *font, Color color, const char *format, ...) {
|
void DisplayBuffer::printf(int x, int y, BaseFont *font, Color color, const char *format, ...) {
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
this->vprintf_(x, y, font, color, TextAlign::TOP_LEFT, format, arg);
|
this->vprintf_(x, y, font, color, TextAlign::TOP_LEFT, format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::printf(int x, int y, Font *font, TextAlign align, const char *format, ...) {
|
void DisplayBuffer::printf(int x, int y, BaseFont *font, TextAlign align, const char *format, ...) {
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
this->vprintf_(x, y, font, COLOR_ON, align, format, arg);
|
this->vprintf_(x, y, font, COLOR_ON, align, format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::printf(int x, int y, Font *font, const char *format, ...) {
|
void DisplayBuffer::printf(int x, int y, BaseFont *font, const char *format, ...) {
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
this->vprintf_(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, arg);
|
this->vprintf_(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, arg);
|
||||||
|
@ -470,19 +426,20 @@ void DisplayOnPageChangeTrigger::process(DisplayPage *from, DisplayPage *to) {
|
||||||
if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
|
if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
|
||||||
this->trigger(from, to);
|
this->trigger(from, to);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::strftime(int x, int y, Font *font, Color color, TextAlign align, const char *format, ESPTime time) {
|
void DisplayBuffer::strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format,
|
||||||
|
ESPTime time) {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
size_t ret = time.strftime(buffer, sizeof(buffer), format);
|
size_t ret = time.strftime(buffer, sizeof(buffer), format);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
this->print(x, y, font, color, align, buffer);
|
this->print(x, y, font, color, align, buffer);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::strftime(int x, int y, Font *font, Color color, const char *format, ESPTime time) {
|
void DisplayBuffer::strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time) {
|
||||||
this->strftime(x, y, font, color, TextAlign::TOP_LEFT, format, time);
|
this->strftime(x, y, font, color, TextAlign::TOP_LEFT, format, time);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::strftime(int x, int y, Font *font, TextAlign align, const char *format, ESPTime time) {
|
void DisplayBuffer::strftime(int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time) {
|
||||||
this->strftime(x, y, font, COLOR_ON, align, format, time);
|
this->strftime(x, y, font, COLOR_ON, align, format, time);
|
||||||
}
|
}
|
||||||
void DisplayBuffer::strftime(int x, int y, Font *font, const char *format, ESPTime time) {
|
void DisplayBuffer::strftime(int x, int y, BaseFont *font, const char *format, ESPTime time) {
|
||||||
this->strftime(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, time);
|
this->strftime(x, y, font, COLOR_ON, TextAlign::TOP_LEFT, format, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#include "esphome/components/qr_code/qr_code.h"
|
#include "esphome/components/qr_code/qr_code.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "animation.h"
|
|
||||||
#include "font.h"
|
|
||||||
#include "image.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -175,6 +171,24 @@ using display_writer_t = std::function<void(DisplayBuffer &)>;
|
||||||
ESP_LOGCONFIG(TAG, "%s Dimensions: %dpx x %dpx", prefix, (obj)->get_width(), (obj)->get_height()); \
|
ESP_LOGCONFIG(TAG, "%s Dimensions: %dpx x %dpx", prefix, (obj)->get_width(), (obj)->get_height()); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Turn the pixel OFF.
|
||||||
|
extern const Color COLOR_OFF;
|
||||||
|
/// Turn the pixel ON.
|
||||||
|
extern const Color COLOR_ON;
|
||||||
|
|
||||||
|
class BaseImage {
|
||||||
|
public:
|
||||||
|
virtual void draw(int x, int y, DisplayBuffer *display, Color color_on, Color color_off) = 0;
|
||||||
|
virtual int get_width() const = 0;
|
||||||
|
virtual int get_height() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseFont {
|
||||||
|
public:
|
||||||
|
virtual void print(int x, int y, DisplayBuffer *display, Color color, const char *text) = 0;
|
||||||
|
virtual void measure(const char *str, int *width, int *x_offset, int *baseline, int *height) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class DisplayBuffer {
|
class DisplayBuffer {
|
||||||
public:
|
public:
|
||||||
/// Fill the entire screen with the given color.
|
/// Fill the entire screen with the given color.
|
||||||
|
@ -221,7 +235,7 @@ class DisplayBuffer {
|
||||||
* @param align The alignment of the text.
|
* @param align The alignment of the text.
|
||||||
* @param text The text to draw.
|
* @param text The text to draw.
|
||||||
*/
|
*/
|
||||||
void print(int x, int y, Font *font, Color color, TextAlign align, const char *text);
|
void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text);
|
||||||
|
|
||||||
/** Print `text` with the top left at [x,y] with `font`.
|
/** Print `text` with the top left at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -231,7 +245,7 @@ class DisplayBuffer {
|
||||||
* @param color The color to draw the text with.
|
* @param color The color to draw the text with.
|
||||||
* @param text The text to draw.
|
* @param text The text to draw.
|
||||||
*/
|
*/
|
||||||
void print(int x, int y, Font *font, Color color, const char *text);
|
void print(int x, int y, BaseFont *font, Color color, const char *text);
|
||||||
|
|
||||||
/** Print `text` with the anchor point at [x,y] with `font`.
|
/** Print `text` with the anchor point at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -241,7 +255,7 @@ class DisplayBuffer {
|
||||||
* @param align The alignment of the text.
|
* @param align The alignment of the text.
|
||||||
* @param text The text to draw.
|
* @param text The text to draw.
|
||||||
*/
|
*/
|
||||||
void print(int x, int y, Font *font, TextAlign align, const char *text);
|
void print(int x, int y, BaseFont *font, TextAlign align, const char *text);
|
||||||
|
|
||||||
/** Print `text` with the top left at [x,y] with `font`.
|
/** Print `text` with the top left at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -250,7 +264,7 @@ class DisplayBuffer {
|
||||||
* @param font The font to draw the text with.
|
* @param font The font to draw the text with.
|
||||||
* @param text The text to draw.
|
* @param text The text to draw.
|
||||||
*/
|
*/
|
||||||
void print(int x, int y, Font *font, const char *text);
|
void print(int x, int y, BaseFont *font, const char *text);
|
||||||
|
|
||||||
/** Evaluate the printf-format `format` and print the result with the anchor point at [x,y] with `font`.
|
/** Evaluate the printf-format `format` and print the result with the anchor point at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -262,7 +276,7 @@ class DisplayBuffer {
|
||||||
* @param format The format to use.
|
* @param format The format to use.
|
||||||
* @param ... The arguments to use for the text formatting.
|
* @param ... The arguments to use for the text formatting.
|
||||||
*/
|
*/
|
||||||
void printf(int x, int y, Font *font, Color color, TextAlign align, const char *format, ...)
|
void printf(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ...)
|
||||||
__attribute__((format(printf, 7, 8)));
|
__attribute__((format(printf, 7, 8)));
|
||||||
|
|
||||||
/** Evaluate the printf-format `format` and print the result with the top left at [x,y] with `font`.
|
/** Evaluate the printf-format `format` and print the result with the top left at [x,y] with `font`.
|
||||||
|
@ -274,7 +288,7 @@ class DisplayBuffer {
|
||||||
* @param format The format to use.
|
* @param format The format to use.
|
||||||
* @param ... The arguments to use for the text formatting.
|
* @param ... The arguments to use for the text formatting.
|
||||||
*/
|
*/
|
||||||
void printf(int x, int y, Font *font, Color color, const char *format, ...) __attribute__((format(printf, 6, 7)));
|
void printf(int x, int y, BaseFont *font, Color color, const char *format, ...) __attribute__((format(printf, 6, 7)));
|
||||||
|
|
||||||
/** Evaluate the printf-format `format` and print the result with the anchor point at [x,y] with `font`.
|
/** Evaluate the printf-format `format` and print the result with the anchor point at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -285,7 +299,8 @@ class DisplayBuffer {
|
||||||
* @param format The format to use.
|
* @param format The format to use.
|
||||||
* @param ... The arguments to use for the text formatting.
|
* @param ... The arguments to use for the text formatting.
|
||||||
*/
|
*/
|
||||||
void printf(int x, int y, Font *font, TextAlign align, const char *format, ...) __attribute__((format(printf, 6, 7)));
|
void printf(int x, int y, BaseFont *font, TextAlign align, const char *format, ...)
|
||||||
|
__attribute__((format(printf, 6, 7)));
|
||||||
|
|
||||||
/** Evaluate the printf-format `format` and print the result with the top left at [x,y] with `font`.
|
/** Evaluate the printf-format `format` and print the result with the top left at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -295,7 +310,7 @@ class DisplayBuffer {
|
||||||
* @param format The format to use.
|
* @param format The format to use.
|
||||||
* @param ... The arguments to use for the text formatting.
|
* @param ... The arguments to use for the text formatting.
|
||||||
*/
|
*/
|
||||||
void printf(int x, int y, Font *font, const char *format, ...) __attribute__((format(printf, 5, 6)));
|
void printf(int x, int y, BaseFont *font, const char *format, ...) __attribute__((format(printf, 5, 6)));
|
||||||
|
|
||||||
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
@ -307,7 +322,7 @@ class DisplayBuffer {
|
||||||
* @param format The strftime format to use.
|
* @param format The strftime format to use.
|
||||||
* @param time The time to format.
|
* @param time The time to format.
|
||||||
*/
|
*/
|
||||||
void strftime(int x, int y, Font *font, Color color, TextAlign align, const char *format, ESPTime time)
|
void strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time)
|
||||||
__attribute__((format(strftime, 7, 0)));
|
__attribute__((format(strftime, 7, 0)));
|
||||||
|
|
||||||
/** Evaluate the strftime-format `format` and print the result with the top left at [x,y] with `font`.
|
/** Evaluate the strftime-format `format` and print the result with the top left at [x,y] with `font`.
|
||||||
|
@ -319,7 +334,7 @@ class DisplayBuffer {
|
||||||
* @param format The strftime format to use.
|
* @param format The strftime format to use.
|
||||||
* @param time The time to format.
|
* @param time The time to format.
|
||||||
*/
|
*/
|
||||||
void strftime(int x, int y, Font *font, Color color, const char *format, ESPTime time)
|
void strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time)
|
||||||
__attribute__((format(strftime, 6, 0)));
|
__attribute__((format(strftime, 6, 0)));
|
||||||
|
|
||||||
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
||||||
|
@ -331,7 +346,7 @@ class DisplayBuffer {
|
||||||
* @param format The strftime format to use.
|
* @param format The strftime format to use.
|
||||||
* @param time The time to format.
|
* @param time The time to format.
|
||||||
*/
|
*/
|
||||||
void strftime(int x, int y, Font *font, TextAlign align, const char *format, ESPTime time)
|
void strftime(int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time)
|
||||||
__attribute__((format(strftime, 6, 0)));
|
__attribute__((format(strftime, 6, 0)));
|
||||||
|
|
||||||
/** Evaluate the strftime-format `format` and print the result with the top left at [x,y] with `font`.
|
/** Evaluate the strftime-format `format` and print the result with the top left at [x,y] with `font`.
|
||||||
|
@ -342,7 +357,7 @@ class DisplayBuffer {
|
||||||
* @param format The strftime format to use.
|
* @param format The strftime format to use.
|
||||||
* @param time The time to format.
|
* @param time The time to format.
|
||||||
*/
|
*/
|
||||||
void strftime(int x, int y, Font *font, const char *format, ESPTime time) __attribute__((format(strftime, 5, 0)));
|
void strftime(int x, int y, BaseFont *font, const char *format, ESPTime time) __attribute__((format(strftime, 5, 0)));
|
||||||
|
|
||||||
/** Draw the `image` with the top-left corner at [x,y] to the screen.
|
/** Draw the `image` with the top-left corner at [x,y] to the screen.
|
||||||
*
|
*
|
||||||
|
@ -412,7 +427,7 @@ class DisplayBuffer {
|
||||||
* @param width A pointer to store the returned text width in.
|
* @param width A pointer to store the returned text width in.
|
||||||
* @param height A pointer to store the returned text height in.
|
* @param height A pointer to store the returned text height in.
|
||||||
*/
|
*/
|
||||||
void get_text_bounds(int x, int y, const char *text, Font *font, TextAlign align, int *x1, int *y1, int *width,
|
void get_text_bounds(int x, int y, const char *text, BaseFont *font, TextAlign align, int *x1, int *y1, int *width,
|
||||||
int *height);
|
int *height);
|
||||||
|
|
||||||
/// Internal method to set the display writer lambda.
|
/// Internal method to set the display writer lambda.
|
||||||
|
@ -487,7 +502,7 @@ class DisplayBuffer {
|
||||||
bool is_clipping() const { return !this->clipping_rectangle_.empty(); }
|
bool is_clipping() const { return !this->clipping_rectangle_.empty(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void vprintf_(int x, int y, Font *font, Color color, TextAlign align, const char *format, va_list arg);
|
void vprintf_(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, va_list arg);
|
||||||
|
|
||||||
virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
|
virtual void draw_absolute_pixel_internal(int x, int y, Color color) = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
static const char *const TAG = "display";
|
||||||
|
|
||||||
bool Glyph::get_pixel(int x, int y) const {
|
bool Glyph::get_pixel(int x, int y) const {
|
||||||
const int x_data = x - this->glyph_data_->offset_x;
|
const int x_data = x - this->glyph_data_->offset_x;
|
||||||
const int y_data = y - this->glyph_data_->offset_y;
|
const int y_data = y - this->glyph_data_->offset_y;
|
||||||
|
@ -14,6 +17,20 @@ bool Glyph::get_pixel(int x, int y) const {
|
||||||
const uint32_t pos = x_data + y_data * width_8;
|
const uint32_t pos = x_data + y_data * width_8;
|
||||||
return progmem_read_byte(this->glyph_data_->data + (pos / 8u)) & (0x80 >> (pos % 8u));
|
return progmem_read_byte(this->glyph_data_->data + (pos / 8u)) & (0x80 >> (pos % 8u));
|
||||||
}
|
}
|
||||||
|
void Glyph::draw(int x_at, int y_start, DisplayBuffer *display, Color color) const {
|
||||||
|
int scan_x1, scan_y1, scan_width, scan_height;
|
||||||
|
this->scan_area(&scan_x1, &scan_y1, &scan_width, &scan_height);
|
||||||
|
|
||||||
|
const int glyph_x_max = scan_x1 + scan_width;
|
||||||
|
const int glyph_y_max = scan_y1 + scan_height;
|
||||||
|
for (int glyph_x = scan_x1; glyph_x < glyph_x_max; glyph_x++) {
|
||||||
|
for (int glyph_y = scan_y1; glyph_y < glyph_y_max; glyph_y++) {
|
||||||
|
if (this->get_pixel(glyph_x, glyph_y)) {
|
||||||
|
display->draw_pixel_at(glyph_x + x_at, glyph_y + y_start, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const char *Glyph::get_char() const { return this->glyph_data_->a_char; }
|
const char *Glyph::get_char() const { return this->glyph_data_->a_char; }
|
||||||
bool Glyph::compare_to(const char *str) const {
|
bool Glyph::compare_to(const char *str) const {
|
||||||
// 1 -> this->char_
|
// 1 -> this->char_
|
||||||
|
@ -47,6 +64,12 @@ void Glyph::scan_area(int *x1, int *y1, int *width, int *height) const {
|
||||||
*width = this->glyph_data_->width;
|
*width = this->glyph_data_->width;
|
||||||
*height = this->glyph_data_->height;
|
*height = this->glyph_data_->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Font::Font(const GlyphData *data, int data_nr, int baseline, int height) : baseline_(baseline), height_(height) {
|
||||||
|
glyphs_.reserve(data_nr);
|
||||||
|
for (int i = 0; i < data_nr; ++i)
|
||||||
|
glyphs_.emplace_back(&data[i]);
|
||||||
|
}
|
||||||
int Font::match_next_glyph(const char *str, int *match_length) {
|
int Font::match_next_glyph(const char *str, int *match_length) {
|
||||||
int lo = 0;
|
int lo = 0;
|
||||||
int hi = this->glyphs_.size() - 1;
|
int hi = this->glyphs_.size() - 1;
|
||||||
|
@ -95,10 +118,31 @@ void Font::measure(const char *str, int *width, int *x_offset, int *baseline, in
|
||||||
*x_offset = min_x;
|
*x_offset = min_x;
|
||||||
*width = x - min_x;
|
*width = x - min_x;
|
||||||
}
|
}
|
||||||
Font::Font(const GlyphData *data, int data_nr, int baseline, int height) : baseline_(baseline), height_(height) {
|
void Font::print(int x_start, int y_start, DisplayBuffer *display, Color color, const char *text) {
|
||||||
glyphs_.reserve(data_nr);
|
int i = 0;
|
||||||
for (int i = 0; i < data_nr; ++i)
|
int x_at = x_start;
|
||||||
glyphs_.emplace_back(&data[i]);
|
while (text[i] != '\0') {
|
||||||
|
int match_length;
|
||||||
|
int glyph_n = this->match_next_glyph(text + i, &match_length);
|
||||||
|
if (glyph_n < 0) {
|
||||||
|
// Unknown char, skip
|
||||||
|
ESP_LOGW(TAG, "Encountered character without representation in font: '%c'", text[i]);
|
||||||
|
if (!this->get_glyphs().empty()) {
|
||||||
|
uint8_t glyph_width = this->get_glyphs()[0].glyph_data_->width;
|
||||||
|
display->filled_rectangle(x_at, y_start, glyph_width, this->height_, color);
|
||||||
|
x_at += glyph_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Glyph &glyph = this->get_glyphs()[glyph_n];
|
||||||
|
glyph.draw(x_at, y_start, display, color);
|
||||||
|
x_at += glyph.glyph_data_->width + glyph.glyph_data_->offset_x;
|
||||||
|
|
||||||
|
i += match_length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esphome/core/datatypes.h"
|
#include "esphome/core/datatypes.h"
|
||||||
|
#include "display_buffer.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
@ -23,6 +24,8 @@ class Glyph {
|
||||||
|
|
||||||
bool get_pixel(int x, int y) const;
|
bool get_pixel(int x, int y) const;
|
||||||
|
|
||||||
|
void draw(int x, int y, DisplayBuffer *display, Color color) const;
|
||||||
|
|
||||||
const char *get_char() const;
|
const char *get_char() const;
|
||||||
|
|
||||||
bool compare_to(const char *str) const;
|
bool compare_to(const char *str) const;
|
||||||
|
@ -33,12 +36,11 @@ class Glyph {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend Font;
|
friend Font;
|
||||||
friend DisplayBuffer;
|
|
||||||
|
|
||||||
const GlyphData *glyph_data_;
|
const GlyphData *glyph_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Font {
|
class Font : public BaseFont {
|
||||||
public:
|
public:
|
||||||
/** Construct the font with the given glyphs.
|
/** Construct the font with the given glyphs.
|
||||||
*
|
*
|
||||||
|
@ -50,7 +52,8 @@ class Font {
|
||||||
|
|
||||||
int match_next_glyph(const char *str, int *match_length);
|
int match_next_glyph(const char *str, int *match_length);
|
||||||
|
|
||||||
void measure(const char *str, int *width, int *x_offset, int *baseline, int *height);
|
void print(int x_start, int y_start, DisplayBuffer *display, Color color, const char *text) override;
|
||||||
|
void measure(const char *str, int *width, int *x_offset, int *baseline, int *height) override;
|
||||||
inline int get_baseline() { return this->baseline_; }
|
inline int get_baseline() { return this->baseline_; }
|
||||||
inline int get_height() { return this->height_; }
|
inline int get_height() { return this->height_; }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
#include "display_buffer.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "esphome/core/color.h"
|
#include "esphome/core/color.h"
|
||||||
|
#include "display_buffer.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace display {
|
namespace display {
|
||||||
|
@ -30,20 +31,6 @@ inline int image_type_to_bpp(ImageType type) {
|
||||||
|
|
||||||
inline int image_type_to_width_stride(int width, ImageType type) { return (width * image_type_to_bpp(type) + 7u) / 8u; }
|
inline int image_type_to_width_stride(int width, ImageType type) { return (width * image_type_to_bpp(type) + 7u) / 8u; }
|
||||||
|
|
||||||
/// Turn the pixel OFF.
|
|
||||||
extern const Color COLOR_OFF;
|
|
||||||
/// Turn the pixel ON.
|
|
||||||
extern const Color COLOR_ON;
|
|
||||||
|
|
||||||
class DisplayBuffer;
|
|
||||||
|
|
||||||
class BaseImage {
|
|
||||||
public:
|
|
||||||
virtual void draw(int x, int y, DisplayBuffer *display, Color color_on, Color color_off) = 0;
|
|
||||||
virtual int get_width() const = 0;
|
|
||||||
virtual int get_height() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Image : public BaseImage {
|
class Image : public BaseImage {
|
||||||
public:
|
public:
|
||||||
Image(const uint8_t *data_start, int width, int height, ImageType type);
|
Image(const uint8_t *data_start, int width, int height, ImageType type);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "esphome/components/display/display_buffer.h"
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
#include "esphome/components/display/font.h"
|
||||||
#include "esphome/core/color.h"
|
#include "esphome/core/color.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
Loading…
Reference in a new issue