HW_Lib/lib/font/font.cpp

194 lines
5.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}