Bug in SDL_ttf2?

Hi!

Today I tried SDL_ttf 2.0.2. All worked fine until I tried to create a
red blended text (same goes to blue). Green worked fine. I hacked a small
example (no error checking, so if anything fails, it fails), which you can
try. compile done with:
gcc test-sdl_ttf2.c -o test-sdl_ttf2 $(sdl-config --cflags --libs) -lSDL_ttf

And as an attachment there is graffiti.ttf.gz.

Please verify this strange thing. BTW, when will there be a cropped surface
after TTF_RenderText_xxx?

#include #include #include

main ()
{
SDL_Surface *screen, *surf[3];
TTF_Font *font;
char *txt[3] = { “red hugo”, “blue hugo”, “green hugo” };
SDL_Color col[3] = { { r: 0xff, g: 0x00, b: 0x00 },
{ r: 0x00, g: 0x00, b: 0xff },
{ r: 0x00, g: 0xff, b: 0x00 }};
SDL_Rect rect;
SDL_Event event;
int i;

atexit (SDL_Quit);

SDL_Init (SDL_INIT_VIDEO);
TTF_Init ();

screen = SDL_SetVideoMode (640, 480, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);

font = TTF_OpenFont (“graffiti.ttf”, 40);
TTF_SetFontStyle (font, TTF_STYLE_NORMAL);

for (i = 0; i < 3; ++i)
{
rect.x = i * 40;
rect.y = i * 40;

  surf[i] = TTF_RenderText_Blended (font, txt[i], col[i]);
  SDL_BlitSurface (surf[i], NULL, screen, &rect);
}

TTF_CloseFont (font);

SDL_Flip (screen);

for (;:wink:
{
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
exit (1);
}
}
}
}

so long
Thomas–
__
/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/
-------------- next part --------------
A non-text attachment was scrubbed…
Name: graffiti.ttf.gz
Type: application/x-gunzip
Size: 16399 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20010515/f37dccbb/attachment.bin

Try changing this:

screen = SDL_SetVideoMode (640, 480, 16, SDL_DOUBLEBUF |
SDL_HWSURFACE);

to:

screen = SDL_SetVideoMode (640, 480, 24, SDL_DOUBLEBUF |
SDL_HWSURFACE);

and see what happens.–

Olivier A. Dagenais - Software Architect and Developer

“Thomas Krennwallner” wrote in message
news:20010515101814.A8591 at slipstream.code-foo.org

Hi!

Today I tried SDL_ttf 2.0.2. All worked fine until I tried to create
a
red blended text (same goes to blue). Green worked fine. I hacked a
small
example (no error checking, so if anything fails, it fails), which
you can
try. compile done with:
gcc test-sdl_ttf2.c -o test-sdl_ttf2
$(sdl-config --cflags --libs) -lSDL_ttf

And as an attachment there is graffiti.ttf.gz.

Please verify this strange thing. BTW, when will there be a cropped
surface
after TTF_RenderText_xxx?

#include #include #include

main ()
{
SDL_Surface *screen, *surf[3];
TTF_Font *font;
char *txt[3] = { “red hugo”, “blue hugo”, “green hugo” };
SDL_Color col[3] = { { r: 0xff, g: 0x00, b: 0x00 },
{ r: 0x00, g: 0x00, b: 0xff },
{ r: 0x00, g: 0xff, b: 0x00 }};
SDL_Rect rect;
SDL_Event event;
int i;

atexit (SDL_Quit);

SDL_Init (SDL_INIT_VIDEO);
TTF_Init ();

screen = SDL_SetVideoMode (640, 480, 16, SDL_DOUBLEBUF |
SDL_HWSURFACE);

font = TTF_OpenFont (“graffiti.ttf”, 40);
TTF_SetFontStyle (font, TTF_STYLE_NORMAL);

for (i = 0; i < 3; ++i)
{
rect.x = i * 40;
rect.y = i * 40;

  surf[i] = TTF_RenderText_Blended (font, txt[i], col[i]);
  SDL_BlitSurface (surf[i], NULL, screen, &rect);
}

TTF_CloseFont (font);

SDL_Flip (screen);

for (;:wink:
{
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_QUIT:
exit (1);
}
}
}
}

so long
Thomas


__
/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3
D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/

same stuff, green good, red and blue swapped.

so long
Thomas

PS: Sorry Olivier for replying only to you, I accidently forgot
sdl at lokigames.comOn Tue, May 15, 2001 at 04:19:09AM -0700, the boisterous Olivier Dagenais <olivier.dagenais at canada.com> wrote:

Try changing this:

screen = SDL_SetVideoMode (640, 480, 16, SDL_DOUBLEBUF |
SDL_HWSURFACE);

to:

screen = SDL_SetVideoMode (640, 480, 24, SDL_DOUBLEBUF |
SDL_HWSURFACE);

and see what happens.


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/

same stuff, green good, red and blue swapped.

try saving the TTF-generated surface (before blitting) using the TGA
save code I posted earlier (ftp://ptah.lnf.kth.se/pub/misc/savetga.c)
and look at it with an image viewer or Gimp to see if it’s all right

same in green :wink:

here are the tga’s.

gimps output:
TGA: 24 bit image, 0 bit alpha is less than 32 total bits per pixel
TGA: increasing to 8 bit alpha

but i think thats normal (SDL_SetVideoMode (640,480,24,…)).

I attached ttf2-test.tar.bz2 which includes
ttf2-test/
ttf2-test/Makefile
ttf2-test/blue_hugo.tga
ttf2-test/green_hugo.tga
ttf2-test/red_hugo.tga
ttf2-test/test-sdl_ttf2.c

cp graffiti.ttf and savetga.c into it and give it a try.

so long
ThomasOn Tue, May 15, 2001 at 04:04:42PM +0200, the boisterous Mattias Engdeg?rd wrote:

same stuff, green good, red and blue swapped.

try saving the TTF-generated surface (before blitting) using the TGA
save code I posted earlier (ftp://ptah.lnf.kth.se/pub/misc/savetga.c)
and look at it with an image viewer or Gimp to see if it’s all right


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/
-------------- next part --------------
A non-text attachment was scrubbed…
Name: ttf2-test.tar.bz2
Type: application/octet-stream
Size: 16997 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20010515/3b237b96/attachment.obj

same in green :wink:

ok, that puts the blame on TTF rather than SDL’s blit, which is what I
wanted to know. I don’t use TTF so can someone look at it?

gimps output:
TGA: 24 bit image, 0 bit alpha is less than 32 total bits per pixel
TGA: increasing to 8 bit alpha

ah, right. I’ll add code to savetga that fixes that. Thanks

Is your machine big-endian or little endian?

The only thing that I can think of off-ahand is that the endian masks might
be wrong when it creates the surface. (I’ve only been using white text and
coloring after, using the blended text not the 8-bit surface ones.)

Okay, after testing other colors on mine, I had “blended” with backwards
colors, but 8-bit surfaces have the colors correct

Could this be the culprit? (line 1107)
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Rmask = 0x000000FF;
Gmask = 0x0000FF00;
Bmask = 0x00FF0000;
Amask = 0xFF000000;
} else {
Rmask = 0xFF000000;
Gmask = 0x00FF0000;
Bmask = 0x0000FF00;
Amask = 0x000000FF;
}

If Rmask and Bmask are swapped, it corrects the problem, but IMO,
technically isn’t it supposed to be in this order? All the other times I
create a surface it uses this mask, this was copied straight out of
sdl_image in fact.

The question is, why is the R and B being swapped? Is it freetype2 that’s
swapping it?> ----- Original Message -----

From: owner-sdl@lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of Mattias Engdeg?rd
Sent: May 15, 2001 8:58 AM
To: sdl at lokigames.com
Subject: Re: [SDL] Re: Bug in SDL_ttf2?

same in green :wink:

ok, that puts the blame on TTF rather than SDL’s blit, which is what I
wanted to know. I don’t use TTF so can someone look at it?

gimps output:
TGA: 24 bit image, 0 bit alpha is less than 32 total bits per pixel
TGA: increasing to 8 bit alpha

ah, right. I’ll add code to savetga that fixes that. Thanks


Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

Could this be the culprit? (line 1107)

yes I just saw it, it’s botched for both endiannesses. I’m not sure
what motivated the changes since the ttf 1.x code looked all right

I’m also curious to know why bitwise OR is used for alpha combination;
is it a speed hack?

little endian

so long
ThomasOn Tue, May 15, 2001 at 11:20:23AM -0700, the boisterous Kisai <kisai_z at yahoo.com> wrote:

Is your machine big-endian or little endian?


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/

Could this be the culprit? (line 1107)
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Rmask = 0x000000FF;
Gmask = 0x0000FF00;
Bmask = 0x00FF0000;
Amask = 0xFF000000;
} else {
Rmask = 0xFF000000;
Gmask = 0x00FF0000;
Bmask = 0x0000FF00;
Amask = 0x000000FF;
}

If Rmask and Bmask are swapped, it corrects the problem, but IMO,
technically isn’t it supposed to be in this order? All the other times I
create a surface it uses this mask, this was copied straight out of
sdl_image in fact.

Yes I swapped it this way:

if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Amask = 0xFF000000;
Rmask = 0x00FF0000;
Gmask = 0x0000FF00;
Bmask = 0x000000FF;
} else {
.
.

And it worked out of the box. I don’t have a bigendian machine so I couldn’t
check that. BTW, this ARGB mask is the same as in SDL_ttf-1.2.2. And this
should also be patched in TTF_RenderGlyph_Blended(line 1191).

The question is, why is the R and B being swapped? Is it freetype2 that’s
swapping it?

I think so. I put this stuff into a patch, but I left the bigendian part
original. Can someone put this into cvs/tarball for SDL_ttf-2.0.3 and
verify the bigendian stuff?

So long
ThomasOn Tue, May 15, 2001 at 11:20:23AM -0700, the boisterous Kisai <kisai_z at yahoo.com> wrote:


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/
-------------- next part --------------
diff -Naur SDL_ttf-2.0.2.orig/SDL_ttf.c SDL_ttf-2.0.2/SDL_ttf.c
— SDL_ttf-2.0.2.orig/SDL_ttf.c Sun Apr 29 21:53:03 2001
+++ SDL_ttf-2.0.2/SDL_ttf.c Fri May 18 10:15:26 2001
@@ -1105,10 +1105,10 @@

/* Create the target surface, 32-bit ARGB format */
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
      Amask = 0xFF000000;
    
  •   Rmask = 0x00FF0000;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x000000FF;
    

    } else {
    Rmask = 0xFF000000;
    Gmask = 0x00FF0000;
    @@ -1189,10 +1189,11 @@

    /* Create the target surface, 32-bit ARGB format */
    if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {

  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
      Amask = 0xFF000000;
    
  •   Amask = 0xFF000000;
    
  •   Rmask = 0x00FF0000;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x000000FF;
    
    } else {
    Rmask = 0xFF000000;
    Gmask = 0x00FF0000;

Yes I swapped it this way:

if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Amask = 0xFF000000;
Rmask = 0x00FF0000;
Gmask = 0x0000FF00;
Bmask = 0x000000FF;
} else {
.
.

Didn’t you read the rest of the code at all? It’s not endian dependent.
If you look further down you find lines like

    pixel = (fg.r<<16)|(fg.g<<8)|fg.b;

and

		*dst++ = pixel | (alpha << 24);

which should make it clear as crystal that the code expects the ARGB format
regardless of endianness.

Didn’t you read the rest of the code at all? It’s not endian dependent.
If you look further down you find lines like

    pixel = (fg.r<<16)|(fg.g<<8)|fg.b;

and

  	*dst++ = pixel | (alpha << 24);

which should make it clear as crystal that the code expects the ARGB format
regardless of endianness.

Mattias, can you whip up a patch to correct that? I was just pulling
in a patch that somebody sent me, and I missed that.

Thanks!
-Sam Lantinga, Lead Programmer, Loki Software, Inc.

Mattias, can you whip up a patch to correct that? I was just pulling
in a patch that somebody sent me, and I missed that.

try this. I still don’t know why it was changed, so it might break something
else — I haven’t tested the stuff below, but at least it’s consistent with
nearby code

Nice to see you back, Sam

— SDL_ttf.c~ Sun Apr 29 21:53:03 2001
+++ SDL_ttf.c Tue May 22 11:23:32 2001
@@ -1091,7 +1091,6 @@
const Uint16 *ch;
Uint8 *src;
Uint32 *dst;

  • Uint32 Rmask, Gmask, Bmask, Amask;
    int row, col;
    c_glyph *glyph;
    FT_Error error;
    @@ -1104,19 +1103,11 @@
    height = font->height;

    /* Create the target surface, 32-bit ARGB format */

  • if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {

  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
    
  •   Amask = 0xFF000000;
    
  • } else {

  •   Rmask = 0xFF000000;
    
  •   Gmask = 0x00FF0000;
    
  •   Bmask = 0x0000FF00;
    
  •   Amask = 0x000000FF;
    
  • }
    textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 32,

  •                          Rmask, Gmask, Bmask, Amask);
    
  •                          0x00ff0000,
    
  •   		   0x0000ff00,
    
  •   		   0x000000ff,
    
  •   		   0xff000000);
    
    if ( textbuf == NULL ) {
    return(NULL);
    }
    @@ -1175,7 +1166,6 @@
    Uint32 pixel;
    Uint8 *src;
    Uint32 *dst;
  • Uint32 Rmask, Gmask, Bmask, Amask;
    int row, col;
    FT_Error error;
    c_glyph *glyph;
    @@ -1188,20 +1178,12 @@
    glyph = font->current;

    /* Create the target surface, 32-bit ARGB format */

  • if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {

  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
    
  •   Amask = 0xFF000000;
    
  • } else {

  •   Rmask = 0xFF000000;
    
  •   Gmask = 0x00FF0000;
    
  •   Bmask = 0x0000FF00;
    
  •   Amask = 0x000000FF;
    
  • }
    textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE,
    glyph->pixmap.width, glyph->pixmap.rows, 32,

  •                          Rmask, Gmask, Bmask, Amask);
    
  •   		       0x00ff0000,
    
  •   		       0x0000ff00,
    
  •   		       0x000000ff,
    
  •   		       0xff000000);
    
    if ( ! textbuf ) {
    return(NULL);
    }

Hi!

I tried this patch, but through removing the mask variables it brokes
TTF_RenderUNICODE_Blended and TTF_RenderGlyph_Blended.

output from gcc:
SDL_ttf.c: In function TTF_RenderUNICODE_Blended': SDL_ttf.c:1151:Amask’ undeclared (first use in this function)
SDL_ttf.c:1151: (Each undeclared identifier is reported only once
SDL_ttf.c:1151: for each function it appears in.)
SDL_ttf.c: In function TTF_RenderGlyph_Blended': SDL_ttf.c:1209:Amask’ undeclared (first use in this function)
make: *** [SDL_ttf.lo] Error 1

This now works:

diff -Naur SDL_ttf-2.0.2.orig/SDL_ttf.c SDL_ttf-2.0.2/SDL_ttf.c
— SDL_ttf-2.0.2.orig/SDL_ttf.c Sun Apr 29 21:53:03 2001
+++ SDL_ttf-2.0.2/SDL_ttf.c Wed May 23 12:53:58 2001
@@ -1091,7 +1091,6 @@
const Uint16 *ch;
Uint8 *src;
Uint32 *dst;

  • Uint32 Rmask, Gmask, Bmask, Amask;
    int row, col;
    c_glyph *glyph;
    FT_Error error;
    @@ -1103,20 +1102,11 @@
    }
    height = font->height;

  • /* Create the target surface, 32-bit ARGB format */

  • if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {

  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
    
  •   Amask = 0xFF000000;
    
  • } else {

  •   Rmask = 0xFF000000;
    
  •   Gmask = 0x00FF0000;
    
  •   Bmask = 0x0000FF00;
    
  •   Amask = 0x000000FF;
    
  • }
    textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 32,

  •                          Rmask, Gmask, Bmask, Amask);
    
  •                               0x00FF0000,
    
  •                               0x0000FF00,
    
  •                               0x000000FF,
    
  •                               0xFF000000);
    
    if ( textbuf == NULL ) {
    return(NULL);
    }
    @@ -1157,7 +1147,7 @@
    row = (textbuf->h-1) - font->underline_height;
    }
    dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
  •   pixel |= Amask;
    
  •   pixel |= 0xFF000000; /* Amask */
      for ( row=font->underline_height; row>0; --row ) {
      	for ( col=0; col < textbuf->w; ++col ) {
      		dst[col] = pixel;
    

@@ -1175,7 +1165,6 @@
Uint32 pixel;
Uint8 *src;
Uint32 *dst;

  • Uint32 Rmask, Gmask, Bmask, Amask;
    int row, col;
    FT_Error error;
    c_glyph *glyph;
    @@ -1187,21 +1176,12 @@
    }
    glyph = font->current;

  • /* Create the target surface, 32-bit ARGB format */

  • if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {

  •   Rmask = 0x000000FF;
    
  •   Gmask = 0x0000FF00;
    
  •   Bmask = 0x00FF0000;
    
  •   Amask = 0xFF000000;
    
  • } else {

  •   Rmask = 0xFF000000;
    
  •   Gmask = 0x00FF0000;
    
  •   Bmask = 0x0000FF00;
    
  •   Amask = 0x000000FF;
    
  • }
    textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE,
    glyph->pixmap.width, glyph->pixmap.rows, 32,

  •                          Rmask, Gmask, Bmask, Amask);
    
  •                                   0x00FF0000,
    
  •                                   0x0000FF00,
    
  •                                   0x000000FF,
    
  •                                   0xFF000000); 
    
    if ( ! textbuf ) {
    return(NULL);
    }
    @@ -1224,7 +1204,7 @@
    row = (textbuf->h-1) - font->underline_height;
    }
    dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
  •   pixel |= Amask;
    
  •   pixel |= 0xFF000000; /* Amask */
      for ( row=font->underline_height; row>0; --row ) {
      	for ( col=0; col < textbuf->w; ++col ) {
      		dst[col] = pixel;
    

so long
Thomas–


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/

How about adding the patch to the next beta release of SDL_ttf 2.0.x? It worked
really fine for me and it should be included. The ARGB troubles are fixed.

BTW, how about adding support for freetype1 in SDL_ttf 2.0.x through simply
copying SDL_ttf.c from the 1.2.x branch to the 2.0.x branch and renaming it to
say SDL_ttf1.c. Then a simple and small configure.in check for the freetype lib
versions and a conditional compile in Makefile.am? Is it good to add freetype1
support to SDL_ttf 2.0.x?

So long
Thomas–
___ Obviously we do not want to leave zombies around.
/\ - W. Richard Stevens
( ^ >
/ \ Thomas Krennwallner
(
/) Fingerprint: 9484 D99D 2E1E 4E02 5446 DAD9 FF58 4E59 67A1 DA7B