SDL入门教程(十):2、直接通过Unicode让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,
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的数组,也意味着我们可以直接用数字作为这个数组的元素。
// 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);
}
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可以渲染的编码,所以,研究还得继续。所有的问题总是能解决的。^^