Patch for SDL_ttf to support Freetype2

Hi all,

I’ve done a mechanical port of Michael Chen’s port to Freetype2 to
the otop of the ttf tree. The code compiles and runs, but has errors
in the output font size (it looks like I missed some code duplication
around the font height somewhere) that I’m not familiar enough with
Freetype to fix.

So in case it is useful to someone else with more experience, here is
the patch.–
// .–=,
…::://::::::::::::::::::::::::::::… (o O & @kevin_at_ank.com
:::::::://:::://://://:/:://::||// / V K
:::::://:::://:/:|//’/’ // ,|’ r , ‘qk
:’’’/
__ // / // |_// // || .’~. .~`,
kls _/-=_/
-------------- next part --------------
? README-mc.txt
? .deps
? patch
? INSTALL
? NEWS
? AUTHORS
? ChangeLog
? .libs
? SDL_ttf.lo
? libSDL_ttf.la
? showfont
Index: CHANGES

RCS file: /cvs/SDL_ttf/CHANGES,v
retrieving revision 1.6
diff -u -r1.6 CHANGES
— CHANGES 2000/12/17 19:00:14 1.6
+++ CHANGES 2001/05/14 18:57:50
@@ -1,4 +1,3 @@

1.2.3:
Mathias Holst - Sun, 17 Dec 2000 16:06:56 +0100

  • Fixed bug in TTF_Render*_Blended() underlining
    @@ -16,6 +15,12 @@
  • Added TTF_FontAscent() for completeness
    Ray Kelm - Fri, 04 Aug 2000 20:58:00 -0400
  • Added support for cross-compiling Windows DLL from Linux

+1.2.1-mc:
+
+Michael Chent - 25 Jul 2000

    • Port to support Freetype 2 beta
  • (Apologies for the #if ugliness.)

1.2.1:
Sam Lantinga - Wed May 10 19:54:56 PDT 2000
Index: SDL_ttf.c

RCS file: /cvs/SDL_ttf/SDL_ttf.c,v
retrieving revision 1.7
diff -u -r1.7 SDL_ttf.c
— SDL_ttf.c 2000/12/17 19:00:14 1.7
+++ SDL_ttf.c 2001/05/14 18:57:50
@@ -1,3 +1,8 @@
+// SDL_ttf 1.2.1-mc
+//
+// Original author: Sam Lantinga
+// Modified 7/25/2000 by Michael Chen to support Freetype 2 beta
+// (Apologies for the #if ugliness.)

#include <math.h>
#include <stdio.h>
@@ -5,12 +10,28 @@
#include <string.h>
#include <assert.h>

+// Michael Chen
+// For Freetype 2, this is necessary.
+// Apologies in advance to those with Freetype 1 without it.
+#define FREETYPE_HDR_DIRECTORY
+
#ifdef FREETYPE_HDR_DIRECTORY
#include <freetype/freetype.h>
#else
#include <freetype.h>
#endif

+// Auto-detect Freetype version from header file define.
+#if FREETYPE_MAJOR > 1
+#define FREETYPE2 1
+#endif
+
+#if FREETYPE2
+# define FTPITCH pitch
+#else
+# define FTPITCH cols
+#endif
+
#include “SDL.h”
#include “SDL_ttf.h”

@@ -35,8 +56,14 @@
/* The structure used to hold glyph information (cached) */
struct glyph {
int cached;
+#if FREETYPE2

  • // need to make equivalents for bitmap and pixmap
  • FT_Bitmap bitmap;
  • FT_Bitmap pixmap;
    +#else
    TT_Raster_Map bitmap;
    TT_Raster_Map pixmap;
    +#endif
    int minx;
    int maxx;
    int miny;
    @@ -46,11 +73,15 @@

/* The structure used to hold internal font information */
struct _TTF_Font {
+#if FREETYPE2

  • FT_Face face;
  • FT_GlyphSlot glyph;
    +#else
    TT_Face face;
    TT_Instance inst;
    TT_Glyph glyph;
    TT_CharMap map;

+#endif
/* Font metrics /
int pointsize;
int height; /
ascent - descent */
@@ -72,13 +103,21 @@
};

/* The FreeType font engine */
+#if FREETYPE2
+static FT_Library engine;
+#else
static TT_Engine engine;
+#endif

int TTF_Init(void)
{
int error;

+#if FREETYPE2

  • error = FT_Init_FreeType(&engine);
    +#else
    error = TT_Init_FreeType(&engine);
    +#endif
    if ( error ) {
    SDL_SetError(“Couldn’t init FreeType engine”);
    return(-1);
    @@ -89,11 +128,15 @@
    TTF_Font *TTF_OpenFont(const char *file, int ptsize)
    {
    TTF_Font *font;
    +#if FREETYPE2
  • FT_Error error;
    +#else
    TT_Face_Properties properties;
    TT_Instance_Metrics imetrics;
  • int i, n;
    TT_UShort platform, encoding;
    TT_Error error;
  • int i, n;
    +#endif

    font = (TTF_Font *)malloc(sizeof(*font));
    if ( font == NULL ) {
    @@ -103,12 +146,42 @@
    memset(font, 0, sizeof(*font));

    /* Open the font and create ancillary data */
    +#if FREETYPE2

  • error = FT_New_Face(engine, file, 0, &font->face);
    +#else
    error = TT_Open_Face(engine, file, &font->face);
    +#endif
    if ( error ) {
    SDL_SetError(“Couldn’t load font file”);
    free(font);
    return(NULL);
    }
    +#if FREETYPE2

  • // don’t need TT_New_Glyph

  • // don’t need TT_New_Instance

  • error = FT_Set_Pixel_Sizes(font->face,0,ptsize);

  • if ( error ) {

  •   SDL_SetError("Couldn't set font size");
    
  •   TTF_CloseFont(font);
    
  •   return(NULL);
    
  • }

  • error = FT_Select_Charmap(font->face,ft_encoding_unicode);

  • if ( error ) {

  •   SDL_SetError("Font doesn't have a Unicode mapping");
    
  •   TTF_CloseFont(font);
    
  •   return(NULL);
    
  • }

  • /* Get the font metrics for this font */

  • font->pointsize = font->face->size->metrics.y_ppem;

  • font->ascent = (float)font->face->ascender / font->face->units_per_EM;

  • font->descent = (float)-font->face->descender /

  •                font->face->units_per_EM;
    
  • font->lineskip = ((float)font->face->height - font->face->ascender - font->face->descender) /

  •                 font->face->units_per_EM;
    

+#else
error = TT_New_Glyph(font->face, &font->glyph);
if ( error ) {
SDL_SetError(“Couldn’t create glyph container”);
@@ -121,7 +194,6 @@
TTF_CloseFont(font);
return(NULL);
}

/* Set the display resolution */
error = TT_Set_Instance_Resolutions(font->inst, 75, 75);
if ( error ) {

@@ -160,12 +232,13 @@
font->pointsize = imetrics.y_ppem;
font->ascent = (float)properties.horizontal->Ascender /
properties.header->Units_Per_EM;

  • font->ascent *= font->pointsize;
    font->descent = (float)properties.horizontal->Descender /
    properties.header->Units_Per_EM;
  • font->descent *= font->pointsize;
    font->lineskip = (float)properties.horizontal->Line_Gap /
    properties.header->Units_Per_EM;
    +#endif
  • font->ascent *= font->pointsize;
  • font->descent *= font->pointsize;
    font->lineskip *= font->pointsize;
    font->height = round(font->ascent - font->descent);

@@ -173,7 +246,7 @@
font->style = TTF_STYLE_NORMAL;
font->glyph_overhang = font->pointsize/10;
/* x offset = cos(((90.0-12)/360)2M_PI), or 12 degree angle */

  • font->glyph_italics = 0.207;
  • font->glyph_italics = 0.207F;
    font->glyph_italics *= font->height;

    return(font);
    @@ -181,6 +254,9 @@

static void Flush_Glyph(struct glyph *glyph)
{
+#if FREETYPE2

  • // need to figure this out
    +#else
    if ( glyph->bitmap.bitmap ) {
    free(glyph->bitmap.bitmap);
    glyph->bitmap.bitmap = 0;
    @@ -189,6 +265,7 @@
    free(glyph->pixmap.bitmap);
    glyph->pixmap.bitmap = 0;
    }
    +#endif
    glyph->cached = 0;
    }

@@ -206,15 +283,37 @@
}
}

-static TT_Error Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph)
+static
+#if FREETYPE2
+FT_Error
+#else
+TT_Error
+#endif
+Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph)
{
+#if FREETYPE2

  • FT_Error error;
  • int size;
    +#else
    TT_UShort index;
    TT_Glyph_Metrics metrics;
    TT_Outline outline;
  • TT_Error error;
    +#endif
    int x_offset;
    int y_offset;
  • TT_Error error;

+#if FREETYPE2

  • error = FT_Load_Char(font->face, UNICODE(ch), FT_LOAD_DEFAULT); //NO_BITMAP);

  • if ( error ) return error;

  • /* Get the bounding box */

  • glyph->minx = (font->face->glyph->metrics.horiBearingX & -64) / 64;

  • glyph->maxx = ((font->face->glyph->metrics.horiBearingX + font->face->glyph->metrics.width + 63) & -64) / 64;

  • glyph->miny = ((font->face->glyph->metrics.height - font->face->glyph->metrics.horiBearingY) & -64) / 64;

  • glyph->maxy = ((font->face->glyph->metrics.height + 63) & -64) / 64;

  • glyph->advance = (font->face->glyph->metrics.horiAdvance & -64) / 64;
    +#else
    /* Load the glyph */
    index = TT_Char_Index(font->map, UNICODE(ch));
    error = TT_Load_Glyph(font->inst, font->glyph, index, TTLOAD_DEFAULT);
    @@ -227,6 +326,7 @@
    glyph->miny = (metrics.bbox.yMin & -64) / 64;
    glyph->maxy = ((metrics.bbox.yMax + 63) & -64) / 64;
    glyph->advance = (metrics.advance & -64) / 64;
    +#endif

    /* Adjust for bold and italic text */
    if ( font->style & TTF_STYLE_BOLD ) {
    @@ -236,9 +336,125 @@
    glyph->maxx += round(font->glyph_italics);
    }

  • glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7;

  • glyph->bitmap.rows = font->height;

  • glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3;

  • glyph->pixmap.rows = font->height;

+#if FREETYPE2

  • // prepare bitmap for rendering
  • /* set-up a bitmap descriptor for our target bitmap */
  • glyph->bitmap.pitch = glyph->bitmap.width / 8;
  • /* render into a mono bitmap */
  • glyph->bitmap.pixel_mode = ft_pixel_mode_mono;
  • size = glyph->bitmap.pitch * glyph->bitmap.rows;
  • if (size)
  • {
  •   // allocate memory for bitmap
    
  •   glyph->bitmap.buffer = malloc(size);
    
  •   if ( ! glyph->bitmap.buffer ) {
    
  •   	error = FT_Err_Out_Of_Memory;
    
  •   	goto was_error;
    
  •   }
    
  •   memset(glyph->bitmap.buffer, 0, size);
    
  • }
  • else
  • {
  •   glyph->bitmap.buffer = 0;
    
  • }
  • // prepare pixmap for rendering
  • /* set-up a bitmap descriptor for our target pixmap */
  • glyph->pixmap.pitch = glyph->pixmap.width;
  • /* render into a pixmap */
  • glyph->pixmap.pixel_mode = ft_pixel_mode_grays;
  • glyph->pixmap.num_grays = 128;
  • size = glyph->pixmap.pitch * glyph->pixmap.rows;
  • if (size)
  • {
  •   // allocate memory for bitmap
    
  •   glyph->pixmap.buffer = malloc(size);
    
  •   if ( ! glyph->pixmap.buffer ) {
    
  •   	error = FT_Err_Out_Of_Memory;
    
  •   	goto was_error;
    
  •   }
    
  •   memset(glyph->pixmap.buffer, 0, size);
    
  • }
  • else
  • {
  •   glyph->pixmap.buffer = 0;
    
  • }
  • /* Render the glyph into the bitmap and pixmap */
  • /* Handle the italic style */
  • if ( font->style & TTF_STYLE_ITALIC ) {
  •   FT_Matrix shear;
    
  •   shear.xx = 1<<16;
    
  •   shear.xy = (int)(font->glyph_italics*(1<<16))/font->height;
    
  •   shear.yx = 0;
    
  •   shear.yy = 1<<16;
    
  •   FT_Outline_Transform(&font->face->glyph->outline, &shear);
    
  • }
  • x_offset = -glyph->minx * 64;
  • y_offset = -round(font->descent) * 64;
  • FT_Outline_Translate(&font->face->glyph->outline, x_offset, y_offset);
  • error += FT_Outline_Get_Bitmap(engine, &font->face->glyph->outline, &glyph->bitmap);
  • error += FT_Outline_Get_Bitmap(engine, &font->face->glyph->outline, &glyph->pixmap);
  • /* Handle the bold style */
  • if ( font->style & TTF_STYLE_BOLD ) {
  •   int row, col;
    
  •   int offset;
    
  •   int pixel;
    
  •   Uint8 *pixmap;
    
  •   /* The bitmap is easy, just render another copy */
    
  •   for ( offset=0; offset < font->glyph_overhang; ++offset ) {
    
  •   	FT_Outline_Translate(&font->face->glyph->outline, 64, 0);
    
  •   	error += FT_Outline_Get_Bitmap(engine,
    
  •   								   &font->face->glyph->outline,&glyph->bitmap);
    
  •   }
    
  •   x_offset += font->glyph_overhang*64;
    
  •   /* The pixmap is a little harder, we have to add and clamp */
    
  •   for ( row=glyph->pixmap.rows-1; row >= 0; --row ) {
    
  •   	pixmap = (Uint8 *)glyph->pixmap.buffer +
    
  •   					  row*glyph->pixmap.pitch;
    
  •   	for (offset=1; offset<=font->glyph_overhang; ++offset) {
    
  •   		for (col=glyph->pixmap.pitch-1; col > 0; --col) {
    
  •   			pixel=(pixmap[col]+pixmap[col-1]);
    
  •   			if ( pixel > 4 ) {
    
  •   				pixel = 4;
    
  •   			}
    
  •   			pixmap[col] = (Uint8)pixel;
    
  •   		}
    
  •   	}
    
  •   }
    
  • }
  • FT_Outline_Translate(&font->face->glyph->outline, -x_offset, -y_offset);
    +was_error:
  • if ( error ) {
  •   if ( glyph->bitmap.buffer ) {
    
  •   	free(glyph->bitmap.buffer);
    
  •   	glyph->bitmap.buffer = 0;
    
  •   }
    
  •   if ( glyph->pixmap.buffer ) {
    
  •   	free(glyph->pixmap.buffer);
    
  •   	glyph->pixmap.buffer = 0;
    
  •   }
    
  •   return error;
    
  • }
  • /* We’re done, mark this glyph cached */
  • glyph->cached = ch;
  • return FT_Err_Ok;
    +#else
    /* Get the bitmap memory */
  • glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7;

  • glyph->bitmap.rows = font->height;
    glyph->bitmap.cols = glyph->bitmap.width/8;
    glyph->bitmap.flow = TT_Flow_Down;
    glyph->bitmap.size = (glyph->bitmap.rows * glyph->bitmap.cols);
    @@ -254,8 +470,6 @@
    }

    /* Get the pixmap memory */

  • glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3;

  • glyph->pixmap.rows = font->height;
    glyph->pixmap.cols = glyph->pixmap.width;
    glyph->pixmap.flow = TT_Flow_Down;
    glyph->pixmap.size = (glyph->pixmap.rows * glyph->pixmap.cols);
    @@ -334,9 +548,16 @@
    /* We’re done, mark this glyph cached */
    glyph->cached = ch;
    return TT_Err_Ok;
    +#endif
    }

-static TT_Error Find_Glyph(TTF_Font *font, Uint16 ch)
+static
+#if FREETYPE2
+FT_Error
+#else
+TT_Error
+#endif
+Find_Glyph(TTF_Font *font, Uint16 ch)
{
int retval;

@@ -358,7 +579,11 @@
void TTF_CloseFont(TTF_Font *font)
{
Flush_Cache(font);
+#if FREETYPE2

  • FT_Done_Face(font->face);
    +#else
    TT_Close_Face(font->face);
    +#endif
    free(font);
    }

@@ -426,7 +651,11 @@
int TTF_GlyphMetrics(TTF_Font font, Uint16 ch,
int
minx, int* maxx, int* miny, int* maxy, int* advance)
{
+#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif

    error = Find_Glyph(font, ch);

@@ -503,7 +732,11 @@
int status;
const Uint16 *ch;
int x, z, minx, maxx;
+#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif

    /* Initialize everything to 0 */
    status = 0;
    @@ -605,7 +838,11 @@
    const Uint16 *ch;
    Uint8 *src, *dst;
    int row, col;
    +#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif

    /* Get the dimensions of the text surface */
    if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) {
    @@ -637,7 +874,11 @@
    error = Find_Glyph(font, *ch);
    if ( ! error ) {
    w = font->current->bitmap.width;
    +#if FREETYPE2

  •   	src = (Uint8 *)font->current->bitmap.buffer;
    

+#else
src = (Uint8 *)font->current->bitmap.bitmap;
+#endif
for ( row = 0; row < h; ++row ) {
dst = (Uint8 *)textbuf->pixels +
row * textbuf->pitch +
@@ -687,7 +928,11 @@
SDL_Palette *palette;
Uint8 *src, *dst;
int row, col;
+#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif
    struct glyph *glyph;

    /* Get the glyph itself */
    @@ -715,7 +960,11 @@
    SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0);

    /* Load and render each character */
    +#if FREETYPE2

  • src = (Uint8 *)font->current->bitmap.buffer;
    +#else
    src = (Uint8 *)font->current->bitmap.bitmap;
    +#endif
    for ( row = 0; row < textbuf->h; ++row ) {
    dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;
    for ( col = 0; col < textbuf->w; col += 8 ) {
    @@ -817,7 +1066,11 @@
    const Uint16 *ch;
    Uint8 *src, *dst;
    int row, col;
    +#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif

    /* Get the dimensions of the text surface */
    if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) {
    @@ -833,11 +1086,19 @@
    return(NULL);
    }

  • /* Fill the palette with 5 levels of shading from bg to fg */
    palette = textbuf->format->palette;
    rdiff = fg.r - bg.r;
    gdiff = fg.g - bg.g;
    bdiff = fg.b - bg.b;
    +#if FREETYPE2
  • /* Fill the palette with 128 levels of shading from bg to fg */
  • for ( index=0; index<128; ++index ) {
  •   palette->colors[index].r = bg.r + (index*rdiff)/127;
    
  •   palette->colors[index].g = bg.g + (index*gdiff)/127;
    
  •   palette->colors[index].b = bg.b + (index*bdiff)/127;
    
  • }
    +#else
  • /* Fill the palette with 5 levels of shading from bg to fg /
    for ( index=0; index<5; ++index ) {
    palette->colors[index].r = bg.r + (index
    rdiff)/4;
    palette->colors[index].g = bg.g + (index*gdiff)/4;
    @@ -847,14 +1108,18 @@
    for ( ; index<8; ++index ) {
    palette->colors[index] = palette->colors[4];
    }

+#endif
/* Load and render each character */
xstart = 0;
for ( ch=text; *ch; ++ch ) {
error = Find_Glyph(font, *ch);
if ( ! error ) {
w = font->current->pixmap.width;
+#if FREETYPE2

  •   	src = (Uint8 *)font->current->pixmap.buffer;
    

+#else
src = (Uint8 *)font->current->pixmap.bitmap;
+#endif
for ( row = 0; row < h; ++row ) {
dst = (Uint8 )textbuf->pixels +
row * textbuf->pitch +
@@ -875,13 +1140,19 @@
/
Handle the underline style */
if ( font->style & TTF_STYLE_UNDERLINE ) {
int row_offset;
+#if FREETYPE2

  •       int ival=127;
    

+#else

  •   int ival=4;
    

+#endif

	row_offset = round(font->ascent) + 1;
	if ( row_offset > font->height ) {
		row_offset = font->height-1;
	}
  •   memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch,
    
  •   						4, width);
    
  •   memset( (Uint8 *)textbuf->pixels+row_offset*textbuf->pitch,
    
  •   	ival,
    
  •   	width);
    

    }
    return(textbuf);
    }
    @@ -895,7 +1166,11 @@
    int rdiff, gdiff, bdiff;
    Uint8 *src, *dst;
    int row, col;
    +#if FREETYPE2

  • FT_Error error;
    +#else
    TT_Error error;
    +#endif
    struct glyph *glyph;

    /* Get the glyph itself */
    @@ -925,21 +1200,34 @@

    /* Copy the character from the pixmap */
    for ( row=0; rowh; ++row ) {
    +#if FREETYPE2

  •            int pitch = glyph->pixmap.pitch;
    
  •   src = (Uint8 *)glyph->pixmap.buffer + row * glyph->pixmap.pitch;
    

+#else

  •            int pitch = glyph->pixmap.cols;
      src = (Uint8 *)glyph->pixmap.bitmap + row * glyph->pixmap.cols;
    

+#endif
dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;

  •   memcpy(dst, src, glyph->pixmap.cols);
    
  •   memcpy(dst, src, pitch);
    

    }

    /* Handle the underline style */
    if ( font->style & TTF_STYLE_UNDERLINE ) {
    int row_offset;
    +#if FREETYPE2

  •       int ival=127;
    
  •   int pitch=glyph->pixmap.pitch;
    

+#else

  •   int ival=4;
    
  •   int pitch=glyph->pixmap.cols;
    

+#endif

	row_offset = round(font->ascent) + 1;
	if ( row_offset > font->height ) {
		row_offset = font->height-1;
	}
  •   memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch,
    
  •   					4, glyph->pixmap.cols);
    
  •   memset( (Uint8 *)textbuf->pixels+row_offset*textbuf->pitch,
    
  •   	ival, pitch);
    
    }
    return(textbuf);
    }
    @@ -1002,23 +1290,27 @@
    int xstart, width;
    int w, h;
    SDL_Surface *textbuf;
    -#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
  • Uint32 pixel;
  • const Uint16 *ch;
  • Uint8 *src;
  • Uint32 *dst;
  • int row, col;
    +#if FREETYPE2
  • FT_Error error;
    +#else
  • TT_Error error;
    +# if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >=
    SDL_VERSIONNUM(1, 1, 5) /* The great alpha flip */
    Uint32 alpha_table[] = {
    (0)<<24, (255-128)<<24, (255-64)<<24, (255-32)<<24,
    (255)<<24, (255)<<24, (255)<<24, (255)<<24
    };
    -#else
    +# else
    Uint32 alpha_table[] = {
    (255<<24), (128<<24), (64<<24), (32<<24), 0, 0, 0, 0
    };
    +# endif
    #endif
  • Uint32 pixel;

  • const Uint16 *ch;

  • Uint8 *src;

  • Uint32 *dst;

  • int row, col;

  • TT_Error error;

    /* Get the dimensions of the text surface */
    if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) {
    @@ -1042,16 +1334,27 @@
    error = Find_Glyph(font, *ch);
    if ( ! error ) {
    w = font->current->pixmap.width;
    +#if FREETYPE2

  •   	src = (Uint8 *)font->current->pixmap.buffer;
    

+#else
src = (Uint8 *)font->current->pixmap.bitmap;
+#endif
for ( row = 0; row < h; ++row ) {
dst = (Uint32 *)textbuf->pixels +
row * textbuf->pitch/4 +
xstart + font->current->minx;
for ( col=w; col>0; col -= 4 ) {
+#if FREETYPE2

  •   			*dst++ += *src++;
    
  •   			*dst++ += *src++;
    
  •   			*dst++ += *src++;
    
  •   			*dst++ += *src++;
    

+#else
*dst++ |= *src++;
*dst++ |= *src++;
*dst++ |= *src++;
*dst++ |= *src++;
+#endif
}
}
xstart += font->current->advance;
@@ -1071,12 +1374,33 @@
}
dst = (Uint32 )textbuf->pixels+row_offsettextbuf->pitch/4;
for ( col = width; col > 0; --col ) {
+#if FREETYPE2

  •   	*dst++ = 127;
    

+#else
*dst++ = 4;
+#endif
}
}

  • /* Build the alpha table */
    pixel = (fg.r<<16)|(fg.g<<8)|fg.b;

+#if FREETYPE2

  • /* Transform the alpha values */
  • for ( row = 0; row < textbuf->h; ++row ) {
  •   dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
    
  •   for ( col=textbuf->w; col>0; col -= 4 ) {
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   }
    
  • }
    +#else
  • /* Build the alpha table */
    for ( xstart = 0; xstart < 8; ++xstart ) {
    alpha_table[xstart] |= pixel;
    }
    @@ -1095,28 +1419,33 @@
    ++dst;
    }
    }
    +#endif
    return(textbuf);
    }

SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font, Uint16 ch, SDL_Color fg)
{
SDL_Surface *textbuf;
-#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >=
+#if FREETYPE2

  • FT_Error error;
    +#else
  • TT_Error error;
    +# if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >=
    SDL_VERSIONNUM(1, 1, 5) /* The great alpha flip */
    Uint32 alpha_table[] = {
    (0)<<24, (255-128)<<24, (255-64)<<24, (255-32)<<24,
    (255)<<24, (255)<<24, (255)<<24, (255)<<24
    };
    -#else
    +# else
    Uint32 alpha_table[] = {
    (255<<24), (128<<24), (64<<24), (32<<24), 0, 0, 0, 0
    };
    +# endif
    #endif
    Uint32 pixel;
    Uint8 *src;
    Uint32 *dst;
    int row, col;
  • TT_Error error;
    struct glyph *glyph;

    /* Get the glyph itself */
    @@ -1136,9 +1465,15 @@

    /* Copy the character from the pixmap */
    for ( row=0; rowh; ++row ) {

  •   src = (Uint8 *)glyph->pixmap.bitmap + row * glyph->pixmap.cols;
    

+#if FREETYPE2

  •            int pitch = glyph->pixmap.pitch;
    
  •   src = (Uint8 *)glyph->pixmap.buffer + row * pitch;
    

+#else

  •            int pitch = glyph->pixmap.cols;
    
  •   src = (Uint8 *)glyph->pixmap.bitmap + row * pitch;
    

+#endif
dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;

  •   for ( col=0; col<glyph->pixmap.cols; ++col ) {
    
  •   for ( col=0; col<pitch; ++col ) {
      	*dst++ = *src++;
      }
    
    }
    @@ -1152,11 +1487,27 @@
    row_offset = font->height-1;
    }
    dst = (Uint32 )textbuf->pixels+row_offsettextbuf->pitch/4;
  •   for ( col = glyph->pixmap.cols; col > 0; --col ) {
    
  •   for ( col = glyph->pixmap.FTPITCH; col > 0; --col ) {
      	*dst++ = 4;
      }
    
    }

+#if FREETYPE2

  • /* Transform the alpha values */
  • for ( row = 0; row < textbuf->h; ++row ) {
  •   dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
    
  •   for ( col=textbuf->w; col>0; col -= 4 ) {
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   	*dst = (*dst >= 127) ? pixel : pixel | ((255 ^ *dst) << 24);
    
  •   	++dst;
    
  •   }
    
  • }
    +#else
    /* Build the alpha table */
    pixel = (fg.r<<16)|(fg.g<<8)|fg.b;
    for ( col = 0; col < 8; ++col ) {
    @@ -1177,6 +1528,7 @@
    ++dst;
    }
    }
    +#endif
    return(textbuf);
    }

@@ -1193,5 +1545,9 @@

void TTF_Quit(void)
{
+#if FREETYPE2

  • FT_Done_FreeType(engine);
    +#else
    TT_Done_FreeType(engine);
    +#endif
    }
    Index: configure.in
    ===================================================================
    RCS file: /cvs/SDL_ttf/configure.in,v
    retrieving revision 1.1
    diff -u -r1.1 configure.in
    configure.in 2000/08/10 06:04:19 1.1
    +++ configure.in 2001/05/14 18:57:50
    @@ -13,9 +13,9 @@

MAJOR_VERSION=1
MINOR_VERSION=2
-MICRO_VERSION=1
-INTERFACE_AGE=1
-BINARY_AGE=1
+MICRO_VERSION=2
+INTERFACE_AGE=0
+BINARY_AGE=2
VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION

AC_SUBST(MAJOR_VERSION)
@@ -39,19 +39,28 @@
dnl Setup for automake
AM_INIT_AUTOMAKE(SDL_ttf, $VERSION)

+dnl Detect the canonical host and target build environment
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
dnl Check for tools

+AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
AC_PROG_MAKE_SET
AC_PROG_CC
-AM_PROG_LIBTOOL
AC_PROG_INSTALL

dnl The alpha architecture needs special flags for binary portability
-AC_CANONICAL_TARGET
case “$target” in
alpha*--linux)
CFLAGS="$CFLAGS -mcpu=ev4 -Wa,-mall"
;;

  • --cygwin* | --mingw32*)
  •    if test "$build" != "$target"; then # cross-compiling
    
  •        ac_default_prefix=/usr/local/cross-tools/i386-mingw32msvc
    
  •    fi
    
  •    ;;
    

esac

dnl Check for SDL
@@ -65,11 +74,11 @@

dnl Check for the FreeType library
have_freetype=no
-AC_CHECK_LIB(ttf, TT_Init_FreeType, have_freetype=yes)
+AC_CHECK_LIB(freetype, TT_Init_FreeType, have_freetype=yes)
if test x$have_freetype = xyes; then
AC_CHECK_HEADER(freetype/freetype.h,
[CFLAGS="$CFLAGS -DFREETYPE_HDR_DIRECTORY"])

  • LIBS="$LIBS -lttf"

Correct me if I’m wrong, but doesn’t
http://www.libsdl.org/cvs/SDL_ttf-2.0.2.tar.gz cover freetype2 support?
(After all, I am using it with freetype2)> ----- Original Message -----

From: owner-sdl@lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of kevin at ank.com
Sent: May 14, 2001 12:10 PM
To: sdl at mail.lokigames.com
Subject: [SDL] Patch for SDL_ttf to support Freetype2

Hi all,

I’ve done a mechanical port of Michael Chen’s port to Freetype2 to
the otop of the ttf tree. The code compiles and runs, but has errors
in the output font size (it looks like I missed some code duplication
around the font height somewhere) that I’m not familiar enough with
Freetype to fix.

So in case it is useful to someone else with more experience, here is
the patch.


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

Bleah.

I did go looking for an update before doing it myself (in fact I
found Michael Chen’s port from searching through the mailing list
archives.) There are a lot of emails in the SDL archive though.

Thanks for the pointer though.

Cheers,
-klsOn Mon, May 14, 2001 at 08:26:38PM -0700, Kisai wrote:

Correct me if I’m wrong, but doesn’t
http://www.libsdl.org/cvs/SDL_ttf-2.0.2.tar.gz cover freetype2 support?
(After all, I am using it with freetype2)

-----Original Message-----
From: owner-sdl at lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of @kevin_at_ank.com
Sent: May 14, 2001 12:10 PM
To: sdl at mail.lokigames.com
Subject: [SDL] Patch for SDL_ttf to support Freetype2

Hi all,

I’ve done a mechanical port of Michael Chen’s port to Freetype2 to
the otop of the ttf tree. The code compiles and runs, but has errors
in the output font size (it looks like I missed some code duplication
around the font height somewhere) that I’m not familiar enough with
Freetype to fix.

So in case it is useful to someone else with more experience, here is
the patch.


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


// .–=,
…::://::::::::::::::::::::::::::::… (o O & @kevin_at_ank.com
:::::::://:::://://://:/:://::||// / V K
:::::://:::://:/:|//’/’ // ,|’ r , ‘qk
:’’’/
__ // / // |_// // || .’~. .~`,
kls _/-=_/