10 static const char *
const TAG =
"font";
18 for (uint32_t i = 0;; i++) {
32 for (uint32_t i = 0;; i++) {
48 Font::Font(
const GlyphData *data,
int data_nr,
int baseline,
int height, uint8_t bpp)
49 : baseline_(baseline), height_(height), bpp_(bpp) {
50 glyphs_.reserve(data_nr);
51 for (
int i = 0; i < data_nr; ++i)
52 glyphs_.emplace_back(&data[i]);
54 int Font::match_next_glyph(
const uint8_t *str,
int *
match_length) {
56 int hi = this->glyphs_.size() - 1;
58 int mid = (lo + hi + 1) / 2;
65 *match_length = this->glyphs_[lo].match_length(str);
66 if (*match_length <= 0)
71 void Font::measure(
const char *str,
int *width,
int *x_offset,
int *baseline,
int *height) {
72 *baseline = this->baseline_;
73 *height = this->height_;
76 bool has_char =
false;
78 while (str[i] !=
'\0') {
80 int glyph_n = this->match_next_glyph((
const uint8_t *) str + i, &match_length);
83 if (!this->get_glyphs().empty())
84 x += this->get_glyphs()[0].glyph_data_->width;
89 const Glyph &glyph = this->glyphs_[glyph_n];
106 int scan_x1, scan_y1, scan_width, scan_height;
107 while (text[i] !=
'\0') {
109 int glyph_n = this->match_next_glyph((
const uint8_t *) text + i, &match_length);
112 ESP_LOGW(TAG,
"Encountered character without representation in font: '%c'", text[i]);
113 if (!this->get_glyphs().empty()) {
114 uint8_t glyph_width = this->get_glyphs()[0].glyph_data_->width;
115 display->
filled_rectangle(x_at, y_start, glyph_width, this->height_, color);
123 const Glyph &glyph = this->get_glyphs()[glyph_n];
124 glyph.
scan_area(&scan_x1, &scan_y1, &scan_width, &scan_height);
127 const int max_x = x_at + scan_x1 + scan_width;
128 const int max_y = y_start + scan_y1 + scan_height;
131 uint8_t pixel_data = 0;
132 uint8_t bpp_max = (1 << this->bpp_) - 1;
133 auto diff_r = (float) color.
r - (
float) background.
r;
134 auto diff_g = (float) color.
g - (
float) background.
g;
135 auto diff_b = (float) color.
b - (
float) background.
b;
136 auto diff_w = (float) color.
w - (
float) background.
w;
137 auto b_r = (float) background.
r;
138 auto b_g = (
float) background.
g;
139 auto b_b = (float) background.
b;
140 auto b_w = (
float) background.
w;
141 for (
int glyph_y = y_start + scan_y1; glyph_y != max_y; glyph_y++) {
142 for (
int glyph_x = x_at + scan_x1; glyph_x != max_x; glyph_x++) {
144 for (
int bit_num = 0; bit_num != this->bpp_; bit_num++) {
150 if ((pixel_data & bitmask) != 0)
154 if (pixel == bpp_max) {
156 }
else if (pixel != 0) {
157 auto on = (float) pixel / (
float) bpp_max;
158 auto blended =
Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g),
159 (uint8_t) (diff_b * on + b_b), (uint8_t) (diff_w * on + b_w));
const uint8_t * get_char() const
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...
uint8_t progmem_read_byte(const uint8_t *addr)
void draw_pixel_at(int x, int y)
Set a single pixel at the specified coordinates to default color.
Implementation of SPI Controller mode.
int match_length(const uint8_t *str) const
bool compare_to(const uint8_t *str) const
const GlyphData * glyph_data_
void scan_area(int *x1, int *y1, int *width, int *height) const