Commits

Anonymous committed 8df7b59

WIP support for faked styles in FT fonts

Comments (0)

Files changed (7)

examples/freetype/sdlfont.py

 
     screen = video.set_mode (640, 480)
     screen.fill (pygame2.Color (200, 200, 200))
-    w, h, _ = font.render("Hello", pygame2.Color(100, 100, 100), None, screen, 100, 100, ptsize=48)
+    w, h, _ = font.render("Hello", pygame2.Color(100, 100, 100), None, screen, 100, 100, ptsize=48, style=ftconstants.STYLE_BOLD)
 
     w, h, _ = font.render("World", pygame2.Color(200, 100, 100), pygame2.Color(255, 0xCC, 0), screen, 100, 200, ptsize=48, vertical = False, rotation = 0, antialias = True)
 
             "src/freetype/ft_render.c",
             "src/freetype/ft_metrics.c",
             "src/freetype/ft_text.c",
+            "src/freetype/ft_style.c"
         ],
         instheaders = ["src/freetype/pgfreetype.h"],
         docfile = "freetypebase.xml",

src/freetype/ft_font.c

     /* keyword list */
     static char *kwlist[] = 
     { 
-        "text", "vertical", "rotation", "ptsize", NULL
+        "text", "style", "vertical", "rotation", "ptsize", NULL
     };
 
     PyFreeTypeFont *font = (PyFreeTypeFont *)self;
     FontRenderMode render;
     int vertical = 0;
     int rotation = 0;
+    int style = FT_STYLE_NORMAL;
 
     PyObject *vertical_obj = NULL;
 
     FreeTypeInstance *ft;
     ASSERT_GRAB_FREETYPE(ft, NULL);
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oii", kwlist, 
-                &text, &vertical_obj, &rotation, &ptsize))
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iOii", kwlist, 
+                &text, &style, &vertical_obj, &rotation, &ptsize))
         return NULL;
 
     PGFT_CHECK_PTSIZE();
     PGFT_CHECK_BOOL(vertical_obj, vertical);
 
-    PGFT_BuildRenderMode(&render, vertical, FONT_RENDER_ANTIALIAS, rotation);
+    PGFT_BuildRenderMode(&render, style, vertical, FONT_RENDER_ANTIALIAS, rotation);
 
     error = PGFT_GetTextSize(ft, (PyFreeTypeFont *)self, ptsize, &render,
             text, &width, &height);
     static char *kwlist[] = 
     { 
         "text", "fgcolor", "bgcolor", "dstsurface", 
-        "xpos", "ypos", "vertical", "rotation", "antialias", "ptsize", NULL
+        "xpos", "ypos", "style", "vertical", "rotation", "antialias", "ptsize", NULL
     };
 
     PyFreeTypeFont *font = (PyFreeTypeFont *)self;
     PyObject *antialias_obj = NULL;
     int rotation = 0;
     int xpos = 0, ypos = 0;
+    int style = FT_STYLE_NORMAL;
 
     /* output arguments */
     PyObject *rtuple = NULL;
     FreeTypeInstance *ft;
     ASSERT_GRAB_FREETYPE(ft, NULL);
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOiiOiOi", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOiiiOiOi", kwlist,
                 &text, &fg_color, &bg_color, &target_surf, &xpos, &ypos, 
-                &vertical_obj, &rotation, &antialias_obj, &ptsize))
+                &style, &vertical_obj, &rotation, &antialias_obj, &ptsize))
         return NULL;
 
     PGFT_CHECK_PTSIZE();
     PGFT_CHECK_BOOL(antialias_obj, antialias);
 
     /* TODO: handle antialiasing */
-    PGFT_BuildRenderMode(&render, vertical, antialias, rotation);
+    PGFT_BuildRenderMode(&render, style, vertical, antialias, rotation);
 
     if (!target_surf || target_surf == Py_None)
     {

src/freetype/ft_render.c

 void __render_glyph_ByteArray(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 
 void 
-PGFT_BuildRenderMode(FontRenderMode *mode, int vertical, int antialias, int rotation)
+PGFT_BuildRenderMode(FontRenderMode *mode, int style, int vertical, int antialias, int rotation)
 {
     double      radian;
     FT_Fixed    cosinus;
     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;
     FontRenderMode render;
     int array_size;
 
-    PGFT_BuildRenderMode(&render, 
+    /* TODO: pixel arrays must also take custom rendering styles */
+    PGFT_BuildRenderMode(&render, FT_STYLE_NORMAL,
             FONT_RENDER_HORIZONTAL, FONT_RENDER_ANTIALIAS, 0);
 
     /* build font text */

src/freetype/ft_style.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
+#include FT_OUTLINE_H 
+ 
+#define BOLD_FACTOR     0.08
+#define SLANT_FACTOR    0.22
+
+int
+PGFT_Style_MakeBold(FT_Face face)
+{
+    FT_GlyphSlot    slot = face->glyph;
+    FT_Pos          xstr, ystr;
+    FT_Error        error;
+
+    xstr = FT_MulFix(face->units_per_EM,
+            face->size->metrics.y_scale);
+    xstr = (FT_Fixed)(xstr * BOLD_FACTOR);
+    ystr = xstr;
+
+    if (slot->format == FT_GLYPH_FORMAT_OUTLINE)
+    {
+        FT_Outline_Embolden(&slot->outline, xstr);
+        xstr = xstr * 2;
+        ystr = xstr;
+    }
+    else if (slot->format == FT_GLYPH_FORMAT_BITMAP)
+    {
+        FT_Library    library = slot->library;
+
+        xstr &= ~63;
+        ystr &= ~63;
+
+        error = FT_GlyphSlot_Own_Bitmap(slot);
+        if (error)
+            return error;
+
+        error = FT_Bitmap_Embolden(library, &slot->bitmap, xstr, ystr);
+        if (error)
+            return error;
+    }
+
+    if (slot->advance.x)
+        slot->advance.x += xstr;
+
+    if (slot->advance.y)
+        slot->advance.y += ystr;
+
+    slot->metrics.width        += xstr;
+    slot->metrics.height       += ystr;
+    slot->metrics.horiBearingY += ystr;
+    slot->metrics.horiAdvance  += xstr;
+    slot->metrics.vertBearingX -= xstr / 2;
+    slot->metrics.vertBearingY += ystr;
+    slot->metrics.vertAdvance  += ystr;
+    return 0;
+}

src/freetype/ft_text.c

         {
             FT_Glyph_Metrics *metrics = &face->glyph->metrics;
 
+            if (render->style & FT_STYLE_BOLD)
+            {
+                PGFT_Style_MakeBold(face);
+            }
+
             /* note that in vertical layout, y-positive goes downwards */
             glyph->vvector.x  = metrics->vertBearingX - metrics->horiBearingX;
             glyph->vvector.y  = -metrics->vertBearingY - metrics->horiBearingY;

src/freetype/ft_wrap.h

     FT_Byte     antialias;
     FT_Byte     kerning_mode;
     FT_Byte     autohint;
+    FT_Byte     style;
 } FontRenderMode;
 
 typedef struct  FontGlyph_
                 PySDLSurface *_surface, int x, int y, PyColor *fgcolor, PyColor *bgcolor,
                 int *_width, int *_height);
 
-void        PGFT_BuildRenderMode(FontRenderMode *mode, int vertical, 
+void        PGFT_BuildRenderMode(FontRenderMode *mode, int style, int vertical, 
                 int antialias, int rotation);
 
 int         _PGFT_Render_INTERNAL(FreeTypeInstance *ft, PyFreeTypeFont *font, 
                 FontSurface *surface, FontRenderMode *render);
 
 
+/******************************************************************* Fake styles ****/
+int PGFT_Style_MakeBold(FT_Face face);
+
 
 /******************************************************** Font text management ****/
 FontText *  PGFT_LoadFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, int pt_size,