前面教程里,我们只显示图片,没提到如何显示文字, sdl本身没有显示文字功能,它需要用扩展库sdl_ttf来显示文字。ttf是true type font的缩写,ttf是windows下的缺省字体,它有美观,放大缩小不变形的优点,因此广泛应用很多场合。
使用ttf库的第一件事要从windows的字库下拷贝出一个字库出来,最好是中文字体,这样可以同时支持英文和中文显示。它一般在c:\windows\fonts 目录下面。比如simhei.ttf 就是仿黑体的字库,将这个文件拷贝到你的源文件目录下。
下载完成后按以前方式安装(sdl安装教程里有讲),然后在你的源文件里加载头文件"sdl_ttf.h”。要显示文字需要按以下步骤进行:
一.初始ttf库
初始化ttf库要调用ttf_init(),成功返回-1,不成功返回0。
二.打开一个ttf_font字体.
使用 ttf_font *ttf_openfont(const char *file, int ptsize);函数打开字体
其中file是指字体文件的路径,可以为相对路径或绝对路径, ptsize是指字号,即字体大小。它是基于720dpi的,有一个简单办法来估算字体大小,在word中 选择相应的字号即可看出效果来,不成功返回null。以下是打开一个黑体代码,字号20,字体文件跟原文件在同一个目录下。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
三.将文字转换成表面
要想显示文字,首先要将文字渲染成一副图像,将文字渲染成一个图像表面,有三种渲染方式:
solid 渲染的最快,但效果最差,文字不平滑,是单色文字,不带边框。
shaded 比solid渲染的慢,但显示效果好于solid,带阴影。
blend 渲染最慢,但显示效果最好。
四.把文字sdl_surface 输出到屏幕显示,如果不需它,必须释放它
文字表面和其他表面一样,可以传输到显示表面显示。
五.关闭ttf_font字体
使用 void ttf_closefont(ttf_font *font) ;关闭字体
六.释放ttf库
如果不需要再显示文字,可以释放ttf库,使用 void ttf_quit() ;
下面以一个例子展示一下如何显示文字,程序运行效果:
在这个例子里我们要掌握如何显示西文、中文,以及如何给程序设置标题、图标。程序主要代码如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
其中font.h是自己定义的头文件,声明了常用的变量、常量、函数,其代码如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
其中引用了windows.h,因为要做c语言字符串和宽字节字符的转换要用到其中函数。c语言本身没有bool类型,所以用typedef定义了自己的布尔类型,并且声明了布尔常量true和false。
下面我们从主函数说起,在第10行和12行我们看到了一种新的数据类型wcha_t,其实这是c99新加的一种宽字符类型,c语言char类型用一个字节表示一个ansi字符,但汉字、日文等文字无法表示,所以引入了wchar_t,wchar_t用两个字节表示一个字符,所以它可以表示绝大多数字符,无论是那种语言,unicode字符是wchar_t一种实现,在c语言中,unicode字符串一般来说都是wchar_t类型。ttf库中提供了unicode字符串显示和utf8字符串显示,要显示中文必须是这两种串才能显示。
第14行init函数完成系统初始化,包括初始化sdl、建立主窗口、初始化ttf库,设置程序标题、图标。其代码如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
注意要设置程序图标,必须在建立主窗口前调用sdl_wm_seticon(sdl_loadbmp(aicon), null);来设置图标,图标必须是32*32的bmp图片,因为ttf库不是sdl自己的,所以必须调用ttf_init()单独初始化;最后设置程序标题,注意标题如果设英文可以直接显示,但如果像我们这个程序这样显示中文,则必须将字符串转换成utf8的才能显示,所以我们调用了自定义的函数localetoutf8(acaption)完成将c语言的字符串转换成utf8格式的字符串,这个函数定义如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
这个函数完成将c语言字符串转换成utf8格式的字符串。 这样我们就可以设置中文程序标题了。
在主函数的第20行我们打开了一个字体库,并设置字号为20,关于字号的大小你可以打开word看一下字号的大小。接下来,在33行我们调用ttf_rendertext_solid将文字渲染成一幅图片,返回图片表面的指针,这个函数只能显示西文,不能显示中文。其原型:
sdl_surface *ttf_rendertext_solid(ttf_font *font, const char *text, sdl_color fg);
参数:font,打开的字体;text要显示的字符串,c语言格式的字符串(以\0做结束符);fg是文字的颜色,前面我们介绍过sdl_color结构,这里不再多说。
除了这种渲染,还有:
sdl_surface *ttf_rendertext_shaded(ttf_font *font, const char *text, sdl_color fg, sdl_color bg);
其中font、text和fg与ttf_rendertext_solid中的一样,bg是文字背景色。
sdl_surface *ttf_rendertext_blended(ttf_font *font, const char *text, sdl_color fg)和ttf_rendertext_solid参数一样,关于这三种渲染的差别前面已经提过,运行结果页显示了blend效果最好,solid最差,shade可以设置文字背景。
然后我们把这些表面和显示图片一样显示就可以了,36至40我们调用了自定义函数显示文字:
void applysurface( int x, int y, sdl_surface* source, sdl_surface* destination );
x、y是文字显示到屏幕上的位置,source是文字表面,destination是目标表面,一般是显示表面。
显示西文比较简单。显示中文稍微麻烦点,如果你把char tmp[]="世界,你好!";显示到屏幕,调用ttf_rendertext_solid只会显示一堆乱码,因为这个函数只能显示西文,如果要显示中文要调用:
显示utf8字符串
sdl_surface *ttf_renderutf8_solid(ttf_font *font, const char *text, sdl_color fg);
sdl_surface *ttf_renderutf8_shaded(ttf_font *font, const char *text, sdl_color fg, sdl_color bg);
sdl_surface *ttf_renderutf8_blended(ttf_font *font, const char *text, sdl_color fg);
显示unicode字符串
sdl_surface *ttf_renderunicode_solid(ttf_font *font, const uint16 *text, sdl_color fg) ;
sdl_surface *ttf_renderunicode_shaded(ttf_font *font, const uint16 *text, sdl_color fg, sdl_color bg) ;
sdl_surface *ttf_renderunicode_blended(ttf_font *font, const uint16 *text, sdl_color fg) ;
这些函数的参数和前面差不多,唯一不同是要求text必须是utf8或unicode格式的。那么如何将c语言字符串转换成utf8字符串或unicode字符串呢,前面我们使用自定义的函数char *localetoutf8(char *src)将c字符串转换为utf8字符串返回,将c字符串转换成unicode字符串,我们自定义了函数:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLlR2bjlHcvN2LcNXZnFWbp9CXt92YuM3ZvxmYuNmLu9Wbt92Yvw1LcpDc0RHaiojIsJye.gif)
这个函数完成将c语言字符串转换成unicode字符串返回,使用这两个函数要注意,在函数中我们动态分配了内存来保存utf8或unicode字符串,然后将其返回,所以我们在调用函数中显示完后必须释放这些字符串所占空间。主函数第43行我们将tmp串转换成unicode串返回给p,然后显示,在54行释放了p。
在第57行我们关闭了前面打开的字体,因为下面我们将用大一点字体显示,如果要显示中文,其实最简单的办法是在程序里直接定义wchar_t类型数组保存unicode字符串,然后可以直接显示这个字符串,在第12行我们定义了wchar_t msg[] =l"圣 旨";unicode的字符串,注意unicode字符串必须以l开头,否则就是c语言的字符串了。在第66-69行我们直接将其显示到屏幕了。你也可以显示unicode常量串,第71-78行我们分别显示了两个unicode常量串。