9static const char *
const TAG =
"font";
13 auto *fe = (
Font *) font->dsc;
14 const auto *gd = fe->get_glyph_data_(unicode_letter);
21bool Font::get_glyph_dsc_cb(
const lv_font_t *font, lv_font_glyph_dsc_t *dsc, uint32_t unicode_letter, uint32_t next) {
22 auto *fe = (
Font *) font->dsc;
23 const auto *gd = fe->get_glyph_data_(unicode_letter);
27 dsc->adv_w = gd->advance;
28 dsc->ofs_x = gd->offset_x;
29 dsc->ofs_y = fe->height_ - gd->height - gd->offset_y - fe->lv_font_.base_line;
30 dsc->box_w = gd->width;
31 dsc->box_h = gd->height;
32 dsc->is_placeholder = 0;
33 dsc->bpp = fe->get_bpp();
40 auto *glyph = this->
find_glyph(unicode_letter);
41 if (glyph ==
nullptr) {
60static uint32_t extract_unicode_codepoint(
const char *utf8_str,
size_t *
length) {
62 const uint8_t *current =
reinterpret_cast<const uint8_t *
>(utf8_str);
63 uint32_t code_point = 0;
64 uint8_t c1 = *current++;
79 else if ((c1 & 0xE0) == 0xC0) {
80 uint8_t c2 = *current++;
83 if ((c2 & 0xC0) != 0x80) {
88 code_point = (c1 & 0x1F) << 6;
89 code_point |= (c2 & 0x3F);
92 if (code_point <= 0x7F) {
98 else if ((c1 & 0xF0) == 0xE0) {
99 uint8_t c2 = *current++;
100 uint8_t c3 = *current++;
103 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
108 code_point = (c1 & 0x0F) << 12;
109 code_point |= (c2 & 0x3F) << 6;
110 code_point |= (c3 & 0x3F);
114 if (code_point <= 0x7FF || (code_point >= 0xD800 && code_point <= 0xDFFF)) {
120 else if ((c1 & 0xF8) == 0xF0) {
121 uint8_t c2 = *current++;
122 uint8_t c3 = *current++;
123 uint8_t c4 = *current++;
126 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80) || ((c4 & 0xC0) != 0x80)) {
131 code_point = (c1 & 0x07) << 18;
132 code_point |= (c2 & 0x3F) << 12;
133 code_point |= (c3 & 0x3F) << 6;
134 code_point |= (c4 & 0x3F);
138 if (code_point <= 0xFFFF || code_point > 0x10FFFF) {
148 *
length = current -
reinterpret_cast<const uint8_t *
>(utf8_str);
152Font::Font(
const Glyph *data,
int data_nr,
int baseline,
int height,
int descender,
int xheight,
int capheight,
157 descender_(descender),
158 linegap_(height - baseline - descender),
160 capheight_(capheight),
168 this->
lv_font_.subpx = LV_FONT_SUBPX_NONE;
169 this->
lv_font_.underline_position = -1;
170 this->
lv_font_.underline_thickness = 1;
176 int hi = this->
glyphs_.size() - 1;
178 int mid = (lo + hi + 1) / 2;
179 if (this->
glyphs_[mid].is_less_or_equal(codepoint)) {
185 auto *result = &this->
glyphs_[lo];
186 if (result->code_point == codepoint)
192void Font::measure(
const char *str,
int *width,
int *x_offset,
int *baseline,
int *height) {
196 bool has_char =
false;
200 auto code_point = extract_unicode_codepoint(str, &
length);
205 if (glyph ==
nullptr) {
213 min_x = glyph->offset_x;
215 min_x = std::min(min_x,
x + glyph->offset_x);
229 auto code_point = extract_unicode_codepoint(text, &
length);
234 if (glyph ==
nullptr) {
236 ESP_LOGW(TAG,
"Codepoint 0x%08" PRIx32
" not found in font", code_point);
238 uint8_t glyph_width = this->
glyphs_[0].advance;
245 const uint8_t *data = glyph->data;
246 const int max_x = x_at + glyph->offset_x + glyph->width;
247 const int max_y = y_start + glyph->offset_y + glyph->height;
250 uint8_t pixel_data = 0;
251 uint8_t bpp_max = (1 << this->
bpp_) - 1;
252 auto diff_r = (float) color.
r - (
float) background.
r;
253 auto diff_g = (float) color.
g - (
float) background.
g;
254 auto diff_b = (float) color.
b - (
float) background.
b;
255 auto diff_w = (float) color.
w - (
float) background.
w;
256 auto b_r = (float) background.
r;
257 auto b_g = (float) background.
g;
258 auto b_b = (float) background.
b;
259 auto b_w = (float) background.
w;
260 for (
int glyph_y = y_start + glyph->offset_y; glyph_y != max_y; glyph_y++) {
261 for (
int glyph_x = x_at + glyph->offset_x; glyph_x != max_x; glyph_x++) {
263 for (uint8_t bit_num = 0; bit_num != this->
bpp_; bit_num++) {
269 if ((pixel_data & bitmask) != 0)
273 if (pixel == bpp_max) {
275 }
else if (pixel != 0) {
276 auto on = (float) pixel / (
float) bpp_max;
277 auto blended =
Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g),
278 (uint8_t) (diff_b * on + b_b), (uint8_t) (diff_w * on + b_w));
283 x_at += glyph->advance;
Lightweight read-only view over a const array stored in RODATA (will typically be in flash memory) Av...
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+...
void draw_pixel_at(int x, int y)
Set a single pixel at the specified coordinates to default color.
void measure(const char *str, int *width, int *x_offset, int *baseline, int *height) override
const Glyph * find_glyph(uint32_t codepoint) const
void print(int x_start, int y_start, display::Display *display, Color color, const char *text, Color background) override
static const uint8_t * get_glyph_bitmap(const lv_font_t *font, uint32_t unicode_letter)
static bool get_glyph_dsc_cb(const lv_font_t *font, lv_font_glyph_dsc_t *dsc, uint32_t unicode_letter, uint32_t next)
const Glyph * get_glyph_data_(uint32_t unicode_letter)
ConstVector< Glyph > glyphs_
Font(const Glyph *data, int data_nr, int baseline, int height, int descender, int xheight, int capheight, uint8_t bpp=1)
Construct the font with the given glyphs.
Providing packet encoding functions for exchanging data with a remote host.
uint8_t progmem_read_byte(const uint8_t *addr)