Anonymous avatar Anonymous committed a5033fe

Freetype: Direct drawing on 24bpp surfaces.
Alpha-channel supported on FG colors when drawing directly.

Comments (0)

Files changed (1)

src/freetype/ft_wrap.c

     int pitch;
 
     SDL_PixelFormat *format;
-    void (*render)(int, int, struct __fontsurface *, FT_Bitmap *, PyColor *);
+    void (* render)(int, int, struct __fontsurface *, FT_Bitmap *, PyColor *);
 
 } FontSurface;
 
+
+typedef void (* FontRenderPtr)(int, int, FontSurface *, FT_Bitmap *, PyColor *);
+
+
 void    _PGFT_SetError(FreeTypeInstance *, const char *, FT_Error);
 FT_Face _PGFT_GetFace(FreeTypeInstance *, PyFreeTypeFont *);
 FT_Face _PGFT_GetFaceSized(FreeTypeInstance *, PyFreeTypeFont *, int);
 /* blitters */
 void __render_glyph_SDL8(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 void __render_glyph_SDL16(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_SDL24(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 void __render_glyph_SDL32(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 void __render_glyph_ByteArray(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 
 
 #ifdef HAVE_PYGAME_SDL_VIDEO
 
+void __render_glyph_SDL24(int x, int y, FontSurface *surface,
+    FT_Bitmap *bitmap, PyColor *color)
+{
+    const int rx = (x + surface->x_offset);
+    const int ry = (y + surface->y_offset);
+
+    const int max_x = MIN(rx + bitmap->width, surface->width);
+    const int max_y = MIN(ry + bitmap->rows, surface->height);
+
+    FT_Byte *dst = ((FT_Byte *)surface->buffer) + 
+        (rx * 3) + (ry * surface->pitch * 3);
+
+    FT_Byte *dst_cpy;
+
+    const FT_Byte *src = bitmap->buffer;
+    const FT_Byte *src_cpy;
+
+    FT_UInt32 bgR, bgG, bgB, bgA;
+    int j, i;
+
+    if (rx < 0 || ry < 0)
+        return;
+
+    for (j = ry; j < max_y; ++j)
+    {
+        src_cpy = src;
+        dst_cpy = dst;
+
+        for (i = rx; i < max_x; ++i, dst_cpy += 3)
+        {
+            FT_UInt32 alpha = (*src_cpy++); 
+            alpha = (alpha * color->a) / 255;
+
+            if (alpha > 0)
+            {
+                const FT_UInt32 pixel = (FT_UInt32)GET_PIXEL24(dst_cpy);
+
+                GET_RGB_VALS(
+                        pixel, surface->format,              
+                        bgR, bgG, bgB, bgA);
+
+                ALPHA_BLEND(
+                        color->r, color->g, color->b, alpha,
+                        bgR, bgG, bgB, bgA);
+
+                SET_PIXEL24_RGB(
+                        dst_cpy, surface->format,
+                        bgR, bgG, bgB);
+            }                                                   
+        }                                                       
+
+        dst += surface->pitch * 3;
+        src += bitmap->pitch;
+    }                                                           
+} 
+
 #define _CREATE_SDL_RENDER(bpp, T, _build_pixel)                    \
     void __render_glyph_SDL##bpp(int x, int y, FontSurface *surface,\
         FT_Bitmap *bitmap, PyColor *color)                          \
                                                                     \
             for (i = rx; i < max_x; ++i, ++dst_cpy)                 \
             {                                                       \
-                const FT_Byte alpha = *src_cpy++;                   \
+                FT_UInt32 alpha = (*src_cpy++);                     \
+                alpha = (alpha * color->a) / 255;                   \
+                                                                    \
                 if (alpha > 0)                                      \
                 {                                                   \
                     GET_RGB_VALS(                                   \
     int *_width, int *_height, int x, int y,
     PyColor *fgcolor)
 {
+    static const FontRenderPtr __renderFuncs[] =
+    {
+        NULL,
+        __render_glyph_SDL8,
+        __render_glyph_SDL16,
+        __render_glyph_SDL24,
+        __render_glyph_SDL32
+    };
+
     int width, glyph_height, height, locked = 0;
 
     SDL_Surface *surface = PySDLSurface_AsSDLSurface(_surface);
     font_surf.pitch = surface->pitch / surface->format->BytesPerPixel;
 
     font_surf.format = surface->format;
-
-    switch (surface->format->BytesPerPixel)
-    {
-    case 1:
-        font_surf.render = __render_glyph_SDL8;
-        break;
-
-    case 2:
-        font_surf.render = __render_glyph_SDL16;
-        break;
-
-    case 4:
-        font_surf.render = __render_glyph_SDL32;
-        break;
-    }
+    font_surf.render = __renderFuncs[surface->format->BytesPerPixel];
 
     if (_PGFT_Render_INTERNAL(ft, font, text, font_size, fgcolor, &font_surf) != 0)
     {
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.