Getting outlined text in SDL_TTF

I am using SDL 1.2.14 and SDL_ttf 2.0.9 on OS X using fink and I am trying
to display some white text with a sort of shadow / outline so that it will
show up against most backgrounds.

Presently I am using TTF_RenderText_Solid which works fine except that the
text becomes bleached out on the lighter backgrounds.

By changing TTF_RenderText_Solid to TTF_RenderText_Blended results in
nothing appearing on screen regardless of the background colour. I have also
tried TTF_RenderText_Shaded (with a black background colour) but this just
places the text in a black box which I don’t want.

I am assuming that there is some setting that I am getting wrong but there
are far too many moving parts for me to make sense of this but this is sort
of how it works

I have a screen, background and displayed text (all SDL surfaces).

An image is loaded into the background.

The text is added to the displayed text surface with TTF_RenderText_Solid.

Then to display the screen the background is blitted screen surface, then
the displayed text is blitted.

Any ideas as to why TTF_RenderText_Blended might not work?

You can try out the new outline API in the SDL_ttf 2.0.10 preview:
http://www.libsdl.org/tmp/SDL_ttf/On Sun, Jan 24, 2010 at 5:34 AM, Peter Hickman wrote:

I am using SDL 1.2.14 and SDL_ttf 2.0.9 on OS X using fink and I am trying
to display some white text with a sort of shadow / outline so that it will
show up against most backgrounds.
Presently I am using?TTF_RenderText_Solid which works fine except that the
text becomes bleached out on the lighter backgrounds.
By changing?TTF_RenderText_Solid to?TTF_RenderText_Blended results in
nothing appearing on screen regardless of the background colour. I have also
tried?TTF_RenderText_Shaded (with a black background colour) but this just
places the text in a black box which I don’t want.
I am assuming that there is some setting that I am getting wrong but there
are far too many moving parts for me to make sense of this but this is sort
of how it works
I have a screen, background and displayed text (all SDL surfaces).
An image is loaded into the background.
The text is added to the displayed text surface with?TTF_RenderText_Solid.
Then to display the screen the background is blitted screen surface, then
the displayed text is blitted.
Any ideas as to why?TTF_RenderText_Blended might not work?


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


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Thanks, I have tried that and it is an improvement but I think I will need
to get back to it again later.

Hi,On 1/25/10, Peter Hickman wrote:

Thanks, I have tried that and it is an improvement but I think I will need
to get back to it again later.

You are welcome to adapt our BlackOutline() function from tuxmath and
tuxtype if you like - it is GPLv2+. You could simplify it a lot
because it is written to use either SDL_Pango or SDL_ttf, depending on
what is available at build time for a given platform.

The original is at git://git.debian.org/git/tux4kids/tuxtype.git, in
file src/SDL_extras.c

David Bruce

SDL_Surface* BlackOutline(const char* t, int font_size, const SDL_Color* c)
{
SDL_Surface* out = NULL;
SDL_Surface* black_letters = NULL;
SDL_Surface* white_letters = NULL;
SDL_Surface* bg = NULL;
SDL_Rect dstrect;
Uint32 color_key;

/* Make sure everything is sane before we proceed: /
#ifdef HAVE_LIBSDL_PANGO
if (!context)
{
fprintf(stderr, “BlackOutline(): invalid SDL_Pango context - returning.\n”);
return NULL;
}
#else
TTF_Font
font = get_font(font_size);
if (!font)
{
fprintf(stderr, “BlackOutline(): could not load needed font -
returning.\n”);
return NULL;
}
#endif

if (!t || !c)
{
fprintf(stderr, “BlackOutline(): invalid ptr parameter, returning.\n”);
return NULL;
}

if (t[0] == ‘\0’)
{
LOG(“BlackOutline(): empty string, returning\n”);
return NULL;
}

DEBUGCODE
{
fprintf( stderr, “\nEntering BlackOutline(): \n”);
fprintf( stderr, “BlackOutline of “%s”\n”, t );
}

#ifdef HAVE_LIBSDL_PANGO
Set_SDL_Pango_Font_Size(font_size);
SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_BLACK_LETTER);
SDLPango_SetText(context, t, -1);
black_letters = SDLPango_CreateSurfaceDraw(context);
#else
black_letters = TTF_RenderUTF8_Blended(font, t, black);
#endif

if (!black_letters)
{
fprintf (stderr, “Warning - BlackOutline() could not create image
for %s\n”, t);
return NULL;
}

bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
(black_letters->w) + 5,
(black_letters->h) + 5,
32,
rmask, gmask, bmask, amask);
/* Use color key for eventual transparency: */
color_key = SDL_MapRGB(bg->format, 01, 01, 01);
SDL_FillRect(bg, NULL, color_key);

/* Now draw black outline/shadow 2 pixels on each side: */
dstrect.w = black_letters->w;
dstrect.h = black_letters->h;

/* NOTE: can make the “shadow” more or less pronounced by /
/
changing the parameters of these loops. */
for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
SDL_BlitSurface(black_letters , NULL, bg, &dstrect );

SDL_FreeSurface(black_letters);

/* — Put the color version of the text on top! — /
#ifdef HAVE_LIBSDL_PANGO
/
convert color arg: /
SDLPango_Matrix
color_matrix = SDL_Colour_to_SDLPango_Matrix©;

if (color_matrix)
{
SDLPango_SetDefaultColor(context, color_matrix);
free(color_matrix);
}
else /* fall back to just using white if conversion fails: */
SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);

white_letters = SDLPango_CreateSurfaceDraw(context);

#else
white_letters = TTF_RenderUTF8_Blended(font, t, *c);
#endif

if (!white_letters)
{
fprintf (stderr, “Warning - BlackOutline() could not create image
for %s\n”, t);
return NULL;
}

dstrect.x = 1;
dstrect.y = 1;
SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
SDL_FreeSurface(white_letters);

/* — Convert to the screen format for quicker blits — */
SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
out = SDL_DisplayFormatAlpha(bg);
SDL_FreeSurface(bg);

DEBUGCODE
{ fprintf( stderr, “\nLeaving BlackOutline(): \n”); }

return out;
}

Thanks for that, I will have a go.

Thank you.

This is what I’m using, see attachment.
http://old.nabble.com/file/p27316444/OL_Text.zip OL_Text.zip

Looks like you are doing a kind of OSD. I highly recommend you to have a
look at Clement’s SDL_layer, nice stuff.

HTH
Phuoc

Peter Hickman-4 wrote:>

I have a screen, background and displayed text (all SDL surfaces).

An image is loaded into the background.

The text is added to the displayed text surface with TTF_RenderText_Solid.

Then to display the screen the background is blitted screen surface, then
the displayed text is blitted.

Any ideas as to why TTF_RenderText_Blended might not work?


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



www.folksfun.com

View this message in context: http://old.nabble.com/Getting-outlined-text-in-SDL_TTF-tp27294862p27316444.html
Sent from the SDL mailing list archive at Nabble.com.

Hi,

Thank you, by the way SDL_Layer was made for SDL 1.2 only.
I have no time to see what I need to change to make it 1.3 compliant.
Basically it’s a little tool which exposes a quite simple API for
blitting SDL surfaces (sprites, backgrounds, whatever you want)
in multiple levels of display. It manages scrolling so all you need to know are the blit coordinate in each layer space and the transformations are made automatically on the display when they’re
projected (from back to front).

If other people has interest in it, let me know and I’ll deal with
the 1.3 port.

Here is the official website:
http://code.google.com/p/sdl-layer

You may find the code in other places but they don’t have the
latest source code so don’t download it (notably on OS4Depot).

PS: Phuoc, how’s your project gone ? I didn’t find time
to use Windows yet at work. You can answer in private

Regards,>> Looks like you are doing a kind of OSD. I highly recommend you to >> have a

look at Clement’s SDL_layer, nice stuff.

HTH
Phuoc

Julien,
I’ve added some data structures which allow a layer to fade in/out “automatically”. I’m using it for OSD. When I got it documeted I’ll send you the details. But at the moment I’m still struggling with other issues in my program :frowning:

/_/_/_/_/_/_
www.huaonline.com
My Homepage is my Castle— On Wed, 27/1/10, julien CLEMENT wrote:

From: julien CLEMENT
Subject: Re: [SDL] Getting outlined text in SDL_TTF
To: “SDL”
Received: Wednesday, 27 January, 2010, 7:48 AM
Hi,

Thank you, by the way SDL_Layer was made for SDL 1.2 only.
I have no time to see what I need to change to make it 1.3
compliant.
Basically it’s a little tool which exposes a quite simple
API for
blitting SDL surfaces (sprites, backgrounds, whatever you
want)
in multiple levels of display. It manages scrolling so all
you need to know are the blit coordinate in each layer space
and the transformations are made automatically on the
display when they’re
projected (from back to front).

If other people has interest in it, let me know and I’ll
deal with
the 1.3 port.

Here is the official website:
http://code.google.com/p/sdl-layer

You may find the code in other places but they don’t have
the
latest source code so don’t download it (notably on
OS4Depot).

PS: Phuoc, how’s your project gone ? I didn’t find time
to use Windows yet at work. You can answer in private

Regards,

Looks like you are doing a kind of OSD. I highly
recommend you to >> have a

look at Clement’s SDL_layer, nice stuff.

HTH
Phuoc

? ? ?


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

  __________________________________________________________________________________

Yahoo!7: Catch-up on your favourite Channel 7 TV shows easily, legally, and for free at PLUS7. www.tv.yahoo.com.au/plus7

You can try out the new outline API in the SDL_ttf 2.0.10 preview:
http://www.libsdl.org/tmp/SDL_ttf/

Here’s a short working sample:

    #define OUTLINE_SIZE 2

/* load font and its outline */
font = TTF_OpenFont(font_path, font_size);
font_outline = TTF_OpenFont(font_path, font_size);
TTF_SetFontOutline(font_outline, OUTLINE_SIZE);

/* render text and text outline */
SDL_Color white = {0xFF, 0xFF, 0xFF};
SDL_Color black = {0x00, 0x00, 0x00};
SDL_Surface *bg_surface = TTF_RenderText_Blended(font_outline, text, black);
SDL_Surface *fg_surface = TTF_RenderText_Blended(font, text, white);
SDL_Rect rect = {OUTLINE_SIZE, OUTLINE_SIZE, fg_surface->w, fg_surface->h};

/* blit text onto its outline */
SDL_SetSurfaceBlendMode(fg_surface, SDL_BLENDMODE_BLEND);
SDL_BlitSurface(fg_surface, NULL, bg_surface, &rect);
SDL_FreeSurface(fg_surface);

/* we got now RGBA white text with black outline in bg_surface */

In opposition to previously posted methods using some loop drawing black text shifted around and then white text, TTF_SetFontOutline real and accurate outline made of TTF vector path, and IMHO is much simpler.

Regards,–
Adam

1 Like

When developing SabaccBasics for the PSP (2.1.0) the stroker interface was different.

FT_Stroker_New( FT_Memory memory, FT_Stroker * )

as opposed to this which SDL_ttf uses.

FT_Stroker_New( FT_Library library, FT_Stroker * )

In quick look at SDL_TTF I don’t see any checks for this. It looks like this change happened in 2.2.

I don’t have a freetype lib other than 2.3 on here to test it, but this should work as it did on the PSP:

— SDL_ttf-2.10.0/SDL_ttf.c 2010-01-28 05:20:00.000000000 -0500
+++ SDL_ttf-2.10.0-strokefix/SDL_ttf.c 2010-01-28 05:22:34.000000000 -0500
@@ -660,7 +660,11 @@
if( (font->outline > 0) && glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
FT_Stroker stroker;
FT_Get_Glyph( glyph, &bitmap_glyph );
+#if (FREETYPE_MAJOR = 2) && (FREETYPE_MINOR < 2)// was: #if(PSP)

  •   	error = FT_Stroker_New( library->memory, &stroker );
    

+#else
error = FT_Stroker_New( library, &stroker );
+#endif// Pre-2.2 fix
if( error ) {
return error;
}–
Anthony T.

Is that supposed to be a double equals in the #if clause?

Jonny DOn Thu, Jan 28, 2010 at 5:28 AM, wrote:

When developing SabaccBasics for the PSP (2.1.0) the stroker interface was
different.

FT_Stroker_New( FT_Memory memory, FT_Stroker * )

as opposed to this which SDL_ttf uses.

FT_Stroker_New( FT_Library library, FT_Stroker * )

In quick look at SDL_TTF I don’t see any checks for this. It looks like
this change happened in 2.2.

I don’t have a freetype lib other than 2.3 on here to test it, but this
should work as it did on the PSP:

— SDL_ttf-2.10.0/SDL_ttf.c 2010-01-28 05:20:00.000000000 -0500
+++ SDL_ttf-2.10.0-strokefix/SDL_ttf.c 2010-01-28 05:22:34.000000000 -0500
@@ -660,7 +660,11 @@
if( (font->outline > 0) && glyph->format !=
FT_GLYPH_FORMAT_BITMAP ) {
FT_Stroker stroker;
FT_Get_Glyph( glyph, &bitmap_glyph );
+#if (FREETYPE_MAJOR = 2) && (FREETYPE_MINOR < 2)// was: #if(PSP)

  •                   error = FT_Stroker_New( library->memory, &stroker
    

);
+#else
error = FT_Stroker_New( library, &stroker );
+#endif// Pre-2.2 fix
if( error ) {
return error;
}


Anthony T.


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

How do you composite the text layer onto the outline layer like that?

When I attempted to do the same thing, my searching could not find anything like that. I ended up having to write a custom alpha blitting function.
Is this a new feature in SDL that I am not aware of?

D’oh!

I copied and pasted my old code, replaced it with something more
appropriate and rushed.

That’s why I always do something like

#if (2 == FREETYPE_MAJOR) && (1 < FREETYPE_MINOR)

Not that with a macro it matters, either way a compiler error should
result, as you can’t assign a constant to a constant.

So Sam, you just need to fix that #if clause if that patch was good for
you.On Thu, Jan 28, 2010 at 11:01:58AM -0500, Jonathan Dearborn wrote:

Is that supposed to be a double equals in the #if clause?


Anthony T.

Jonny D

On Thu, Jan 28, 2010 at 5:28 AM, wrote:

When developing SabaccBasics for the PSP (2.1.0) the stroker interface was
different.

FT_Stroker_New( FT_Memory memory, FT_Stroker * )

as opposed to this which SDL_ttf uses.

FT_Stroker_New( FT_Library library, FT_Stroker * )

In quick look at SDL_TTF I don’t see any checks for this. It looks like
this change happened in 2.2.

I don’t have a freetype lib other than 2.3 on here to test it, but this
should work as it did on the PSP:

— SDL_ttf-2.10.0/SDL_ttf.c 2010-01-28 05:20:00.000000000 -0500
+++ SDL_ttf-2.10.0-strokefix/SDL_ttf.c 2010-01-28 05:22:34.000000000 -0500
@@ -660,7 +660,11 @@
if( (font->outline > 0) && glyph->format !=
FT_GLYPH_FORMAT_BITMAP ) {
FT_Stroker stroker;
FT_Get_Glyph( glyph, &bitmap_glyph );
+#if (FREETYPE_MAJOR = 2) && (FREETYPE_MINOR < 2)// was: #if(PSP)

  •                   error = FT_Stroker_New( library->memory, &stroker
    

);
+#else
error = FT_Stroker_New( library, &stroker );
+#endif// Pre-2.2 fix
if( error ) {
return error;
}


Anthony T.


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