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.