How to display Chinese characters in SDL2.0 under Deepin Linux

How to display Chinese characters in SDL2.0 under Deepin Linux

**

preface:

**
SDL2 is cross platform, open source and excellent performance. It can develop all kinds of games and industrial software, but it seems that Chinese support is not universal. There are various SDL schemes to display Chinese characters on the Internet, which are very complicated and not easy to succeed. There is also the experience under windows. Fortunately, SDL2.0 supports Utf8 format very well and can display multiple languages, but it is also easy to fail. The reason is that SDL2 needs to install the extension package, relies on free type and loads fonts by itself. After stepping on the pit, it is summarized as follows. Support domestic products, all tested successfully under Deepin Linux 15.8.

1, Install SDL2

Source download https://www.libsdl.org/download-2.0.php
SDL2 official tutorial http://lazyfoo.net/tutorials/SDL/index.php
SDL2 function reference https://wiki.libsdl.org/CategoryAPI
install
Apt get is easy to use, but the source code installation is the latest and complete. After downloading the SDL2-2.0.16.tar.gz source code package, unzip it with the tar command, then generate a makefile with cmake, and finally make and install.

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

2, Install font package freetype

freetype source code download https://sourceforge.net/projects/freetype/
freetype-2.11.0.tar.gz can be installed with cmake, but there are some problems, so use configure instead:

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

3, Install SDL2 extended Font Pack TTF

Font extension ttf source download https://www.libsdl.org/projects/SDL_ttf/
Source package SDL2_ttf-2.0.15.tar.gz, cmake is installed as follows

tar SDL2_ttf-2.0.15
cd SDL2_ttf-2.0.15
mkdir mybuild
cd mybuild
cmake ..
make
sudo make install

If you want to process images in multiple formats, install the image expansion package
https://www.libsdl.org/projects/SDL_image/#source
SDL2_image-2.0.5.tar.gz, now you have to install it with configure

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

4, Coding test

In order to test more than one example, I added png image loading and display, keyboard and mouse control to the example, resulting in more code, but it has great reference significance. For simplicity, it is completed in pure c language, which is suitable for people who are afraid of complex c + + syntax. In addition, the taboo goto statement is used to release the memory in time when an error occurs.

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

// gcc `sdl2-config --cflags --libs` `freetype-config --cflags --libs` font.cpp -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); // Change the font you want here
	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( "Chinese characters and png Image test", 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" ); // Can be replaced with your png picture
	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, "Global linux System ranking: domestic Deepin Ranked 10th");
	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, "chinese Linux"))
						goto end;
					break;					
            }
        }
    }
 end:
	TTF_CloseFont(g_Font);
	SDL_FreeSurface(g_TextSurface);
    SDL_FreeSurface(g_Surface);
    TTF_Quit();
    return 0;
}

Due to the large number of libraries, the compilation instructions are complex as follows:

gcc `sdl2-config --cflags --libs` `freetype-config --cflags --libs` font.cpp -lSDL2_image -lSDL2_ttf

The operation effect is as follows. Click with the mouse, and the words "Chinese Linux" will continue to appear.


You may feel that SDL is more difficult to display text and pictures than other tools, but this is the case with efficient underlying development, because all the details are under your control.

Tags: Linux image processing deepin

Posted on Wed, 17 Nov 2021 07:01:15 -0500 by smarlowe