Deepin Linux 下 SDL2.0 如何显示汉字

Deepin Linux 下 SDL2.0 如何显示汉字

**

前言:

**
SDL2跨平台、开源、优异的性能,能开发各种游戏、工业软件,但貌似中文支持不尿性。网上有各种SDL显示汉字的方案,十分繁杂,还不易成功,还有的是windows下的经验。好在SDL2.0对Utf8格式支持很好,能显示多国语言,但也容易失败,原因是SDL2需要安装扩展包,还依赖free type,还要自己加载字体。踩坑后总结如下。支持国产,全在Deepin Linux 15.8下测试成功。

一、安装SDL2

源码下载 https://www.libsdl.org/download-2.0.php
SDL2官方教程 http://lazyfoo.net/tutorials/SDL/index.php
SDL2 函数参考 https://wiki.libsdl.org/CategoryAPI
安装
apt-get 虽然好用,但源码安装的最新最全,下载SDL2-2.0.16.tar.gz源码包后, 用tar命令解压,然后用cmake 生成makefile, 最后make 和 安装。

tar -xzvf SDL2-2.0.16.tar.gz
cd SDL2-2.0.16
mkdir mybuild
cd mybuild
cmake ..
make
sudo make install

二、安装字体包freetype

freetype源码下载 https://sourceforge.net/projects/freetype/
freetype-2.11.0.tar.gz, 虽然可以用cmake 安装,但有点问题,所以改用configure安装:

tar -xzvf freetype-2.11.0.tar.gz
cd freetype-2.11.0
./configure
make
sudo make install

三、安装SDL2扩展字体包TTF

字体扩展ttf源码下载 https://www.libsdl.org/projects/SDL_ttf/
源码包SDL2_ttf-2.0.15.tar.gz,cmake 安装如下

tar SDL2_ttf-2.0.15
cd SDL2_ttf-2.0.15
./configure
make
sudo make install

如果要处理多种格式的图像,顺便把 image 扩展包也安装了
https://github.com/libsdl-org/SDL_image/releases
SDL2_image-2.0.5.tar.gz,现在又得用configure安装

tar -xzvf SDL2_image-2.0.5.tar.gz
cd SDL2_image-2.0.5
./configure
make
sudo make install

四、编码测试

为了一例多测,我把png图像载入和显示、键盘和鼠标控制也加入例子,导致代码较多,但参考意义大。为了简单,用纯c语言完成,适合怕c++语法复杂的人。另外使用了禁忌goto语句,为了方便发生错误时,能及时释放内存。

#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

// gcc `sdl2-config --cflags --libs` font.c -lSDL2_image -lSDL2_ttf

SDL_Surface * g_TextSurface, * g_Surface, * g_PNGSurface;
SDL_Window * g_Window = NULL;
TTF_Font * g_Font =NULL;
//======================================================================
SDL_Surface * OpenPng( const char * fileName )
{
	SDL_Surface* optimizedSurface = NULL;//The final optimized image
	SDL_Surface* loadedSurface = IMG_Load( fileName);
	if( loadedSurface == NULL )
	{
		printf( "Unable to load image %s! SDL_image Error: %s\n", fileName, IMG_GetError() );
	}
	else
	{
		optimizedSurface = SDL_ConvertSurface( loadedSurface, g_Surface->format, 0 );
		if( optimizedSurface == NULL )
		{
			printf( "Unable to optimize image %s! SDL Error: %s\n", fileName, SDL_GetError() );
		}
		SDL_FreeSurface( loadedSurface );
	}
	return optimizedSurface;
}
//======================================================================
int InitFont()
{
	if(TTF_Init()==-1) 
	{
		printf("TTF_Init: %s\n", TTF_GetError());
		return 0;
	}
	g_Font = TTF_OpenFont("./simhei.ttf", 30); // 此处更换你想的字体
	if (g_Font == NULL)
	{
		fprintf(stderr, "font open failure %s\n", SDL_GetError());
		return 0;
	}
	return 1;
}
//======================================================================
int  Init()
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) 
	{
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        return (0);
    }
  // Register SDL_Quit to be called at exit; makes sure things are
  // cleaned up when we quit.
    atexit(SDL_Quit);
  // Attempt to create a 640x480 window with 32bit pixels.
	g_Window = SDL_CreateWindow( "汉字和png图像测试", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
	if ( !g_Window ) 
	{
		  fprintf(stderr, "error create window: %s\n", SDL_GetError());
		return 0;
    }
	g_Surface = SDL_GetWindowSurface( g_Window );
    if ( !g_Surface )
    {
        fprintf(stderr, "Unable to set up video: %s\n", SDL_GetError());
        return 0;
    }
	g_PNGSurface = OpenPng( "./logo.png" ); // 可替换为你的png图片
	if( g_PNGSurface == NULL )
	{
		printf( "Failed to load PNG image!\n" );
	}
	return InitFont();
}
//======================================================================
int Print(int x, int y, char *text)
{
    SDL_Color color = {0xFF, 0x22, 0};
    SDL_Rect offset = {x,y,x,y};
    
	if(!(g_TextSurface=TTF_RenderUTF8_Solid(g_Font,text, color) ))
	{
		fprintf(stderr, "font open failure %s\n", SDL_GetError());
		return 0;
	} 
	else
	{
		SDL_BlitSurface(g_TextSurface, NULL, g_Surface, &offset);
	}
	return 1;
}
//======================================================================
void DrawImg(int x, int y, int w, int h)
{
	SDL_Rect r;
	r.x = x;
	r.y = y;
	r.w = w;
	r.h = h;
  	if (g_PNGSurface)
	{
		SDL_BlitSurface( g_PNGSurface, NULL, g_Surface, &r ); // SDL_BlitSurface
	}
	else  
	  SDL_FillRect(g_Surface, &r, 0xFF0000);  // red to warning no img 
}
//======================================================================
int  render()
{   int r = Print(20, 30, "全球linux系统排名: 国产Deepin排名第10");
	DrawImg(220, 180, 0, 0);
	SDL_UpdateWindowSurface( g_Window );
	SDL_Delay(20);  // don't take all the cpu time
	return r;
}
//======================================================================
int main(int argc, char *argv[])
{
	if ( ! Init())
		goto end;
	SDL_Rect r = {0,0,640,480};		
    while (1)  // Main loop: loop forever.
    {
        if (! render())
			goto end;

        SDL_Event event; // SDL_Event is a union
        while (SDL_PollEvent(&event))
        {
            switch (event.type) 
            {
				case SDL_QUIT:
					goto end;
				case SDL_KEYUP:
					switch (event.key.keysym.sym)
					{
						case SDLK_ESCAPE: 
							goto end; 
					}
					break;
				case SDL_MOUSEBUTTONUP:
					SDL_FillRect(g_Surface, &r, rand() | 0x77);
					if (! Print(event.motion.x, event.motion.y, "中文 Linux"))
						goto end;
					break;					
            }
        }
    }
 end:
	TTF_CloseFont(g_Font);
	SDL_FreeSurface(g_TextSurface);
    SDL_FreeSurface(g_Surface);
    TTF_Quit();
    return 0;
}

编译指令如下:

gcc `sdl2-config --cflags --libs` font.c -lSDL2_image -lSDL2_ttf

运行效果如下,用鼠标点击,就不断冒出"中文 Linux"文字。

在这里插入图片描述
大家可能感觉到SDL显示文字和图片比其他工具都困难,但高效的底层开发就是这样,因为一切细节都在你的掌控之中。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值