| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include "lvgl.h" |
| |
| |
| typedef struct{ |
| uint16_t min; |
| uint16_t max; |
| uint8_t bpp; |
| uint8_t reserved[3]; |
| }x_header_t; |
| typedef struct{ |
| uint32_t pos; |
| }x_table_t; |
| typedef struct{ |
| uint8_t adv_w; |
| uint8_t box_w; |
| uint8_t box_h; |
| int8_t ofs_x; |
| int8_t ofs_y; |
| uint8_t r; |
| }glyph_dsc_t; |
| |
| |
| static x_header_t __g_xbf_hd = { |
| .min = 0x0020, |
| .max = 0x9fa0, |
| .bpp = 4, |
| }; |
| |
| |
| |
| char *myFontBuf; |
| |
| static uint8_t *__user_font_getdata(int offset, int size){ |
| |
| |
| return myFontBuf + offset; |
| } |
| |
| |
| static const uint8_t opa4_table[16] = { 0, 17, 34, 51, |
| 68, 85, 102, 119, |
| 136, 153, 170, 187, |
| 204, 221, 238, 255 |
| }; |
| |
| static const uint8_t opa2_table[4] = { 0, 85, 170, 255 }; |
| |
| |
| static const void * __user_font_get_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) |
| { |
| uint32_t unicode_letter = g_dsc->gid.index; |
| uint8_t * bitmap_out = draw_buf->data; |
| const lv_font_t *font = g_dsc->resolved_font; |
| lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc; |
| |
| if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min) { |
| return NULL; |
| } |
| |
| uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4; |
| uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4); |
| if (p_pos[0] != 0) { |
| uint32_t pos = p_pos[0]; |
| glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(pos, sizeof(glyph_dsc_t)); |
| glyph_dsc_t gdscPoint = { 0 }; |
| memcpy(&gdscPoint, gdsc, sizeof(glyph_dsc_t)); |
| gdsc = &gdscPoint; |
| |
| int32_t gsize = (int32_t)gdsc->box_w * gdsc->box_h; |
| if (gsize == 0) return NULL; |
| if (fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) { |
| const uint8_t * bitmap_in = __user_font_getdata(pos + sizeof(glyph_dsc_t), gdsc->box_w*gdsc->box_h*__g_xbf_hd.bpp / 8); |
| uint8_t * bitmap_out_tmp = bitmap_out; |
| int32_t i = 0; |
| int32_t x, y; |
| uint32_t stride = lv_draw_buf_width_to_stride(gdsc->box_w, LV_COLOR_FORMAT_A8); |
| if (fdsc->bpp == 1) { |
| for (y = 0; y < gdsc->box_h; y++) { |
| for (x = 0; x < gdsc->box_w; x++, i++) { |
| i = i & 0x7; |
| if (i == 0) bitmap_out_tmp[x] = (*bitmap_in) & 0x80 ? 0xff : 0x00; |
| else if (i == 1) bitmap_out_tmp[x] = (*bitmap_in) & 0x40 ? 0xff : 0x00; |
| else if (i == 2) bitmap_out_tmp[x] = (*bitmap_in) & 0x20 ? 0xff : 0x00; |
| else if (i == 3) bitmap_out_tmp[x] = (*bitmap_in) & 0x10 ? 0xff : 0x00; |
| else if (i == 4) bitmap_out_tmp[x] = (*bitmap_in) & 0x08 ? 0xff : 0x00; |
| else if (i == 5) bitmap_out_tmp[x] = (*bitmap_in) & 0x04 ? 0xff : 0x00; |
| else if (i == 6) bitmap_out_tmp[x] = (*bitmap_in) & 0x02 ? 0xff : 0x00; |
| else if (i == 7) { |
| bitmap_out_tmp[x] = (*bitmap_in) & 0x01 ? 0xff : 0x00; |
| bitmap_in++; |
| } |
| } |
| bitmap_out_tmp += stride; |
| } |
| } |
| else if (fdsc->bpp == 2) { |
| for (y = 0; y < gdsc->box_h; y++) { |
| for (x = 0; x < gdsc->box_w; x++, i++) { |
| i = i & 0x3; |
| if (i == 0) bitmap_out_tmp[x] = opa2_table[(*bitmap_in) >> 6]; |
| else if (i == 1) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 4) & 0x3]; |
| else if (i == 2) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 2) & 0x3]; |
| else if (i == 3) { |
| bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 0) & 0x3]; |
| bitmap_in++; |
| } |
| } |
| bitmap_out_tmp += stride; |
| } |
| |
| } |
| else if (fdsc->bpp == 4) { |
| for (y = 0; y < gdsc->box_h; y++) { |
| for (x = 0; x < gdsc->box_w; x++, i++) { |
| i = i & 0x1; |
| if (i == 0) { |
| bitmap_out_tmp[x] = opa4_table[(*bitmap_in) >> 4]; |
| } |
| else if (i == 1) { |
| bitmap_out_tmp[x] = opa4_table[(*bitmap_in) & 0xF]; |
| bitmap_in++; |
| } |
| } |
| bitmap_out_tmp += stride; |
| } |
| } |
| return draw_buf; |
| } |
| } |
| return NULL; |
| } |
| |
| |
| static bool __user_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { |
| if( unicode_letter>__g_xbf_hd.max || unicode_letter<__g_xbf_hd.min ) { |
| return NULL; |
| } |
| uint32_t unicode_offset = sizeof(x_header_t)+(unicode_letter-__g_xbf_hd.min)*4; |
| uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4); |
| if( p_pos[0] != 0 ) { |
| glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(p_pos[0], sizeof(glyph_dsc_t)); |
| dsc_out->adv_w = gdsc->adv_w; |
| dsc_out->box_h = gdsc->box_h; |
| dsc_out->box_w = gdsc->box_w; |
| dsc_out->ofs_x = gdsc->ofs_x; |
| dsc_out->ofs_y = gdsc->ofs_y; |
| dsc_out->format = (uint8_t)__g_xbf_hd.bpp; |
| dsc_out->gid.index = unicode_letter; |
| dsc_out->is_placeholder = false; |
| return true; |
| } |
| return false; |
| } |
| |
| #if LVGL_VERSION_MAJOR >= 8 |
| static const lv_font_fmt_txt_dsc_t font_dsc = { |
| #else |
| static lv_font_fmt_txt_dsc_t font_dsc = { |
| #endif |
| .glyph_bitmap = NULL, |
| .glyph_dsc = NULL, |
| .cmaps = NULL, |
| .kern_dsc = NULL, |
| .kern_scale = 0, |
| .cmap_num = 0, |
| .bpp = 4, |
| .kern_classes = 0, |
| .bitmap_format = LV_FONT_FMT_TXT_PLAIN, |
| #if LVGL_VERSION_MAJOR == 8 |
| .cache = &cache |
| #endif |
| }; |
| |
| |
| |
| const lv_font_t myFont = { |
| .get_glyph_bitmap = __user_font_get_bitmap, |
| .get_glyph_dsc = __user_font_get_glyph_dsc, |
| .line_height = 28, |
| .base_line = 0, |
| #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) |
| .subpx = LV_FONT_SUBPX_NONE, |
| #endif |
| #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 |
| .underline_position = -2, |
| .underline_thickness = 1, |
| #endif |
| .dsc = &font_dsc, |
| #if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 |
| .fallback = NULL, |
| #endif |
| .user_data = NULL, |
| }; |
| |
| int myFontInit(char *filePath, lv_font_t *retLvFont) |
| { |
| |
| HANDLE hFile = CreateFileA( |
| filePath, |
| GENERIC_READ, |
| 0, |
| NULL, |
| OPEN_EXISTING, |
| FILE_ATTRIBUTE_NORMAL, |
| NULL |
| ); |
| |
| if (hFile == INVALID_HANDLE_VALUE) { |
| |
| printf("Could not open file (error %lu)\n", GetLastError()); |
| return 1; |
| } |
| |
| |
| DWORD fileSize = GetFileSize(hFile, NULL); |
| if (fileSize == INVALID_FILE_SIZE) { |
| |
| printf("Could not get file size (error %lu)\n", GetLastError()); |
| CloseHandle(hFile); |
| return 1; |
| } |
| |
| |
| myFontBuf = (char *)malloc(fileSize + 1); |
| if (myFontBuf == NULL) { |
| |
| printf("Could not allocate memory\n"); |
| CloseHandle(hFile); |
| return 1; |
| } |
| |
| |
| DWORD bytesRead; |
| BOOL readResult = ReadFile( |
| hFile, |
| myFontBuf, |
| fileSize, |
| &bytesRead, |
| NULL |
| ); |
| |
| if (!readResult || bytesRead != fileSize) { |
| |
| printf("Could not read file (error %lu)\n", GetLastError()); |
| free(myFontBuf); |
| CloseHandle(hFile); |
| return 1; |
| } |
| CloseHandle(hFile); |
| retLvFont = &myFont; |
| return 0; |
| } |
| |
| |
| int myFontUninit() |
| { |
| free(myFontBuf); |
| return 0; |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2024-02-19 软件搜索工具
2023-02-19 MQTT连接阿里云IoT(一)
2021-02-19 【转】STL常见问题
2021-02-19 【设计模式 - 结构型模式】5. 外观模式
2021-02-19 APU、BPU、CPU、DPU、FPU、GPU、HPU、IPU、MPU、NPU、RPU、TPU、VPU、WPU、XPU、ZPU 都是什么?
2021-02-19 MySQL8.0.18版本的数据库安装过程
2021-02-19 MySQL5.7.24版本的数据库安装过程