Switch LCD UI to MiSans bitmap fonts and align typography/colors with 0819 UI spec.

Regenerate Chinese/English font tables, extend LCD driver for new sizes, and update screen layouts; add gen_misans_font.py for reproducible font builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-08-28 11:24:06 +08:00
parent d0568a1b00
commit 43083fd3f1
16 changed files with 4984 additions and 1132 deletions

View File

@ -57,6 +57,16 @@
#define WHITE 0xFFFF #define WHITE 0xFFFF
#define BLACK 0x0000 #define BLACK 0x0000
#define BLUE 0x001F #define BLUE 0x001F
#define COLOR_PRIMARY 0x1B9F // #1D73FF MiSans UI 主色
#define COLOR_GRAD_START 0x039D // #003AEE
#define COLOR_GRAD_MID 0x2A5A // #354FD6
#define COLOR_GRAD_END 0x4B1F // #5561F8
#define COLOR_BG_START 0x0849 // #0E1537
#define COLOR_BG_END 0x3189 // #2F3647
#define COLOR_MIXER_RED 0xFB2D // #F85E4B
#define COLOR_MIXER_ORANGE 0xFD26 // #F59C2C
#define COLOR_MIXER_YELLOW 0xFF6E // #F3D939
#define COLOR_MIXER_GREEN 0x071F // #13E17F
#define BRED 0XF81F #define BRED 0XF81F
#define GRED 0XFFE0 #define GRED 0XFFE0
#define GBLUE 0X07FF #define GBLUE 0X07FF
@ -80,8 +90,8 @@
#define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/ #define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/
#define BUTTON_COLOR /*0x5AEB*/BLACK #define BUTTON_COLOR /*0x5AEB*/BLACK
#define START_COLOR /*0x5AEB*/ 0x2988 #define START_COLOR COLOR_GRAD_START
#define END_COLOR 0x2022/*0x5066*/ #define END_COLOR COLOR_GRAD_END
extern void LCD_GPIO_Init(void); //初始化GPIO extern void LCD_GPIO_Init(void); //初始化GPIO
extern void LCD_WR_DATA8(uint8_t data); //写入一个字节 extern void LCD_WR_DATA8(uint8_t data); //写入一个字节
extern void LCD_WR_DATA16(uint16_t data); //写入两个字节 extern void LCD_WR_DATA16(uint16_t data); //写入两个字节

View File

@ -33,11 +33,11 @@ GUI_SWITCH ParamGuiData[] =
const LEBEL_UI UI_Label[] = { const LEBEL_UI UI_Label[] = {
{5, 115, 30, 60, (const uint8_t*)"\xD2\xC6\xB5\xF7", LCD_ALIGN_CENTER, WHITE,BLACK,11, LCD_ALIGN_CENTER,WHITE,BLACK,24, GUI_TRANSPOSE}, {5, 115, 30, 60, (const uint8_t*)"\xD2\xC6\xB5\xF7", LCD_ALIGN_CENTER, WHITE,BLACK,11, LCD_ALIGN_CENTER,WHITE,BLACK,11, GUI_TRANSPOSE},
{125,110, 30, 60, (const uint8_t*)"\xCB\xD9\xB6\xC8", LCD_ALIGN_CENTER, WHITE,BLACK,11, LCD_ALIGN_CENTER,WHITE,BLACK,24, GUI_SPEED}, {125,110, 30, 60, (const uint8_t*)"\xCB\xD9\xB6\xC8", LCD_ALIGN_CENTER, WHITE,BLACK,11, LCD_ALIGN_CENTER,WHITE,BLACK,11, GUI_SPEED},
{5, 230, 95, 55, (const uint8_t*)"\xB8\xE8\xC7\xFA\xD1\xA1\xD2\xE9", LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,13,GUI_MODE_PARAM}, {5, 230, 95, 55, (const uint8_t*)"\xB8\xE8\xC7\xFA\xD1\xA1\xD2\xE9", LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,13,GUI_MODE_PARAM},
{5, 230, 155,55, (const uint8_t*)"\xCF\xD2\xD2\xF4\xC9\xAB\xD1\xA1\xD2\xE9",LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,13,GUI_TIMBRE_SELECT}, {5, 230, 155,55, (const uint8_t*)"\xCF\xD2\xD2\xF4\xC9\xAB\xD1\xA1\xD2\xE9",LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,13,GUI_TIMBRE_SELECT},
{5, 230, 210,55, (const uint8_t*)"\xD1\xDD\xD7\xE0\xB6\xCE\xC2\xE4",LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,24,GUI_PLAY_SECTION}, {5, 230, 210,55, (const uint8_t*)"\xD1\xDD\xD7\xE0\xB6\xCE\xC2\xE4",LCD_ALIGN_LEFT,WHITE,BLACK,11,LCD_ALIGN_CENTER,WHITE,BLACK,13,GUI_PLAY_SECTION},
}; };

View File

@ -22,7 +22,7 @@ void RGB_Y_TO_G()
#define UI_MODE_BG_COLOR 0x1925 #define UI_MODE_BG_COLOR 0x1925
#define UI_MODE_LINE_COLOR DARKBLUE #define UI_MODE_LINE_COLOR DARKBLUE
#define UI_MODE_TEXT_COLOR 0xFFFF #define UI_MODE_TEXT_COLOR 0xFFFF
#define UI_MODE_FONT_SIZE 24 #define UI_MODE_FONT_SIZE 16
void UI_DrawModeSelectScreen(void) void UI_DrawModeSelectScreen(void)
{ {
@ -57,43 +57,43 @@ void UI_DrawModeSelectScreen(void)
uint16_t x1 = LCD_ShowChinese_AutoAlign_Gradient( uint16_t x1 = LCD_ShowChinese_AutoAlign_Gradient(
btn_x, btn_x + btn_w, btn_x, btn_x + btn_w,
40 + (btn_h - 24) / 2, 40 + (btn_h - UI_MODE_FONT_SIZE) / 2,
(uint8_t*)"\xCD\xF2\xC4\xDC\xC4\xA3\xCA\xBD", //<2F><><EFBFBD><EFBFBD>ģʽ (uint8_t*)"\xCD\xF2\xC4\xDC\xC4\xA3\xCA\xBD", //<2F><><EFBFBD><EFBFBD>ģʽ
LCD_ALIGN_CENTER, LCD_ALIGN_CENTER,
UI_MODE_TEXT_COLOR, UI_MODE_TEXT_COLOR,
START_COLOR, END_COLOR, START_COLOR, END_COLOR,
24 UI_MODE_FONT_SIZE
); );
LCD_WR_PIC(x1-45, 40 + (btn_h - 24) / 2-5,40,30,gImage_FreeMode_Icon_40_30); LCD_WR_PIC(x1-45, 40 + (btn_h - UI_MODE_FONT_SIZE) / 2-5,40,30,gImage_FreeMode_Icon_40_30);
// ר???ģʽ<C4A3><CABD>Y=132??????? // ר???ģʽ<C4A3><CABD>Y=132???????
// LCD_FillRoundRect(btn_x, 132, btn_w, btn_h, btn_r, btn_color); // LCD_FillRoundRect(btn_x, 132, btn_w, btn_h, btn_r, btn_color);
LCD_FillRoundRectGradient(btn_x, 132, btn_w, btn_h, btn_r, START_COLOR, END_COLOR); LCD_FillRoundRectGradient(btn_x, 132, btn_w, btn_h, btn_r, START_COLOR, END_COLOR);
uint16_t x2 = LCD_ShowChinese_AutoAlign_Gradient( uint16_t x2 = LCD_ShowChinese_AutoAlign_Gradient(
btn_x, btn_x + btn_w, btn_x, btn_x + btn_w,
132 + (btn_h - 24) / 2, 132 + (btn_h - UI_MODE_FONT_SIZE) / 2,
(uint8_t *)"\xC6\xD5\xCD\xA8\xC4\xA3\xCA\xBD", // <20><>ͨģʽ (uint8_t *)"\xC6\xD5\xCD\xA8\xC4\xA3\xCA\xBD", // <20><>ͨģʽ
LCD_ALIGN_CENTER, LCD_ALIGN_CENTER,
UI_MODE_TEXT_COLOR, UI_MODE_TEXT_COLOR,
START_COLOR, END_COLOR, START_COLOR, END_COLOR,
24 UI_MODE_FONT_SIZE
); );
LCD_WR_PIC(x2-45, 132 + (btn_h - 24) / 2-5,40,30,gImage_NormalMode_Icon_40_30); LCD_WR_PIC(x2-45, 132 + (btn_h - UI_MODE_FONT_SIZE) / 2-5,40,30,gImage_NormalMode_Icon_40_30);
// <20><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>Y=224??????? // <20><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>Y=224???????
// LCD_FillRoundRect(btn_x, 224, btn_w, btn_h, btn_r, btn_color); // LCD_FillRoundRect(btn_x, 224, btn_w, btn_h, btn_r, btn_color);
LCD_FillRoundRectGradient(btn_x, 224, btn_w, btn_h, btn_r, START_COLOR, END_COLOR); LCD_FillRoundRectGradient(btn_x, 224, btn_w, btn_h, btn_r, START_COLOR, END_COLOR);
uint16_t x3 = LCD_ShowChinese_AutoAlign_Gradient( uint16_t x3 = LCD_ShowChinese_AutoAlign_Gradient(
btn_x, btn_x + btn_w, btn_x, btn_x + btn_w,
224 + (btn_h - 24) / 2, 224 + (btn_h - UI_MODE_FONT_SIZE) / 2,
(const uint8_t *)"\xD7\xA8\xD2\xB5\xC4\xA3\xCA\xBD", // רҵģʽ (const uint8_t *)"\xD7\xA8\xD2\xB5\xC4\xA3\xCA\xBD", // רҵģʽ
LCD_ALIGN_CENTER, LCD_ALIGN_CENTER,
UI_MODE_TEXT_COLOR, UI_MODE_TEXT_COLOR,
START_COLOR, END_COLOR, START_COLOR, END_COLOR,
24 UI_MODE_FONT_SIZE
); );
LCD_WR_PIC(x3-45, 224 + (btn_h - 24) / 2-5,40,30,gImage_ExpressMode_Icon_40_30); LCD_WR_PIC(x3-45, 224 + (btn_h - UI_MODE_FONT_SIZE) / 2-5,40,30,gImage_ExpressMode_Icon_40_30);
} }
const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = { const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = {
@ -253,7 +253,7 @@ void IdleProcess(DisplayTaskMessage_Type msg)
{ {
uint8_t Info[10] = {0,}; uint8_t Info[10] = {0,};
sprintf ((char*)Info, "%d%%", msg.ID); sprintf ((char*)Info, "%d%%", msg.ID);
LCD_ShowString_AutoAlign(0,240,250,Info,LCD_ALIGN_CENTER,WHITE,BLACK,0,24); LCD_ShowString_AutoAlign(0,240,250,Info,LCD_ALIGN_CENTER,WHITE,BLACK,0,28);
} }
//else //else
//BSP_MainPowerEnable(0); //BSP_MainPowerEnable(0);

View File

@ -34,7 +34,7 @@ void DrawFader(Fader_t *f)
} }
// 底部文字 // 底部文字
LCD_ShowChinese_AutoAlign(x + 10, x + (w / 2) - 8, y + h + 20, LCD_ShowChinese_AutoAlign(x + 10, x + (w / 2) - 8, y + h + 20,
(uint8_t*)f->name, LCD_ALIGN_CENTER, FADER_TEXT, BLACK, 0, 16); (uint8_t*)f->name, LCD_ALIGN_CENTER, FADER_TEXT, BLACK, 0, 12);
// 画滑块并记录位置 // 画滑块并记录位置
uint16_t slider_y = CalcSliderY(f); uint16_t slider_y = CalcSliderY(f);
DrawFaderSlider(f, slider_y); DrawFaderSlider(f, slider_y);
@ -126,9 +126,9 @@ static void DrawFaderSlider(Fader_t *f, uint16_t slider_y)
{ {
uint16_t x = f->x, w = f->w, slider_h = 20; uint16_t x = f->x, w = f->w, slider_h = 20;
char buf[8]; char buf[8];
LCD_FillRoundRect(x+5, slider_y, w-10, slider_h, 5, BLUE); LCD_FillRoundRect(x+5, slider_y, w-10, slider_h, 5, COLOR_PRIMARY);
sprintf(buf, "%d", f->val); sprintf(buf, "%d", f->val);
LCD_ShowString_AutoAlign(x, x + w, slider_y, (uint8_t*)buf, LCD_ALIGN_CENTER, FADER_TEXT, BLUE, 0, 16); LCD_ShowString_AutoAlign(x, x + w, slider_y, (uint8_t*)buf, LCD_ALIGN_CENTER, FADER_TEXT, COLOR_PRIMARY, 0, 15);
} }
// ============================================================ // ============================================================
// 完整重绘滑块(槽背景 + 刻度线 + 滑块) // 完整重绘滑块(槽背景 + 刻度线 + 滑块)

View File

@ -77,7 +77,7 @@ void UI_Draw_Buttons(void)
#define TOP_TITLE_Y2 35 #define TOP_TITLE_Y2 35
#define TOP_TITLE_BG_COLOR BLACK // <20><><EFBFBD><EFBFBD>ɫ #define TOP_TITLE_BG_COLOR BLACK // <20><><EFBFBD><EFBFBD>ɫ
#define TOP_TITLE_TEXT_COLOR WHITE // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ #define TOP_TITLE_TEXT_COLOR WHITE // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
#define TOP_TITLE_FONT_SIZE 16 // <20><><EFBFBD><EFBFBD><EFBFBD>С #define TOP_TITLE_FONT_SIZE 13 // 标题字号
#define TOP_TITLE_ALIGN LCD_ALIGN_CENTER // <20><><EFBFBD><EFBFBD> #define TOP_TITLE_ALIGN LCD_ALIGN_CENTER // <20><><EFBFBD><EFBFBD>
// ============================== // ==============================

View File

@ -43,10 +43,10 @@ GUI_SWITCH mGuiData_SystemSETTING[] = {
LEBEL_UI SystemSetting[] = LEBEL_UI SystemSetting[] =
{ {
{15, 230,35+10,60, (const uint8_t*)"\xB9\xCC\xBC\xFE\xB0\xE6\xB1\xBE", LCD_ALIGN_LEFT, WHITE, BLACK, 12, LCD_ALIGN_CENTER, WHITE, BLACK, 24, GUI_VERSION}, {15, 230,35+10,60, (const uint8_t*)"\xB9\xCC\xBC\xFE\xB0\xE6\xB1\xBE", LCD_ALIGN_LEFT, WHITE, BLACK, 13, LCD_ALIGN_CENTER, WHITE, BLACK, 11, GUI_VERSION},
{15, 230,95+10+5,60, (const uint8_t*)"\xC0\xB6\xD1\xC0\xC1\xB4\xBD\xD3", LCD_ALIGN_LEFT, WHITE, BLACK, 12, LCD_ALIGN_CENTER, WHITE, BLACK, 24, GUI_BLUETOOTH_SW}, {15, 230,95+10+5,60, (const uint8_t*)"\xC0\xB6\xD1\xC0\xC1\xB4\xBD\xD3", LCD_ALIGN_LEFT, WHITE, BLACK, 13, LCD_ALIGN_CENTER, WHITE, BLACK, 11, GUI_BLUETOOTH_SW},
{15, 230,160+10+5,60,(const uint8_t*)"\xD7\xD4\xB6\xAF\xB9\xD8\xBB\xFA", LCD_ALIGN_LEFT, WHITE, BLACK, 12, LCD_ALIGN_CENTER, WHITE, BLACK, 24, GUI_AUTOCLOSE}, {15, 230,160+10+5,60,(const uint8_t*)"\xD7\xD4\xB6\xAF\xB9\xD8\xBB\xFA", LCD_ALIGN_LEFT, WHITE, BLACK, 13, LCD_ALIGN_CENTER, WHITE, BLACK, 11, GUI_AUTOCLOSE},
{15, 230,225+10+5,60,(const uint8_t*)"\xBB\xD6\xB8\xB4\xB3\xF6\xB3\xA7\xC9\xE8\xD6\xC3", LCD_ALIGN_LEFT, WHITE, BLACK, 12, LCD_ALIGN_CENTER, WHITE, BLACK, 24, GUI_RESTORE}, {15, 230,225+10+5,60,(const uint8_t*)"\xBB\xD6\xB8\xB4\xB3\xF6\xB3\xA7\xC9\xE8\xD6\xC3", LCD_ALIGN_LEFT, WHITE, BLACK, 13, LCD_ALIGN_CENTER, WHITE, BLACK, 11, GUI_RESTORE},
}; };
// ============================== // ==============================

View File

@ -17,7 +17,7 @@ void Draw_Tab_Mode_Menu(const LEBEL_UI *UI, GUI_SWITCH *Group)
const uint16_t text_y = UI->y + 2; // 鏂囧<E98F82>????Y const uint16_t text_y = UI->y + 2; // 鏂囧<E98F82>????Y
// ===================== 棰滆壊瀹氫<E780B9>???? ===================== // ===================== 棰滆壊瀹氫<E780B9>???? =====================
uint16_t color_sel_bg = BLUE; // <20>????変腑鑳屾<E991B3>???? uint16_t color_sel_bg = COLOR_PRIMARY; // 选中背景
uint16_t color_unsel_bg = DARKLGRAY; // 鏈<E98F88>????変腑鑳屾<E991B3>???? uint16_t color_unsel_bg = DARKLGRAY; // 鏈<E98F88>????変腑鑳屾<E991B3>????
uint16_t color_text = UI->Text_fc; // 鏂囧瓧棰滆<E6A3B0>?? uint16_t color_text = UI->Text_fc; // 鏂囧瓧棰滆<E6A3B0>??

View File

@ -6,7 +6,7 @@
#define UI_MODE_BG_COLOR 0x1925 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭͼ<D4AD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ #define UI_MODE_BG_COLOR 0x1925 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭͼ<D4AD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
#define UI_MODE_LINE_COLOR DARKBLUE // <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> #define UI_MODE_LINE_COLOR DARKBLUE // <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define UI_MODE_TEXT_COLOR 0xFFFF // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ #define UI_MODE_TEXT_COLOR 0xFFFF // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ
#define UI_MODE_FONT_SIZE 24 // <20><><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><D6BF>޸<EFBFBD> #define UI_MODE_FONT_SIZE 16 // 模式按钮字号MiSans 16
// ============================== // ==============================
// <20><><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD> // <20><><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>

View File

@ -554,7 +554,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
uint16_t x2 = 10+40+20; uint16_t x2 = 10+40+20;
uint16_t x3 = 10+40+20+40+20; uint16_t x3 = 10+40+20+40+20;
uint16_t x4 = 10+40+20+40+20+40+20; uint16_t x4 = 10+40+20+40+20+40+20;
uint8_t TextSize = 12; uint8_t TextSize = 8;
char *str1 = "\xCD\xF2\xC4\xDC\xC4\xA3\xCA\xBD\x00"; //FreeMode char *str1 = "\xCD\xF2\xC4\xDC\xC4\xA3\xCA\xBD\x00"; //FreeMode
char *str2 = "\xC6\xD5\xCD\xA8\xC4\xA3\xCA\xBD\x00"; //NormalMode char *str2 = "\xC6\xD5\xCD\xA8\xC4\xA3\xCA\xBD\x00"; //NormalMode
char *str3 = "\xD7\xA8\xD2\xB5\xC4\xA3\xCA\xBD\x00"; //ExpressMode char *str3 = "\xD7\xA8\xD2\xB5\xC4\xA3\xCA\xBD\x00"; //ExpressMode
@ -573,7 +573,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
// 文字:选中=蓝色,未选中=白色 // 文字:选中=蓝色,未选中=白色
LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, BLUE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, COLOR_PRIMARY, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
break; break;
@ -585,7 +585,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
LCD_WR_PIC(x4, Icon_Y,30,24,gImage_Setting_notSelect); LCD_WR_PIC(x4, Icon_Y,30,24,gImage_Setting_notSelect);
LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, BLUE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, COLOR_PRIMARY, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
break; break;
case 2: // 万能选中 case 2: // 万能选中
@ -593,7 +593,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
LCD_WR_PIC(x2, Icon_Y,30,22,gImage_NormalMode_notSelect); LCD_WR_PIC(x2, Icon_Y,30,22,gImage_NormalMode_notSelect);
LCD_WR_PIC(x3, Icon_Y,30,22,gImage_ExpressMode_notSelect); LCD_WR_PIC(x3, Icon_Y,30,22,gImage_ExpressMode_notSelect);
LCD_WR_PIC(x4, Icon_Y,30,24,gImage_Setting_notSelect); LCD_WR_PIC(x4, Icon_Y,30,24,gImage_Setting_notSelect);
LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, BLUE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, COLOR_PRIMARY, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
@ -607,7 +607,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x1, x1+30-1, Text_Y, (const uint8_t *)str1,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x2, x2+30-1, Text_Y, (const uint8_t *)str2,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x3, x3+30-1, Text_Y, (const uint8_t *)str3,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, BLUE, BLACK,0,TextSize); LCD_ShowChinese_AutoAlign(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, COLOR_PRIMARY, BLACK,0,TextSize);
break; break;
} }
} }
@ -624,7 +624,7 @@ void Draw_Tab_Section_Menu(const LEBEL_UI *UI, TAB_SECTION_INDEX select_tab)
const uint16_t start_y = UI->y + 28 - 6; // 起<>?<3F>Y const uint16_t start_y = UI->y + 28 - 6; // 起<>?<3F>Y
const uint16_t text_y = UI->y + 28 - 3; // 文字Y const uint16_t text_y = UI->y + 28 - 3; // 文字Y
// ===================== 颜色定义 ===================== // ===================== 颜色定义 =====================
uint16_t color_sel_bg = BLUE; // 选中背景 uint16_t color_sel_bg = COLOR_PRIMARY; // 选中背景
// uint16_t color_unsel_bg = BLACK; // <20>?选中背景 // uint16_t color_unsel_bg = BLACK; // <20>?选中背景
uint16_t color_text = UI->Text_fc; // 文字颜色 uint16_t color_text = UI->Text_fc; // 文字颜色
@ -984,7 +984,7 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
case GUI_VERSION: case GUI_VERSION:
LCD_WR_PIC(UI->x+10, UI->y+18,20,20,gImage_FimewareVection); LCD_WR_PIC(UI->x+10, UI->y+18,20,20,gImage_FimewareVection);
sprintf (Info, "%d.%d.%d", Version[0], Version[1],Version[2]); sprintf (Info, "%d.%d.%d", Version[0], Version[1],Version[2]);
LCD_ShowString_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)Info,LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,24); LCD_ShowString_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)Info,LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,11);
break; break;
case GUI_BLUETOOTH_SW: case GUI_BLUETOOTH_SW:
LCD_WR_PIC(UI->x+10, UI->y+18,20,20,gImage_BlueTooth); LCD_WR_PIC(UI->x+10, UI->y+18,20,20,gImage_BlueTooth);
@ -992,10 +992,10 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
LCD_DrawArrow_Right(UI->x+100+95, UI->y+UI->h/2-8+12-5, 12, WHITE, GRAY); LCD_DrawArrow_Right(UI->x+100+95, UI->y+UI->h/2-8+12-5, 12, WHITE, GRAY);
if(Group->Current) if(Group->Current)
{ {
LCD_ShowChinese_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xBF\xAA",LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,24); LCD_ShowChinese_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xBF\xAA",LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,11);
}else }else
{ {
LCD_ShowChinese_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xB9\xD8",LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,24); LCD_ShowChinese_AutoAlign_Gradient(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xB9\xD8",LCD_ALIGN_CENTER, UI->Text_fc,START_COLOR, END_COLOR,11);
} }
BSP_BlueToothPowerEnable (Group->Current); BSP_BlueToothPowerEnable (Group->Current);
mGuiData[GUI_BL_SW].Current = Group->Current; mGuiData[GUI_BL_SW].Current = Group->Current;
@ -1016,11 +1016,11 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
sprintf (Info, "%d",AutoCloseTime); sprintf (Info, "%d",AutoCloseTime);
// uint16_t x = LCD_ShowChinese_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xB7\xD6\xD6\xD3",LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,0,24); // uint16_t x = LCD_ShowChinese_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)"\xB7\xD6\xD6\xD3",LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,0,24);
// LCD_ShowString_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)Info,LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,0,24); // LCD_ShowString_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(const uint8_t*)Info,LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,0,24);
LCD_ShowString(UI->x+100+20,UI->y+UI->h/2-8-5, (uint8_t *)Info, UI->Text_fc, UI->Text_bc, 24, 1); LCD_ShowString(UI->x+100+20,UI->y+UI->h/2-8-5, (uint8_t *)Info, UI->Text_fc, UI->Text_bc, 11, 1);
LCD_ShowChineseString(UI->x+100+20+25, UI->y+UI->h/2-8-5,(uint8_t*)"\xB7\xD6\xD6\xD3", UI->Text_fc,UI->Text_bc,24,1); LCD_ShowChineseString(UI->x+100+20+25, UI->y+UI->h/2-8-5,(uint8_t*)"\xB7\xD6\xD6\xD3", UI->Text_fc,UI->Text_bc,11,1);
}else }else
{ {
LCD_ShowChinese_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(uint8_t*)"\xB9\xD8",LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,1,24); LCD_ShowChinese_AutoAlign(UI->x+100,UI->x+100+110, UI->y+UI->h/2-8-5,(uint8_t*)"\xB9\xD8",LCD_ALIGN_CENTER, UI->Text_fc,UI->Text_bc,1,11);
} }
if(nvm->param.AutoCloseTime != Group->Current) if(nvm->param.AutoCloseTime != Group->Current)

View File

@ -4,6 +4,102 @@
#include "w25q128.h" #include "w25q128.h"
#define PIC_BATCH_SIZE 1024 #define PIC_BATCH_SIZE 1024
static uint8_t LCD_CnFontMetrics(uint8_t sizey, uint8_t *sizex, uint16_t *typeface_num)
{
switch (sizey)
{
case 8: *sizex = 8; *typeface_num = 8; return 1;
case 11: *sizex = 11; *typeface_num = 22; return 1;
case 12: *sizex = 12; *typeface_num = 24; return 1;
case 13: *sizex = 13; *typeface_num = 26; return 1;
case 15: *sizex = 15; *typeface_num = 30; return 1;
case 16: *sizex = 16; *typeface_num = 32; return 1;
case 24: *sizex = 24; *typeface_num = 72; return 1;
case 28: *sizex = 28; *typeface_num = 112; return 1;
default: return 0;
}
}
static uint8_t LCD_GetCnFontByte(uint8_t sizey, uint8_t index, uint16_t i)
{
switch (sizey)
{
case 8: return Chinese_font_8[index][i];
case 11: return Chinese_font_11[index][i];
case 12: return Chinese_font_12[index][i];
case 13: return Chinese_font_13[index][i];
case 15: return Chinese_font_15[index][i];
case 16: return Chinese_font_16[index][i];
case 24: return Chinese_font_24[index][i];
case 28: return Chinese_font_28[index][i];
default: return 0;
}
}
static uint8_t LCD_GetAsciiFontByte(uint8_t sizey, uint8_t num, uint16_t i)
{
switch (sizey)
{
case 8: return ascii_84[num][i];
case 11: return ascii_115[num][i];
case 12: return ascii_126[num][i];
case 13: return ascii_1306[num][i];
case 15: return ascii_157[num][i];
case 16: return ascii_1608[num][i];
case 24: return ascii_2412[num][i];
case 28: return ascii_2814[num][i];
default: return 0;
}
}
static const char (*LCD_GetChsTable(uint8_t sizey))[2]
{
switch (sizey)
{
case 8: return CHS8Table;
case 11: return CHS11Table;
case 12: return CHS12Table;
case 13: return CHS13Table;
case 15: return CHS15Table;
case 16: return CHS16Table;
case 24: return CHS24Table;
case 28: return CHS24Table;
default: return NULL;
}
}
static uint16_t LCD_GetChsTableSize(uint8_t sizey)
{
switch (sizey)
{
case 8: return (uint16_t)(sizeof(CHS8Table) / 2);
case 11: return (uint16_t)(sizeof(CHS11Table) / 2);
case 12: return (uint16_t)(sizeof(CHS12Table) / 2);
case 13: return (uint16_t)(sizeof(CHS13Table) / 2);
case 15: return (uint16_t)(sizeof(CHS15Table) / 2);
case 16: return (uint16_t)(sizeof(CHS16Table) / 2);
case 24: return (uint16_t)(sizeof(CHS24Table) / 2);
case 28: return (uint16_t)(sizeof(CHS24Table) / 2);
default: return 0;
}
}
static uint8_t LCD_GetAsciiMetrics(uint8_t size, uint8_t *char_width, uint8_t *char_height)
{
*char_height = size;
switch (size)
{
case 8: *char_width = 4; return 1;
case 11: *char_width = 5; return 1;
case 12: *char_width = 6; return 1;
case 13: *char_width = 6; return 1;
case 15: *char_width = 7; return 1;
case 16: *char_width = 8; return 1;
case 24: *char_width = 12; return 1;
case 28: *char_width = 14; return 1;
default: return 0;
}
}
//r:0-31 g:0-63 b:0-31 //r:0-31 g:0-63 b:0-31
uint16_t RGB(int r,int g,int b) uint16_t RGB(int r,int g,int b)
@ -407,9 +503,14 @@ void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint16_t fc, uint16_t bc,
uint16_t i, TypefaceNum; uint16_t i, TypefaceNum;
uint16_t x0 = x; uint16_t x0 = x;
sizex = sizey / 2; uint8_t char_h;
TypefaceNum = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey;
num = num - ' '; num = num - ' ';
if (!LCD_GetAsciiMetrics(sizey, &sizex, &char_h))
{
return;
}
TypefaceNum = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey;
// 一次性设置窗口LCD地址自动递增无需每像素都设 // 一次性设置窗口LCD地址自动递增无需每像素都设
LCD_SetWindow(x, y, x + sizex - 1, y + sizey - 1); LCD_SetWindow(x, y, x + sizex - 1, y + sizey - 1);
@ -425,11 +526,7 @@ void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint16_t fc, uint16_t bc,
for (i = 0; i < TypefaceNum; i++) for (i = 0; i < TypefaceNum; i++)
{ {
temp = LCD_GetAsciiFontByte(sizey, num, i);
if (sizey == 16) temp = ascii_1608[num][i];
else if (sizey == 13) temp = ascii_1306[num][i];
else if (sizey == 24) temp = ascii_2412[num][i];
else { LCD_DC_Clr(); return; }
for (uint8_t t = 0; t < 8; t++) for (uint8_t t = 0; t < 8; t++)
{ {
@ -456,13 +553,10 @@ void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint16_t fc, uint16_t bc,
} }
else // 叠加模式(保持逐点画,不改动) else // 叠加模式(保持逐点画,不改动)
{ {
uint8_t temp;
for (i = 0; i < TypefaceNum; i++) for (i = 0; i < TypefaceNum; i++)
{ {
uint8_t temp; temp = LCD_GetAsciiFontByte(sizey, num, i);
if (sizey == 16) temp = ascii_1608[num][i];
else if (sizey == 13) temp = ascii_1306[num][i];
else if (sizey == 24) temp = ascii_2412[num][i];
else { LCD_DC_Clr(); return; }
for (uint8_t t = 0; t < 8; t++) for (uint8_t t = 0; t < 8; t++)
{ {
@ -488,15 +582,8 @@ void LCD_ShowChinese(uint16_t x, uint16_t y, uint8_t index, uint16_t fc, uint16_
uint16_t i, TypefaceNum = 0; uint16_t i, TypefaceNum = 0;
uint16_t x0 = x; uint16_t x0 = x;
switch(sizey) if (!LCD_CnFontMetrics(sizey, &sizex, &TypefaceNum))
{ return;
case 11:sizex = 11;TypefaceNum = 22;break;
case 12:sizex = 12;TypefaceNum = 24;break;
case 13:sizex = 13;TypefaceNum = 26;break;
case 16:sizex = 16;TypefaceNum = 32;break;
case 24:sizex = 24;TypefaceNum = 72;break;
default: return;break;
}
// 一次性设置窗口 // 一次性设置窗口
LCD_SetWindow(x, y, x + sizex - 1, y + sizey - 1); LCD_SetWindow(x, y, x + sizex - 1, y + sizey - 1);
@ -512,14 +599,7 @@ void LCD_ShowChinese(uint16_t x, uint16_t y, uint8_t index, uint16_t fc, uint16_
for (i = 0; i < TypefaceNum; i++) for (i = 0; i < TypefaceNum; i++)
{ {
switch(sizey) temp = LCD_GetCnFontByte(sizey, index, i);
{
case 11:temp = Chinese_font_11[index][i];break;
case 12:temp = Chinese_font_12[index][i];break;
case 13:temp = Chinese_font_13[index][i];break;
case 16:temp = Chinese_font_16[index][i];break;
case 24:temp = Chinese_font_24[index][i];break;
}
for (uint8_t t = 0; t < 8; t++) for (uint8_t t = 0; t < 8; t++)
{ {
@ -546,17 +626,10 @@ void LCD_ShowChinese(uint16_t x, uint16_t y, uint8_t index, uint16_t fc, uint16_
} }
else // 叠加模式(保持逐点画) else // 叠加模式(保持逐点画)
{ {
uint8_t temp;
for (i = 0; i < TypefaceNum; i++) for (i = 0; i < TypefaceNum; i++)
{ {
uint8_t temp; temp = LCD_GetCnFontByte(sizey, index, i);
switch(sizey)
{
case 11:temp = Chinese_font_11[index][i];break;
case 12:temp = Chinese_font_12[index][i];break;
case 13:temp = Chinese_font_13[index][i];break;
case 16:temp = Chinese_font_16[index][i];break;
case 24:temp = Chinese_font_24[index][i];break;
}
for (uint8_t t = 0; t < 8; t++) for (uint8_t t = 0; t < 8; t++)
{ {
@ -837,6 +910,10 @@ void LCD_ShowChineseString(uint16_t x, uint16_t y, uint8_t *str, uint16_t fc, ui
switch (sizey)// 根据字体大小选择对应的字库和步进 switch (sizey)// 根据字体大小选择对应的字库和步进
{ {
case 8:
codeTab = CHS8Table;
xStep = 8;
break;
case 11: case 11:
codeTab = CHS11Table; codeTab = CHS11Table;
xStep = 11; xStep = 11;
@ -849,6 +926,10 @@ void LCD_ShowChineseString(uint16_t x, uint16_t y, uint8_t *str, uint16_t fc, ui
codeTab = CHS13Table; codeTab = CHS13Table;
xStep = 13; xStep = 13;
break; break;
case 15:
codeTab = CHS15Table;
xStep = 15;
break;
case 16: case 16:
codeTab = CHS16Table; codeTab = CHS16Table;
xStep = 16; xStep = 16;
@ -857,6 +938,10 @@ void LCD_ShowChineseString(uint16_t x, uint16_t y, uint8_t *str, uint16_t fc, ui
codeTab = CHS24Table; codeTab = CHS24Table;
xStep = 24; xStep = 24;
break; break;
case 28:
codeTab = CHS24Table;
xStep = 28;
break;
default: default:
return; return;
} }
@ -930,14 +1015,9 @@ uint16_t LCD_ShowMixedString(uint16_t x1, uint16_t x2, uint16_t y, uint8_t *str,
uint8_t xStepAscii = sizey / 2; uint8_t xStepAscii = sizey / 2;
uint16_t draw_x; uint16_t draw_x;
switch(sizey) codeTab = LCD_GetChsTable(sizey);
{ if (codeTab == NULL)
case 13: codeTab = CHS13Table; break; return x1;
case 12: codeTab = CHS12Table; break;
case 16: codeTab = CHS16Table; break;
case 24: codeTab = CHS24Table; break;
default: return x1;
}
// 先计算字符串总像素宽度再根据对齐方式确定起始X坐标 // 先计算字符串总像素宽度再根据对齐方式确定起始X坐标
uint16_t total_width = LCD_GetMixedStringWidth(str, sizey); uint16_t total_width = LCD_GetMixedStringWidth(str, sizey);
@ -969,10 +1049,7 @@ uint16_t LCD_ShowMixedString(uint16_t x1, uint16_t x2, uint16_t y, uint8_t *str,
uint8_t ch_low = str[1]; uint8_t ch_low = str[1];
if(ch_low == 0) break; if(ch_low == 0) break;
uint16_t maxIndex = (sizey == 12) ? (sizeof(CHS12Table)/2) : uint16_t maxIndex = LCD_GetChsTableSize(sizey);
(sizey == 13) ? (sizeof(CHS13Table)/2) :
(sizey == 16) ? (sizeof(CHS16Table)/2) :
(sizey == 24) ? (sizeof(CHS24Table)/2) : 0;
for(uint16_t j = 0; j < maxIndex; j++) for(uint16_t j = 0; j < maxIndex; j++)
{ {
@ -1215,29 +1292,8 @@ uint16_t LCD_ShowString_AutoAlign(uint16_t x1, uint16_t x2, uint16_t y, const ui
{ {
uint8_t CHAR_WIDTH, CHAR_HEIGHT; uint8_t CHAR_WIDTH, CHAR_HEIGHT;
switch(size) if (!LCD_GetAsciiMetrics(size, &CHAR_WIDTH, &CHAR_HEIGHT))
{ return 0;
case 12:CHAR_WIDTH = 6; CHAR_HEIGHT = 12;break;
case 16:CHAR_WIDTH = 8; CHAR_HEIGHT = 16;break;
case 24:CHAR_WIDTH = 12; CHAR_HEIGHT = 24;break;
default :return 0; break;
}
// // 根据字体尺寸设置字符宽度
// if(size == 16)
// {
// CHAR_WIDTH = 8;
// CHAR_HEIGHT = 16;
// }
// else if(size == 24)
// {
// CHAR_WIDTH = 12;
// CHAR_HEIGHT = 24;
// }
// else
// {
// return 0;
// }
uint16_t str_len = 0; uint16_t str_len = 0;
uint16_t str_total_width; uint16_t str_total_width;
@ -1420,14 +1476,8 @@ uint16_t LCD_ShowString_AutoAlign_Gradient(uint16_t x1, uint16_t x2, uint16_t y,
{ {
uint8_t CHAR_WIDTH, CHAR_HEIGHT; uint8_t CHAR_WIDTH, CHAR_HEIGHT;
switch(size) if (!LCD_GetAsciiMetrics(size, &CHAR_WIDTH, &CHAR_HEIGHT))
{ return 0;
case 12:CHAR_WIDTH = 6; CHAR_HEIGHT = 12;break;
case 16:CHAR_WIDTH = 8; CHAR_HEIGHT = 16;break;
case 24:CHAR_WIDTH = 12; CHAR_HEIGHT = 24;break;
default :return 0; break;
}
uint16_t str_len = 0; uint16_t str_len = 0;
uint16_t str_total_width; uint16_t str_total_width;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,16 @@
#define WHITE 0xFFFF #define WHITE 0xFFFF
#define BLACK 0x0000 #define BLACK 0x0000
#define BLUE 0x001F #define BLUE 0x001F
#define COLOR_PRIMARY 0x1B9F // #1D73FF MiSans UI 主色
#define COLOR_GRAD_START 0x039D // #003AEE
#define COLOR_GRAD_MID 0x2A5A // #354FD6
#define COLOR_GRAD_END 0x4B1F // #5561F8
#define COLOR_BG_START 0x0849 // #0E1537
#define COLOR_BG_END 0x3189 // #2F3647
#define COLOR_MIXER_RED 0xFB2D // #F85E4B
#define COLOR_MIXER_ORANGE 0xFD26 // #F59C2C
#define COLOR_MIXER_YELLOW 0xFF6E // #F3D939
#define COLOR_MIXER_GREEN 0x071F // #13E17F
#define BRED 0XF81F #define BRED 0XF81F
#define GRED 0XFFE0 #define GRED 0XFFE0
#define GBLUE 0X07FF #define GBLUE 0X07FF
@ -80,8 +90,8 @@
#define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/ #define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/
#define BUTTON_COLOR /*0x5AEB*/BLACK #define BUTTON_COLOR /*0x5AEB*/BLACK
#define START_COLOR 0x10E6/*0x5AEB*/ /*0x2988*/ #define START_COLOR COLOR_GRAD_START
#define END_COLOR 0x10E6/*0x2022*//*0x5066*/ #define END_COLOR COLOR_GRAD_END
extern void LCD_GPIO_Init(void); //初始化GPIO extern void LCD_GPIO_Init(void); //初始化GPIO
extern void LCD_WR_DATA8(uint8_t data); //写入一个字节 extern void LCD_WR_DATA8(uint8_t data); //写入一个字节
extern void LCD_WR_DATA16(uint16_t data); //写入两个字节 extern void LCD_WR_DATA16(uint16_t data); //写入两个字节

295
tools/gen_misans_font.py Normal file
View File

@ -0,0 +1,295 @@
#!/usr/bin/env python3
"""Generate MiSans bitmap font C arrays for ILI9341 LCD driver."""
import glob
import math
import os
import re
import sys
from PIL import Image, ImageDraw, ImageFont
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
HEADER_IN = os.path.join(ROOT, "device", "LCD_ILI9341", "Drv_ILI9341_Lcd_ChineseFont.h")
HEADER_OUT = HEADER_IN
ENG_HEADER_IN = os.path.join(ROOT, "device", "LCD_ILI9341", "Drv_ILI9341_Lcd_EnglishFont.h")
ENG_HEADER_OUT = ENG_HEADER_IN
MISANS_DIR = os.path.join(os.path.dirname(ROOT), "..", "Doc", "UI", "MiSans")
MISANS_DIR = os.path.normpath(MISANS_DIR)
def find_ttf(name_part):
for path in glob.glob(os.path.join(MISANS_DIR, "**", "*.ttf"), recursive=True):
if name_part.lower() in os.path.basename(path).lower():
return path
raise FileNotFoundError(f"TTF matching {name_part} not found under {MISANS_DIR}")
def parse_chs_tables(text):
tables = {}
for m in re.finditer(r"const char (CHS\d+Table)\[\]\[2\] = \{(.*?)\};", text, re.S):
name = m.group(1)
body = m.group(2)
entries = []
comments = []
for line in body.splitlines():
cm = re.search(r"\{(0x[0-9A-Fa-f]{2})\s*,\s*(0x[0-9A-Fa-f]{2})\}", line)
if cm:
entries.append((int(cm.group(1), 16), int(cm.group(2), 16)))
cmt = re.search(r"//\s*(.+)", line)
comments.append(cmt.group(1).strip() if cmt else "")
tables[name] = list(zip(entries, comments))
return tables
def gbk_char(h, l):
return bytes([h, l]).decode("gbk", errors="replace")
def render_glyph(ch, size, font, square=True):
if square:
w = h = size
else:
w = size // 2
h = size
img = Image.new("L", (w, h), 0)
draw = ImageDraw.Draw(img)
bbox = draw.textbbox((0, 0), ch, font=font)
tw = bbox[2] - bbox[0]
th = bbox[3] - bbox[1]
x = (w - tw) // 2 - bbox[0]
y = (h - th) // 2 - bbox[1]
draw.text((x, y), ch, fill=255, font=font)
pixels = []
for row in range(h):
for col in range(w):
pixels.append(1 if img.getpixel((col, row)) > 127 else 0)
return pixels, w, h
def cn_to_bytes_msb(pixels, width, height):
row_bytes = (width + 7) // 8
out = []
for row in range(height):
for bi in range(row_bytes):
val = 0
for bit in range(8):
col = bi * 8 + bit
if col < width and pixels[row * width + col]:
val |= (0x80 >> bit)
elif col >= width:
pass
out.append(val)
return out
def ascii_to_bytes_lsb(pixels, width, height):
row_bytes = (width + 7) // 8
out = []
for row in range(height):
for bi in range(row_bytes):
val = 0
for bit in range(8):
col = bi * 8 + bit
if col < width and pixels[row * width + col]:
val |= (0x01 << bit)
out.append(val)
return out
def fmt_bytes(data):
parts = []
for i, b in enumerate(data):
parts.append(f"0x{b:02X}")
lines = []
for i in range(0, len(parts), 16):
lines.append(",".join(parts[i:i + 16]))
return "{" + ",".join(lines) + "}"
def generate_chinese_array(table_name, entries, size, font):
lines = [f"const unsigned char Chinese_font_{size}[][{((size + 7)//8)*size}] = {{"]
for idx, ((h, l), comment) in enumerate(entries):
ch = gbk_char(h, l)
pixels, w, hgt = render_glyph(ch, size, font, square=True)
data = cn_to_bytes_msb(pixels, w, hgt)
cmt = comment or ch
lines.append(f"{fmt_bytes(data)},/*\"{cmt}\",{idx}*/")
lines.append("};")
return "\n".join(lines)
def generate_ascii_array(size, font, array_name=None):
sizex = size // 2
row_bytes = (sizex + 7) // 8
total = row_bytes * size
suffix = f"{size}{sizex}"
name = array_name or f"ascii_{suffix}"
lines = [f"const unsigned char {name}[][{total}]={{"]
for num in range(95):
ch = chr(num + 32)
pixels, w, hgt = render_glyph(ch, size, font, square=False)
data = ascii_to_bytes_lsb(pixels, w, hgt)
lines.append(f"{fmt_bytes(data)},/*\"{ch}\",{num}*/")
lines.append("};")
return name, "\n".join(lines)
def patch_header_chinese(text, tables, fonts_by_size):
# Replace each Chinese_font_XX array
for size, font in fonts_by_size.items():
table_key = {
8: "CHS8Table",
11: "CHS11Table",
12: "CHS12Table",
13: "CHS13Table",
15: "CHS15Table",
16: "CHS16Table",
28: "CHS24Table", # reuse 24 table chars for 28 if no CHS28
}.get(size)
if size == 28:
table_key = "CHS24Table"
if table_key not in tables:
print(f"Skip size {size}: no {table_key}")
continue
entries = tables[table_key]
new_array = generate_chinese_array(table_key, entries, size, font)
pat = rf"const unsigned char Chinese_font_{size}\[\]\[\d+\] = \{{.*?\}};"
if re.search(pat, text, re.S):
text = re.sub(pat, new_array, text, count=1, flags=re.S)
else:
# insert before Chinese_font for next size or at end of tables section
insert_after = f"const char {table_key}"
# add new table for CHS8/CHS15 if missing
pass
return text
def ensure_chs8_table(text, tables):
if "CHS8Table" in tables:
return text, tables
if "CHS12Table" not in tables:
return text, tables
# Insert CHS8Table copy of CHS12Table before CHS11Table
entries = tables["CHS12Table"]
block = "const char CHS8Table[][2] = {\n"
for (h, l), cmt in entries:
block += f" {{0x{h:02X},0x{l:02X}}}, // {cmt}\n"
block += "};\n\n"
text = text.replace("const char CHS11Table", block + "const char CHS11Table", 1)
tables["CHS8Table"] = entries
return text, tables
def ensure_chs15_table(text, tables):
if "CHS15Table" in tables:
return text, tables
if "CHS13Table" not in tables:
return text, tables
entries = tables["CHS13Table"]
block = "const char CHS15Table[][2] = {\n"
for (h, l), cmt in entries:
block += f" {{0x{h:02X},0x{l:02X}}}, // {cmt}\n"
block += "};\n\n"
text = text.replace("const char CHS16Table", block + "const char CHS16Table", 1)
tables["CHS15Table"] = entries
return text, tables
def main():
medium = find_ttf("MiSans-Medium")
semibold = find_ttf("MiSans-Semibold")
print("Medium:", medium)
print("Semibold:", semibold)
with open(HEADER_IN, "r", encoding="utf-8", errors="replace") as f:
text = f.read()
tables = parse_chs_tables(text)
print("Tables:", {k: len(v) for k, v in tables.items()})
text, tables = ensure_chs8_table(text, tables)
text, tables = ensure_chs15_table(text, tables)
# Regenerate all Chinese font arrays
cn_sizes = [8, 11, 12, 13, 15, 16, 24, 28]
for size in cn_sizes:
if size in (24, 28):
table_key = "CHS24Table"
font = ImageFont.truetype(semibold if size == 28 else medium, size - 2)
else:
table_key = {
8: "CHS8Table", 11: "CHS11Table", 12: "CHS12Table",
13: "CHS13Table", 15: "CHS15Table", 16: "CHS16Table",
}[size]
font = ImageFont.truetype(medium, size - 1)
if table_key not in tables:
continue
entries = tables[table_key]
new_array = generate_chinese_array(table_key, entries, size, font)
pat = rf"const unsigned char Chinese_font_{size}\[\]\[\d+\] =[\s\S]*?\}};"
if re.search(pat, text, re.S):
text = re.sub(pat, new_array, text, count=1, flags=re.S)
print(f"Updated Chinese_font_{size} ({len(entries)} glyphs)")
else:
# Insert new array before Chinese_font for next existing or after CHS tables
anchor = "const unsigned char Chinese_font_11"
if size == 8:
anchor = "const unsigned char Chinese_font_11"
elif size == 15:
anchor = "const unsigned char Chinese_font_16"
elif size == 28:
anchor = None
if anchor and anchor in text:
text = text.replace(anchor, new_array + "\n\n" + anchor, 1)
print(f"Inserted Chinese_font_{size}")
elif size == 28:
text = text.rstrip() + "\n\n" + new_array + "\n"
print(f"Appended Chinese_font_{size}")
with open(HEADER_OUT, "w", encoding="utf-8", newline="\n") as f:
f.write(text)
# English / ASCII fonts
with open(ENG_HEADER_IN, "r", encoding="utf-8", errors="replace") as f:
eng = f.read()
ascii_targets = [
(8, medium, None), (11, medium, None), (12, medium, None), (13, medium, "ascii_1306"),
(15, medium, None), (16, medium, "ascii_1608"), (24, medium, "ascii_2412"),
(28, semibold, None),
]
for size, ttf, legacy_name in ascii_targets:
font = ImageFont.truetype(ttf, size - 1)
name, arr = generate_ascii_array(size, font, legacy_name)
pat = rf"const unsigned char {name}\[\]\[\d+\][\s\S]*?\}};"
if re.search(pat, eng, re.S):
eng = re.sub(pat, arr, eng, count=1, flags=re.S)
print(f"Updated {name}")
else:
auto_name, _ = generate_ascii_array(size, font)
pat2 = rf"const unsigned char {auto_name}\[\]\[\d+\][\s\S]*?\}};"
if auto_name != name and re.search(pat2, eng, re.S):
eng = re.sub(pat2, arr, eng, count=1, flags=re.S)
print(f"Updated {auto_name} -> {name}")
else:
eng = eng.rstrip() + "\n\n" + arr + "\n"
print(f"Appended {name}")
with open(ENG_HEADER_OUT, "w", encoding="utf-8", newline="\n") as f:
f.write(eng)
print("Done.")
if __name__ == "__main__":
main()