9static const char *
const TAG =
"font";
12static const uint8_t OPA4_TABLE[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
14static const uint8_t OPA2_TABLE[4] = {0, 85, 170, 255};
17 const auto *font = dsc->resolved_font;
18 auto *
const fe = (
Font *) font->dsc;
20 const auto *gd = fe->get_glyph_data_(dsc->gid.index);
25 const uint8_t *bitmap_in = gd->data;
26 uint8_t *bitmap_out_tmp = draw_buf->data;
29 uint32_t stride = lv_draw_buf_width_to_stride(gd->width, LV_COLOR_FORMAT_A8);
31 switch (fe->get_bpp()) {
35 for (
y = 0;
y != gd->height;
y++) {
36 for (
x = 0;
x != gd->width;
x++) {
41 bitmap_out_tmp[
x] =
byte & mask ? 255 : 0;
44 bitmap_out_tmp += stride;
49 for (
y = 0;
y != gd->height;
y++) {
50 for (
x = 0;
x != gd->width;
x++, i++) {
53 bitmap_out_tmp[
x] = OPA2_TABLE[(*bitmap_in) >> 6];
56 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 4) & 0x3];
59 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 2) & 0x3];
62 bitmap_out_tmp[
x] = OPA2_TABLE[((*bitmap_in) >> 0) & 0x3];
66 bitmap_out_tmp += stride;
71 for (
y = 0;
y != gd->height;
y++) {
72 for (
x = 0;
x != gd->width;
x++, i++) {
75 bitmap_out_tmp[
x] = OPA4_TABLE[(*bitmap_in) >> 4];
77 bitmap_out_tmp[
x] = OPA4_TABLE[(*bitmap_in) & 0xF];
81 bitmap_out_tmp += stride;
86 memcpy(bitmap_out_tmp, bitmap_in, gd->width * gd->height);
89 ESP_LOGD(TAG,
"Unknown bpp: %d", fe->get_bpp());
96 auto *fe = (
Font *) font->dsc;
97 const auto *gd = fe->get_glyph_data_(unicode_letter);
101 dsc->adv_w = gd->advance;
102 dsc->ofs_x = gd->offset_x;
103 dsc->ofs_y = fe->height_ - gd->height - gd->offset_y - fe->lv_font_.base_line;
104 dsc->box_w = gd->width;
105 dsc->box_h = gd->height;
106 dsc->is_placeholder = 0;
107 dsc->format = (lv_font_glyph_format_t) fe->get_bpp();
108 dsc->gid.index = unicode_letter;
115 auto *glyph = this->
find_glyph(unicode_letter);
116 if (glyph ==
nullptr) {
135static uint32_t extract_unicode_codepoint(
const char *utf8_str,
size_t *
length) {
137 const uint8_t *current =
reinterpret_cast<const uint8_t *
>(utf8_str);
139 uint8_t c1 = *current++;
154 else if ((c1 & 0xE0) == 0xC0) {
155 uint8_t c2 = *current++;
158 if ((c2 & 0xC0) != 0x80) {
163 code_point = (c1 & 0x1F) << 6;
164 code_point |= (c2 & 0x3F);
167 if (code_point <= 0x7F) {
173 else if ((c1 & 0xF0) == 0xE0) {
174 uint8_t c2 = *current++;
175 uint8_t c3 = *current++;
178 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
183 code_point = (c1 & 0x0F) << 12;
184 code_point |= (c2 & 0x3F) << 6;
185 code_point |= (c3 & 0x3F);
189 if (code_point <= 0x7FF || (code_point >= 0xD800 && code_point <= 0xDFFF)) {
195 else if ((c1 & 0xF8) == 0xF0) {
196 uint8_t c2 = *current++;
197 uint8_t c3 = *current++;
198 uint8_t c4 = *current++;
201 if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80) || ((c4 & 0xC0) != 0x80)) {
206 code_point = (c1 & 0x07) << 18;
207 code_point |= (c2 & 0x3F) << 12;
208 code_point |= (c3 & 0x3F) << 6;
209 code_point |= (c4 & 0x3F);
213 if (code_point <= 0xFFFF || code_point > 0x10FFFF) {
223 *
length = current -
reinterpret_cast<const uint8_t *
>(utf8_str);
227Font::Font(
const Glyph *data,
int data_nr,
int baseline,
int height,
int descender,
int xheight,
int capheight,
232 descender_(descender),
233 linegap_(height - baseline - descender),
235 capheight_(capheight),
243 this->
lv_font_.subpx = LV_FONT_SUBPX_NONE;
244 this->
lv_font_.underline_position = -1;
245 this->
lv_font_.underline_thickness = 1;
251 int hi = this->
glyphs_.size() - 1;
253 int mid = (lo + hi + 1) / 2;
254 if (this->
glyphs_[mid].is_less_or_equal(codepoint)) {
260 auto *result = &this->
glyphs_[lo];
261 if (result->code_point == codepoint)
267void Font::measure(
const char *str,
int *width,
int *x_offset,
int *baseline,
int *height) {
271 bool has_char =
false;
275 auto code_point = extract_unicode_codepoint(str, &
length);
280 if (glyph ==
nullptr) {
288 min_x = glyph->offset_x;
290 min_x = std::min(min_x,
x + glyph->offset_x);
304 auto code_point = extract_unicode_codepoint(text, &
length);
309 if (glyph ==
nullptr) {
311 ESP_LOGW(TAG,
"Codepoint 0x%08" PRIx32
" not found in font", code_point);
313 uint8_t glyph_width = this->
glyphs_[0].advance;
320 const uint8_t *data = glyph->data;
321 const int max_x = x_at + glyph->offset_x + glyph->width;
322 const int max_y = y_start + glyph->offset_y + glyph->height;
325 uint8_t pixel_data = 0;
326 uint8_t bpp_max = (1 << this->
bpp_) - 1;
327 auto diff_r = (float) color.
r - (
float) background.
r;
328 auto diff_g = (float) color.
g - (
float) background.
g;
329 auto diff_b = (float) color.
b - (
float) background.
b;
330 auto diff_w = (float) color.
w - (
float) background.
w;
331 auto b_r = (float) background.
r;
332 auto b_g = (float) background.
g;
333 auto b_b = (float) background.
b;
334 auto b_w = (float) background.
w;
335 for (
int glyph_y = y_start + glyph->offset_y; glyph_y != max_y; glyph_y++) {
336 for (
int glyph_x = x_at + glyph->offset_x; glyph_x != max_x; glyph_x++) {
338 for (uint8_t bit_num = 0; bit_num != this->
bpp_; bit_num++) {
344 if ((pixel_data & bitmask) != 0)
348 if (pixel == bpp_max) {
350 }
else if (pixel != 0) {
351 auto on = (float) pixel / (
float) bpp_max;
352 auto blended =
Color((uint8_t) (diff_r * on + b_r), (uint8_t) (diff_g * on + b_g),
353 (uint8_t) (diff_b * on + b_b), (uint8_t) (diff_w * on + b_w));
358 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.
Providing packet encoding functions for exchanging data with a remote host.
uint8_t progmem_read_byte(const uint8_t *addr)