Commits

Anonymous committed f120248

Added default styles for fonts.
Fixed issues with underline rendering.

Comments (0)

Files changed (6)

src/freetype/ft_font.c

 static int
 _ftfont_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
+    static char *kwlist[] = 
+    { 
+        "font", "ptsize", "style", "face_index", NULL
+    };
+
     PyFreeTypeFont *font = (PyFreeTypeFont *)self;
     
     PyObject *file;
     int face_index = 0;
     int ptsize = -1;
+    int font_style = FT_STYLE_NORMAL;
 
     FreeTypeInstance *ft;
     ASSERT_GRAB_FREETYPE(ft, -1);
 
-    if (!PyArg_ParseTuple(args, "O|ii", &file, &ptsize, &face_index))
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iii", kwlist, 
+                &file, &ptsize, &font_style, &face_index))
         return -1;
 
     if (face_index < 0)
     }
 
     font->default_ptsize = (ptsize <= 0) ? -1 : ptsize;
+    font->default_style = font_style;
 
     /*
      * TODO: Handle file-like objects
 static PyObject*
 _ftfont_getstyle (PyObject *self, void *closure)
 {
-    /* TODO */
+    PyFreeTypeFont *font = (PyFreeTypeFont *)self;
+
+    return PyInt_FromLong(font->default_style);
 }
 
 static int
 _ftfont_setstyle(PyObject *self, PyObject *value, void *closure)
 {
-    /* TODO */
+    PyFreeTypeFont *font = (PyFreeTypeFont *)self;
+
+    if (!PyInt_Check(value))
+    {
+        PyErr_SetString(PyExc_TypeError, "Invalid style value");
+        return -1;
+    }
+
+    font->default_style = PyInt_AsLong(value);
+    return 0;
 }
 
 static PyObject*
     FontRenderMode render;
     int vertical = 0;
     int rotation = 0;
-    int style = FT_STYLE_NORMAL;
+    int style = 0;
 
     PyObject *vertical_obj = NULL;
 
     PyObject *antialias_obj = NULL;
     int rotation = 0;
     int xpos = 0, ypos = 0;
-    int style = FT_STYLE_NORMAL;
+    int style = FT_STYLE_DEFAULT;
 
     /* output arguments */
     PyObject *rtuple = NULL;
 
     /* TODO: Create a constructor for fonts with default sizes? */
     font->default_ptsize = -1;
+    font->default_style = FT_STYLE_NORMAL;
 
     if (PGFT_TryLoadFont_Filename(ft, font, filename, face_index) != 0)
     {

src/freetype/ft_render.c

     }
 
     mode->pt_size = (FT_UInt16)pt_size;
-    mode->style = (FT_Byte)style;
+
+    if (style == FT_STYLE_DEFAULT)
+        mode->style = font->default_style;
+    else
+        mode->style = (FT_Byte)style;
+
     mode->render_flags = FT_RFLAG_DEFAULTS;
 
     if (vertical)
         FT_Done_Glyph(image);
     } /* END OF RENDERING LOOP */
 
-    if (render->style & FT_STYLE_UNDERLINE)
+    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...
+         *
+         */
+
         surface->fill(
-                surface->x_offset, 
-                surface->y_offset + text->baseline_offset.y + text->underline_pos, 
-                text->text_size.x >> 6, text->underline_h, 
+                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, fg_color);
     }
 

src/freetype/ft_text.c

 
     y_scale = face->size->metrics.y_scale;
 
-    /*
-     * Calculate the position for the underline.
-     * underline_pos is the offset of the underline based on top of the
-     * font's baseline.
-     *
-     * HACK: When emboldening the font, the baseline nor the offset change,
-     * however the font is indeed thicker and the type overlays the underline
-     * on most cases. We manually adjust for this by increasing the offset
-     * a proportional amount to the bold strength.
-     */
-    if (render->style & FT_STYLE_BOLD)
-        bold_str = PGFT_GetBoldStrength(face);
-
-    ftext->underline_pos = (FT_Int16)(
-            PGFT_FLOOR(FT_MulFix(face->underline_position + bold_str / 2, y_scale)) >> 6);
-
-    ftext->underline_h = (FT_Int16)(
-            (bold_str + PGFT_FLOOR(FT_MulFix(face->underline_thickness, y_scale))) >> 6);
-
     /* fill it with the glyphs */
     glyph_array = ftext->glyphs;
 

src/freetype/ft_wrap.c

 
     font->_internals = malloc(sizeof(FontInternals));
     memset(font->_internals, 0x0, sizeof(FontInternals));
-    
+
     PGFT_Cache_Init(&PGFT_INTERNALS(font)->cache, font);
 
     return _PGFT_GetFace(ft, font) ? 0 : -1;
     if (ft != NULL)
         FTC_Manager_RemoveFaceID(ft->cache_manager, (FTC_FaceID)(&font->id));
 
-    PGFT_Cache_Destroy(&PGFT_INTERNALS(font)->cache);
-    free(PGFT_INTERNALS(font)->active_text.glyphs);
-    free(PGFT_INTERNALS(font));
+    if (PGFT_INTERNALS(font))
+    {
+        PGFT_Cache_Destroy(&PGFT_INTERNALS(font)->cache);
+        free(PGFT_INTERNALS(font)->active_text.glyphs);
+        free(PGFT_INTERNALS(font));
+    }
 
     free(font->id.open_args.pathname);
 }

src/freetype/ft_wrap.h

     FT_Vector glyph_size;       /* 26.6 */
     FT_Vector text_size;        /* 26.6 */
     FT_Vector baseline_offset;  /* 26.6 */
-
-    FT_Int16 underline_pos;
-    FT_Int16 underline_h;
 } FontText;
 
 typedef struct __glyphcache

src/freetype/pgfreetype.h

 #define FT_STYLE_BOLD		0x01
 #define FT_STYLE_ITALIC     0x02
 #define FT_STYLE_UNDERLINE  0x04
+#define FT_STYLE_DEFAULT    0xFF
 
 /* Sane constant names */
 #define FT_BBOX_EXACT           FT_GLYPH_BBOX_SUBPIXELS
     PyFont pyfont;
     FontId id;
 
+    int default_ptsize;
+    int default_style;
+
     void *_internals;
-    int default_ptsize;
-
 } PyFreeTypeFont;
 
 #define PyFreeTypeFont_AsFont(x) (((PyFreeTypeFont *)x)->font)