Anonymous avatar Anonymous committed 95c69bb

Respect background alpha when drawing on existing surfaces.

Comments (0)

Files changed (6)

 * >8 bpp surfaces with palettes - it is supported (although it might be
   pointless) by SDL and so should we.
 
-* freetype: bgcolor with alpha transparency needs to be respected on rendering
 * freetype: render to buffer buffer support (like new bytearray, but
   write to a buffer instead)
-* freetype: support different rendering modes (antialiased, aliased, ...)?
-* freetype: add style support (bold, italic, underlined)
+* freetype: add style support (underlined)
 * freetype: correct error messages (e.g. on trying to scale pcf fonts)
 * freetype: brush up docs and examples
 * freetype: description/markup language for rendering text (like e.g. pango

examples/freetype/sdlfont.py

     fontdir = os.path.dirname (os.path.abspath (__file__))
     font = freetype.Font (os.path.join (fontdir, "sans.ttf"))
 
-    screen = video.set_mode (640, 480)
+    screen = video.set_mode (800, 600)
     screen.fill (colors["grey_light"])
 
     font.render("Hello World", colors["red"], None, screen, 32, 32, ptsize=64, style=ftconstants.STYLE_BOLD)
             "src/freetype/ft_font.c",
             "src/freetype/ft_wrap.c",
             "src/freetype/ft_render.c",
+            "src/freetype/ft_render_cb.c",
             "src/freetype/ft_metrics.c",
             "src/freetype/ft_text.c",
         ],

src/freetype/ft_render.c

 #endif
 
 typedef void (* FontRenderPtr)(int, int, FontSurface *, FT_Bitmap *, PyColor *);
-
-/* blitters */
-void __render_glyph_MONO1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_MONO2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_MONO3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_MONO4(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-
-void __render_glyph_RGB1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_RGB2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_RGB3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
-void __render_glyph_RGB4(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);
-
+typedef void (* FontFillPtr)(int, int, int, int, FontSurface *, PyColor *);
 
 #define SLANT_FACTOR    0.22
 FT_Matrix PGFT_SlantMatrix = 
 
 FT_Fixed PGFT_GetBoldStrength(FT_Face face)
 {
-    const float bold_factor = 0.06;
+    const float bold_factor = 0.06f;
     FT_Fixed bold_str;
 
     bold_str = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale);
  *
  *********************************************************/
 #ifdef HAVE_PYGAME_SDL_VIDEO
-
-#define __MONO_RENDER_INNER_LOOP(_bpp, _code)                       \
-    for (j = ry; j < max_y; ++j)                                    \
-    {                                                               \
-        unsigned char*  _src = src;                                 \
-        unsigned char*  _dst = dst;                                 \
-        FT_UInt32       val = (FT_UInt32)(*_src++ | 0x100) << shift;\
-                                                                    \
-        for (i = rx; i < max_x; ++i, _dst += _bpp)                  \
-        {                                                           \
-            if (val & 0x10000)                                      \
-                val = (FT_UInt32)(*_src++ | 0x100);                 \
-                                                                    \
-            if (val & 0x80)                                         \
-            {                                                       \
-                _code;                                              \
-            }                                                       \
-                                                                    \
-            val   <<= 1;                                            \
-        }                                                           \
-                                                                    \
-        src += bitmap->pitch;                                       \
-        dst += surface->pitch * _bpp;                               \
-    }                                                               \
-
-#define _CREATE_MONO_RENDER(_bpp, _getp, _setp, _blendp)                \
-    void __render_glyph_MONO##_bpp(int x, int y, FontSurface *surface,  \
-            FT_Bitmap *bitmap, PyColor *color)                          \
-    {                                                                   \
-        const int off_x = (x < 0) ? -x : 0;                             \
-        const int off_y = (y < 0) ? -y : 0;                             \
-                                                                        \
-        const int max_x = MIN(x + bitmap->width, surface->width);       \
-        const int max_y = MIN(y + bitmap->rows, surface->height);       \
-                                                                        \
-        const int rx = MAX(0, x);                                       \
-        const int ry = MAX(0, y);                                       \
-                                                                        \
-        int             i, j, shift;                                    \
-        unsigned char*  src;                                            \
-        unsigned char*  dst;                                            \
-        FT_UInt32       full_color;                                     \
-        FT_UInt32 bgR, bgG, bgB, bgA;                                   \
-                                                                        \
-        src  = bitmap->buffer + (off_y * bitmap->pitch) + (off_x >> 3); \
-        dst = (unsigned char *)surface->buffer + (rx * _bpp) +          \
-                    (ry * _bpp * surface->pitch);                       \
-                                                                        \
-        full_color = SDL_MapRGBA(surface->format, (FT_Byte)color->r,    \
-                (FT_Byte)color->g, (FT_Byte)color->b, 255);             \
-                                                                        \
-        shift = off_x & 7;                                              \
-                                                                        \
-        if (color->a == 0xFF)                                           \
-        {                                                               \
-            __MONO_RENDER_INNER_LOOP(_bpp,                              \
-            {                                                           \
-                _setp;                                                  \
-            });                                                         \
-        }                                                               \
-        else if (color->a > 0)                                          \
-        {                                                               \
-            __MONO_RENDER_INNER_LOOP(_bpp,                              \
-            {                                                           \
-                FT_UInt32 pixel = (FT_UInt32)_getp;                     \
-                                                                        \
-                GET_RGB_VALS(                                           \
-                        pixel, surface->format,                         \
-                        bgR, bgG, bgB, bgA);                            \
-                                                                        \
-                ALPHA_BLEND(                                            \
-                        color->r, color->g, color->b, color->a,         \
-                        bgR, bgG, bgB, bgA);                            \
-                                                                        \
-                _blendp;                                                \
-            });                                                         \
-        }                                                               \
-    }
-
-#define _CREATE_RGB_RENDER(_bpp, _getp, _setp, _blendp)                 \
-    void __render_glyph_RGB##_bpp(int x, int y, FontSurface *surface,   \
-        FT_Bitmap *bitmap, PyColor *color)                              \
-    {                                                                   \
-        const int off_x = (x < 0) ? -x : 0;                             \
-        const int off_y = (y < 0) ? -y : 0;                             \
-                                                                        \
-        const int max_x = MIN(x + bitmap->width, surface->width);       \
-        const int max_y = MIN(y + bitmap->rows, surface->height);       \
-                                                                        \
-        const int rx = MAX(0, x);                                       \
-        const int ry = MAX(0, y);                                       \
-                                                                        \
-        FT_Byte *dst = ((FT_Byte*)surface->buffer) + (rx * _bpp) +      \
-                        (ry * _bpp * surface->pitch);                   \
-        FT_Byte *_dst;                                                  \
-                                                                        \
-        const FT_Byte *src = bitmap->buffer + off_x +                   \
-                                (off_y * bitmap->pitch);                \
-        const FT_Byte *_src;                                            \
-                                                                        \
-        const FT_UInt32 full_color =                                    \
-            SDL_MapRGBA(surface->format, (FT_Byte)color->r,             \
-                    (FT_Byte)color->g, (FT_Byte)color->b, 255);         \
-                                                                        \
-        FT_UInt32 bgR, bgG, bgB, bgA;                                   \
-        int j, i;                                                       \
-                                                                        \
-        for (j = ry; j < max_y; ++j)                                    \
-        {                                                               \
-            _src = src;                                                 \
-            _dst = dst;                                                 \
-                                                                        \
-            for (i = rx; i < max_x; ++i, _dst += _bpp)                  \
-            {                                                           \
-                FT_UInt32 alpha = (*_src++);                            \
-                alpha = (alpha * color->a) / 255;                       \
-                                                                        \
-                if (alpha == 0xFF)                                      \
-                {                                                       \
-                    _setp;                                              \
-                }                                                       \
-                else if (alpha > 0)                                     \
-                {                                                       \
-                    FT_UInt32 pixel = (FT_UInt32)_getp;                 \
-                                                                        \
-                    GET_RGB_VALS(                                       \
-                            pixel, surface->format,                     \
-                            bgR, bgG, bgB, bgA);                        \
-                                                                        \
-                    ALPHA_BLEND(                                        \
-                            color->r, color->g, color->b, alpha,        \
-                            bgR, bgG, bgB, bgA);                        \
-                                                                        \
-                    _blendp;                                            \
-                }                                                       \
-            }                                                           \
-                                                                        \
-            dst += surface->pitch * _bpp;                               \
-            src += bitmap->pitch;                                       \
-        }                                                               \
-    }
-
-
-#define _SET_PIXEL_24   \
-    SET_PIXEL24_RGB(_dst, surface->format, color->r, color->g, color->b);
-
-#define _BLEND_PIXEL_24 \
-    SET_PIXEL24_RGB(_dst, surface->format, bgR, bgG, bgB);
-
-#define _SET_PIXEL(T) \
-    *(T*)_dst = (T)full_color;
-
-#define _BLEND_PIXEL(T) *((T*)_dst) = (T)(                          \
-    ((bgR >> surface->format->Rloss) << surface->format->Rshift) |  \
-    ((bgG >> surface->format->Gloss) << surface->format->Gshift) |  \
-    ((bgB >> surface->format->Bloss) << surface->format->Bshift) |  \
-    ((255 >> surface->format->Aloss) << surface->format->Ashift  &  \
-     surface->format->Amask)                                        )
-
-#define _BLEND_PIXEL_GENERIC(T) *(T*)_dst = (T)(    \
-    SDL_MapRGB(surface->format,                     \
-        (FT_Byte)bgR, (FT_Byte)bgG, (FT_Byte)bgB)   )
-
-#define _GET_PIXEL(T)    (*((T*)_dst))
-
-_CREATE_RGB_RENDER(4,  _GET_PIXEL(FT_UInt32),   _SET_PIXEL(FT_UInt32),  _BLEND_PIXEL(FT_UInt32))
-_CREATE_RGB_RENDER(3,  GET_PIXEL24(_dst),       _SET_PIXEL_24,          _BLEND_PIXEL_24)
-_CREATE_RGB_RENDER(2,  _GET_PIXEL(FT_UInt16),   _SET_PIXEL(FT_UInt16),  _BLEND_PIXEL(FT_UInt16))
-_CREATE_RGB_RENDER(1,  _GET_PIXEL(FT_Byte),     _SET_PIXEL(FT_Byte),    _BLEND_PIXEL_GENERIC(FT_Byte))
-
-_CREATE_MONO_RENDER(4,  _GET_PIXEL(FT_UInt32),   _SET_PIXEL(FT_UInt32),  _BLEND_PIXEL(FT_UInt32))
-_CREATE_MONO_RENDER(3,  GET_PIXEL24(_dst),       _SET_PIXEL_24,          _BLEND_PIXEL_24)
-_CREATE_MONO_RENDER(2,  _GET_PIXEL(FT_UInt16),   _SET_PIXEL(FT_UInt16),  _BLEND_PIXEL(FT_UInt16))
-_CREATE_MONO_RENDER(1,  _GET_PIXEL(FT_Byte),     _SET_PIXEL(FT_Byte),    _BLEND_PIXEL_GENERIC(FT_Byte))
-
 int PGFT_Render_ExistingSurface(FreeTypeInstance *ft, PyFreeTypeFont *font,
     int font_size, FontRenderMode *render, PyObject *text, PySDLSurface *_surface, 
     int x, int y, PyColor *fgcolor, PyColor *bgcolor, int *_width, int *_height)
         __render_glyph_MONO1,
         __render_glyph_MONO2,
         __render_glyph_MONO3,
-        __render_glyph_MONO4,
+        __render_glyph_MONO4
+    };
+
+    static const FontFillPtr __RGBfillFuncs[] =
+    {
+        NULL,
+        __fill_glyph_RGB1,
+        __fill_glyph_RGB2,
+        __fill_glyph_RGB3,
+        __fill_glyph_RGB4
     };
 
     int         locked = 0;
     width = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.x));
     height = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.y));
 
-    /* if bg color exists, paint background */
-    if (bgcolor)
-    {
-        SDL_Rect    bg_fill; 
-        FT_UInt32   fillcolor;
-
-        fillcolor = SDL_MapRGBA(surface->format, 
-                bgcolor->r, bgcolor->g, bgcolor->b, 255);
-
-        bg_fill.x = (FT_Int16)x;
-        bg_fill.y = (FT_Int16)y;
-        bg_fill.w = (FT_UInt16)width;
-        bg_fill.h = (FT_UInt16)height;
-
-        SDL_FillRect(surface, &bg_fill, fillcolor);
-    }
 
     /*
      * Setup target surface struct
     font_surf.format = surface->format;
 
     if (render->antialias == FONT_RENDER_ANTIALIAS)
+        font_surf.render = __SDLrenderFuncs[surface->format->BytesPerPixel];
+    else
+        font_surf.render = __MONOrenderFuncs[surface->format->BytesPerPixel];
+
+    font_surf.fill = __RGBfillFuncs[surface->format->BytesPerPixel];
+
+    /* 
+     * if bg color exists, paint background 
+     */
+    if (bgcolor)
     {
-        font_surf.render = __SDLrenderFuncs[surface->format->BytesPerPixel];
-    }
-    else
-    {
-        font_surf.render = __MONOrenderFuncs[surface->format->BytesPerPixel];
+        if (bgcolor->a == 0xFF)
+        {
+            SDL_Rect    bg_fill; 
+            FT_UInt32   fillcolor;
+
+            fillcolor = SDL_MapRGBA(surface->format, 
+                    bgcolor->r, bgcolor->g, bgcolor->b, bgcolor->a);
+
+            bg_fill.x = (FT_Int16)x;
+            bg_fill.y = (FT_Int16)y;
+            bg_fill.w = (FT_UInt16)width;
+            bg_fill.h = (FT_UInt16)height;
+
+            SDL_FillRect(surface, &bg_fill, fillcolor);
+        }
+        else
+        {
+            font_surf.fill(x, y, width, height, &font_surf, bgcolor);
+        }
     }
 
     /*
         locked = 1;
     }
 
-    if (bgcolor)
-    {
-        fillcolor = SDL_MapRGBA(surface->format, 
-                bgcolor->r, bgcolor->g, bgcolor->b, 255);
-    }
-    else
-    {
-        fillcolor = SDL_MapRGBA(surface->format, 0, 0, 0, 0);
-    }
-
-    SDL_FillRect(surface, NULL, fillcolor);
-
     font_surf.buffer = surface->pixels;
     font_surf.buffer_cap = ((FT_Byte *)surface->pixels) + (surface->pitch * surface->h);
     font_surf.x_offset = font_surf.y_offset = 0;
 
     font_surf.format = surface->format;
     font_surf.render = __render_glyph_RGB4;
+    font_surf.fill = __fill_glyph_RGB4;
 
+    /*
+     * Fill our texture with the required bg color
+     */
+    if (bgcolor)
+    {
+        fillcolor = SDL_MapRGBA(surface->format, 
+                bgcolor->r, bgcolor->g, bgcolor->b, bgcolor->a);
+    }
+    else
+    {
+        fillcolor = SDL_MapRGBA(surface->format, 0, 0, 0, 0);
+    }
+
+    SDL_FillRect(surface, NULL, fillcolor);
+
+    /*
+     * Render the text!
+     */
     if (_PGFT_Render_INTERNAL(ft, font, font_text, ptsize, fgcolor, &font_surf, render) != 0)
     {
         SDL_FreeSurface(surface);
  * Rendering on generic arrays
  *
  *********************************************************/
-void __render_glyph_ByteArray(int x, int y, FontSurface *surface,
-    FT_Bitmap *bitmap, PyColor *fg_color)
-{
-    FT_Byte *dst = ((FT_Byte *)surface->buffer) + x + (y * surface->pitch);
-    FT_Byte *dst_cpy;
-
-    const FT_Byte *src = bitmap->buffer;
-    const FT_Byte *src_cpy;
-
-    int j, i;
-
-    for (j = 0; j < bitmap->rows; ++j)
-    {
-        src_cpy = src;
-        dst_cpy = dst;
-
-        LOOP_UNROLLED4({ *dst_cpy++ = (FT_Byte)(~(*src_cpy++)); }, i, bitmap->width);
-
-        dst += surface->pitch;
-        src += bitmap->pitch;
-    }
-}
 
 PyObject *PGFT_Render_PixelArray(FreeTypeInstance *ft, PyFreeTypeFont *font,
     int ptsize, PyObject *text, int *_width, int *_height)
  *
  *********************************************************/
 int _PGFT_Render_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, 
-    FontText *text, int font_size, PyColor *fg_color, FontSurface *surface, 
-    FontRenderMode *render)
+    FontText *text, int font_size, PyColor *fg_color,
+    FontSurface *surface, FontRenderMode *render)
 {
     const FT_Fixed center = (1 << 15); // 0.5
 

src/freetype/ft_render_cb.c

+/*
+  pygame - Python Game Library
+  Copyright (C) 2009 Vicent Marti
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#define PYGAME_FREETYPE_INTERNAL
+
+#include "ft_mod.h"
+#include "ft_wrap.h"
+#include "pgfreetype.h"
+#include "pgtypes.h"
+#include "freetypebase_doc.h"
+
+#include FT_MODULE_H
+
+#ifdef HAVE_PYGAME_SDL_VIDEO
+#   include "surface.h"
+#endif
+
+void __render_glyph_ByteArray(int x, int y, FontSurface *surface,
+    FT_Bitmap *bitmap, PyColor *fg_color)
+{
+    FT_Byte *dst = ((FT_Byte *)surface->buffer) + x + (y * surface->pitch);
+    FT_Byte *dst_cpy;
+
+    const FT_Byte *src = bitmap->buffer;
+    const FT_Byte *src_cpy;
+
+    int j, i;
+
+    for (j = 0; j < bitmap->rows; ++j)
+    {
+        src_cpy = src;
+        dst_cpy = dst;
+
+        LOOP_UNROLLED4({ *dst_cpy++ = (FT_Byte)(~(*src_cpy++)); }, i, bitmap->width);
+
+        dst += surface->pitch;
+        src += bitmap->pitch;
+    }
+}
+
+#ifdef HAVE_PYGAME_SDL_VIDEO
+
+#define _CREATE_RGB_FILLER(_bpp, _getp, _setp, _blendp)     \
+    void __fill_glyph_RGB##_bpp(int x, int y, int w, int h, \
+            FontSurface *surface, PyColor *color)           \
+    {                                                       \
+        int i, j;                                           \
+        unsigned char *dst;                                 \
+        FT_UInt32 bgR, bgG, bgB, bgA;                       \
+                                                            \
+        x = MAX(0, x);                                      \
+        y = MAX(0, y);                                      \
+                                                            \
+        if (x + w > surface->width)                         \
+            w = surface->width - x;                         \
+                                                            \
+        if (y + h > surface->height)                        \
+            h = surface->height - y;                        \
+                                                            \
+        dst = (unsigned char *)surface->buffer + (x * _bpp) +\
+              (y * _bpp * surface->pitch);                  \
+                                                            \
+        for (j = 0; j < h; ++j)                             \
+        {                                                   \
+            unsigned char *_dst = dst;                      \
+                                                            \
+            for (i = 0; i < w; ++i, _dst += _bpp)           \
+            {                                               \
+                FT_UInt32 pixel = (FT_UInt32)_getp;         \
+                                                            \
+                GET_RGB_VALS(                               \
+                        pixel, surface->format,             \
+                        bgR, bgG, bgB, bgA);                \
+                                                            \
+                ALPHA_BLEND(                                \
+                        color->r, color->g, color->b,       \
+                        color->a, bgR, bgG, bgB, bgA);      \
+                                                            \
+                _blendp;                                    \
+            }                                               \
+                                                            \
+            dst += surface->pitch * _bpp;                   \
+        }                                                   \
+    }
+
+#define __MONO_RENDER_INNER_LOOP(_bpp, _code)                       \
+    for (j = ry; j < max_y; ++j)                                    \
+    {                                                               \
+        unsigned char*  _src = src;                                 \
+        unsigned char*  _dst = dst;                                 \
+        FT_UInt32       val = (FT_UInt32)(*_src++ | 0x100) << shift;\
+                                                                    \
+        for (i = rx; i < max_x; ++i, _dst += _bpp)                  \
+        {                                                           \
+            if (val & 0x10000)                                      \
+                val = (FT_UInt32)(*_src++ | 0x100);                 \
+                                                                    \
+            if (val & 0x80)                                         \
+            {                                                       \
+                _code;                                              \
+            }                                                       \
+                                                                    \
+            val   <<= 1;                                            \
+        }                                                           \
+                                                                    \
+        src += bitmap->pitch;                                       \
+        dst += surface->pitch * _bpp;                               \
+    }                                                               \
+
+#define _CREATE_MONO_RENDER(_bpp, _getp, _setp, _blendp)                \
+    void __render_glyph_MONO##_bpp(int x, int y, FontSurface *surface,  \
+            FT_Bitmap *bitmap, PyColor *color)                          \
+    {                                                                   \
+        const int off_x = (x < 0) ? -x : 0;                             \
+        const int off_y = (y < 0) ? -y : 0;                             \
+                                                                        \
+        const int max_x = MIN(x + bitmap->width, surface->width);       \
+        const int max_y = MIN(y + bitmap->rows, surface->height);       \
+                                                                        \
+        const int rx = MAX(0, x);                                       \
+        const int ry = MAX(0, y);                                       \
+                                                                        \
+        int             i, j, shift;                                    \
+        unsigned char*  src;                                            \
+        unsigned char*  dst;                                            \
+        FT_UInt32       full_color;                                     \
+        FT_UInt32 bgR, bgG, bgB, bgA;                                   \
+                                                                        \
+        src  = bitmap->buffer + (off_y * bitmap->pitch) + (off_x >> 3); \
+        dst = (unsigned char *)surface->buffer + (rx * _bpp) +          \
+                    (ry * _bpp * surface->pitch);                       \
+                                                                        \
+        full_color = SDL_MapRGBA(surface->format, (FT_Byte)color->r,    \
+                (FT_Byte)color->g, (FT_Byte)color->b, 255);             \
+                                                                        \
+        shift = off_x & 7;                                              \
+                                                                        \
+        if (color->a == 0xFF)                                           \
+        {                                                               \
+            __MONO_RENDER_INNER_LOOP(_bpp,                              \
+            {                                                           \
+                _setp;                                                  \
+            });                                                         \
+        }                                                               \
+        else if (color->a > 0)                                          \
+        {                                                               \
+            __MONO_RENDER_INNER_LOOP(_bpp,                              \
+            {                                                           \
+                FT_UInt32 pixel = (FT_UInt32)_getp;                     \
+                                                                        \
+                GET_RGB_VALS(                                           \
+                        pixel, surface->format,                         \
+                        bgR, bgG, bgB, bgA);                            \
+                                                                        \
+                ALPHA_BLEND(                                            \
+                        color->r, color->g, color->b, color->a,         \
+                        bgR, bgG, bgB, bgA);                            \
+                                                                        \
+                _blendp;                                                \
+            });                                                         \
+        }                                                               \
+    }
+
+#define _CREATE_RGB_RENDER(_bpp, _getp, _setp, _blendp)                 \
+    void __render_glyph_RGB##_bpp(int x, int y, FontSurface *surface,   \
+        FT_Bitmap *bitmap, PyColor *color)                              \
+    {                                                                   \
+        const int off_x = (x < 0) ? -x : 0;                             \
+        const int off_y = (y < 0) ? -y : 0;                             \
+                                                                        \
+        const int max_x = MIN(x + bitmap->width, surface->width);       \
+        const int max_y = MIN(y + bitmap->rows, surface->height);       \
+                                                                        \
+        const int rx = MAX(0, x);                                       \
+        const int ry = MAX(0, y);                                       \
+                                                                        \
+        FT_Byte *dst = ((FT_Byte*)surface->buffer) + (rx * _bpp) +      \
+                        (ry * _bpp * surface->pitch);                   \
+        FT_Byte *_dst;                                                  \
+                                                                        \
+        const FT_Byte *src = bitmap->buffer + off_x +                   \
+                                (off_y * bitmap->pitch);                \
+        const FT_Byte *_src;                                            \
+                                                                        \
+        const FT_UInt32 full_color =                                    \
+            SDL_MapRGBA(surface->format, (FT_Byte)color->r,             \
+                    (FT_Byte)color->g, (FT_Byte)color->b, 255);         \
+                                                                        \
+        FT_UInt32 bgR, bgG, bgB, bgA;                                   \
+        int j, i;                                                       \
+                                                                        \
+        for (j = ry; j < max_y; ++j)                                    \
+        {                                                               \
+            _src = src;                                                 \
+            _dst = dst;                                                 \
+                                                                        \
+            for (i = rx; i < max_x; ++i, _dst += _bpp)                  \
+            {                                                           \
+                FT_UInt32 alpha = (*_src++);                            \
+                alpha = (alpha * color->a) / 255;                       \
+                                                                        \
+                if (alpha == 0xFF)                                      \
+                {                                                       \
+                    _setp;                                              \
+                }                                                       \
+                else if (alpha > 0)                                     \
+                {                                                       \
+                    FT_UInt32 pixel = (FT_UInt32)_getp;                 \
+                                                                        \
+                    GET_RGB_VALS(                                       \
+                            pixel, surface->format,                     \
+                            bgR, bgG, bgB, bgA);                        \
+                                                                        \
+                    ALPHA_BLEND(                                        \
+                            color->r, color->g, color->b, alpha,        \
+                            bgR, bgG, bgB, bgA);                        \
+                                                                        \
+                    _blendp;                                            \
+                }                                                       \
+            }                                                           \
+                                                                        \
+            dst += surface->pitch * _bpp;                               \
+            src += bitmap->pitch;                                       \
+        }                                                               \
+    }
+
+
+#define _SET_PIXEL_24   \
+    SET_PIXEL24_RGB(_dst, surface->format, color->r, color->g, color->b);
+
+#define _BLEND_PIXEL_24 \
+    SET_PIXEL24_RGB(_dst, surface->format, bgR, bgG, bgB);
+
+#define _SET_PIXEL(T) \
+    *(T*)_dst = (T)full_color;
+
+#define _BLEND_PIXEL(T) *((T*)_dst) = (T)(                          \
+    ((bgR >> surface->format->Rloss) << surface->format->Rshift) |  \
+    ((bgG >> surface->format->Gloss) << surface->format->Gshift) |  \
+    ((bgB >> surface->format->Bloss) << surface->format->Bshift) |  \
+    ((255 >> surface->format->Aloss) << surface->format->Ashift  &  \
+     surface->format->Amask)                                        )
+
+#define _BLEND_PIXEL_GENERIC(T) *(T*)_dst = (T)(    \
+    SDL_MapRGB(surface->format,                     \
+        (FT_Byte)bgR, (FT_Byte)bgG, (FT_Byte)bgB)   )
+
+#define _GET_PIXEL(T)    (*((T*)_dst))
+
+_CREATE_RGB_RENDER(4,  _GET_PIXEL(FT_UInt32),   _SET_PIXEL(FT_UInt32),  _BLEND_PIXEL(FT_UInt32))
+_CREATE_RGB_RENDER(3,  GET_PIXEL24(_dst),       _SET_PIXEL_24,          _BLEND_PIXEL_24)
+_CREATE_RGB_RENDER(2,  _GET_PIXEL(FT_UInt16),   _SET_PIXEL(FT_UInt16),  _BLEND_PIXEL(FT_UInt16))
+_CREATE_RGB_RENDER(1,  _GET_PIXEL(FT_Byte),     _SET_PIXEL(FT_Byte),    _BLEND_PIXEL_GENERIC(FT_Byte))
+
+_CREATE_MONO_RENDER(4,  _GET_PIXEL(FT_UInt32),   _SET_PIXEL(FT_UInt32),  _BLEND_PIXEL(FT_UInt32))
+_CREATE_MONO_RENDER(3,  GET_PIXEL24(_dst),       _SET_PIXEL_24,          _BLEND_PIXEL_24)
+_CREATE_MONO_RENDER(2,  _GET_PIXEL(FT_UInt16),   _SET_PIXEL(FT_UInt16),  _BLEND_PIXEL(FT_UInt16))
+_CREATE_MONO_RENDER(1,  _GET_PIXEL(FT_Byte),     _SET_PIXEL(FT_Byte),    _BLEND_PIXEL_GENERIC(FT_Byte))
+
+_CREATE_RGB_FILLER(4,  _GET_PIXEL(FT_UInt32),   _SET_PIXEL(FT_UInt32),  _BLEND_PIXEL(FT_UInt32))
+_CREATE_RGB_FILLER(3,  GET_PIXEL24(_dst),       _SET_PIXEL_24,          _BLEND_PIXEL_24)
+_CREATE_RGB_FILLER(2,  _GET_PIXEL(FT_UInt16),   _SET_PIXEL(FT_UInt16),  _BLEND_PIXEL(FT_UInt16))
+_CREATE_RGB_FILLER(1,  _GET_PIXEL(FT_Byte),     _SET_PIXEL(FT_Byte),    _BLEND_PIXEL_GENERIC(FT_Byte))
+
+#endif

src/freetype/ft_wrap.h

     int pitch;
 
     SDL_PixelFormat *format;
-    void (* render)(int, int, struct __fontsurface *, FT_Bitmap *, PyColor *);
+
+    void (* render) (int, int, struct __fontsurface *, FT_Bitmap *, PyColor *);
+    void (* fill)   (int, int, int, int, struct __fontsurface *, PyColor *);
 
 } FontSurface;
 
                 FontSurface *surface, FontRenderMode *render);
 
 
+/******************************************************************* Render callbacks ****/
+
+void __fill_glyph_RGB1(int x, int y, int w, int h, FontSurface *surface, PyColor *color);
+void __fill_glyph_RGB2(int x, int y, int w, int h, FontSurface *surface, PyColor *color);
+void __fill_glyph_RGB3(int x, int y, int w, int h, FontSurface *surface, PyColor *color);
+void __fill_glyph_RGB4(int x, int y, int w, int h, FontSurface *surface, PyColor *color);
+
+void __render_glyph_MONO1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_MONO2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_MONO3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_MONO4(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+
+void __render_glyph_RGB1(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_RGB2(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_RGB3(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
+void __render_glyph_RGB4(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);
+
+
 /******************************************************************* Fake styles ****/
 int PGFT_Style_MakeBold(FT_Face face);
 
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.