Commits

Anonymous committed 95cefb6

Massive refactoring on rendering parameters.

Comments (0)

Files changed (6)

examples/freetype/sdlfont.py

     screen.fill (colors["grey_light"])
 
     font.render("Hello World", colors["red"], None, screen, 32, 32, ptsize=64, style=ftconstants.STYLE_UNDERLINE|ftconstants.STYLE_BOLD)
-    font.render("do it now with this...", colors["grey_dark"], colors["green"], screen, 32, 128, ptsize=64)
+    font.render("abcdefghijklm", colors["grey_dark"], colors["green"], screen, 32, 128, ptsize=64)
     font.render("Vertical?", colors["blue"], None, screen, 32, 190, ptsize=32, vertical=True)
     font.render("Let's spin!", colors["red"], None, screen, 64, 190, ptsize=48, rotation=55)
     font.render("All around!", colors["green"], None, screen, 150, 270, ptsize=48, rotation=-55)

src/freetype/ft_font.c

     PGFT_CHECK_PTSIZE();
     PGFT_CHECK_BOOL(vertical_obj, vertical);
 
-    PGFT_BuildRenderMode(&render, style, vertical, FONT_RENDER_ANTIALIAS, rotation);
+    /* Build rendering mode, always anti-aliased by default */
+    PGFT_BuildRenderMode(&render, style, vertical, 1, rotation);
 
     error = PGFT_GetTextSize(ft, (PyFreeTypeFont *)self, ptsize, &render,
             text, &width, &height);

src/freetype/ft_metrics.c

 
     extent = advances[text->length - 1];
 
-    if (render->vertical)
+    if (render->render_flags & FT_RFLAG_VERTICAL)
     {
         size.x = text->glyph_size.x;
         size.y = ABS(extent.y);
         size.y = text->glyph_size.y;
     }
 
-    if (render->matrix)
+    if (render->rotation_angle)
     {   
         size.x = MAX(size.x, size.y);
         size.y = MAX(size.x, size.y);

src/freetype/ft_render.c

     FT_Fixed bold_str;
 
     bold_str = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale);
-    bold_str = (FT_Fixed)(bold_str * bold_factor);
+    bold_str = (FT_Fixed)((float)bold_str * bold_factor);
 
     return bold_str;
 }
 void 
 PGFT_BuildRenderMode(FontRenderMode *mode, int style, int vertical, int antialias, int rotation)
 {
-    double      radian;
-    FT_Fixed    cosinus;
-    FT_Fixed    sinus;
-    int         angle;
+    int angle;
+
+    mode->style = (FT_Byte)style;
+    mode->render_flags = FT_RFLAG_DEFAULTS;
+
+    if (vertical)
+        mode->render_flags |= FT_RFLAG_VERTICAL;
+
+    if (antialias)
+        mode->render_flags |= FT_RFLAG_ANTIALIAS;
 
     angle = rotation % 360;
     while (angle < 0) angle += 360;
-
-    mode->kerning_mode = 1;
-    mode->kerning_degree = 0;
-
-    mode->style = (FT_Byte)style;
-
-    mode->vertical = (FT_Byte)vertical;
-    mode->hinted = (FT_Byte)1;
-    mode->autohint = 0;
-    mode->antialias = (FT_Byte)antialias;
-    mode->matrix = NULL;
-    mode->_rotation_angle = 0;
-
-    if (angle != 0)
-    {
-        radian  = angle * 3.14159 / 180.0;
-        cosinus = (FT_Fixed)(cos(radian) * 65536.0);
-        sinus   = (FT_Fixed)(sin(radian) * 65536.0);
-
-        mode->_rotation_matrix.xx = cosinus;
-        mode->_rotation_matrix.yx = sinus;
-        mode->_rotation_matrix.xy = -sinus;
-        mode->_rotation_matrix.yy = cosinus;
-        mode->_rotation_angle = (angle << 16);
-
-        mode->matrix = &mode->_rotation_matrix;
-    }
+    mode->rotation_angle = (FT_UInt16)angle;
 }
 
 
      * Setup target surface struct
      */
     font_surf.buffer = surface->pixels;
-    font_surf.buffer_cap = ((FT_Byte *)surface->pixels) + (surface->pitch * surface->h);
     font_surf.x_offset = x;
     font_surf.y_offset = y;
 
 
     font_surf.format = surface->format;
 
-    if (render->antialias == FONT_RENDER_ANTIALIAS)
+    if (render->render_flags & FT_RFLAG_ANTIALIAS)
         font_surf.render = __SDLrenderFuncs[surface->format->BytesPerPixel];
     else
         font_surf.render = __MONOrenderFuncs[surface->format->BytesPerPixel];
     }
 
     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.width = surface->w;
     FontRenderMode render;
     int array_size;
 
-    /* TODO: pixel arrays must also take custom rendering styles */
-    PGFT_BuildRenderMode(&render, FT_STYLE_NORMAL,
-            FONT_RENDER_HORIZONTAL, FONT_RENDER_ANTIALIAS, 0);
+    /* 
+     * TODO: pixel arrays must also take custom rendering styles
+     * ... or should them?
+     */
+    PGFT_BuildRenderMode(&render, FT_STYLE_NORMAL, 0, 1, 0);
 
     /* build font text */
     font_text = PGFT_LoadFontText(ft, font, ptsize, &render, text);
 
     int         n;
     FT_Vector   pen, advances[MAX_GLYPHS];
+    FT_Matrix   rotation_matrix;
     FT_Face     face;
     FT_Error    error;
 
     /******************************************************
      * Load advance information
      ******************************************************/
-
     error = PGFT_GetTextAdvances(ft, font, font_size, render, text, advances);
 
     if (error)
     }
 
     /******************************************************
+     * Build rotation matrix for rotated text
+     ******************************************************/
+    if (render->rotation_angle != 0)
+    {
+        double      radian;
+        FT_Fixed    cosinus;
+        FT_Fixed    sinus;
+
+        radian  = render->rotation_angle * 3.14159 / 180.0;
+        cosinus = (FT_Fixed)(cos(radian) * 65536.0);
+        sinus   = (FT_Fixed)(sin(radian) * 65536.0);
+
+        rotation_matrix.xx = cosinus;
+        rotation_matrix.yx = sinus;
+        rotation_matrix.xy = -sinus;
+        rotation_matrix.yy = cosinus;
+    }
+
+    /******************************************************
      * Prepare pen for drawing 
      ******************************************************/
 
     pen.x = FT_MulFix(pen.x, center); 
     pen.y = FT_MulFix(pen.y, center);
 
-    if (!render->vertical)
+    if ((render->render_flags & FT_RFLAG_VERTICAL) == 0)
         pen.y += PGFT_ROUND(text->glyph_size.y / 2);
 
     /* get pen position */
-    if (render->matrix && FT_IS_SCALABLE(face))
+    if (render->rotation_angle && FT_IS_SCALABLE(face))
     {
-        FT_Vector_Transform(&pen, render->matrix);
+        FT_Vector_Transform(&pen, &rotation_matrix);
         pen.x = x - pen.x;
         pen.y = y - pen.y;
     }
         if (image->format == FT_GLYPH_FORMAT_OUTLINE)
         {
             FT_OutlineGlyph outline;
+            FT_Vector *trans_vector = NULL;
+            FT_Matrix *trans_matrix = NULL;
+
             outline = (FT_OutlineGlyph)image;
 
             if (render->style & FT_STYLE_BOLD)
-            {
                 FT_Outline_Embolden(&(outline->outline), bold_str);
-            }
 
             if (render->style & FT_STYLE_ITALIC)
-            {
                 FT_Outline_Transform(&(outline->outline), &PGFT_SlantMatrix);
-            }
 
-            if (render->vertical)
-                error = FT_Glyph_Transform(image, NULL, &glyph->vvector);
+            if (render->render_flags & FT_RFLAG_VERTICAL)
+                trans_vector = &glyph->vvector;
 
-            if (!error)
-                error = FT_Glyph_Transform(image, render->matrix, &pen);
+            if (render->rotation_angle)
+                trans_matrix = &rotation_matrix;
 
-            if (error)
+            if (FT_Glyph_Transform(image, NULL, trans_vector) != 0 ||
+                FT_Glyph_Transform(image, trans_matrix, &pen) != 0)
             {
                 FT_Done_Glyph(image);
                 continue;
         {
             FT_BitmapGlyph  bitmap = (FT_BitmapGlyph)image;
 
-            if (render->vertical)
+            if (render->render_flags & FT_RFLAG_VERTICAL)
             {
                 bitmap->left += (glyph->vvector.x + pen.x) >> 6;
                 bitmap->top  += (glyph->vvector.x + pen.y) >> 6;
             }
         }
 
-        if (render->matrix)
-            FT_Vector_Transform(advances + n, render->matrix);
+        if (render->rotation_angle)
+            FT_Vector_Transform(advances + n, &rotation_matrix);
 
         pen.x += advances[n].x;
         pen.y += advances[n].y;
             if (image->format == FT_GLYPH_FORMAT_OUTLINE)
             {
                 FT_Render_Mode render_mode = 
-                    render->antialias ?
+                    (render->render_flags & FT_RFLAG_ANTIALIAS) ?
                     FT_RENDER_MODE_NORMAL :
                     FT_RENDER_MODE_MONO;
 
 
     if (render->style & FT_STYLE_UNDERLINE)
     {
-        surface->fill(surface->x_offset, surface->y_offset + text->baseline_offset.y + text->underline_pos, 
+        surface->fill(
+                surface->x_offset, 
+                surface->y_offset + text->baseline_offset.y + text->underline_pos, 
                 text->text_size.x >> 6, text->underline_h, 
                 surface, fg_color);
     }

src/freetype/ft_text.c

     /* compute proper load flags */
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
-    if (render->autohint)
+    if (render->render_flags & FT_RFLAG_AUTOHINT)
         load_flags |= FT_LOAD_FORCE_AUTOHINT;
 
-    if (render->hinted)
+    if (render->render_flags & FT_RFLAG_HINTED)
     {
-        load_flags |=   render->antialias ?
+        load_flags |=   (render->render_flags & FT_RFLAG_ANTIALIAS) ?
                         FT_LOAD_TARGET_NORMAL :
                         FT_LOAD_TARGET_MONO;
     }
     if (render->style & FT_STYLE_BOLD)
         bold_str = PGFT_GetBoldStrength(face);
 
-    if (!render->vertical && render->kerning_degree)
+#if 0
+    if (!(render->render_flags & FT_RFLAG_VERTICAL) && render->kerning_degree)
     {
         FT_Fixed  ptsize;
 
         else
             track_kern >>= 10;
     }
+#endif
 
     for (i = 0; i < text->length; i++)
     {
         if (!glyph->image)
             continue;
 
-        if (render->vertical)
+        if (render->render_flags & FT_RFLAG_VERTICAL)
             advances[i] = glyph->vadvance;
         else
         {
             {
                 prev_advance->x += track_kern;
 
-                if (render->kerning_mode)
+                if (FT_KERNING_MODE > 0)
                 {
                     FT_Vector  kern;
 
                     prev_advance->x += kern.x;
                     prev_advance->y += kern.y;
 
-                    if (render->kerning_mode > 1) /* KERNING_MODE_NORMAL */
+                    if (FT_KERNING_MODE > 1) /* KERNING_MODE_NORMAL */
                         prev_advance->x += glyph->delta;
                 }
             }
 
         if (prev_advance)
         {
-            if (render->hinted)
+            if (render->render_flags & FT_RFLAG_HINTED)
             {
                 prev_advance->x = PGFT_ROUND(prev_advance->x);
                 prev_advance->y = PGFT_ROUND(prev_advance->y);
 
     if (prev_advance)
     {
-        if (render->hinted)
+        if (render->render_flags & FT_RFLAG_HINTED)
         {
             prev_advance->x = PGFT_ROUND(prev_advance->x);
             prev_advance->y = PGFT_ROUND(prev_advance->y);

src/freetype/ft_wrap.h

 #define UNICODE_BOM_NATIVE	0xFEFF
 #define UNICODE_BOM_SWAPPED	0xFFFE
 
-#define FONT_RENDER_HORIZONTAL  0
-#define FONT_RENDER_VERTICAL    1
+#define FT_KERNING_MODE 1 /* KERNING_MODE_DEFAULT */
 
-#define FONT_RENDER_ALIASED     0
-#define FONT_RENDER_ANTIALIAS   1
+#define FT_RFLAG_NONE           (0)
+#define FT_RFLAG_ANTIALIAS      (1 << 0)
+#define FT_RFLAG_AUTOHINT       (1 << 1)
+#define FT_RFLAG_VERTICAL       (1 << 2)
+#define FT_RFLAG_HINTED         (1 << 3)
+
+/*
+ * Default render flags:
+ *      - Antialiasing off
+ *      - Autohint off
+ *      - Vertical text off
+ *      - Hinted on
+ */
+#define FT_RFLAG_DEFAULTS       (FT_RFLAG_NONE | FT_RFLAG_HINTED)
 
 #define MAX_GLYPHS      64
 
 typedef struct __fontsurface
 {
     void *buffer;
-    void *buffer_cap;
 
     int x_offset;
     int y_offset;
 
 typedef struct __rendermode
 {
-    int         kerning_degree;
-    FT_Matrix*  matrix;
-
-    FT_Matrix   _rotation_matrix;
-    FT_Fixed    _rotation_angle;
-
-    FT_Byte     hinted;
-    FT_Byte     vertical;
-    FT_Byte     antialias;
-    FT_Byte     kerning_mode;
-    FT_Byte     autohint;
+    FT_UInt16   rotation_angle;
+    FT_Byte     render_flags;
     FT_Byte     style;
 } FontRenderMode;