#include "lvgl_font.h" #include "font_t.h" uint8_t Font_utf8_to_unicode(uint8_t *pInput, uint32_t *unicode_letter) { uint8_t outputSize = 0; uint8_t * tmp= ( uint8_t *) unicode_letter; if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字) { *tmp = *pInput; tmp++; *tmp = 0; //小端法表示,在高地址填补0 outputSize = 1; } else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符 { uint8_t high = *pInput; pInput++; uint8_t low = *pInput; if ((low & 0xC0) != 0x80) //检查是否为合法的UTF8字符表示 return 0; //如果不是则报错 *tmp = (high << 6) + (low & 0x3F); tmp++; *tmp = (high >> 2) & 0x07; outputSize = 2; } else if (((*pInput) & 0xF0) == 0xE0) //处理三字节UTF8字符 { uint8_t high = *pInput; pInput++; uint8_t middle = *pInput; pInput++; uint8_t low = *pInput; if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80)) return 0; *tmp = (middle << 6) | (low & 0x3F); tmp++; *tmp = (high << 4) | ((middle >> 2) & 0x0F); outputSize = 3; } else //对于其他字节数的UTF8字符不进行处理 { return 0; } return outputSize; } void draw_letter_normal(Font_f_t *fd, uint16_t pos_x, uint16_t pos_y, lv_font_glyph_dsc_t *g, const uint8_t *map_p) { uint32_t bitmask_init; uint32_t bitmask; uint32_t bpp = g->bpp; if (bpp == 3) bpp = 4; switch (bpp) { case 1: bitmask_init = 0x80; break; case 2: bitmask_init = 0xC0; break; case 4: bitmask_init = 0xF0; break; case 8: bitmask_init = 0xFF; break; default: return; /*Invalid bpp. Can't render the letter*/ } int32_t col, row; int32_t box_w = g->box_w; int32_t box_h = g->box_h; int32_t width_bit = box_w * bpp; /*Letter width in bits*/ /* Calculate the col/row start/end on the map*/ int32_t col_start = 0; int32_t col_end = box_w; int32_t row_start = 0; int32_t row_end = box_h; /*Move on the map too*/ uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp); map_p += bit_ofs >> 3; uint8_t letter_px; uint32_t col_bit; col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */ // uint32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : box_w * box_h; // unsigned short mask_buf[LV_HOR_RES_MAX / 2]; #if PIX_COLOR_SIZE == 1 uint8_t fd_buf[fd->dev_w / 2]; #endif #if PIX_COLOR_SIZE == 16 uint16_t fd_buf[fd->dev_w / 2]; #endif uint32_t col_bit_max = 8 - bpp; uint32_t col_bit_row_ofs = (box_w + col_start - col_end) * bpp; uint16_t index = 0; for (row = row_start; row < row_end; row++) { bitmask = bitmask_init >> col_bit; for (col = col_start; col < col_end; col++) { /*Load the pixel's opacity into the mask*/ letter_px = (*map_p & bitmask) >> (col_bit_max - col_bit); #if PIX_COLOR_SIZE == 1 if (letter_px) { fd_buf[index / 8] |= (1 << (index % 8)); } else { fd_buf[index / 8] &= ~(1 << (index % 8)); } index++; #endif #if PIX_COLOR_SIZE == 16 if (letter_px) { fd_buf[index] = fd->pixcolor; } else { fd_buf[index] = fd->backgroundcolor; } index++; #endif /*Go to the next column*/ if (col_bit < col_bit_max) { col_bit += bpp; bitmask >>= bpp; } else { col_bit = 0; bitmask = bitmask_init; map_p++; } } { // LCD_fill_fast(pos_x, pos_y, box_w, 1, (uint8_t *)mask_buf, box_w); #ifdef LINE_FAST_SHOW fd->x = pos_x; fd->y = pos_y; fd->w = box_w; fd->h = 1; fd->show(fd, fd_buf, box_w); pos_y++; index = 0; #endif } //避免大字体,大缓存 ,单行即刻刷入 col_bit += col_bit_row_ofs; map_p += (col_bit >> 3); col_bit = col_bit & 0x7; } #ifndef LINE_FAST_SHOW fd->x = pos_x; fd->y = pos_y; fd->w = box_w; fd->h = box_h; fd->show(fd, fd_buf, box_w * box_h); #endif } uint8_t Font_draw_letter(const lv_font_t *font, Font_f_t *fd, uint32_t letter, int16_t pos_x, int16_t pos_y) { const uint8_t *map_p; lv_font_glyph_dsc_t g; if (!font->get_glyph_dsc(font, &g, letter, '\0')) //获取字体 信息 return 0; if (letter == ' ') // lvgl 空格没有实际数据 直接跳过 return g.box_w; /* Don't draw anything if the character is empty. E.g. space */ if ((g.box_h == 0) || (g.box_w == 0)) return 0; map_p = font->get_glyph_bitmap(font, letter); //获取字体 实际数据 if (map_p == NULL) return 0; pos_x += g.ofs_x; //偏移修正 pos_y += font->line_height - g.box_h - g.ofs_y; if (pos_x < 1) //有的时候会为负 pos_x = 1; if (pos_y < 1) //有的时候会为负 pos_y = 1; draw_letter_normal(fd, pos_x, pos_y, &g, map_p); return g.box_w; }