1.1 --- a/CHANGES Fri Oct 16 13:39:46 2009 +0000
1.2 +++ b/CHANGES Sat Oct 17 18:16:33 2009 +0000
1.3 @@ -1,4 +1,8 @@
1.4 2.0.10:
1.5 +Loïc LAMBERT - Sat Oct 17 11:15:33 PDT 2009
1.6 + * Set the appropriate font styles for bold and italic fonts
1.7 + * Added font style TTF_STYLE_STRIKETHROUGH
1.8 + * Fixed size calculations taking outline and underline into account
1.9 Adam Strzelecki - Sun Oct 11 03:51:31 PDT 2009
1.10 * Added API for font outlining: TTF_GetFontOutline()/TTF_SetFontOutline()
1.11 Sam Lantinga - Sat Sep 26 01:13:29 PDT 2009
2.1 --- a/SDL_ttf.c Fri Oct 16 13:39:46 2009 +0000
2.2 +++ b/SDL_ttf.c Sat Oct 17 18:16:33 2009 +0000
2.3 @@ -128,6 +128,10 @@
2.4 #define TTF_HANDLE_STYLE_ITALIC(font) (((font)->style & TTF_STYLE_ITALIC) && \
2.5 !((font)->face_style & TTF_STYLE_ITALIC))
2.6 #define TTF_HANDLE_STYLE_UNDERLINE(font) ((font)->style & TTF_STYLE_UNDERLINE)
2.7 +#define TTF_HANDLE_STYLE_STRIKETHROUGH(font) ((font)->style & TTF_STYLE_STRIKETHROUGH)
2.8 +
2.9 +/* Font styles that does not impact glyph drawing */
2.10 +#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH)
2.11
2.12 /* The FreeType font engine/library */
2.13 static FT_Library library;
2.14 @@ -162,13 +166,138 @@
2.15 }
2.16 }
2.17
2.18 -static __inline__ int TTF_underline_row(TTF_Font *font, int height)
2.19 +/* Gets the top row of the underline. The outline
2.20 + is taken into account.
2.21 +*/
2.22 +static __inline__ int TTF_underline_top_row(TTF_Font *font)
2.23 {
2.24 - int result = font->ascent - font->underline_offset - 1;
2.25 - if ( result >= height) {
2.26 - result = (height-1) - font->underline_height;
2.27 + /* With outline, the underline_offset is underline_offset+outline. */
2.28 + /* So, we don't have to remove the top part of the outline height. */
2.29 + return font->ascent - font->underline_offset - 1;
2.30 +}
2.31 +
2.32 +/* Gets the bottom row of the underline. The outline
2.33 + is taken into account.
2.34 +*/
2.35 +static __inline__ int TTF_underline_bottom_row(TTF_Font *font)
2.36 +{
2.37 + int row = TTF_underline_top_row(font) + font->underline_height;
2.38 + if( font->outline > 0 ) {
2.39 + /* Add underline_offset outline offset and */
2.40 + /* the bottom part of the outline. */
2.41 + row += font->outline * 2;
2.42 }
2.43 - return result;
2.44 + return row;
2.45 +}
2.46 +
2.47 +/* Gets the top row of the strikethrough. The outline
2.48 + is taken into account.
2.49 +*/
2.50 +static __inline__ int TTF_strikethrough_top_row(TTF_Font *font)
2.51 +{
2.52 + /* With outline, the first text row is 'outline'. */
2.53 + /* So, we don't have to remove the top part of the outline height. */
2.54 + return font->height / 2;
2.55 +}
2.56 +
2.57 +/* Gets the bottom row of the strikethrough. The outline
2.58 + is taken into account.
2.59 +*/
2.60 +static __inline__ int TTF_strikethrough_bottom_row(TTF_Font *font)
2.61 +{
2.62 + int row = TTF_strikethrough_top_row(font) + font->underline_height;
2.63 + if( font->outline > 0 ) {
2.64 + /* Add first text row outline offset and */
2.65 + /* the bottom part of the outline. */
2.66 + row += font->outline * 2;
2.67 + }
2.68 + return row;
2.69 +}
2.70 +
2.71 +static void TTF_initLineMectrics(const TTF_Font *font, const SDL_Surface *textbuf, const int row, Uint8 **pdst, int *pheight)
2.72 +{
2.73 + Uint8 *dst;
2.74 + int height;
2.75 +
2.76 + dst = (Uint8 *)textbuf->pixels;
2.77 + if( row > 0 ) {
2.78 + dst += row * textbuf->pitch;
2.79 + }
2.80 +
2.81 + height = font->underline_height;
2.82 + /* Take outline into account */
2.83 + if( font->outline > 0 ) {
2.84 + height += font->outline * 2;
2.85 + }
2.86 + *pdst = dst;
2.87 + *pheight = height;
2.88 +}
2.89 +
2.90 +/* Draw a solid line of underline_height (+ optional outline)
2.91 + at the given row. The row value must take the
2.92 + outline into account.
2.93 +*/
2.94 +static void TTF_drawLine_Solid(const TTF_Font *font, const SDL_Surface *textbuf, const int row)
2.95 +{
2.96 + int line;
2.97 + Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
2.98 + Uint8 *dst;
2.99 + int height;
2.100 +
2.101 + TTF_initLineMectrics(font, textbuf, row, &dst, &height);
2.102 +
2.103 + /* Draw line */
2.104 + for ( line=height; line>0 && dst < dst_check; --line ) {
2.105 + /* 1 because 0 is the bg color */
2.106 + memset( dst, 1, textbuf->w );
2.107 + dst += textbuf->pitch;
2.108 + }
2.109 +}
2.110 +
2.111 +/* Draw a shaded line of underline_height (+ optional outline)
2.112 + at the given row. The row value must take the
2.113 + outline into account.
2.114 +*/
2.115 +static void TTF_drawLine_Shaded(const TTF_Font *font, const SDL_Surface *textbuf, const int row)
2.116 +{
2.117 + int line;
2.118 + Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
2.119 + Uint8 *dst;
2.120 + int height;
2.121 +
2.122 + TTF_initLineMectrics(font, textbuf, row, &dst, &height);
2.123 +
2.124 + /* Draw line */
2.125 + for ( line=height; line>0 && dst < dst_check; --line ) {
2.126 + memset( dst, NUM_GRAYS - 1, textbuf->w );
2.127 + dst += textbuf->pitch;
2.128 + }
2.129 +}
2.130 +
2.131 +/* Draw a blended line of underline_height (+ optional outline)
2.132 + at the given row. The row value must take the
2.133 + outline into account.
2.134 +*/
2.135 +static void TTF_drawLine_Blended(const TTF_Font *font, const SDL_Surface *textbuf, const int row, const Uint32 color)
2.136 +{
2.137 + int line;
2.138 + Uint32 *dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h;
2.139 + Uint8 *dst8; /* destination, byte version */
2.140 + Uint32 *dst;
2.141 + int height;
2.142 + int col;
2.143 + Uint32 pixel = color | 0xFF000000; /* Amask */
2.144 +
2.145 + TTF_initLineMectrics(font, textbuf, row, &dst8, &height);
2.146 + dst = (Uint32 *) dst8;
2.147 +
2.148 + /* Draw line */
2.149 + for ( line=height; line>0 && dst < dst_check; --line ) {
2.150 + for ( col=0; col < textbuf->w; ++col ) {
2.151 + dst[col] = pixel;
2.152 + }
2.153 + dst += textbuf->pitch/4;
2.154 + }
2.155 }
2.156
2.157 /* rcg06192001 get linked library's version. */
2.158 @@ -368,6 +497,8 @@
2.159 font->height, font->lineskip);
2.160 printf("\tunderline_offset = %d, underline_height = %d\n",
2.161 font->underline_offset, font->underline_height);
2.162 + printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n",
2.163 + TTF_underline_top_row(font), TTF_strikethrough_top_row(font));
2.164 #endif
2.165
2.166 /* Initialize the font face style */
2.167 @@ -995,6 +1126,12 @@
2.168 /* check kerning */
2.169 use_kerning = FT_HAS_KERNING( font->face ) && font->kerning;
2.170
2.171 + /* Init outline handling */
2.172 + int outline_delta = 0;
2.173 + if ( font->outline > 0 ) {
2.174 + outline_delta = font->outline * 2;
2.175 + }
2.176 +
2.177 /* Load each character and sum it's bounding box */
2.178 x= 0;
2.179 for ( ch=text; *ch; ++ch ) {
2.180 @@ -1078,19 +1215,21 @@
2.181
2.182 /* Fill the bounds rectangle */
2.183 if ( w ) {
2.184 - *w = (maxx - minx);
2.185 + /* Add outline extra width */
2.186 + *w = (maxx - minx) + outline_delta;
2.187 }
2.188 if ( h ) {
2.189 /* Some fonts descend below font height (FletcherGothicFLF) */
2.190 - *h = (font->ascent - miny);
2.191 - if (*h < font->height) {
2.192 + /* Add outline extra height */
2.193 + *h = (font->ascent - miny) + outline_delta;
2.194 + if ( *h < font->height ) {
2.195 *h = font->height;
2.196 }
2.197 /* Update height according to the needs of the underline style */
2.198 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.199 - int rowMax = TTF_underline_row(font, *h) + font->underline_height;
2.200 - if ( rowMax > *h ) {
2.201 - *h = rowMax;
2.202 + int bottom_row = TTF_underline_bottom_row(font);
2.203 + if ( *h < bottom_row ) {
2.204 + *h = bottom_row;
2.205 }
2.206 }
2.207 }
2.208 @@ -1179,7 +1318,7 @@
2.209 }
2.210
2.211 /* Create the target surface */
2.212 - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width + font->outline * 2, height + font->outline * 2, 8, 0, 0, 0, 0);
2.213 + textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0);
2.214 if( textbuf == NULL ) {
2.215 return NULL;
2.216 }
2.217 @@ -1276,13 +1415,14 @@
2.218
2.219 /* Handle the underline style */
2.220 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.221 - row = TTF_underline_row(font, textbuf->h);
2.222 - dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;
2.223 - for ( row=font->underline_height; row>0 && dst < dst_check; --row ) {
2.224 - /* 1 because 0 is the bg color */
2.225 - memset( dst, 1, textbuf->w );
2.226 - dst += textbuf->pitch;
2.227 - }
2.228 + row = TTF_underline_top_row(font);
2.229 + TTF_drawLine_Solid(font, textbuf, row);
2.230 + }
2.231 +
2.232 + /* Handle the strikethrough style */
2.233 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.234 + row = TTF_strikethrough_top_row(font);
2.235 + TTF_drawLine_Solid(font, textbuf, row);
2.236 }
2.237 return textbuf;
2.238 }
2.239 @@ -1333,13 +1473,14 @@
2.240
2.241 /* Handle the underline style */
2.242 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.243 - row = TTF_underline_row(font, textbuf->h);
2.244 - dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;
2.245 - for ( row=font->underline_height; row>0; --row ) {
2.246 - /* 1 because 0 is the bg color */
2.247 - memset( dst, 1, textbuf->w );
2.248 - dst += textbuf->pitch;
2.249 - }
2.250 + row = TTF_underline_top_row(font);
2.251 + TTF_drawLine_Solid(font, textbuf, row);
2.252 + }
2.253 +
2.254 + /* Handle the strikethrough style */
2.255 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.256 + row = TTF_strikethrough_top_row(font);
2.257 + TTF_drawLine_Solid(font, textbuf, row);
2.258 }
2.259 return(textbuf);
2.260 }
2.261 @@ -1432,7 +1573,7 @@
2.262 }
2.263
2.264 /* Create the target surface */
2.265 - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width + font->outline * 2, height + font->outline * 2, 8, 0, 0, 0, 0);
2.266 + textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0);
2.267 if( textbuf == NULL ) {
2.268 return NULL;
2.269 }
2.270 @@ -1530,12 +1671,14 @@
2.271
2.272 /* Handle the underline style */
2.273 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.274 - row = TTF_underline_row(font, textbuf->h);
2.275 - dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;
2.276 - for ( row=font->underline_height; row>0 && dst < dst_check; --row ) {
2.277 - memset( dst, NUM_GRAYS - 1, textbuf->w );
2.278 - dst += textbuf->pitch;
2.279 - }
2.280 + row = TTF_underline_top_row(font);
2.281 + TTF_drawLine_Shaded(font, textbuf, row);
2.282 + }
2.283 +
2.284 + /* Handle the strikethrough style */
2.285 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.286 + row = TTF_strikethrough_top_row(font);
2.287 + TTF_drawLine_Shaded(font, textbuf, row);
2.288 }
2.289 return textbuf;
2.290 }
2.291 @@ -1595,12 +1738,14 @@
2.292
2.293 /* Handle the underline style */
2.294 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.295 - row = TTF_underline_row(font, textbuf->h);
2.296 - dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch;
2.297 - for ( row=font->underline_height; row>0; --row ) {
2.298 - memset( dst, NUM_GRAYS - 1, textbuf->w );
2.299 - dst += textbuf->pitch;
2.300 - }
2.301 + row = TTF_underline_top_row(font);
2.302 + TTF_drawLine_Shaded(font, textbuf, row);
2.303 + }
2.304 +
2.305 + /* Handle the strikethrough style */
2.306 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.307 + row = TTF_strikethrough_top_row(font);
2.308 + TTF_drawLine_Shaded(font, textbuf, row);
2.309 }
2.310 return textbuf;
2.311 }
2.312 @@ -1685,7 +1830,7 @@
2.313 }
2.314
2.315 /* Create the target surface */
2.316 - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width + font->outline * 2, height + font->outline * 2, 32,
2.317 + textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 32,
2.318 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
2.319 if ( textbuf == NULL ) {
2.320 return(NULL);
2.321 @@ -1779,15 +1924,14 @@
2.322
2.323 /* Handle the underline style */
2.324 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.325 - row = TTF_underline_row(font, textbuf->h);
2.326 - dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
2.327 - pixel |= 0xFF000000; /* Amask */
2.328 - for ( row=font->underline_height; row>0 && dst < dst_check; --row ) {
2.329 - for ( col=0; col < textbuf->w; ++col ) {
2.330 - dst[col] = pixel;
2.331 - }
2.332 - dst += textbuf->pitch/4;
2.333 - }
2.334 + row = TTF_underline_top_row(font);
2.335 + TTF_drawLine_Blended(font, textbuf, row, pixel);
2.336 + }
2.337 +
2.338 + /* Handle the strikethrough style */
2.339 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.340 + row = TTF_strikethrough_top_row(font);
2.341 + TTF_drawLine_Blended(font, textbuf, row, pixel);
2.342 }
2.343 return(textbuf);
2.344 }
2.345 @@ -1833,15 +1977,14 @@
2.346
2.347 /* Handle the underline style */
2.348 if( TTF_HANDLE_STYLE_UNDERLINE(font) ) {
2.349 - row = TTF_underline_row(font, textbuf->h);
2.350 - dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
2.351 - pixel |= 0xFF000000; /* Amask */
2.352 - for ( row=font->underline_height; row>0; --row ) {
2.353 - for ( col=0; col < textbuf->w; ++col ) {
2.354 - dst[col] = pixel;
2.355 - }
2.356 - dst += textbuf->pitch/4;
2.357 - }
2.358 + row = TTF_underline_top_row(font);
2.359 + TTF_drawLine_Blended(font, textbuf, row, pixel);
2.360 + }
2.361 +
2.362 + /* Handle the strikethrough style */
2.363 + if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) {
2.364 + row = TTF_strikethrough_top_row(font);
2.365 + TTF_drawLine_Blended(font, textbuf, row, pixel);
2.366 }
2.367 return(textbuf);
2.368 }
2.369 @@ -1854,7 +1997,7 @@
2.370 /* Flush the cache if the style has changed.
2.371 * Ignore UNDERLINE which does not impact glyph drawning.
2.372 * */
2.373 - if ( (font->style | TTF_STYLE_UNDERLINE ) != ( prev_style | TTF_STYLE_UNDERLINE )) {
2.374 + if ( (font->style | TTF_STYLE_NO_GLYPH_CHANGE ) != ( prev_style | TTF_STYLE_NO_GLYPH_CHANGE )) {
2.375 Flush_Cache( font );
2.376 }
2.377 }
3.1 --- a/SDL_ttf.h Fri Oct 16 13:39:46 2009 +0000
3.2 +++ b/SDL_ttf.h Sat Oct 17 18:16:33 2009 +0000
3.3 @@ -91,14 +91,12 @@
3.4 extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize);
3.5 extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index);
3.6
3.7 -/* Set and retrieve the font style
3.8 - This font style is implemented by modifying the font glyphs, and
3.9 - doesn't reflect any inherent properties of the truetype font file.
3.10 -*/
3.11 +/* Set and retrieve the font style */
3.12 #define TTF_STYLE_NORMAL 0x00
3.13 #define TTF_STYLE_BOLD 0x01
3.14 #define TTF_STYLE_ITALIC 0x02
3.15 #define TTF_STYLE_UNDERLINE 0x04
3.16 +#define TTF_STYLE_STRIKETHROUGH 0x08
3.17 extern DECLSPEC int SDLCALL TTF_GetFontStyle(const TTF_Font *font);
3.18 extern DECLSPEC void SDLCALL TTF_SetFontStyle(TTF_Font *font, int style);
3.19 extern DECLSPEC int SDLCALL TTF_GetFontOutline(const TTF_Font *font);