NXP

EMWIN中文字库添加方法

2019-07-12 13:13发布

emWin图形库由德国SEGGER公司开发的嵌入式GUI。用STM32及NXP系列MCU设计时,可以免费获得编译好的emWin库。 emWin默认是不支持中文显示的,如果要用到中文显示,只有自己添加了。 在工程中添加如下几个文件:ASCII_CODE.c、GUI_Font.c.、GUI_UC_EncodeNone.c、GUICharPEx.c。 在ASCII_CODE.c中写入如下两个数组用与存储对应汉字字体的半角ASCII字符点阵: const unsigned char ASCII_08X16[95][16]= {1608ASCII字符点阵码,对应16X16汉字}; const unsigned char ASCII_12X24[95][48] = {2412ASCII字符点阵码,对应24X24汉字}; 在GUI_Font.c文件中填入以下代码: #include "GUI.H" #ifndef GUI_FLASH    #define GUI_FLASH   #endif #define HZ_16X16  0x00000 //16x16汉字字库在FALSH中存储的偏移地址 #define HZ_24X24  0x40000 //24x24汉字字库在FALSH中存储的偏移地址 extern void GUIPROP_HZ_DispChar(U16P c); extern int GUIPROP_HZ_GetCharDistX(U16P c, int * pSizeX); extern const unsigned char ASCII_08X16[95][16]; extern const unsigned char ASCII_12X24[95][48]; GUI_CONST_STORAGE GUI_CHARINFO GUI_FontHZ_CharInfo[8] =  {     {  8,  8, 1, ( void *)ASCII_08X16}, { 16, 16, 2, ( void *)HZ_16X16},   { 12, 12, 2, ( void *)ASCII_12X24}, { 24, 24, 3, ( void *)HZ_24X24}, }; GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ16_PropHZ = {       0xA1A1,        0xF7FE,       &GUI_FontHZ_CharInfo[1],       (void *)0,  }; GUI_CONST_STORAGE  GUI_FONT_PROP GUI_FontHZ16_PropASCII = {       0x0000,        0x007F,        &GUI_FontHZ_CharInfo[0],       (void GUI_CONST_STORAGE *)&GUI_FontHZ16_PropHZ,  }; GUI_CONST_STORAGE  GUI_FONT GUI_FontHZ16 =  {       GUI_FONTTYPE_PROP_HZ,        16,        16,        1,         1,         (void GUI_CONST_STORAGE *)&GUI_FontHZ16_PropASCII }; GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ24_PropHZ = {       0xA1A1,        0xF7FE,       &GUI_FontHZ_CharInfo[3],       (void *)0,  }; GUI_CONST_STORAGE  GUI_FONT_PROP GUI_FontHZ24_PropASCII = {       0x0000,        0x007F,        &GUI_FontHZ_CharInfo[2],       (void GUI_CONST_STORAGE *)&GUI_FontHZ24_PropHZ,  }; GUI_CONST_STORAGE  GUI_FONT GUI_FontHZ24 =  {       GUI_FONTTYPE_PROP_HZ,        24,        24,        1,         1,         (void GUI_CONST_STORAGE *)&GUI_FontHZ24_PropASCII }; 在GUI_UC_EncodeNone.c文件中填放如下代码: #include "GUI_Private.h" static U16 _GetCharCode(const char GUI_UNI_PTR * s) { if((*s)>0xA1){ return *(const U16 GUI_UNI_PTR *)s;  } return *(const U8 GUI_UNI_PTR *)s; } static int _GetCharSize(const char GUI_UNI_PTR * s)  { GUI_USE_PARA(s); if((*s) >= 0xA1) { return 2;  } return 1; } static int _CalcSizeOfChar(U16 Char) { GUI_USE_PARA(Char); if(Char >= 0xA1A1) { return 2; } return 1; } static int _Encode(char *s, U16 Char)  { if(Char >= 0xA1A1){ *((U16 *)s) = (U16)(Char); return 2; } *s = (U8)(Char); return 1; } const GUI_UC_ENC_APILIST GUI_UC_None = { _GetCharCode,     _GetCharSize,     _CalcSizeOfChar,   _Encode           }; const GUI_UC_ENC_APILIST GUI__API_TableNone = { _GetCharCode,   _GetCharSize,   _CalcSizeOfChar,   _Encode   }; void GUI_UC_SetEncodeNone(void) { #if GUI_SUPPORT_UNICODE GUI_LOCK(); GUI_Context.pUC_API = &GUI_UC_None; GUI_UNLOCK(); #endif } 在GUICharPEx.c文件中填入如下代码: #include "GUI_Private.h" #include "flash.h" extern const unsigned char ASCII_08X16[95][16]; extern const unsigned char ASCII_12X24[95][48]; //字模数据的暂存数组,以单个字模的最大字节数为设定值 #define BYTES_PER_FONT              48 static U8 GUI_FontDataBuf[BYTES_PER_FONT]; static void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c) { U8 qh,ql;   U32 foffset;  U32 i; U16 BytesPerFont; U8 *asciiaddr; U8 *baseaddr; baseaddr = (U8 *)pProp->paCharInfo->pData; BytesPerFont = GUI_pContext->pAFont->YSize * pProp->paCharInfo->BytesPerLine; //每个字模的数据字节数 if (BytesPerFont > BYTES_PER_FONT) BytesPerFont = BYTES_PER_FONT; if (c<0x80){                                  //英文字符地址偏移算法 if (c<0x20){ for(i=0;i GUI_FontDataBuf[i] = 0x00; //ASCII控制字符用黑块表示  } } else { asciiaddr = baseaddr + (c-0x20)*BytesPerFont; for(i=0;i GUI_FontDataBuf[i] = asciiaddr[i]; //调用ASCII字体  } }   } else { ql = c/256; qh = c%256; if (qh<0xA1||ql<0xA1||ql>0xFE||qh>0xF7){ //非常用汉字 for (i=0;i return; //结束访问 }           ql -= 0xA1; qh -= 0xA1;    foffset=((unsigned long)94*qh+ql)*BytesPerFont;//得到字库中的字节偏移量 flash_read(GUI_FontDataBuf,foffset+(U32)baseaddr,BytesPerFont); }   } void GUIPROP_HZ_DispChar(U16P c)  { int BytesPerLine; GUI_DRAWMODE DrawMode = GUI_pContext->TextMode; const GUI_FONT_PROP GUI_UNI_PTR *pProp = GUI_pContext->pAFont->p.pProp;  for (; pProp; pProp = pProp->pNext){ if ((c >= pProp->First) && (c <= pProp->Last)){ break; }     }     if (pProp){         GUI_DRAWMODE OldDrawMode;         const GUI_CHARINFO GUI_UNI_PTR * pCharInfo = pProp->paCharInfo;         GUI_GetDataFromMemory(pProp, c);//取出字模数据         BytesPerLine = pCharInfo->BytesPerLine;                         OldDrawMode  = LCD_SetDrawMode(DrawMode);         LCD_DrawBitmap(GUI_pContext->DispPosX, GUI_pContext->DispPosY,                        pCharInfo->XSize, GUI_pContext->pAFont->YSize,                        GUI_pContext->pAFont->XMag, GUI_pContext->pAFont->YMag,                        1,     /* Bits per Pixel */                        BytesPerLine,                        &GUI_FontDataBuf[0],//&GUI_FontDataBufText[0],//                        &LCD_BKCOLORINDEX                        ); if (GUI_pContext->pAFont->YDist > GUI_pContext->pAFont->YSize){ int YMag = GUI_pContext->pAFont->YMag; int YDist = GUI_pContext->pAFont->YDist * YMag; int YSize = GUI_pContext->pAFont->YSize * YMag; if (DrawMode != LCD_DRAWMODE_TRANS) { LCD_COLOR OldColor = GUI_GetColor(); GUI_SetColor(GUI_GetBkColor()); LCD_FillRect(GUI_pContext->DispPosX, GUI_pContext->DispPosY + YSize,  GUI_pContext->DispPosX + pCharInfo->XSize,                           GUI_pContext->DispPosY + YDist); GUI_SetColor(OldColor); } } LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */                 GUI_pContext->DispPosX += pCharInfo->XDist * GUI_pContext->pAFont->XMag;     } } int GUIPROP_HZ_GetCharDistX(U16P c, int * pSizeX)  { const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUI_pContext->pAFont->p.pProp;   for (; pProp; pProp = pProp->pNext) { if ((c >= pProp->First) && (c <= pProp->Last))break; } return (pProp) ? (pProp->paCharInfo)->XSize * GUI_pContext->pAFont->XMag : 0; } 最后,在emWin库的头文件GUI.h的恰当位置,约1750行处添加如下代码: extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16; extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ24; #define GUI_FONT_HZ16           &GUI_FontHZ16      #define GUI_FONT_HZ24           &GUI_FontHZ24 完成之后,编译一般不会不通过的,通过之后,可写如下小程序测试一下效果: int main( void ) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); //如果用stmemwin,这条代码必须有 flash_init(); //字库FLASH驱动初始化 GUI_Init(); GUI_Clear(); GUI_DispString("Hello!,草泥马就是羊驼! "); while (1){ GUI_Delay(100); } } OK!祝你成功!