Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2003:
[Freeciv-Dev] (PR#3561) New Blended_Shaded patch to SDL_ttf2 lib
Home

[Freeciv-Dev] (PR#3561) New Blended_Shaded patch to SDL_ttf2 lib

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#3561) New Blended_Shaded patch to SDL_ttf2 lib
From: "Rafa³ Bursig" <bursig@xxxxxxxxx>
Date: Fri, 28 Feb 2003 06:15:00 -0800
Reply-to: rt@xxxxxxxxxxxxxx

Hi

This is new version of Blended_Shaded patch targeted to cvs version of 
SDL_ttf2 lib

Rafal

----------------------------------------------------------------------
KLIKAJ!!! Nie pytaj dlaczego... >>> http://link.interia.pl/f16e2

diff -u -r SDL_ttf.c SDL_ttf.c
--- SDL_ttf.c   Fri Feb 21 18:38:15 2003
+++ SDL_ttf.c   Mon Feb 24 15:03:43 2003
@@ -1602,6 +1602,276 @@
        return(textbuf);
 }
 
+/* Convert the Latin-1 text to UNICODE and render it
+*/
+SDL_Surface *TTF_RenderText_Blended_Shaded(TTF_Font *font,
+                       const char *text, SDL_Color fg, SDL_Color bg)
+{
+       SDL_Surface *textbuf;
+       Uint16 *unicode_text;
+       int unicode_len;
+
+       /* Copy the Latin-1 text to a UNICODE text buffer */
+       unicode_len = strlen(text);
+       unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof 
*unicode_text));
+       if ( unicode_text == NULL ) {
+               TTF_SetError("Out of memory");
+               return(NULL);
+       }
+       *unicode_text = UNICODE_BOM_NATIVE;
+       LATIN1_to_UNICODE(unicode_text+1, text, unicode_len);
+
+       /* Render the new text */
+       textbuf = TTF_RenderUNICODE_Blended_Shaded(font, unicode_text, fg, bg);
+
+       /* Free the text buffer and return */
+       FREEA(unicode_text);
+       return(textbuf);
+}
+
+/* Convert the UTF-8 text to UNICODE and render it
+*/
+SDL_Surface *TTF_RenderUTF8_Blended_Shaded(TTF_Font *font,
+               const char *text, SDL_Color fg, SDL_Color bg)
+{
+       SDL_Surface *textbuf;
+       Uint16 *unicode_text;
+       int unicode_len;
+
+       /* Copy the UTF-8 text to a UNICODE text buffer */
+       unicode_len = strlen(text);
+       unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof 
*unicode_text));
+       if ( unicode_text == NULL ) {
+               TTF_SetError("Out of memory");
+               return(NULL);
+       }
+       *unicode_text = UNICODE_BOM_NATIVE;
+       UTF8_to_UNICODE(unicode_text+1, text, unicode_len);
+
+       /* Render the new text */
+       textbuf = TTF_RenderUNICODE_Blended_Shaded(font, unicode_text, fg, bg);
+
+       /* Free the text buffer and return */
+       FREEA(unicode_text);
+       return(textbuf);
+}
+
+SDL_Surface *TTF_RenderUNICODE_Blended_Shaded(TTF_Font *font,
+                       const Uint16 *text, SDL_Color fg, SDL_Color bg)
+{
+       int xstart;
+       int width, height;
+       SDL_Surface *textbuf;
+       Uint32 alpha;
+       Uint32 dst_pixel;
+       Uint32 pixel;
+       Uint32 buf1, buf2;
+       const Uint16 *ch;
+       Uint8 *src;
+       Uint32 *dst;
+       int row, col;
+       int swapped;
+       c_glyph *glyph;
+       FT_Error error;
+
+       if(!bg.unused) { /* background ALPHA = 0 */
+         return TTF_RenderUNICODE_Blended(font, text, fg);
+       }
+
+       /* Get the dimensions of the text surface */
+       if ( (TTF_SizeUNICODE(font, text, &width, NULL) < 0) || !width ) {
+               TTF_SetError("Text has zero width");
+               return(NULL);
+       }
+       height = font->height;
+
+       textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 32,
+                  0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+       if ( textbuf == NULL ) {
+               return(NULL);
+       }
+
+       /* Load and render each character */
+       xstart = 0;
+       swapped = TTF_byteswapped;
+       pixel = (fg.r<<16)|(fg.g<<8)|fg.b|0xFF000000;
+       dst_pixel = (bg.unused<<24)|(bg.r<<16)|(bg.g<<8)|bg.b;
+
+       buf1 = (pixel & 0x00FF00FF) - (dst_pixel & 0x00FF00FF);
+       buf2 = ((pixel & 0xFF00FF00) >> 8) - ((dst_pixel & 0xFF00FF00) >> 8);
+       
+       SDL_FillRect(textbuf, NULL , dst_pixel);
+       
+       for ( ch=text; *ch; ++ch ) {
+               Uint16 c = *ch;
+               if ( c == UNICODE_BOM_NATIVE ) {
+                       swapped = 0;
+                       if ( text == ch ) {
+                               ++text;
+                       }
+                       continue;
+               }
+               if ( c == UNICODE_BOM_SWAPPED ) {
+                       swapped = 1;
+                       if ( text == ch ) {
+                               ++text;
+                       }
+                       continue;
+               }
+               if ( swapped ) {
+                       c = SDL_Swap16(c);
+               }
+       
+               error = Find_Glyph(font, *ch, CACHED_METRICS|CACHED_PIXMAP);
+               if( error ) {
+                       SDL_FreeSurface( textbuf );
+                       return NULL;
+               }
+               glyph = font->current;
+               width = glyph->pixmap.width;
+               
+               /* Compensate for the wrap around bug with negative minx's */
+               if ( (ch == text) && (glyph->minx < 0) ) {
+                       xstart -= glyph->minx;
+               }
+
+               for ( row = 0; row < glyph->pixmap.rows; ++row ) {
+                       /* Make sure we don't go over the limit */
+                       if ( row+glyph->yoffset >= textbuf->h ) {
+                               continue;
+                       }
+                       dst = (Uint32*) textbuf->pixels +
+                               (row+glyph->yoffset) * textbuf->pitch/4 +
+                               xstart + glyph->minx;
+                       /* Added code to adjust src pointer for pixmaps to
+                        * account for pitch.
+                        * */
+                       src = (Uint8*) (glyph->pixmap.buffer + 
glyph->pixmap.pitch * row);
+               
+                       for ( col=width; col>0; --col ) {
+                               alpha = *src++;
+                               if(alpha)
+                               {
+                                 if(alpha == SDL_ALPHA_OPAQUE)
+                                 {
+                                   *dst = pixel;
+                                 } else {
+                                   *dst = (((dst_pixel & 0x00FF00FF) +
+                                       (buf1 * alpha >> 8)) & 0x00FF00FF) |
+                                       (((((dst_pixel & 0xFF00FF00) >> 8) +
+                                       (buf2 * alpha >> 8)) & 0x00FF00FF) << 
8);
+                                 } 
+                               }
+                               dst++;
+                       }
+               }
+
+               xstart += glyph->advance;
+               if ( font->style & TTF_STYLE_BOLD ) {
+                       xstart += font->glyph_overhang;
+               }
+       }
+
+       /* Handle the underline style */
+       if( font->style & TTF_STYLE_UNDERLINE ) {
+               row = font->ascent - font->underline_offset - 1;
+               if ( row >= textbuf->h) {
+                       row = (textbuf->h-1) - font->underline_height;
+               }
+               dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
+               pixel |= 0xFF000000; /* Amask */
+               for ( row=font->underline_height; row>0; --row ) {
+                       for ( col=0; col < textbuf->w; ++col ) {
+                               dst[col] = pixel;
+                       }
+                       dst += textbuf->pitch/4;
+               }
+       }
+       return(textbuf);
+}
+
+SDL_Surface *TTF_RenderGlyph_Blended_Shaded(TTF_Font *font,
+                            Uint16 ch, SDL_Color fg, SDL_Color bg)
+{
+       SDL_Surface *textbuf;
+       Uint32 alpha;
+       Uint32 dst_pixel;
+       Uint32 pixel;
+       Uint32 buf1, buf2;
+       Uint8 *src;
+       Uint32 *dst;
+       int row, col;
+       FT_Error error;
+       c_glyph *glyph;
+
+       if(!bg.unused) {
+         return TTF_RenderGlyph_Blended(font, ch, fg);
+       }
+       
+       /* Get the glyph itself */
+       error = Find_Glyph(font, ch, CACHED_METRICS|CACHED_PIXMAP);
+       if ( error ) {
+               return(NULL);
+       }
+       glyph = font->current;
+
+       textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                     glyph->pixmap.width, glyph->pixmap.rows, 32,
+                  0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+       if ( ! textbuf ) {
+               return(NULL);
+       }
+
+       /* Copy the character from the pixmap */
+       pixel = (fg.r<<16)|(fg.g<<8)|fg.b|0xFF000000;
+       dst_pixel = (bg.unused<<24)|(bg.r<<16)|(bg.g<<8)|bg.b;
+       
+       buf1 = (pixel & 0x00FF00FF) - (dst_pixel & 0x00FF00FF);
+       buf2 = ((pixel & 0xFF00FF00) >> 8) - ((dst_pixel & 0xFF00FF00) >> 8);
+       
+       SDL_FillRect(textbuf, NULL , dst_pixel);        
+       
+       for ( row=0; row<textbuf->h; ++row ) {
+               /* Changed src to take pitch into account, not just width */
+               src = glyph->pixmap.buffer + row * glyph->pixmap.pitch;
+               dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
+               for ( col=0; col<glyph->pixmap.width; ++col ) {
+                       alpha = *src++;
+                       if(alpha)
+                       {
+                         if(alpha == SDL_ALPHA_OPAQUE)
+                         {
+                           *dst = pixel;
+                         } else {
+                           *dst = (((dst_pixel & 0x00FF00FF) +
+                                   (buf1 * alpha >> 8)) & 0x00FF00FF) |
+                                   (((((dst_pixel & 0xFF00FF00) >> 8)
+                                    + (buf2 * alpha >> 8)) & 0x00FF00FF) << 8);
+                         }    
+                       }
+                       dst++;
+               }
+       }
+
+       /* Handle the underline style */
+       if( font->style & TTF_STYLE_UNDERLINE ) {
+               row = font->ascent - font->underline_offset - 1;
+               if ( row >= textbuf->h) {
+                       row = (textbuf->h-1) - font->underline_height;
+               }
+               dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4;
+               pixel |= 0xFF000000; /* Amask */
+               for ( row=font->underline_height; row>0; --row ) {
+                       for ( col=0; col < textbuf->w; ++col ) {
+                               dst[col] = pixel;
+                       }
+                       dst += textbuf->pitch/4;
+               }
+       }
+       return(textbuf);
+}
+
+
 void TTF_SetFontStyle( TTF_Font* font, int style )
 {
        font->style = style;
diff -u -r SDL_ttf.h SDL_ttf.h
--- SDL_ttf.h   Mon Feb 10 15:29:09 2003
+++ SDL_ttf.h   Mon Feb 24 14:59:50 2003
@@ -195,6 +195,29 @@
 extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font,
                                                Uint16 ch, SDL_Color fg);
 
+
+/* Create a 32-bit ARGB surface, fill it with the given background, and
+   render the given text at high quality.  Alpha blending is used to dither
+   the font with the given color on top of the background color (which
+   may itself be partially transparent).  This function returns the new
+   surface, or NULL if there was an error. */
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Shaded(
+           TTF_Font *font, const char *text, SDL_Color fg, SDL_Color bg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended_Shaded(
+           TTF_Font *font, const char *text, SDL_Color fg,  SDL_Color bg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended_Shaded(
+           TTF_Font *font, const Uint16 *text, SDL_Color fg, SDL_Color bg);
+
+/* Create a 32-bit ARGB surface, fill it with the given background, and
+   render the given glyph at high quality.  Alpha blending is used to dither
+   the font with the given color on top of the background color (which
+   may itself be partially transparent).  The glyph is rendered without any
+   padding or centering in the X direction, and aligned normally in the Y
+   direction.  This function returns the new surface, or NULL if there was
+   an error. */
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended_Shaded(
+           TTF_Font *font, Uint16 ch, SDL_Color fg, SDL_Color bg);
+
 /* For compatibility with previous versions, here are the old functions */
 #define TTF_RenderText(font, text, fg, bg)     \
        TTF_RenderText_Shaded(font, text, fg, bg)

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#3561) New Blended_Shaded patch to SDL_ttf2 lib, Rafa³ Bursig <=