SDL入門教程(十):2、直接通過Unicode讓SDL顯示中文
阿新 • • 發佈:2019-02-20
作者:龍飛
2.1:SDL本身可以顯示中文嗎?
SDL的擴充套件庫SDL_ttf本身具備顯示中文的功能嗎?網上很多觀點,說不能顯示的,甚至做了分析解釋了原因。但是,事實是,SDL本身就可以顯示中文。如果我們看看SDL_ttf.c的原始碼,我們可以看到,最終用於構建SDL_Surface平面的函式,在三種顯示模式(Solid, Shaded, Blended)下,都是其對應的TTF_RenderUNICODE_Xxx()函式。我們以TTF_RenderUNICODE_Blended()為例:
SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font, const Uint16 *text, SDL_Color fg)
可以看到,Unicode碼是通過Uint16的陣列傳遞的。在官方文件中,採用這樣的形式:
// Render some UNICODE text in blended black to a new surface
// then blit to the upper left of the screen
// then free the text surface
//SDL_Surface *screen;SDL_Color color={0,0,0};
SDL_Surface *text_surface;
Uint16 text[]={'H','e','l' ,'l','o','',
'W','o','r','l','d','!'};
if(!(text_surface=TTF_RenderUNICODE_Blended(font,text,color))) {
//handle error here, perhaps print TTF_GetError at least} else {
SDL_BlitSurface(text_surface,NULL,screen,NULL);
//perhaps we can reuse it, but I assume not for simplicity. SDL_FreeSurface(text_surface);
}
請注意對Uint16 text[]的定義,既然是Uint16的陣列,也意味著我們可以直接用數字作為這個陣列的元素。
2.2:獲得字串的Unicode碼
SDL的不能正確顯示中文的問題,首先出在SDL_ttf沒有提供正確渲染中文的函式,或者再精確點說,沒有提供正確渲染GB2312碼的函式。SDL_ttf提供了渲染UTF-8的函式,但是很不幸,漢字資訊並不是通過UTF-8傳遞給程式的——即使是我們在po檔案中指明瞭使用UTF-8,程式呼叫的時候依然被轉化成了GB2312——至少在win32下是這樣。
所以,顯示中文最簡單的辦法——同時也是最複雜的實現,即直接給渲染Unicode的SDL_ttf函式傳遞漢字字串的Unicode碼。我們可以通過MFC的函式得到,而事實上,我根本沒裝MFC。獲得漢字Unicode的方法,一方面可以查表,另外,也可以通過工具軟體查詢。以下是個實用的小工具,事實上,在以後的研究中,我一直用這個工具檢驗編碼之間轉換的正確性。
http://blog.ednchina.com/chinaluou/85656/Message.aspx
這下就簡單了。比如我們要輸出“你好”,找到它的Unicode碼:4F60 597D。因為SDL是通過Uint16傳遞Unicode的,所以,對應的陣列應該寫成:(別忘了最後加一個空元素表示結尾)
Uint16 text[] = {0x4F60, 0x597D, 0}; 這樣,SDL就可以正確的顯示中文了。注意:請使用支援中文的字型檔TTF檔案。
但是很麻煩,不是嗎?我們當然希望漢字是可以自動轉換為SDL可以渲染的編碼,所以,研究還得繼續。所有的問題總是能解決的。^^
2.1:SDL本身可以顯示中文嗎?
SDL的擴充套件庫SDL_ttf本身具備顯示中文的功能嗎?網上很多觀點,說不能顯示的,甚至做了分析解釋了原因。但是,事實是,SDL本身就可以顯示中文。如果我們看看SDL_ttf.c的原始碼,我們可以看到,最終用於構建SDL_Surface平面的函式,在三種顯示模式(Solid, Shaded, Blended)下,都是其對應的TTF_RenderUNICODE_Xxx()函式。我們以TTF_RenderUNICODE_Blended()為例:
SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font,
// Render some UNICODE text in blended black to a new surface
// then blit to the upper left of the screen
// then free the text surface
//SDL_Surface *screen;SDL_Color color={0,0,0};
SDL_Surface *text_surface;
Uint16 text[]={'H','e','l'
'W','o','r','l','d','!'};
if(!(text_surface=TTF_RenderUNICODE_Blended(font,text,color))) {
//handle error here, perhaps print TTF_GetError at least} else {
SDL_BlitSurface(text_surface,NULL,screen,NULL);
//perhaps we can reuse it, but I assume not for simplicity. SDL_FreeSurface(text_surface);
}
2.2:獲得字串的Unicode碼
SDL的不能正確顯示中文的問題,首先出在SDL_ttf沒有提供正確渲染中文的函式,或者再精確點說,沒有提供正確渲染GB2312碼的函式。SDL_ttf提供了渲染UTF-8的函式,但是很不幸,漢字資訊並不是通過UTF-8傳遞給程式的——即使是我們在po檔案中指明瞭使用UTF-8,程式呼叫的時候依然被轉化成了GB2312——至少在win32下是這樣。
所以,顯示中文最簡單的辦法——同時也是最複雜的實現,即直接給渲染Unicode的SDL_ttf函式傳遞漢字字串的Unicode碼。我們可以通過MFC的函式得到,而事實上,我根本沒裝MFC。獲得漢字Unicode的方法,一方面可以查表,另外,也可以通過工具軟體查詢。以下是個實用的小工具,事實上,在以後的研究中,我一直用這個工具檢驗編碼之間轉換的正確性。
http://blog.ednchina.com/chinaluou/85656/Message.aspx
這下就簡單了。比如我們要輸出“你好”,找到它的Unicode碼:4F60 597D。因為SDL是通過Uint16傳遞Unicode的,所以,對應的陣列應該寫成:(別忘了最後加一個空元素表示結尾)
Uint16 text[] = {0x4F60, 0x597D, 0}; 這樣,SDL就可以正確的顯示中文了。注意:請使用支援中文的字型檔TTF檔案。
但是很麻煩,不是嗎?我們當然希望漢字是可以自動轉換為SDL可以渲染的編碼,所以,研究還得繼續。所有的問題總是能解決的。^^