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:
parent
d0568a1b00
commit
43083fd3f1
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -57,6 +57,16 @@
|
|||
#define WHITE 0xFFFF
|
||||
#define BLACK 0x0000
|
||||
#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 GRED 0XFFE0
|
||||
#define GBLUE 0X07FF
|
||||
|
|
@ -79,9 +89,9 @@
|
|||
|
||||
#define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/
|
||||
#define BUTTON_COLOR /*0x5AEB*/BLACK
|
||||
|
||||
#define START_COLOR /*0x5AEB*/ 0x2988
|
||||
#define END_COLOR 0x2022/*0x5066*/
|
||||
|
||||
#define START_COLOR COLOR_GRAD_START
|
||||
#define END_COLOR COLOR_GRAD_END
|
||||
extern void LCD_GPIO_Init(void); //初始化GPIO
|
||||
extern void LCD_WR_DATA8(uint8_t data); //写入一个字节
|
||||
extern void LCD_WR_DATA16(uint16_t data); //写入两个字节
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ GUI_SWITCH ParamGuiData[] =
|
|||
|
||||
|
||||
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},
|
||||
{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},
|
||||
{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,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, 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},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
22
UI/UI_Idle.c
22
UI/UI_Idle.c
|
|
@ -22,7 +22,7 @@ void RGB_Y_TO_G()
|
|||
#define UI_MODE_BG_COLOR 0x1925
|
||||
#define UI_MODE_LINE_COLOR DARKBLUE
|
||||
#define UI_MODE_TEXT_COLOR 0xFFFF
|
||||
#define UI_MODE_FONT_SIZE 24
|
||||
#define UI_MODE_FONT_SIZE 16
|
||||
|
||||
void UI_DrawModeSelectScreen(void)
|
||||
{
|
||||
|
|
@ -57,43 +57,43 @@ void UI_DrawModeSelectScreen(void)
|
|||
|
||||
uint16_t x1 = LCD_ShowChinese_AutoAlign_Gradient(
|
||||
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>ģʽ
|
||||
LCD_ALIGN_CENTER,
|
||||
UI_MODE_TEXT_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???????
|
||||
// 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);
|
||||
uint16_t x2 = LCD_ShowChinese_AutoAlign_Gradient(
|
||||
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><>ͨģʽ
|
||||
LCD_ALIGN_CENTER,
|
||||
UI_MODE_TEXT_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???????
|
||||
// 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);
|
||||
uint16_t x3 = LCD_ShowChinese_AutoAlign_Gradient(
|
||||
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", // רҵģʽ
|
||||
LCD_ALIGN_CENTER,
|
||||
UI_MODE_TEXT_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[] = {
|
||||
|
|
@ -253,7 +253,7 @@ void IdleProcess(DisplayTaskMessage_Type msg)
|
|||
{
|
||||
uint8_t Info[10] = {0,};
|
||||
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
|
||||
//BSP_MainPowerEnable(0);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ void DrawFader(Fader_t *f)
|
|||
}
|
||||
// 底部文字
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
// ============================================================
|
||||
// 完整重绘滑块(槽背景 + 刻度线 + 滑块)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ void UI_Draw_Buttons(void)
|
|||
#define TOP_TITLE_Y2 35
|
||||
#define TOP_TITLE_BG_COLOR BLACK // <20><><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>
|
||||
|
||||
// ==============================
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ GUI_SWITCH mGuiData_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,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,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,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,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, 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, 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, 13, LCD_ALIGN_CENTER, WHITE, BLACK, 11, GUI_RESTORE},
|
||||
};
|
||||
|
||||
// ==============================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
// ===================== 棰滆壊瀹氫<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_text = UI->Text_fc; // 鏂囧瓧棰滆<E6A3B0>??
|
||||
|
||||
|
|
|
|||
|
|
@ -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_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_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>
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ void label_Tab_Select_ui(const LEBEL_UI *UI,GUI_SWITCH * Group)
|
|||
uint16_t x2 = 10+40+20;
|
||||
uint16_t x3 = 10+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 *str2 = "\xC6\xD5\xCD\xA8\xC4\xA3\xCA\xBD\x00"; //NormalMode
|
||||
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(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(x4, x4+30-1, Text_Y, (const uint8_t *)str4,LCD_ALIGN_CENTER, WHITE, BLACK,0,TextSize);
|
||||
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_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(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);
|
||||
break;
|
||||
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(x3, Icon_Y,30,22,gImage_ExpressMode_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(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);
|
||||
|
|
@ -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(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(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 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_text = UI->Text_fc; // 文字颜色
|
||||
|
||||
|
|
@ -984,7 +984,7 @@ void Draw_System_Item_List(const LEBEL_UI *UI, GUI_SWITCH *Group)
|
|||
case GUI_VERSION:
|
||||
LCD_WR_PIC(UI->x+10, UI->y+18,20,20,gImage_FimewareVection);
|
||||
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;
|
||||
case GUI_BLUETOOTH_SW:
|
||||
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);
|
||||
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
|
||||
{
|
||||
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);
|
||||
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);
|
||||
// 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(UI->x+100+20,UI->y+UI->h/2-8-5, (uint8_t *)Info, 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,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,11,1);
|
||||
}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)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,102 @@
|
|||
#include "w25q128.h"
|
||||
#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
|
||||
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 x0 = x;
|
||||
|
||||
sizex = sizey / 2;
|
||||
TypefaceNum = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey;
|
||||
uint8_t char_h;
|
||||
|
||||
num = num - ' ';
|
||||
if (!LCD_GetAsciiMetrics(sizey, &sizex, &char_h))
|
||||
{
|
||||
return;
|
||||
}
|
||||
TypefaceNum = (sizex / 8 + ((sizex % 8) ? 1 : 0)) * sizey;
|
||||
|
||||
// 一次性设置窗口(LCD地址自动递增,无需每像素都设)
|
||||
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++)
|
||||
{
|
||||
|
||||
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; }
|
||||
temp = LCD_GetAsciiFontByte(sizey, num, i);
|
||||
|
||||
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 // 叠加模式(保持逐点画,不改动)
|
||||
{
|
||||
uint8_t temp;
|
||||
for (i = 0; i < TypefaceNum; i++)
|
||||
{
|
||||
uint8_t temp;
|
||||
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; }
|
||||
temp = LCD_GetAsciiFontByte(sizey, num, i);
|
||||
|
||||
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 x0 = x;
|
||||
|
||||
switch(sizey)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (!LCD_CnFontMetrics(sizey, &sizex, &TypefaceNum))
|
||||
return;
|
||||
|
||||
// 一次性设置窗口
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
temp = LCD_GetCnFontByte(sizey, index, i);
|
||||
|
||||
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 // 叠加模式(保持逐点画)
|
||||
{
|
||||
uint8_t temp;
|
||||
for (i = 0; i < TypefaceNum; i++)
|
||||
{
|
||||
uint8_t temp;
|
||||
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;
|
||||
}
|
||||
temp = LCD_GetCnFontByte(sizey, index, i);
|
||||
|
||||
for (uint8_t t = 0; t < 8; t++)
|
||||
{
|
||||
|
|
@ -837,17 +910,25 @@ void LCD_ShowChineseString(uint16_t x, uint16_t y, uint8_t *str, uint16_t fc, ui
|
|||
|
||||
switch (sizey)// 根据字体大小选择对应的字库和步进
|
||||
{
|
||||
case 8:
|
||||
codeTab = CHS8Table;
|
||||
xStep = 8;
|
||||
break;
|
||||
case 11:
|
||||
codeTab = CHS11Table;
|
||||
xStep = 11;
|
||||
break;
|
||||
break;
|
||||
case 12:
|
||||
codeTab = CHS12Table;
|
||||
xStep = 12;
|
||||
break;
|
||||
case 13:
|
||||
codeTab = CHS13Table;
|
||||
xStep = 13;
|
||||
xStep = 13;
|
||||
break;
|
||||
case 15:
|
||||
codeTab = CHS15Table;
|
||||
xStep = 15;
|
||||
break;
|
||||
case 16:
|
||||
codeTab = CHS16Table;
|
||||
|
|
@ -857,6 +938,10 @@ void LCD_ShowChineseString(uint16_t x, uint16_t y, uint8_t *str, uint16_t fc, ui
|
|||
codeTab = CHS24Table;
|
||||
xStep = 24;
|
||||
break;
|
||||
case 28:
|
||||
codeTab = CHS24Table;
|
||||
xStep = 28;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
uint16_t draw_x;
|
||||
|
||||
switch(sizey)
|
||||
{
|
||||
case 13: codeTab = CHS13Table; break;
|
||||
case 12: codeTab = CHS12Table; break;
|
||||
case 16: codeTab = CHS16Table; break;
|
||||
case 24: codeTab = CHS24Table; break;
|
||||
default: return x1;
|
||||
}
|
||||
codeTab = LCD_GetChsTable(sizey);
|
||||
if (codeTab == NULL)
|
||||
return x1;
|
||||
|
||||
// 先计算字符串总像素宽度,再根据对齐方式确定起始X坐标
|
||||
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];
|
||||
if(ch_low == 0) break;
|
||||
|
||||
uint16_t maxIndex = (sizey == 12) ? (sizeof(CHS12Table)/2) :
|
||||
(sizey == 13) ? (sizeof(CHS13Table)/2) :
|
||||
(sizey == 16) ? (sizeof(CHS16Table)/2) :
|
||||
(sizey == 24) ? (sizeof(CHS24Table)/2) : 0;
|
||||
uint16_t maxIndex = LCD_GetChsTableSize(sizey);
|
||||
|
||||
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;
|
||||
|
||||
switch(size)
|
||||
{
|
||||
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;
|
||||
// }
|
||||
if (!LCD_GetAsciiMetrics(size, &CHAR_WIDTH, &CHAR_HEIGHT))
|
||||
return 0;
|
||||
|
||||
uint16_t str_len = 0;
|
||||
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;
|
||||
|
||||
switch(size)
|
||||
{
|
||||
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 (!LCD_GetAsciiMetrics(size, &CHAR_WIDTH, &CHAR_HEIGHT))
|
||||
return 0;
|
||||
|
||||
uint16_t str_len = 0;
|
||||
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
|
|
@ -57,6 +57,16 @@
|
|||
#define WHITE 0xFFFF
|
||||
#define BLACK 0x0000
|
||||
#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 GRED 0XFFE0
|
||||
#define GBLUE 0X07FF
|
||||
|
|
@ -80,8 +90,8 @@
|
|||
#define DARKLGRAY 0x5AEB/*0x2988*//*0x1926*//*0x252E*//*0X2B12*/
|
||||
#define BUTTON_COLOR /*0x5AEB*/BLACK
|
||||
|
||||
#define START_COLOR 0x10E6/*0x5AEB*/ /*0x2988*/
|
||||
#define END_COLOR 0x10E6/*0x2022*//*0x5066*/
|
||||
#define START_COLOR COLOR_GRAD_START
|
||||
#define END_COLOR COLOR_GRAD_END
|
||||
extern void LCD_GPIO_Init(void); //初始化GPIO
|
||||
extern void LCD_WR_DATA8(uint8_t data); //写入一个字节
|
||||
extern void LCD_WR_DATA16(uint16_t data); //写入两个字节
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
Loading…
Reference in New Issue