Anonymous avatar Anonymous committed 2af4a9c

Fixed obtaining font metrics on cached glyphs.

Comments (0)

Files changed (1)

src/freetype/ft_wrap.c

 #include "pgtypes.h"
 #include "freetypebase_doc.h"
 
+#include FT_MODULE_H
+
 void    _PGFT_SetError(FreeTypeInstance *, const char *, FT_Error);
 FT_Face _PGFT_GetFace(FreeTypeInstance *, PyFreeTypeFont *);
 FT_Face _PGFT_GetFaceSized(FreeTypeInstance *, PyFreeTypeFont *, int);
 void    _PGFT_BuildScaler(PyFreeTypeFont *, FTC_Scaler, int);
-int     _PGFT_LoadGlyph(FreeTypeInstance *, PyFreeTypeFont *, FTC_Scaler, int);
+int     _PGFT_LoadGlyph(FreeTypeInstance *, PyFreeTypeFont *, FTC_Scaler, int, FT_Glyph *);
+void    _PGFT_GetMetrics_INTERNAL(FT_Glyph, int *, int *, int *, int *, int *);
 
 
-void _PGFT_GetMetrics_FIXED(FT_Glyph_Metrics *, 
-        int *, int *, int *, int *, int *);
-
-void _PGFT_GetMetrics_SCALABLE(FT_Glyph_Metrics *, 
-        int *, int *, int *, int *, int *);
-
 static FT_Error
 _PGFT_face_request(FTC_FaceID face_id, 
     FT_Library library, 
 _PGFT_LoadGlyph(FreeTypeInstance *ft, 
         PyFreeTypeFont *font,
         FTC_Scaler scale, 
-        int character)
+        int character, FT_Glyph *glyph)
 {
     FT_Error error;
-    FT_Glyph glyph;
     FT_UInt32 char_index;
 
     char_index = FTC_CMapCache_Lookup(
             scale,
             FT_LOAD_DEFAULT, /* TODO: proper load flags */
             char_index,
-            &glyph, NULL);
+            glyph, NULL);
 
     return error;
 }
 
-void _PGFT_GetMetrics_SCALABLE(FT_Glyph_Metrics *metrics, 
+void _PGFT_GetMetrics_INTERNAL(FT_Glyph glyph, 
         int *minx, int *maxx, int *miny, int *maxy, int *advance)
 {
-    *minx = FT_FLOOR(metrics->horiBearingX);
-    *maxx = *minx + FT_CEIL(metrics->width);
+    FT_BBox box;
 
-    *maxy = FT_FLOOR(metrics->horiBearingY);
-    *miny = *maxy - FT_CEIL(metrics->height);
+    /*
+     * FIXME: We need to return pixel-based coordinates...
+     * It would make sense to use FT_GLYPH_BBOX_TRUNCATE
+     * to get the fixed point coordinates truncated, but
+     * the results are usually off by 1 pixel from what we
+     * get from SDL_TTF.
+     *
+     * Using FT_GLYPH_BBOX_PIXELS (truncated + grid fitted
+     * coordinates) we get exactly the same results as
+     * SDL_TTF, but does SDL actually do this properly?
+     * 
+     * Which are the *right* results? 
+     */
+    FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &box);
 
-    *advance = FT_CEIL(metrics->horiAdvance);
+    *minx = box.xMin;
+    *maxx = box.xMax;
+    *miny = box.yMin;
+    *maxy = box.yMax;
+    *advance = (glyph->advance.x >> 16);
 }
 
-void _PGFT_GetMetrics_FIXED(FT_Glyph_Metrics *metrics, 
-        int *minx, int *maxx, int *miny, int *maxy, int *advance)
-{
-    *minx = FT_FLOOR(metrics->horiBearingX);
-    *maxx = *minx + FT_CEIL(metrics->horiAdvance);
-
-    *maxy = FT_FLOOR(metrics->horiBearingY);
-    *miny = *maxy - FT_CEIL(metrics->height);
-
-    *advance = FT_CEIL(metrics->horiAdvance);
-}
 
 int PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font,
         int character, int font_size, 
     FT_Error error;
     FTC_ScalerRec scale;
     FT_Face face;
+    FT_Glyph glyph;
 
     _PGFT_BuildScaler(font, &scale, font_size);
     face = font->face;
 
-    error = _PGFT_LoadGlyph(ft, font, &scale, character);
+    error = _PGFT_LoadGlyph(ft, font, &scale, character, &glyph);
 
     if (error)
     {
         return error;
     }
 
-    if (FT_IS_SCALABLE(face))
-    {
-        _PGFT_GetMetrics_SCALABLE(&face->glyph->metrics, 
-                minx, maxx, miny, maxy, advance);
-    }
-    else
-    {
-        _PGFT_GetMetrics_FIXED(&face->glyph->metrics, 
-                minx, maxx, miny, maxy, advance);
-    }
-
+    _PGFT_GetMetrics_INTERNAL(glyph, minx, maxx, miny, maxy, advance);
     return 0;
 }
 
     int swapped;
     FTC_ScalerRec scale;
     FT_Face face;
+    FT_Glyph glyph;
 
     int minx, maxx, miny, maxy, x, z;
     int gl_maxx, gl_maxy, gl_minx, gl_miny, gl_advance;
         if (swapped)
             c = (FT_UInt16)((c << 8) | (c >> 8));
 
-        if (_PGFT_LoadGlyph(ft, font, &scale, c) != 0)
+        if (_PGFT_LoadGlyph(ft, font, &scale, c, &glyph) != 0)
             continue;
 
         /* TODO: Handle kerning */
 
-        if (FT_IS_SCALABLE(face))
-        {
-            _PGFT_GetMetrics_SCALABLE(&face->glyph->metrics, 
-                    &gl_minx, &gl_maxx, &gl_miny, &gl_maxy, &gl_advance);
-        }
-        else
-        {
-            _PGFT_GetMetrics_FIXED(&face->glyph->metrics, 
-                    &gl_minx, &gl_maxx, &gl_miny, &gl_maxy, &gl_advance);
-        }
+        _PGFT_GetMetrics_INTERNAL(glyph, 
+                &gl_minx, &gl_maxx, &gl_miny, &gl_maxy, &gl_advance);
 
         z = x + gl_minx;
 		if (minx > z) 
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.