Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SDL
SDL Forum d'entraide sur l'API SDL. Avant de poster -> FAQ SDL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 27/10/2012, 08h25   #1
YuGiOhJCJ
Membre régulier
 
Avatar de YuGiOhJCJ
 
Étudiant
Inscription : janvier 2005
Messages : 188
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2005
Messages : 188
Points : 80
Points : 80
Par défaut SDL_keysym.unicode n'est pas encodé en UTF-8

Bonjour,

J'ai déjà posté sur la mailing-list de SDL pour ce problème mais je n'ai pas eu de réponse... Alors j’essaie ici en espérant avoir plus de chance.

J'ai un programme écrit en C[1] utilisant la bibliothèque SDL.
Le code source est encodé en UTF-8.
Donc quand je souhaite afficher du texte codé en dur je fais ça:
Code :
TTF_RenderUTF8_Solid(font, text, color);
Maintenant, je souhaite afficher également le texte saisi par l'utilisateur.
Les caractères saisis par l'utilisateur semblent être encodés en UTF-16:
typedef struct{
[...]
Uint16 unicode;
} SDL_keysym;
Donc quand je souhaite afficher le texte saisis par l'utilisateur je fais ça :
Code :
TTF_RenderUNICODE_Solid(font, &event.key.keysym.unicode, color);
Le problème c'est que je souhaite avoir le même encodage (UTF-8) dans les deux cas.

J'ai entendu parlé d'une solution avec iconv mais peut être que SDL a déjà une solution toute faite pour ça.

Y a t'il une solution simple pour récupérer la saisie de l'utilisateur en UTF-8 ?
Est-ce que vous pouvez me confirmer que j'ai bien de l'UTF-16 dans SDL_keysym.unicode ?
Pourquoi les caractères en UTF-16 s'affichent très bien dans ma console sans conversion nécessaire vers de l'UTF-8 alors que quand j'essaie de les afficher avec la fonction TTF_RenderUTF8_Solid, les caractères ne s'affichent pas correctement?
Est-ce que vous pouvez me montrer sur ce petit exemple comment appliquer la solution iconv pour convertir mon caractère UTF-16 en UTF-8 ?

Merci.

[1]
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#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);
}
YuGiOhJCJ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/12/2012, 13h55   #2
Markand
Invité de passage
 
Inscription : octobre 2008
Messages : 4
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 4
Points : 2
Points : 2
Oui la gestion de l'utf8 est très pénible, parce qu'en effet lorsqu'un utilisateur écrit 'é' l'évènement remplira keysym.unicode en UCS-2 (Unicode sur 2 octets, 16 bits).

L'avantage d'avoir les caractère sous forme d'entier en 16 bits, c'est que tu peux les mettre dans un tableau et les traiter bien plus facilement !

Je ne sais pas ce que tu souhaite faire, mais si tu veux faire une pseudo textbox, il est préférable de stocker ce que l'utilisateur entre avec le champ .unicode comme ça tu pourras effacer le dernier caractère, et autre manipulations plus simple.

Si tu veux tout de même convertir tu peux passer par iconv, mais c'est lourd surtout pour ça. Il existe des fonctions toutes faites pour convertir de l'UCS-2 en UTF-8 voici par exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
void
ucs4_to_utf8(char *dst, Uint32 c)
{
	if (c < 128) {
		dst[0] = c;
	} else if (c >= 128 && c < 2048) {
		dst[0] = 0xC0	| ((c >> 6)	& 0x1F);
		dst[1] = 0x80	| (c & 0x3F);
	} else if (c >= 2048 && c < 65535) {
		dst[0] = 0xE0	| ((c >> 12)	& 0xF);
		dst[1] = 0x80	| ((c >> 6)	& 0x3F);
		dst[2] = 0x80	| (c & 0x3F);
	} else if (c >= 65535 && c < 2097151) {
		dst[0] = 0xF0	| ((c >> 18)	& 0x7);
		dst[1] = 0x80	| ((c >> 12)	& 0x3F);
		dst[2] = 0x80	| ((c >> 6)	& 0x3F);
		dst[3] = 0x80	| (c & 0x3F);
	}
}
Dans cette fonction, il suffit de passer en chaine (taille 4 minimum) le résultat de la conversion et en deuxième paramètre le champ .unicode. Ensuite tu aura ta chaîne prête à être utilisée avec RenderUTF8.

Il est important de mettre tout à zéro dans ta chaîne avant de la passer en paramètre, comme tu sais pas à l'avance combien de caractères vont être utilisés pour la conversion.

NOTE: cette fonction considère que le deuxième paramètre est un UCS-4 (caractère unicode sur 32 bits) mais ce n'est pas gênant.
Markand est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 06h41.


 
 
 
 
Partenaires

Hébergement Web