8static const char *
const TAG =
"font";
11static const uint8_t OPA4_TABLE[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
13static const uint8_t OPA2_TABLE[4] = {0, 85, 170, 255};
16 const auto *font = dsc->resolved_font;
17 auto *
const fe = (
Font *) font->dsc;
19 const auto *gd = fe->get_glyph_data_(dsc->gid.index);
24 const uint8_t *bitmap_in = gd->data;
25 uint8_t *bitmap_out_tmp = draw_buf->data;
28 uint32_t stride = lv_draw_buf_width_to_stride(gd->width, LV_COLOR_FORMAT_A8);
30 switch (fe->get_bpp()) {
34 for (
y = 0;
y != gd->height;
y++) {
35 for (
x = 0;
x != gd->width;
x++) {
40 bitmap_out_tmp[
x] =
byte & mask ? 255 : 0;
43 bitmap_out_tmp += stride;
48 for (
y = 0;
y != gd->height;
y++) {
49 for (
x = 0;
x != gd->width;
x++, i++) {
52 bitmap_out_tmp[
x] = OPA2_TABLE[(*bitmap_in) >> 6];
55 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 4) & 0x3];
58 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 2) & 0x3];
61 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 0) & 0x3];
65 bitmap_out_tmp += stride;
70 for (
y = 0;
y != gd->height;
y++) {
71 for (
x = 0;
x != gd->width;
x++, i++) {
74 bitmap_out_tmp[
x] = OPA4_TABLE[(*bitmap_in) >> 4];
76 bitmap_out_tmp[
x] = OPA4_TABLE[(*bitmap_in) & 0xF];
80 bitmap_out_tmp += stride;
85 memcpy(bitmap_out_tmp, bitmap_in, gd->width * gd->height);
88 ESP_LOGD(TAG,
"Unknown bpp: %d", fe->get_bpp());
95 auto *fe = (
Font *) font->dsc;
96 const auto *gd = fe->get_glyph_data_(unicode_letter);
100 dsc->adv_w = gd->advance;
101 dsc->ofs_x = gd->offset_x;
102 dsc->ofs_y = fe->height_ - gd->height - gd->offset_y - fe->lv_font_.base_line;
103 dsc->box_w = gd->width;
104 dsc->box_h = gd->height;
105 dsc->is_placeholder = 0;
106 dsc->format = (lv_font_glyph_format_t) fe->get_bpp();
107 dsc->gid.index = unicode_letter;
114 auto *glyph = this->
find_glyph(unicode_letter);
115 if (glyph ==
nullptr) {
134static uint32_t extract_unicode_codepoint(
const char *utf8_str,
size_t *
length) {
136 const uint8_t *current =
reinterpret_cast<const uint8_t *
>(utf8_str);
138 uint8_t c1 = *current++;
153 else if ((c1 & 0xE0) == 0xC0) {
154 uint8_t c2 = *current++;
157 if ((c2 & 0xC0) != 0x80) {
162 code_point = (c1 & 0x1F) << 6;
163 code_point |= (c2 & 0x3F);
166 if (code_point <= 0x7F) {
172 else if ((c1 & 0xF0) == 0xE0) {
173 uint8_t c2 = *current++;
174 uint8_t c3 = *current++;
177 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
182 code_point = (c1 & 0x0F) << 12;
183 code_point |= (c2 & 0x3F) << 6;
184 code_point |= (c3 & 0x3F);
188 if (code_point <= 0x7FF || (code_point >= 0xD800 && code_point <= 0xDFFF)) {
194 else if ((c1 & 0xF8) == 0xF0) {
195 uint8_t c2 = *current++;
196 uint8_t c3 = *current++;
197 uint8_t c4 = *current++;
200 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80) || ((c4 & 0xC0) != 0x80)) {
205 code_point = (c1 & 0x07) << 18;
206 code_point |= (c2 & 0x3F) << 12;
207 code_point |= (c3 & 0x3F) << 6;
208 code_point |= (c4 & 0x3F);
212 if (code_point <= 0xFFFF || code_point > 0x10FFFF) {
222 *
length = current -
reinterpret_cast<const uint8_t *
>(utf8_str);
226Font::Font(
const Glyph *data,
int data_nr,
int baseline,
int height,
int descender,
int xheight,
int capheight,
231 descender_(descender),
232 linegap_(height - baseline - descender),
234 capheight_(capheight),
242 this->
lv_font_.subpx = LV_FONT_SUBPX_NONE;
243 this->
lv_font_.underline_position = -1;
244 this->
lv_font_.underline_thickness = 1;
250 int hi = this->
glyphs_.size() - 1;
252 int mid = (lo + hi + 1) / 2;
253 if (this->
glyphs_[mid].is_less_or_equal(codepoint)) {
259 auto *result = &this->
glyphs_[lo];
260 if (result->code_point == codepoint)
266void Font::measure(
const char *str,
int *width,
int *x_offset,
int *baseline,
int *height) {
270 bool has_char =
false;
274 auto code_point = extract_unicode_codepoint(str, &
length);
279 if (glyph ==
nullptr) {
287 min_x = glyph->offset_x;
289 min_x = std::min(min_x,
x + glyph->offset_x);
303 auto code_point = extract_unicode_codepoint(text, &
length);
308 if (glyph ==
nullptr) {
310 ESP_LOGW(TAG,
"Codepoint 0x%08" PRIx32
" not found in font", code_point);
312 uint8_t glyph_width = this->
glyphs_[0].advance;
319 const uint8_t *data = glyph->data;
320 const int max_x = x_at + glyph->offset_x + glyph->width;
321 const int max_y = y_start + glyph->offset_y + glyph->height;
324 uint8_t pixel_data = 0;
325 uint8_t bpp_max = (1 << this->
bpp_) - 1;
326 auto diff_r = (float) color.
r - (
float) background.
r;
327 auto diff_g = (float) color.
g - (
float) background.
g;
328 auto diff_b = (float) color.
b - (
float) background.
b;
329 auto diff_w = (float) color.
w - (
float) background.
w;
330 auto b_r = (float) background.
r;
331 auto b_g = (float) background.
g;
332 auto b_b = (float) background.
b;
333 auto b_w = (float) background.
w;
334 for (
int glyph_y = y_start + glyph->offset_y; glyph_y != max_y; glyph_y++) {
335 for (
int glyph_x = x_at + glyph->offset_x; glyph_x != max_x; glyph_x++) {
337 for (uint8_t bit_num = 0; bit_num != this->
bpp_; bit_num++) {
343 if ((pixel_data & bitmask) != 0)
347 if (pixel == bpp_max) {
349 }
else if (pixel != 0) {
350 auto on = (float) pixel / (
float) bpp_max;
351 auto blended =
Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g),
352 (uint8_t) (diff_b * on + b_b), (uint8_t) (diff_w * on + b_w));
357 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 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)
static const void * get_glyph_bitmap(lv_font_glyph_dsc_t *dsc, lv_draw_buf_t *draw_buf)
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.
uint8_t progmem_read_byte(const uint8_t *addr)