SDL_keysym.unicode, UTF-8, UTF-16, Unicode, SDL_ttf

Hello,

I am writing a C program[1] using the SDL library.

The source code is written in the UTF-8 encoding.
So, when I want to display a hardcoded text with SDL_ttf I use this:
TTF_RenderUTF8_Solid(font, text, color);

I also want to display the characters that the user has typed on his keyboard.
The characters are encoded with UTF-16 as I can see in the man:
typedef struct{
[…]
Uint16 unicode;
} SDL_keysym;
So, when I want a user text with SDL_ttf I use this:
TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);

The problem is I would like to use the same encoding (UTF-8) for the characters that the user has typed on his keyboard.

I heard about an iconv solution but maybe SDL has already something to do that.

Is there an easy way to do this?

Thank you.
Regards.

[1]
#include <SDL/SDL.h> // for SDL_Surface
#include <SDL/SDL_ttf.h> // for TTF_Font
int main()
{
TTF_Font *font = NULL;
SDL_Surface *screen_surface = NULL;
SDL_Surface *font_surface = NULL;
char text[4];
strcpy(text, “a??\0”);
SDL_Color color;
color.r = 255;
color.g = 255;
color.b = 255;
// Initialize SDL
if((SDL_Init(SDL_INIT_VIDEO)==-1))
{
printf(“SDL_Init: %s\n”, SDL_GetError());
exit(1);
}
// Enable UNICODE
SDL_EnableUNICODE(1);
// Create the screen surface
screen_surface = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
if(screen_surface == NULL)
{
printf(“SDL_SetVideoMode: %s\n”, SDL_GetError());
exit(1);
}
// Initialize TTF
if(TTF_Init()==-1)
{
printf(“TTF_Init: %s\n”, TTF_GetError());
exit(1);
}
// Load the font
font = TTF_OpenFont(“font.ttf”, 48);
if(font == NULL)
{
printf(“TTF_OpenFont: %s\n”, TTF_GetError());
exit(1);
}
// Display the text in the console
printf(“text = %s\n”, text);
// Create the font surface
font_surface = TTF_RenderUTF8_Solid(font, text, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUTF8_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
SDL_Event event;
while(SDL_WaitEvent(&event))
{
if(event.type == SDL_QUIT)
{
break;
}
if(event.type == SDL_KEYDOWN)
{
SDL_FillRect(screen_surface, NULL, 0);
// Display the text in the console
printf("%c\n", event.key.keysym.unicode);
// Create the font surface
font_surface = TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUNICODE_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
}
}
// Quit
SDL_Quit();
exit(0);
}

OK. Maybe I can be more understood by editing the previous example to show you an example[1] where the problem appears.

In this example, I try to display the characters that the user has typed on his keyboard using the TTF_RenderUTF8_Solid function.
It’s a bad idea to use this function because it can only display characters encoded in UTF-8. The user input is encoded in UTF-16 (see SDL_keysym). So some characters can’t be displayed.

The thing which is strange is that I can see correctly the characters in the console.
The display problem is only visible in the Graphical User Interface (GUI).
See here :
$ ./a.out
text = a??
a
?
?
?

Do you know why my terminal is able to display correctly the specials characters (encoded in UTF-16) whereas my GUI isn’t able to display them (with the TTF_RenderUTF8_Solid function)?

Thank you.
Regards.

[1]
#include <SDL/SDL.h> // for SDL_Surface
#include <SDL/SDL_ttf.h> // for TTF_Font
int main()
{
TTF_Font *font = NULL;
SDL_Surface *screen_surface = NULL;
SDL_Surface font_surface = NULL;
char text[4];
strcpy(text, “a??\0”);
SDL_Color color;
color.r = 255;
color.g = 255;
color.b = 255;
// Initialize SDL
if((SDL_Init(SDL_INIT_VIDEO)==-1))
{
printf(“SDL_Init: %s\n”, SDL_GetError());
exit(1);
}
// Enable UNICODE
SDL_EnableUNICODE(1);
// Create the screen surface
screen_surface = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
if(screen_surface == NULL)
{
printf(“SDL_SetVideoMode: %s\n”, SDL_GetError());
exit(1);
}
// Initialize TTF
if(TTF_Init()==-1)
{
printf(“TTF_Init: %s\n”, TTF_GetError());
exit(1);
}
// Load the font
font = TTF_OpenFont(“font.ttf”, 48);
if(font == NULL)
{
printf(“TTF_OpenFont: %s\n”, TTF_GetError());
exit(1);
}
// Display the text in the console
printf(“text = %s\n”, text);
// Create the font surface
font_surface = TTF_RenderUTF8_Solid(font, text, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUTF8_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
SDL_Event event;
while(SDL_WaitEvent(&event))
{
if(event.type == SDL_QUIT)
{
break;
}
if(event.type == SDL_KEYDOWN)
{
SDL_FillRect(screen_surface, NULL, 0);
// Display the text in the console
printf("%c\n", event.key.keysym.unicode);
// Create the font surface
sprintf(text, “%c\0”, event.key.keysym.unicode);
font_surface = TTF_RenderUTF8_Solid(font, text, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUTF8_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Create the font surface
/

font_surface = TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUNICODE_Solid: %s\n”, TTF_GetError());
exit(1);
}
*/
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
}
}
// Quit
SDL_Quit();
exit(0);
}On Fri, 19 Oct 2012 17:34:13 +0200 YuGiOhJCJ Mailing-List <@YuGiOhJCJ_Mailing-Li> wrote:

Hello,

I am writing a C program[1] using the SDL library.

The source code is written in the UTF-8 encoding.
So, when I want to display a hardcoded text with SDL_ttf I use this:
TTF_RenderUTF8_Solid(font, text, color);

I also want to display the characters that the user has typed on his keyboard.
The characters are encoded with UTF-16 as I can see in the man:
typedef struct{
[…]
Uint16 unicode;
} SDL_keysym;
So, when I want a user text with SDL_ttf I use this:
TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);

The problem is I would like to use the same encoding (UTF-8) for the characters that the user has typed on his keyboard.

I heard about an iconv solution but maybe SDL has already something to do that.

Is there an easy way to do this?

Thank you.
Regards.

[1]
#include <SDL/SDL.h> // for SDL_Surface
#include <SDL/SDL_ttf.h> // for TTF_Font
int main()
{
TTF_Font *font = NULL;
SDL_Surface *screen_surface = NULL;
SDL_Surface *font_surface = NULL;
char text[4];
strcpy(text, “a??\0”);
SDL_Color color;
color.r = 255;
color.g = 255;
color.b = 255;
// Initialize SDL
if((SDL_Init(SDL_INIT_VIDEO)==-1))
{
printf(“SDL_Init: %s\n”, SDL_GetError());
exit(1);
}
// Enable UNICODE
SDL_EnableUNICODE(1);
// Create the screen surface
screen_surface = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
if(screen_surface == NULL)
{
printf(“SDL_SetVideoMode: %s\n”, SDL_GetError());
exit(1);
}
// Initialize TTF
if(TTF_Init()==-1)
{
printf(“TTF_Init: %s\n”, TTF_GetError());
exit(1);
}
// Load the font
font = TTF_OpenFont(“font.ttf”, 48);
if(font == NULL)
{
printf(“TTF_OpenFont: %s\n”, TTF_GetError());
exit(1);
}
// Display the text in the console
printf(“text = %s\n”, text);
// Create the font surface
font_surface = TTF_RenderUTF8_Solid(font, text, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUTF8_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
SDL_Event event;
while(SDL_WaitEvent(&event))
{
if(event.type == SDL_QUIT)
{
break;
}
if(event.type == SDL_KEYDOWN)
{
SDL_FillRect(screen_surface, NULL, 0);
// Display the text in the console
printf("%c\n", event.key.keysym.unicode);
// Create the font surface
font_surface = TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);
if(font_surface == NULL)
{
printf(“TTF_RenderUNICODE_Solid: %s\n”, TTF_GetError());
exit(1);
}
// Blit to the screen surface
if(SDL_BlitSurface(font_surface, NULL, screen_surface, NULL) < 0)
{
printf(“SDL_BlitSurface: %s\n”, SDL_GetError());
exit(1);
}
SDL_UpdateRect(screen_surface, 0, 0, 0, 0);
}
}
// Quit
SDL_Quit();
exit(0);
}


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org