Hello,
I’m just wondering why TTF_RenderUTF8 does not support printing
characters that are not (I support UTF8).
My problem, I used gettext to write some french on my screen, my drawing
functions always use TTF_RenderUTF8 and it works, my text that
contains some accents like ‘?’ ‘?’ ‘?’ are written correctly.
However, if I wait for user input, I try to fill a char buffer and print
it on the screen (e.g let the user write his name).
So I read the SDL_keysym unicode member and add it to the buffer, but
then when using TTF_RenderUTF8, the output is broken, only squares are
written (like missing characters)…
In fact, when I press a key like ‘a’, ‘b’ the unicode member will be set
to the ASCII character (normal) but it will also set it for ‘?’ which
value is 233, that’s probably why I get a bad font rendering.
Please try my source code just below, put this font directly in the same
directory as the executable:
– font –
http://markand.malikania.fr/DejaVuSans.ttf
– code –
#include <stdio.h>
#include <stdbool.h>
#include <err.h>
#include <SDL.h>
#include <SDL_ttf.h>
void
addchar(char *buf, size_t len, uint16_t c)
{
size_t max = BUFSIZ - len;
if ((c & 0xFF80) == 0)
snprintf(&buf[len], max, "%c", c & 0x7F);
else
snprintf(&buf[len], max, "%c%c",
c & 0xFF, (c >> 8) & 0xFF);
}
int
main(void)
{
SDL_Surface *sc, *rd;
SDL_Event ev;
SDL_Color fg = { 255, 255, 255 };
SDL_Rect geo;
TTF_Font *ft;
bool running;
char buf[BUFSIZ] = { 0 };
char fake_e[2];
if (SDL_Init(SDL_INIT_VIDEO) < 0)
errx(1, "%s", SDL_GetError());
if (TTF_Init() < 0)
errx(1, "%s", SDL_GetError());
if (!(sc = SDL_SetVideoMode(400, 200, 32, SDL_HWSURFACE)))
errx(1, "%s", SDL_GetError());
if (!(ft = TTF_OpenFont("DejaVuSans.ttf", 10)))
errx(1, "%s", SDL_GetError());
SDL_EnableUNICODE(1);
running = true;
while (running) {
while (SDL_PollEvent(&ev)) {
if (ev.type == SDL_QUIT) {
running = false;
} else if (ev.type == SDL_KEYDOWN) {
addchar(buf, strlen(buf), ev.key.keysym.unicode);
}
}
SDL_FillRect(sc, NULL, SDL_MapRGB(sc->format, 0, 0, 0));
/*
* First render a correct text that will works, NOTE: calling
* strlen("abcd?") should *not* return 5 but 6 because of the
* wide char
*/
geo.x = geo.y = 10;
rd = TTF_RenderUTF8_Blended(ft, "abcd?", fg);
SDL_BlitSurface(rd, NULL, sc, &geo);
if (rd)
SDL_FreeSurface(rd);
/*
* Render the broken input from user, press the '?' key if
* you have one on your keyboard. It will prints some square
* because the caracter is truncated to a one-byte char.
*/
geo.y += 20;
rd = TTF_RenderUTF8_Blended(ft, buf, fg);
SDL_BlitSurface(rd, NULL, sc, &geo);
if (rd)
SDL_FreeSurface(rd);
/*
* For people that do not have a '?' on their keyboard, I
* simulate the case where you press it, the unicode member
* is set to '233' probably a Latin character.
*/
geo.y += 20;
fake_e[0] = 233; fake_e[1] = '\0';
rd = TTF_RenderUTF8_Blended(ft, fake_e, fg);
SDL_BlitSurface(rd, NULL, sc, &geo);
if (rd)
SDL_FreeSurface(rd);
SDL_Flip(sc);
SDL_Delay(100);
}
}
Cheers,–
David Demelier