SDL入门教程(十):5、SDL完美显示中文
作者:龙飞
注意:请使用支持中文的TTF字库。
5.1:构建可以正确显示中文的SDL_ttf函数
世界终于又充满了光明!任何事情都是有答案的,不知道仅仅是因为我们还没有找到。解决了以上一系列问题,我们终于可以不依赖MFC,完全使用自由开源的资源,让SDL显示中文了!我们通过TTF_RenderUNICODE_Xxx()来构建这些函数:
//FileName: font.h
#ifndef FONT_H_
#define FONT_H_
#include " gb2312_to_Unicode.h "
#include " SDL/SDL_ttf.h "
SDL_Surface * myTTF_RenderString_Blended(TTF_Font * font, const std:: string & str, SDL_Color fg);
SDL_Surface * myTTF_RenderString_Solid(TTF_Font * font, const std:: string & str, SDL_Color fg);
SDL_Surface * myTTF_RenderString_Shaded(TTF_Font * font, const std:: string & str, SDL_Color fg, SDL_Color bg);
#endif
三种显示模式的实现文件:
#ifndef FONT_H_
#define FONT_H_
#include " gb2312_to_Unicode.h "
#include " SDL/SDL_ttf.h "
SDL_Surface * myTTF_RenderString_Blended(TTF_Font * font, const std:: string & str, SDL_Color fg);
SDL_Surface * myTTF_RenderString_Solid(TTF_Font * font, const std:: string & str, SDL_Color fg);
SDL_Surface * myTTF_RenderString_Shaded(TTF_Font * font, const std:: string & str, SDL_Color fg, SDL_Color bg);
#endif
#include
"
font.h
"
SDL_Surface * myTTF_RenderString_Blended(TTF_Font * font, const std:: string & str, SDL_Color fg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Blended(font, perOne, fg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
SDL_Surface * myTTF_RenderString_Solid(TTF_Font * font, const std:: string & str, SDL_Color fg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Solid(font, perOne, fg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
SDL_Surface * myTTF_RenderString_Shaded(TTF_Font * font, const std:: string & str, SDL_Color fg, SDL_Color bg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Shaded(font, perOne, fg, bg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
SDL_Surface * myTTF_RenderString_Blended(TTF_Font * font, const std:: string & str, SDL_Color fg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Blended(font, perOne, fg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
SDL_Surface * myTTF_RenderString_Solid(TTF_Font * font, const std:: string & str, SDL_Color fg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Solid(font, perOne, fg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
SDL_Surface * myTTF_RenderString_Shaded(TTF_Font * font, const std:: string & str, SDL_Color fg, SDL_Color bg)
{
SDL_Surface * textbuf;
// Get Unicode
std::vector < Uint16 > unicodeUnit = getUnicode(str);
int arraySize = unicodeUnit.size();
Uint16 * perOne = new Uint16[arraySize + 1 ];
for ( int i = 0 ; i < arraySize; i ++ )
perOne[i] = unicodeUnit[i];
perOne[arraySize] = 0 ;
// Render the new text
textbuf = TTF_RenderUNICODE_Shaded(font, perOne, fg, bg);
// Free the text buffer and return
delete [] perOne;
return textbuf;
}
5.2:修改DisplaySurface的类方法
其它接口都是不需要改动的,我们仅仅把类方法中,原来用于构建文本面的函数换成我们自己的函数就可以了。当然,先把这些函数#include进来:
#include
"
SurfaceClass.h
"
#include " font.h "
//
DisplaySurface::DisplaySurface( const std:: string & msg_name, const std:: string & message, const ScreenSurface & screen,
Uint8 r, Uint8 g , Uint8 b,
int ttf_size, const std:: string & ttf_fileName):
fileName(msg_name)
{
if ( textNum == 0 )
if ( TTF_Init() < 0 )
throw ErrorInfo( " TTF_Init() failed! " );
SDL_Color textColor;
textColor.r = r;
textColor.g = g;
textColor.b = b;
pFont = TTF_OpenFont(ttf_fileName.c_str(), ttf_size);
if ( pFont == 0 )
throw ErrorInfo( " TTF_OpenFont() failed! " );
pSurface = myTTF_RenderString_Blended(pFont, message, textColor);
if ( pSurface == 0 )
throw ErrorInfo( " myTTF_RenderString_Blended() failed! " );
pScreen = screen.point();
textNum ++ ;
}
#include " font.h "
//
DisplaySurface::DisplaySurface( const std:: string & msg_name, const std:: string & message, const ScreenSurface & screen,
Uint8 r, Uint8 g , Uint8 b,
int ttf_size, const std:: string & ttf_fileName):
fileName(msg_name)
{
if ( textNum == 0 )
if ( TTF_Init() < 0 )
throw ErrorInfo( " TTF_Init() failed! " );
SDL_Color textColor;
textColor.r = r;
textColor.g = g;
textColor.b = b;
pFont = TTF_OpenFont(ttf_fileName.c_str(), ttf_size);
if ( pFont == 0 )
throw ErrorInfo( " TTF_OpenFont() failed! " );
pSurface = myTTF_RenderString_Blended(pFont, message, textColor);
if ( pSurface == 0 )
throw ErrorInfo( " myTTF_RenderString_Blended() failed! " );
pScreen = screen.point();
textNum ++ ;
}
5.3:StringData在主程序中的调用
最后,我们演示一下StringData在主程序中的调用方法。
//
must #include "string_data.h"
// Load a textSurface
StringData myData;
const std:: string uInfo = myData[ 0 ];
const std:: string dInfo = myData[ 1 ];
const std:: string lInfo = myData[ 2 ];
const std:: string rInfo = myData[ 3 ];
const std:: string oInfo = myData[ 4 ];
TextSurface upMessage( " upMsg " , uInfo, screen);
TextSurface downMessage( " downMsg " , dInfo, screen, 0xFF , 0 , 0 );
TextSurface leftMessage( " leftMsg " , lInfo, screen, 0 , 0xFF , 0 );
TextSurface rightMessage( " rightMsg " , rInfo, screen, 0 , 0 , 0xFF );
TextSurface otherMessage( " otherMsg " , oInfo, screen, 100 , 100 , 100 , 35 );
嘿嘿,就这么简单!
// Load a textSurface
StringData myData;
const std:: string uInfo = myData[ 0 ];
const std:: string dInfo = myData[ 1 ];
const std:: string lInfo = myData[ 2 ];
const std:: string rInfo = myData[ 3 ];
const std:: string oInfo = myData[ 4 ];
TextSurface upMessage( " upMsg " , uInfo, screen);
TextSurface downMessage( " downMsg " , dInfo, screen, 0xFF , 0 , 0 );
TextSurface leftMessage( " leftMsg " , lInfo, screen, 0 , 0xFF , 0 );
TextSurface rightMessage( " rightMsg " , rInfo, screen, 0 , 0 , 0xFF );
TextSurface otherMessage( " otherMsg " , oInfo, screen, 100 , 100 , 100 , 35 );
5.4:本章演示程序和完整源代码下载
包含SDL显示中文的演示程序(win32)以及完整的源代码。
http://www.fs2you.com/zh-cn/files/62f0acf0-ff11-11dc-a4f4-0014221b798a/