SDL_ttf font blitting problem (ALPHA issue)

If I do this (as in the SDL_ttf showfont.exe test app) my true type font looks
great:

  1. Call TTF_RenderText_Solid() which returns a newly created SDL_Surface with
    the text printed with the true type font.
  2. Call SDL_BlitSurface() to blit to the screen.

With the above steps it is smooth and antialiased. Unfortunately what I have
to do for our text and textbox classes is to blit to an additional
intermediate surface before blitting to the screen.

  1. Call TTF_RenderText_Solid() which returns a newly created SDL_Surface with
    the text printed with the true type font.
  2. Call SDL_BlitSurface() to blit to the text or textbox surface.
  3. Blit the surface in #2 to the screen.

This looks bad. We lose all of the alpha data so what we get is only the
pixels that had full Alpha getting drawn; anything that had partial alpha does
not show up.

I have tried converting the surfaces, setting SRCCOLORKEY, setting SRCALPHA,
etc. I have also tried using TTF_RenderText_Blended(). Nothing makes a
difference.

Well, that isn’t strictly true, when I use TTF_RenderText_Blended() there is a
combination that DOES seem to blit the extra pixels that had an alpha
component, but instead of showing up in the font color (black), they show up
in blue on some screens and white on others. Very weird and odd.

Any ideas? Anything you can suggest would be appreciated.

  • Ken

Ken Rogoway wrote:

If I do this (as in the SDL_ttf showfont.exe test app) my true type font looks
great:

  1. Call TTF_RenderText_Solid() which returns a newly created SDL_Surface with
    the text printed with the true type font.
  2. Call SDL_BlitSurface() to blit to the screen.

With the above steps it is smooth and antialiased. Unfortunately what I have
to do for our text and textbox classes is to blit to an additional
intermediate surface before blitting to the screen.

  1. Call TTF_RenderText_Solid() which returns a newly created SDL_Surface with
    the text printed with the true type font.
  2. Call SDL_BlitSurface() to blit to the text or textbox surface.
  3. Blit the surface in #2 to the screen.

This looks bad. We lose all of the alpha data so what we get is only the
pixels that had full Alpha getting drawn; anything that had partial alpha does
not show up.

I have tried converting the surfaces, setting SRCCOLORKEY, setting SRCALPHA,
etc. I have also tried using TTF_RenderText_Blended(). Nothing makes a
difference.

Well, that isn’t strictly true, when I use TTF_RenderText_Blended() there is a
combination that DOES seem to blit the extra pixels that had an alpha
component, but instead of showing up in the font color (black), they show up
in blue on some screens and white on others. Very weird and odd.

Any ideas? Anything you can suggest would be appreciated.

  • Ken

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

If you’re going to render fonts onto other surfaces, all these surfaces
should be either RGB
or RGBA, not a combination. This is easiest to deal with. If you blend
a TTF rendered
font onto a surface with a color key, you might have a problem for this
reason.
Try putting your textbox into an alpha surface, then putting the text on
top of that.
Without more specific code I can’t really offer another (better) suggestion.

-TomT64

TomT64 <tomt64 users.sf.net> writes:

If you’re going to render fonts onto other surfaces, all these surfaces
should be either RGB
or RGBA, not a combination. This is easiest to deal with. If you blend
a TTF rendered
font onto a surface with a color key, you might have a problem for this
reason.
Try putting your textbox into an alpha surface, then putting the text on
top of that.
Without more specific code I can’t really offer another (better) suggestion.

-TomT64

Tom,

I modified the showfont example (in SDL_ttf) to do the following:

Line 188: screen = SDL_SetVideoMode(800, 600,24, SDL_SWSURFACE);

Line 204: /SDL_SetColors(screen, colors, 0, NUM_COLORS);/

Line 214: text = TTF_RenderText_Blended(font, string, *forecol);

Line 237: text = TTF_RenderText_Blended(font,message,*forecol);

I changed/added around line 322:

#if 0
/* Set the text colorkey and convert to display format */
if ( SDL_SetColorKey(text, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0) < 0 ) {
fprintf(stderr, “Warning: Couldn’t set text colorkey: %s\n”,
SDL_GetError
());
}
temp = SDL_DisplayFormat(text);
if ( temp != NULL ) {
SDL_FreeSurface(text);
text = temp;
}
#endif

pTextCopy = SDL_CreateRGBSurface( SDL_SWSURFACE,
				text->w,
				text->h,
				32,
				0xFF000000,
				0x00FF0000,
				0x0000FF00,
				0x000000FF );

SDL_BlitSurface( text,NULL,pTextCopy,NULL );

Finally I changed the blit to use the text copy:

		case SDL_MOUSEBUTTONDOWN:
			dstrect.x = event.button.x - text->w/2;
			dstrect.y = event.button.y - text->h/2;
			dstrect.w = text->w;
			dstrect.h = text->h;
			if ( SDL_BlitSurface(pTextCopy, NULL, screen,
						&dstrect) == 0 ) {

Now, I see my initial blit, the font info blit (in the upper left corner), but
none of the mouse clicks blit anything visible. I can email the modified
showfont.c file if that would make it easier to test.

Any ideas? I appreciate your time and help.

  • Ken

Ken Rogoway <Ken HomebrewSoftware.com> writes:

If you use this instead it works great!

pTextCopy = SDL_CreateRGBSurface( SDL_SWSURFACE,
				text->w,
				text->h,
				32,
				0xFF000000,
				0x00FF0000,
				0x0000FF00,
				0x000000FF );

SDL_SetAlpha( text,0,0xFF );
SDL_SetAlpha( pTextCopy,SDL_SRCALPHA,SDL_ALPHA_TRANSPARENT );

SDL_BlitSurface( text,NULL,pTextCopy,NULL );