Commits

Anonymous committed d4368b6

Fixed sizing for slanted and underlined text. 0 errors on unit tests.

Comments (0)

Files changed (5)

examples/freetype/sdlfont.py

     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_UNDERLINE|ftconstants.STYLE_BOLD)
+    font.render("Hello World", colors["red"], colors['grey_dark'], screen, 32, 32, ptsize=64, style=ftconstants.STYLE_UNDERLINE|ftconstants.STYLE_ITALIC)
     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)

src/freetype/ft_metrics.c

 
 #include FT_MODULE_H
 
+extern FT_Matrix PGFT_SlantMatrix;
+
+/* Declarations */
+void _PGFT_GetMetrics_INTERNAL(FT_Glyph, FT_UInt, int *, int *, int *, int *, int *);
+int  _PGFT_GetTextSize_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, 
+        const FontRenderMode *render, FontText *text);
+
+
+/* Real text metrics */
 void _PGFT_GetMetrics_INTERNAL(FT_Glyph glyph, FT_UInt bbmode,
     int *minx, int *maxx, int *miny, int *maxy, int *advance)
 {
 }
 
 int
+PGFT_GetSurfaceSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
+        const FontRenderMode *render, FontText *text, 
+        int *width, int *height)
+{
+    int w, h;
+
+    if (text == NULL || 
+        _PGFT_GetTextSize_INTERNAL(ft, font, render, text) != 0)
+        return -1;
+
+    w = text->text_size.x;
+    h = text->text_size.y;
+
+    if (text->underline_size > 0)
+    {
+        h = MAX(h, text->underline_pos + text->underline_size);
+    }
+
+    if (render->style & FT_STYLE_ITALIC)
+    {
+        FT_Vector s = {w, h};
+
+        FT_Vector_Transform(&s, &PGFT_SlantMatrix);
+        w = s.x; h = s.y;
+    }
+
+    *width = PGFT_TRUNC(PGFT_CEIL(w));
+    *height = PGFT_TRUNC(PGFT_CEIL(h));
+    return 0;
+}
+
+int
 PGFT_GetTextSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
     const FontRenderMode *render, PyObject *text, int *w, int *h)
 {
     if (!font_text)
         return -1;
 
-    if (_PGFT_GetTextSize_INTERNAL(ft, font, render, font_text) != 0)
-        return -1;
-
-    *w = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.x));
-    *h = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.y));
-    return 0;
+    return PGFT_GetSurfaceSize(ft, font, render, font_text, w, h);
 }

src/freetype/ft_render.c

     if (!font_text)
         return -1;
 
-    _PGFT_GetTextSize_INTERNAL(ft, font, render, font_text);
-
-    width = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.x));
-    height = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.y));
-
+    if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0)
+        return -1;
 
     /*
      * Setup target surface struct
     if (!font_text)
         return NULL;
 
-    if (_PGFT_GetTextSize_INTERNAL(ft, font, render, font_text) != 0)
+    if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0)
         return NULL;
 
-    width = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.x));
-    height = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.y));
-
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
     rmask = 0xff000000;
     gmask = 0x00ff0000;
     if (!font_text)
         goto cleanup;
 
-    if (_PGFT_GetTextSize_INTERNAL(ft, font, render, font_text) != 0)
+    if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0)
         goto cleanup;
 
-    width = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.x));
-    height = PGFT_TRUNC(PGFT_ROUND(font_text->text_size.y));
     array_size = width * height;
 
     buffer = malloc((size_t)array_size);
         FT_Done_Glyph(image);
     } /* END OF RENDERING LOOP */
 
-    if (render->style & FT_STYLE_UNDERLINE &&
-        (render->render_flags & FT_RFLAG_VERTICAL) == 0 &&
-        (render->rotation_angle == 0))
+    if (text->underline_size > 0)
     {
-        FT_Fixed scale;
-        FT_Fixed underline_pos;
-        FT_Fixed underline_size;
-        
-        scale = face->size->metrics.y_scale;
-
-        underline_pos = FT_MulFix(face->underline_position, scale);
-        underline_size = FT_MulFix(face->underline_thickness, scale) + bold_str;
-
-        /*
-         * HACK HACK HACK
-         *
-         * According to the FT documentation, 'underline_pos' is the offset 
-         * to draw the underline in 26.6 FP, based on the text's baseline 
-         * (negative values mean below the baseline).
-         *
-         * However, after scaling the underline position, the values for all
-         * fonts are WAY off (e.g. fonts with 32pt size get underline offsets
-         * of -14 pixels).
-         *
-         * Dividing the offset by 4, somehow, returns very sane results for
-         * all kind of fonts; the underline seems to fit perfectly between
-         * the baseline and bottom of the glyphs.
-         *
-         * We'll leave it like this until we can figure out what's wrong
-         * with it...
-         *
-         */
-
         surface->fill(
                 surface->x_offset,
-                surface->y_offset + PGFT_TRUNC(text->text_size.y) -
-                PGFT_TRUNC(text->baseline_offset.y) - PGFT_TRUNC(underline_pos)/4,
-                PGFT_TRUNC(text->text_size.x), PGFT_TRUNC(underline_size),
+                surface->y_offset + PGFT_TRUNC(text->underline_pos),
+                PGFT_TRUNC(text->text_size.x), PGFT_TRUNC(text->underline_size),
                 surface, fg_color);
     }
 

src/freetype/ft_text.c

     ftext->glyph_size.x = ftext->glyph_size.y = 0;
     ftext->text_size.x = ftext->text_size.y = 0;
     ftext->baseline_offset.x = ftext->baseline_offset.y = 0;
+    ftext->underline_pos = ftext->underline_size = 0;
 
     y_scale = face->size->metrics.y_scale;
 
         *glyph_array++ = glyph;
     }
 
-    /* 
-     * FIXME:
-     * Take into account the extra height added by underlines
-     */
+    if (render->style & FT_STYLE_UNDERLINE &&
+        (render->render_flags & FT_RFLAG_VERTICAL) == 0 &&
+        (render->rotation_angle == 0))
+    {
+        FT_Fixed scale;
+        FT_Fixed underline_pos;
+        FT_Fixed underline_size;
+        
+        scale = face->size->metrics.y_scale;
+
+        underline_pos = FT_MulFix(face->underline_position, scale);
+        underline_size = FT_MulFix(face->underline_thickness, scale) + bold_str;
+
+        /*
+         * HACK HACK HACK
+         *
+         * According to the FT documentation, 'underline_pos' is the offset 
+         * to draw the underline in 26.6 FP, based on the text's baseline 
+         * (negative values mean below the baseline).
+         *
+         * However, after scaling the underline position, the values for all
+         * fonts are WAY off (e.g. fonts with 32pt size get underline offsets
+         * of -14 pixels).
+         *
+         * Dividing the offset by 4, somehow, returns very sane results for
+         * all kind of fonts; the underline seems to fit perfectly between
+         * the baseline and bottom of the glyphs.
+         *
+         * We'll leave it like this until we can figure out what's wrong
+         * with it...
+         *
+         */
+
+        ftext->underline_pos =
+            ftext->glyph_size.y - ftext->baseline_offset.y - (underline_pos / 4);
+
+        ftext->underline_size = underline_size;
+    }
 
     free(orig_buffer);
     return ftext;

src/freetype/ft_wrap.h

     FT_Vector glyph_size;       /* 26.6 */
     FT_Vector text_size;        /* 26.6 */
     FT_Vector baseline_offset;  /* 26.6 */
+
+    FT_Fixed underline_size;
+    FT_Fixed underline_pos;
 } FontText;
 
 typedef struct __cachenode
                 int character, const FontRenderMode *render, int bbmode, 
                 void *minx, void *maxx, void *miny, void *maxy, void *advance);
 
-int         _PGFT_GetTextSize_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, 
-                const FontRenderMode *render, FontText *text);
-
-void        _PGFT_GetMetrics_INTERNAL(FT_Glyph, FT_UInt, int *, int *, int *, int *, int *);
+int         PGFT_GetSurfaceSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
+                const FontRenderMode *render, FontText *text, 
+                int *width, int *height);
 
 
 
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.