首先,我们从WIN10系统以下路径中找到字体库:simsun.ttc,他的路径一般为:
C:\Windows\Fonts
文件夹中的宋体,常规即是我们要的内容
将其拷贝出来,即可作为我们显示时所用的字体库。
SDL显示字体的一般流程为:
首先使用SDL_CreateWindow;以及SDL_CreateRenderer函数分别创建SDL窗口以及窗口对应的渲染器。
1. 使用TTF_OpenFont()函数打开字体库,同时设置字体大小;
2. 根据打开的字体库,要显示的内容以及字体颜色创建文本表面Surface,根据你采用的编码不同使用的函数为:(本文推荐采用UNICODE编码,这意味着字符需要采用16位来表示,这样可以同时显示中英文内容)
TTF_RenderText_Blended(TTF_Font *font,
const char *text, SDL_Color fg);
TTF_RenderUTF8_Blended(TTF_Font *font,
const char *text, SDL_Color fg);
TTF_RenderUNICODE_Blended(TTF_Font *font,
const Uint16 *text, SDL_Color fg);;
3. 根据得到的Surface使用SDL_CreateTextureFromSurface()函数创建纹理Texture;
4. 使用SDL_RenderCopy()函数将文本纹理复制到窗口渲染器,以及使用SDL_RenderPresent(pWndRenderer); 将渲染器内容显示出来;
5. 使用 SDL_DestroyTexture(pTextTexture); SDL_FreeSurface(pTextSurface);函数释放Surface以及Texture。通常这2个函数的错误使用往往会照成多次显示内容后,内存疯狂泄露,解决办法是:每使用一次TTF_RenderUNICODE_Blended()、SDL_CreateTextureFromSurface()函数,就执行一次对应的释放函数,注意是每一次。
假如你在某个调用函数中多次执行这2个函数,而只在该函数退出前执行了一次对应的内存释放,恭喜你,你的操作将会造成大量的内存泄露,不信你放在while循环里泡个几百遍看看。
记住是每使用一次TTF_RenderUNICODE_Blended()、SDL_CreateTextureFromSurface()函数,在退出前就执行一次对应的释放函数,注意是每一次,而不是退出时仅执行一次。
6. 注意事项:如果你要显示出来的字体无失真,不要自己指定显示内容所需要的区域大小,而是指定显示起始位置,使用TTF_SizeUNICODE()函数计算所需要的显示区域,如果需要调整字体大小,请使用TTF_OpenFont()函数更改。这样你的字体才能保证不失真变形。
以下是代码部分:
首先是主函数:
int main()
{
SDL_Window* pSDLWindow = NULL; //sdl窗口
SDL_Renderer* pWndRenderer = NULL;//窗口渲染器
wchar_t display_word[] = L"H***************你好啊,jackiewmt!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*";
//初始化SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return -1;
//创建窗口
pSDLWindow = SDL_CreateWindow("SDLWind", 200, 200, 1600, 800, SDL_WINDOW_RESIZABLE);
if (NULL == pSDLWindow) return -1;
//创建窗口渲染器
pWndRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);
sdl_OutWord(pSDLWindow, pWndRenderer,display_word);
SDL_Event sdl_event;
bool bQuit = false;
while (!bQuit)
{
if (SDL_PollEvent(&sdl_event))
{
switch (sdl_event.type)
{
case SDL_QUIT:
bQuit = true;
break;
case SDL_WINDOWEVENT:
{
if (sdl_event.window.event == SDL_WINDOWEVENT_RESIZED)
{
SDL_DestroyRenderer(pWndRenderer);
pWndRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);
//创建窗口渲染器
sdl_OutWord(pSDLWindow, pWndRenderer, display_word);
printf("一次 ");
break;
}
else
break;
}
default:
break;
}
}
}
SDL_DestroyRenderer(pWndRenderer);
SDL_DestroyWindow(pSDLWindow);
}
然后是调用函数部分:
void sdl_OutWord(SDL_Window* pSDLWindow, SDL_Renderer* pWndRenderer, wchar_t* display_word)
{
SDL_Surface * pTextSurface = NULL;//文本表面
SDL_Texture* pTextTexture = NULL;//文本纹理
int Font_size = 32;
//文本显示区域
SDL_Rect rcText;
rcText.x = 0;
rcText.y = 0;
rcText.w = 0;
rcText.h = 0;
//设置窗口背景色
SDL_SetRenderDrawColor(pWndRenderer, 120, 120, 120, 255);
//用设置的颜色清屏窗口渲染器
SDL_RenderClear(pWndRenderer);
//初始化字体库
if (TTF_Init() == -1)
return;
//打开字体
TTF_Font *font;
font = TTF_OpenFont("data/simsun.ttc", Font_size);
if (!font)
{
printf("TTF_OpenFont: Open simsun.ttf %s\n", TTF_GetError());
return;
}
TTF_SizeUNICODE(font, (const Uint16 *)display_word, &rcText.w, &rcText.h);//计算所需要的显示区域大小
//创建文本表面
SDL_Color color2 = { 255,255,255 };
pTextSurface = TTF_RenderUNICODE_Blended(font, (Uint16*)display_word, color2);
//创建文本纹理
pTextTexture = SDL_CreateTextureFromSurface(pWndRenderer, pTextSurface);
//将文本纹理复制到窗口渲染器
SDL_RenderCopy(pWndRenderer, pTextTexture, NULL, &rcText); // NULL means that use all texture( and renderer)
//刷新窗口渲染器的显示
SDL_RenderPresent(pWndRenderer);
//清理
TTF_CloseFont(font);
TTF_Quit();
SDL_RenderClear(pWndRenderer);
SDL_DestroyTexture(pTextTexture);
SDL_FreeSurface(pTextSurface);
return ;
}
显示效果如下:
当然,这个函数也有弊端,那就是当你缩小显示区域的时候,会发现显示部分超出了显示框,像下面这样:
所以也可以稍作更改,将显示内容做到自动换行,具体效果如下:
至于具体实现,下次有空了再发吧。