2024-06-25 10:17:14 +00:00
|
|
|
|
|
2024-08-29 08:46:54 +00:00
|
|
|
|
#include "lvgl_font.h"
|
2024-09-17 08:32:06 +00:00
|
|
|
|
#include "font_t.h"
|
2024-06-25 10:17:14 +00:00
|
|
|
|
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t Font_utf8_to_unicode(uint8_t *pInput, uint32_t *unicode_letter) {
|
|
|
|
|
uint8_t outputSize = 0;
|
|
|
|
|
uint8_t * tmp= ( uint8_t *) unicode_letter;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字)
|
|
|
|
|
{
|
|
|
|
|
*tmp = *pInput;
|
|
|
|
|
tmp++;
|
|
|
|
|
*tmp = 0; //小端法表示,在高地址填补0
|
|
|
|
|
outputSize = 1;
|
|
|
|
|
} else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字符
|
|
|
|
|
{
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t high = *pInput;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
pInput++;
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t low = *pInput;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
|
|
|
|
|
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字符
|
|
|
|
|
{
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t high = *pInput;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
pInput++;
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t middle = *pInput;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
pInput++;
|
2024-07-05 15:09:54 +00:00
|
|
|
|
uint8_t low = *pInput;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80))
|
|
|
|
|
return 0;
|
2024-07-05 15:09:54 +00:00
|
|
|
|
*tmp = (middle << 6) | (low & 0x3F);
|
2024-06-25 10:17:14 +00:00
|
|
|
|
tmp++;
|
2024-07-05 15:09:54 +00:00
|
|
|
|
*tmp = (high << 4) | ((middle >> 2) & 0x0F);
|
2024-06-25 10:17:14 +00:00
|
|
|
|
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
|
2024-06-25 14:09:23 +00:00
|
|
|
|
uint16_t fd_buf[fd->dev_w / 2];
|
2024-06-25 10:17:14 +00:00
|
|
|
|
#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);
|
2024-06-26 07:54:30 +00:00
|
|
|
|
pos_y++;
|
|
|
|
|
index = 0;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2024-06-26 07:54:30 +00:00
|
|
|
|
|
2024-06-25 10:17:14 +00:00
|
|
|
|
} //避免大字体,大缓存 ,单行即刻刷入
|
|
|
|
|
|
|
|
|
|
col_bit += col_bit_row_ofs;
|
|
|
|
|
map_p += (col_bit >> 3);
|
|
|
|
|
col_bit = col_bit & 0x7;
|
|
|
|
|
}
|
|
|
|
|
#ifndef LINE_FAST_SHOW
|
2024-06-26 07:54:30 +00:00
|
|
|
|
fd->x = pos_x;
|
|
|
|
|
fd->y = pos_y;
|
|
|
|
|
fd->w = box_w;
|
|
|
|
|
fd->h = box_h;
|
2024-06-25 10:17:14 +00:00
|
|
|
|
fd->show(fd, fd_buf, box_w * box_h);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 15:09:54 +00:00
|
|
|
|
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) {
|
2024-06-25 10:17:14 +00:00
|
|
|
|
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;
|
2024-08-29 08:46:54 +00:00
|
|
|
|
}
|