【第3版emWin教程】第28章 emWin6.x的C文件格式的漢字生成和實現(Unicode編碼)


教程不斷更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

第28章       emWin6.x的C文件格式的漢字生成和實現(Unicode編碼)

本章節主要為大家講解官方的字體生成軟件FontCvt的使用方法,使用此軟件可以生成C文件格式的漢字全字庫,也可以生成C文件格式的小字庫,所謂小字庫就是需要顯示什么漢字就僅生成這些漢字。

FontCvt全稱Font Converter。

28.1 初學者重要提示

28.2  使用FontCvt生成字庫C文件的方法

28.3 C文件格式漢字的使用方法

28..4生成的是Unicode編碼字體,而使用時為什么是UTF-8

28.5 MDK4.X,MDK5.X和IAR的UTF-8編碼問題

28.6 實驗例程說明(RTOS)

28.7 實驗例程說明(裸機)

28.8 總結

 

 

28.1 初學者重要提示

1、  emWin官方提供的字體生成軟件FontCvt不支持GB編碼,所以只能使用FontCvt支持的Unicode編碼。

2、  字體小工具需要使用此貼提供的,其它大部分是Demo版本:

http://www.armbbs.cn/forum.php?mod=viewthread&tid=107218

3、  教程中讓大家將要顯示漢字的C文件轉換為UTF-8編碼,指的是將這個漢字所在的C文件轉換為UTF-8編碼,這點要切記,詳情請看28.4小節的說明。

另外特別注意MDK5編譯錯誤missing closing quote,解決辦法看本章教程第28.6.2小節。

4、  FontCvt的使用方法在emWin手冊中有講解,這個只有英文版手冊進行了詳細說明:

 

28.2 使用FontCvt生成C文件格式小字庫的方法

所謂小字庫就是需要顯示什么漢字就僅生成什么漢字,下面為大家講解如何生成C文件格式的小字庫。這里以生成“安富萊電子”五個字為例進行說明。

  •   第1步:在電腦桌面右擊鼠標->新建->文本文檔,即新建一個txt文本。

 

創建了文本文檔后,輸入“安富萊電子”五個字:

 

然后點擊菜單選項文件->另存為:

 

彈出如下窗口:

 

注:Win10選擇的是UTF-16 LE

此時桌面上就會生成一個名字為FontSong16的文本文檔。

  •   第2步:打開字體生成軟件FontCvt,選擇字體類型Standard,編碼選擇16bit Unicode

 

點擊OK后,彈出如下窗口:

 

再點擊確定后彈出FontCvt界面變成如下效果:

 

  •   第3步:點擊EDIT->Disable all characters

 

禁止所有字符后,字符區就全部變成灰色的了:

 

  •   第4步:點擊Edit->Read pattern file

 

  •   第5步:加載文件FontSong16.txt

 

點擊打開后,FontCvt軟件的字符顯示區中“安富萊電子”五個字的背景已經變成白色,下面是其中一個“萊”字的顯示效果:

 

  •   第6步:最后一步,點擊File->Save As

 

彈出如下窗口:

 

至此就生成了我們所需要的16點陣字體。以同樣的方法,我們再以此生成以下幾種字體:

1. 字體類型Standard,16bit Unicode編碼,32點陣,宋體,生成的文件名為FontSong32.c。

2. 字體類型Standard,16bit Unicode編碼,72點陣,宋體,生成的文件名為FontSong72.c。

3. 字體類型Standard,16bit Unicode編碼,144點陣,宋體,生成的文件名為FontSong144.c。

4. 字體類型Antialiased 4bpp(4倍抗鋸齒),16bit Unicode編碼,144點陣,宋體,生成的文件名為FontSongA144.c。

5. 字體類型Extended framed(擴展模式,帶邊框),16bit Unicode編碼,144點陣,宋體,生成的文件名為FontSongExF144.c。

6. 字體類型Extended antialiased 4bpp(擴展模式,4倍抗鋸齒),16bit Unicode編碼,144點陣,宋體,生成的文件名為FontSongExA144.c。

通過小軟件FontCvt,共生成了7種字體文件:

 

有了這幾個文件就可以進行相應字體的漢字顯示了,由於僅生成了“安富萊電子”這五個字,所以僅支持這五個字的顯示。接下來講解這7種字體文件如何使用。

28.3 使用FontCvt生成C文件格式全字庫的方法

由於FontCvt生成C文件格式的全字庫比較大,放在內部Flash非常占空間,所以基本不使用,不過生成方法要簡單說明下。

  •   第1步:打開字體生成軟件FontCvt,選擇字體類型Standard,編碼選擇16bit Unicode

 

點擊OK后,彈出如下窗口:

 

再點擊確定后彈出FontCvt界面變成如下效果:

 

  •   第2步:點擊File->Save As

 

彈出如下窗口:

 

此時,桌面上就生成了一個名為FontSong16.c的文件,實際在MDK工程中測試,此文件要占用1147060字節,即1MB多,所以實際項目中不推薦。

28.4 C文件格式漢字的使用方法

下面講解28.2小節生成的7種字體C文件的使用方法,這里將MDK和IAR分別進行說明:

28.4.1   MDK編譯器中使用C文件格式漢字的方法

  •   第1步:將生成的7種字體文件添加到MDK工程目錄里面,本章節配套的例子是將其放在User->fonts文件夾下

 

  •   第2步:將生成的7種字體文件添加到MDK工程中

 

  •   第3步:調用函數GUI_UC_SetEncodeUTF8()來使能UTF-8編碼,這一步是必須的,切不可以忘了。
  •   第4步:此時就可以使用這7種字體了,打開這7個字體文件,每個文件的開頭都有一個extern的字體聲明。

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;

如果用戶要在哪個源碼文件里面使用這些字體,就把這些字體聲明放在相應源文件的開頭就行。使用方法,跟使用emWin自帶的ASCII和ISO 8859-1字體基本是一樣的,唯一區別的地方是:調用FontCvt生成的字體時要加上取地址操作&。下面舉一個完整的例子,代碼在本章節配套例子的MainTask.c文件里面(對於初學者來說,對話框,按鈕控件和文本控件還沒有講到,這里只是舉個例子,會使用這些新生成的字體即可,后面會講到這些控件):

#include "MainTask.h"
#include "includes.h"



/*
*********************************************************************************************************
*                     調用外部字體聲明,這個就是第4步中所說的問題
*********************************************************************************************************
*/
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                                
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;


/*
*********************************************************************************************************
*                                      對話框資源列表
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    { FRAMEWIN_CreateIndirect,  "armfly", 0,         0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
    { BUTTON_CreateIndirect,    "安富萊我們我們",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
    { TEXT_CreateIndirect,      "安富萊電子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
    { TEXT_CreateIndirect,      "安富萊電子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
    { TEXT_CreateIndirect,      "安富萊",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
};

/*
*********************************************************************************************************
*    函 數 名: PaintDialog
*    功能說明: 對話框重繪函數
*    形    參:pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
void PaintDialog(WM_MESSAGE   * pMsg)
{
//    WM_HWIN hWin = pMsg->hWin;
    
}

/*
*********************************************************************************************************
*    函 數 名: 對話框初始化
*    功能說明: 對話框初始化
*    形    參: pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
void InitDialog(WM_MESSAGE * pMsg)
{
    WM_HWIN hWin = pMsg->hWin;
    
    //
    // 配置FrameWin
    //
    FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
    FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
    FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
    FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
    FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
    FRAMEWIN_SetTitleHeight(hWin,35);
    
/* 外部的7種字體在文件控件TEXT和按鈕控件BUTTON中都使用了,具體調用方法如下,
跟使用emWin自帶的字體是一樣的。*/
    //
    // 按鈕的字體是4倍抗鋸齒,144點陣
    //                                                               
    BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                    
    
    //
    // 分別用16點陣,32點陣和72點陣字體顯示 安富萊電子 五個字。
    //
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);

    //
    // 分別用144點陣漢字,144點陣的擴展模式且4倍抗鋸齒漢字,144點陣的4倍抗鋸齒漢字和
    // 144點陣的擴展模式且帶邊框漢字。
    //
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
}

/*
*********************************************************************************************************
*    函 數 名: _cbCallback
*    功能說明: 對話框回調函數
*    形    參: pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
static void _cbCallback(WM_MESSAGE * pMsg) 
{
    int NCode, Id;
    WM_HWIN hWin = pMsg->hWin;
    switch (pMsg->MsgId) 
    {
        case WM_PAINT:
            PaintDialog(pMsg);
            break;
        
        case WM_INIT_DIALOG:
            InitDialog(pMsg);
            break;
        
        case WM_KEY:
            switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) 
            {
                case GUI_KEY_ESCAPE:
                    GUI_EndDialog(hWin, 1);
                    break;
                case GUI_KEY_ENTER:
                    GUI_EndDialog(hWin, 0);
                    break;
            }
            break;
            
        case WM_NOTIFY_PARENT:
            Id = WM_GetId(pMsg->hWinSrc); 
            NCode = pMsg->Data.v;        
            switch (Id) 
            {
                case GUI_ID_OK:
                    if(NCode==WM_NOTIFICATION_RELEASED)
                        GUI_EndDialog(hWin, 0);
                    break;
                    
                case GUI_ID_CANCEL:
                    if(NCode==WM_NOTIFICATION_RELEASED)
                        GUI_EndDialog(hWin, 0);
                    break;

            }
            break;
            
        default:
            WM_DefaultProc(pMsg);
    }
}

/*
*********************************************************************************************************
*    函 數 名: MainTask
*    功能說明: GUI主函數
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
void MainTask(void) 
{
    /* 初始化 */
    GUI_Init();
     
    WM_MULTIBUF_Enable(1);
    
    /* 使能UTF-8編碼,這個是第3步中所說的問題,不必限制一定要放在這個位置,使用外部字體之前調用了即可 */     
    GUI_UC_SetEncodeUTF8(); 
    
    /* 調用此函數會自動的刷新桌面窗口 */
    WM_SetDesktopColor(GUI_WHITE); 

    /* 創建對話框 */
    GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
    
    while(1) 
    {
        GUI_Delay(10);
    }
}

通過上面的代碼就實現了這7種字體的顯示,具體效果可以看實驗例程說明。

  •   第5步:這個是最重要的一步,很多初學者顯示漢字失敗就是因為這一步了。

修改漢字顯示所在的源文件,即MainTask.c文件為UTF-8編碼,並不是修改FontCvt生成的C文件為UTF-8編碼,因為FontCvt軟件生成的C文件已經是UTF-8編碼了。也就是說哪個文件用到這種漢字顯示了,哪個文件就修改編碼類型為UTF-8,只有這樣,MDK才可以將這些漢字的編碼識別出來,要不識別出來的漢字編碼與FontCvt生成字體的編碼類型不匹配,從而無法正確顯示。

修改編碼類型也比較容易,使用電腦自帶的記事本即可,將MainTask.C文件用記事本打開:

 

點擊文件->另存為

 

彈出如下窗口:

 

點擊保存后,會彈出如下窗口:

 

重新切換回MDK工程,也會彈出一個窗口:

 

這樣MainTask.c文件就變成UTF-8編碼了。此時就可以全編譯工程並下載例子到開發板進行測試了。

28.4.2   IAR編譯器中使用C文件格式漢字的方法

  •   第1步:將生成的7種字體文件添加到IAR工程目錄里面,本章節配套的例子是將其放在User->fonts文件夾下

 

  •   第2步:將生成的7種字體文件添加到IAR工程中

  •   第3步:調用函數GUI_UC_SetEncodeUTF8()來使能UTF-8編碼,這一步是必須的,切不可以忘了。
  •   第4步:此時就可以使用這7種字體了,打開這7個字體文件,每個文件的開頭都有一個extern的字體聲明。

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;

extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;

如果用戶要在哪個源碼文件里面使用這些字體,就把這些字體聲明放在相應源文件的開頭就行。使用方法,跟使用emWin自帶的ASCII和ISO 8859-1字體基本是一樣的,唯一區別的地方是:調用FontCvt生成的字體時要加上取地址操作&。下面舉一個完整的例子,代碼在本章節配套例子的MainTask.c文件里面(對於初學者來說,對話框,按鈕控件和文本控件還沒有講到,這里只是舉個例子,會使用這些新生成的字體即可,后面會講到這些控件):

#include "MainTask.h"
#include "includes.h"



/*
*********************************************************************************************************
*                     調用外部字體聲明,這個就是第4步中所說的問題
*********************************************************************************************************
*/
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong16;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong32;                                                
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong72;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSong144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongA144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExA144;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontFontSongExF144;


/*
*********************************************************************************************************
*                                      對話框資源列表
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    { FRAMEWIN_CreateIndirect,  "armfly", 0,         0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},
    { BUTTON_CreateIndirect,    "安富萊我們我們",    GUI_ID_BUTTON0,          350,20,420,150,0,0},
    { TEXT_CreateIndirect,      "安富萊電子",        GUI_ID_TEXT0,            5, 10, 300, 33, 0,0},
    { TEXT_CreateIndirect,      "安富萊電子",        GUI_ID_TEXT1,            5, 40,250, 50, 0,0},
    { TEXT_CreateIndirect,      "安富萊",            GUI_ID_TEXT2,            5, 100,360, 90, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT3,            5, 220,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT4,            205, 230,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT5,            405, 230,144, 144, 0,0},
    { TEXT_CreateIndirect,      "",                GUI_ID_TEXT6,            605, 230,144, 144, 0,0}
};

/*
*********************************************************************************************************
*    函 數 名: PaintDialog
*    功能說明: 對話框重繪函數
*    形    參:pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
void PaintDialog(WM_MESSAGE   * pMsg)
{
//    WM_HWIN hWin = pMsg->hWin;
    
}

/*
*********************************************************************************************************
*    函 數 名: 對話框初始化
*    功能說明: 對話框初始化
*    形    參: pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
void InitDialog(WM_MESSAGE * pMsg)
{
    WM_HWIN hWin = pMsg->hWin;
    
    //
    // 配置FrameWin
    //
    FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII);
    FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
    FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
    FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
    FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
    FRAMEWIN_SetTitleHeight(hWin,35);
    
/* 外部的7種字體在文件控件TEXT和按鈕控件BUTTON中都使用了,具體調用方法如下,
跟使用emWin自帶的字體是一樣的。*/
    //
    // 按鈕的字體是4倍抗鋸齒,144點陣
    //                                                               
    BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontFontSongA144);                    
    
    //
    // 分別用16點陣,32點陣和72點陣字體顯示 安富萊電子 五個字。
    //
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontFontSong16);
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontFontSong32);
    TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontFontSong72);

    //
    // 分別用144點陣漢字,144點陣的擴展模式且4倍抗鋸齒漢字,144點陣的4倍抗鋸齒漢字和
    // 144點陣的擴展模式且帶邊框漢字。
    //
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT3),&GUI_FontFontSong144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT4),&GUI_FontFontSongExA144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT5),&GUI_FontFontSongA144);
    TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT6),&GUI_FontFontSongExF144);
}

/*
*********************************************************************************************************
*    函 數 名: _cbCallback
*    功能說明: 對話框回調函數
*    形    參: pMsg   消息指針
*    返 回 值: 無
*********************************************************************************************************
*/
static void _cbCallback(WM_MESSAGE * pMsg) 
{
    int NCode, Id;
    WM_HWIN hWin = pMsg->hWin;
    switch (pMsg->MsgId) 
    {
        case WM_PAINT:
            PaintDialog(pMsg);
            break;
        
        case WM_INIT_DIALOG:
            InitDialog(pMsg);
            break;
        
        case WM_KEY:
            switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) 
            {
                case GUI_KEY_ESCAPE:
                    GUI_EndDialog(hWin, 1);
                    break;
                case GUI_KEY_ENTER:
                    GUI_EndDialog(hWin, 0);
                    break;
            }
            break;
            
        case WM_NOTIFY_PARENT:
            Id = WM_GetId(pMsg->hWinSrc); 
            NCode = pMsg->Data.v;        
            switch (Id) 
            {
                case GUI_ID_OK:
                    if(NCode==WM_NOTIFICATION_RELEASED)
                        GUI_EndDialog(hWin, 0);
                    break;
                    
                case GUI_ID_CANCEL:
                    if(NCode==WM_NOTIFICATION_RELEASED)
                        GUI_EndDialog(hWin, 0);
                    break;

            }
            break;
            
        default:
            WM_DefaultProc(pMsg);
    }
}

/*
*********************************************************************************************************
*    函 數 名: MainTask
*    功能說明: GUI主函數
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
void MainTask(void) 
{
    /* 初始化 */
    GUI_Init();
     
    WM_MULTIBUF_Enable(1);
    
    /* 使能UTF-8編碼,這個是第3步中所說的問題,不必限制一定要放在這個位置,使用外部字體之前調用了即可 */     
    GUI_UC_SetEncodeUTF8(); 
    
    /* 調用此函數會自動的刷新桌面窗口 */
    WM_SetDesktopColor(GUI_WHITE); 

    /* 創建對話框 */
    GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
    
    while(1) 
    {
        GUI_Delay(10);
    }
}

通過上面的代碼就實現了這7種字體的顯示,具體效果可以看實驗例程說明。

  •   第5步:這個是最重要的一步,很多初學者顯示漢字失敗就是因為這一步了。

修改漢字顯示所在的源文件,即MainTask.c文件為UTF-8編碼,並不是修改FontCvt生成的C文件為UTF-8編碼,因為FontCvt軟件生成的C文件已經是UTF-8編碼了。也就是說哪個文件用到這種漢字顯示了,哪個文件就修改編碼類型為UTF-8,只有這樣,IAR將這些漢字的編碼識別出來,要不識別出來的漢字編碼與FontCvt生成字體的編碼類型不匹配,從而無法正確顯示。

修改編碼類型也比較容易,使用IAR的話,不要使用記事本來修改了(為什么不可以使用,在28.5小節有講解),IAR編輯器支持編碼類型的修改。

 

IAR編碼方面的小知識:

默認情況下,IAR創建的工程都是System編碼,也就是你的電腦系統是什么編碼類型,使用IAR創建的.C和.H文件就是什么編碼類型,一般大陸都是用的GBK編碼,查看電腦系統編碼類型可以通過:單擊開始->所有程序->附件->命令提示符,打開命令提示符,輸入chcp,然后點擊鍵盤的回車鍵。

 

這里的936就是代表GBK編碼。而IAR的編碼設置在這里,點擊菜單Tools->Options,彈出如下窗口

 

默認的編碼類型是System。

 

在IAR編譯器中如何查看.C和.H文件的編碼類型,又如何修改呢?查看編碼類型可以任意打開一個文件,然后查看右下角。

 

這里打開的就是一個中文簡體,GB2312編碼,GBK向下是完全兼容GB2312的。修改單個.C和.H文件的編碼類型也比較簡單,這里我們需要修改MainTask.c文件的編碼類型為UTF-8,直接在MainTask.c文件里面右擊鼠標,選擇Character Encoding->Convert to UTF-8。

 

設置后就可以看到右下角已經修改為UTF-8了。

 

此時就可以全編譯工程並下載例子到開發板進行測試了。

28.5 生成的是Unicode編碼字體,而使用時為什么是UTF-8

初學者容易有這樣的疑問,FontCvt軟件生成的是Unicode編碼的漢字,為什么emWin使用的時候不直接使用,還要多一次轉換,即我們操作的時候是用的UTF-8編碼字體,emWin的庫函數會將這個編碼轉換成Unicode編碼,然后從Unicode編碼的字符集中獲取相應的點陣數據。

 

補充點小知識,方便大家理解:

  • Unicode編碼

各個國家都有一套自己的編碼標准,但誰也不懂誰的編碼,誰也不支持別人的編碼。基於此,國際組織決定着手解決這個問題,即重新弄一套包括了地球上所有文化、所有字母和符號的編碼。將其命名為"UniversalMultiple-Octet Coded Character Set“(通用多八位編碼字符集),簡稱 UCS, 俗稱Unicode。Unicode有兩種編碼UCS-2和UCS-4,其中UCS-2用兩個字節編碼,UCS-4用4個字節編碼。

  • UTF-8編碼

事實證明,對可以用ASCⅡ表示的字符使用UNICODE並不高效,因為UNICODE比ASCⅡ占用大一倍的空間,而對ASCⅡ來說高字節的0對他毫無用處。為了解決這個問題,就出現了一些中間格式的字符集,他們被稱為通用轉換格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7,UTF-7.5,UTF-8,UTF-16以及 UTF-32。

 

那么問題來了,emWin中為什么不直接使用Unicode編碼,而要使用UTF-8。

1.  MDK和IAR的編輯器都不支持Unicode編碼,僅支持UTF-8,筆者認為,這個是最主要的原因。

2.  UTF-8編碼相對於Unicode編碼的優勢。

(1) UTF-8表示與ASCII字符表示是一樣的,只占一個字節,解決了Unicode浪費空間的情況。

(2) 與CPU字節順序無關, 可以在不同平台之間交流。

(3) 容錯能力高, 任何一個字節損壞后, 最多只會導致一個編碼碼位損失, 不會連鎖錯誤。

28.6 MDK4.X,MDK5.X和IAR的UTF-8編碼問題

對於初學者來說,下面的問題是必看的,初次看可能不太理解,實際用這三個編譯器操作了本章節配套的例子就有深刻的體會了。

28.6.1   MDK4.X的UTF-8說明

MDK4.74是MDK4系列里面的最后一個版本了。

一直以來都是將漢字顯示所在的源文件使用記事本另存為UTF-8編碼類型,特別注意,記事本另存的是UTF-8 帶 BOM。且用戶修改了這個文件的任何地方,MDK都會自動將這個文件存儲為UTF-8編碼無BOM。實際用Notepad++另存為UTF-8帶BOM或者不帶BOM,使用MDK4.74都可以正確顯示漢字的。

28.6.2   MDK5.X的UTF-8說明

對於MDK5.X來說,也可以使用記事本將漢字顯示所在的源文件另存為UTF-8編碼類型,此時MDK5.21a是可以正確編譯的。但是,用戶一旦修改了這個文件的任何地方,直接編譯或者保存后編譯,MDK都會將這個文件存儲為UTF-8編碼無BOM,而MDK5.X無法像MDK4.X那樣帶BOM或者不帶BOM都能夠識別,所以編譯會出錯。解決方法:options->c/c++->Misc controls 填寫“--locale=english”

 

28.6.3   IAR的UTF-8說明

對於IAR來說,他僅支持UTF-8無BOM,修改的時候不要使用記事本,直接在漢字顯示所在的源文件右擊選擇即可(在28.4.2小節已經講解),或者用Notepad++選擇UTF-8無BOM。

28.6.4   編碼問題總結

  •   IAR僅支持UTF-8編碼無BOM文件的漢字顯示,帶BOM的話,編譯不通過。
  •   MDK4.X對於UTF-8帶BOM或者不帶BOM都支持,但會將帶BOM文件修改為不帶BOM,兩種編碼形式顯示漢字都不受影響。
  •   MDK5.X對於UTF-8帶BOM或者不帶BOM都支持,不過需要大家按照28.6.2小結的說明修改。

 

名詞解釋:BOM

     BOM(Byte Order Mark),字節順序標記,出現在文本文件頭部,Unicode編碼標准中用於標識文件是采用哪種格式的編碼。UTF-8 不需要 BOM 來表明字節順序,但可以用 BOM 來表明編碼方式。字符 "Zero Width No-Break Space" 的 UTF-8 編碼是 EF BB BF。所以如果接收者收到以 EF BB BF 開頭的字節流,就知道這是 UTF-8編碼了。Windows 就是使用 BOM 來標記文本文件的編碼方式的。

     WINDOWS自帶的記事本等軟件,在保存一個以UTF-8編碼的文件時,會在文件開始的地方插入三個不可見的字符(0xEF 0xBB 0xBF,即BOM)。它是一串隱藏的字符,用於讓記事本等編輯器識別這個文件是否以UTF-8編碼。

 

28.7 實驗例程說明(RTOS)

配套例子:

V7-532_emWin6.x實驗_C文件格式的漢字生成和實現,Unicode編碼(RTOS)

實驗目的:

  1. 學習emWin的C文件格式漢字的使用方法,Unicode編碼。
  2. emWin功能的實現在MainTask.c文件里面。

實驗內容:

1、K1按鍵按下,串口或者RTT打印任務執行情況(串口波特率115200,數據位8,奇偶校驗位無,停止位1)。

2、(1) 凡是用到printf函數的全部通過函數App_Printf實現。

(2) App_Printf函數做了信號量的互斥操作,解決資源共享問題。

3、默認上電是通過串口打印信息,如果使用RTT打印信息:

MDK AC5,MDK AC6或IAR通過使能bsp.h文件中的宏定義為1即可

#define Enable_RTTViewer  1

4、各個任務實現的功能如下:

App Task Start   任務 :啟動任務,這里用作BSP驅動包處理。

App Task MspPro任務 :消息處理,這里用作LED閃爍。

App Task UserIF  任務 :按鍵消息處理。

App Task COM   任務 :暫未使用。

App Task GUI    任務 :GUI任務。

μCOS-III任務調試信息(按K1按鍵,串口打印):

 

RTT 打印信息方式:

 

程序設計:

  •   任務棧大小分配:

μCOS-III任務棧大小在app_cfg.h文件中配置:

#define  APP_CFG_TASK_START_STK_SIZE                      512u

#define  APP_CFG_TASK_MsgPro_STK_SIZE                     2048u

#define  APP_CFG_TASK_COM_STK_SIZE                        512u

#define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u

#define  APP_CFG_TASK_GUI_STK_SIZE                        2048u

任務棧大小的單位是4字節,那么每個任務的棧大小如下:

App Task Start   任務 :2048字節。

App Task MspPro任務 :8192字節。

App Task UserIF  任務 :2048字節。

App Task COM   任務 :2048字節。

App Task GUI    任務 :8192字節。

  •   系統棧大小分配:

μCOS-III的系統棧大小在os_cfg_app.h文件中配置:

#define  OS_CFG_ISR_STK_SIZE                      512u     

系統棧大小的單位是4字節,那么這里就是配置系統棧大小為2KB

emWin動態內存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通過宏定義來配置使用內部SRAM還是外部的SDRAM做為emWin的動態內存,當配置:

#define  EX_SRAM     1 表示使用外部SDRAM作為emWin動態內存,大小24MB。

#define  EX_SRAM     0 表示使用內部SRAM作為emWin動態內存,大小100KB。

默認情況下,本教程配套的所有emWin例子都是用外部SDRAM作為emWin動態內存。

emWin界面顯示效果:

800*480分辨率界面效果。

 

28.8 實驗例程說明(裸機)

配套例子:

V7-531_emWin6.x實驗_C文件格式的漢字生成和實現,Unicode編碼(裸機)

實驗目的:

  1. 學習emWin的C文件格式漢字的使用方法,Unicode編碼。
  2. emWin功能的實現在MainTask.c文件里面。

emWin界面顯示效果:

800*480分辨率界面效果。

 

emWin動態內存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通過宏定義來配置使用內部SRAM還是外部的SDRAM做為emWin的動態內存,當配置:

#define  EX_SRAM     1 表示使用外部SDRAM作為emWin動態內存,大小24MB。

#define  EX_SRAM     0 表示使用內部SRAM作為emWin動態內存,大小100KB。

默認情況下,本教程配套的所有emWin例子都是用外部SDRAM作為emWin動態內存。

 

28.9 總結

本章節講解的內容較多,特別是涉及到UTF-8編碼的問題時,望初學者務必將其掌握,有了本章節的基礎,后面幾個章節的漢字顯示操作起來將更加的得心應手。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM