Commits

tanoku  committed d081b5a

Text rotation & vertical drawing on FT fonts mostly working.

  • Participants
  • Parent commits eb45fec
  • Branches pgreloaded

Comments (0)

Files changed (2)

File src/freetype/ft_wrap.c

 #define UNICODE_BOM_NATIVE	0xFEFF
 #define UNICODE_BOM_SWAPPED	0xFFFE
 
+#define FONT_RENDER_HORIZONTAL  0
+#define FONT_RENDER_VERTICAL    1
+
 #define MAX_GLYPHS      64
 
 typedef struct __fontsurface
     FontText *text, int font_size, PyColor *fg_color, FontSurface *surface, 
     FontRenderMode *render);
 
+
+void _PGFT_BuildRenderMode(FontRenderMode *mode, float center, int vertical, int hinted, int rotation);
+
 /* blitters */
 void __render_glyph_SDL8(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 void __render_glyph_SDL16(int x, int y, FontSurface *surface, FT_Bitmap *bitmap, PyColor *color);
 }
 
 FontText *
-PGFT_BuildFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, PyObject *text, int pt_size)
+PGFT_BuildFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, PyObject *text, int pt_size, FontRenderMode *render)
 {
     /*
      * TODO:
      * - return existing ones if available
      */
 
-    const FT_UInt32 load_flags = FT_LOAD_RENDER; /* TODO */
+    FT_Int32 load_flags = FT_LOAD_DEFAULT; 
 
     int         must_free;
     int         swapped = 0;
 
     FT_Face     face;
 
+    /* compute proper load flags */
+    load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
+
+    if (render->autohint)
+        load_flags |= FT_LOAD_FORCE_AUTOHINT;
+
+    if (render->hinted)
+    {
+        load_flags |=   render->antialias ?
+                        FT_LOAD_TARGET_NORMAL :
+                        FT_LOAD_TARGET_MONO;
+    }
+    else
+    {
+        load_flags |= FT_LOAD_NO_HINTING;
+    }
+
     /* load our sized face */
     face = _PGFT_GetFaceSized(ft, font, pt_size);
 
             (FTC_FaceID)(&font->id),
             -1, (FT_UInt32)c);
 
+        /* FIXME: leaks memory, needs to use the cache */
         if (!FT_Load_Glyph(face, glyph->glyph_index, load_flags)  &&
             !FT_Get_Glyph(face->glyph, &glyph->image))
         {
                 {
                     FT_Vector  kern;
 
-
                     FT_Get_Kerning(face, prev_index, glyph->glyph_index,
                             FT_KERNING_UNFITTED, &kern);
 
     i = text->length - 1;
     advances[i] = extent;
 
+    fprintf(stderr, "Text size: %dx%d\n", PGFT_TRUNC(extent.x), PGFT_TRUNC(extent.y));
+
     return 0;
 }
 
     scale->x_res = scale->y_res = 0;
 }
 
+void 
+_PGFT_BuildRenderMode(FontRenderMode *mode, float center, int vertical, int antialias, int rotation)
+{
+    double      radian;
+    FT_Fixed    cosinus;
+    FT_Fixed    sinus;
+    int         angle;
+
+    angle = rotation % 360;
+    while (angle < 0) angle += 360;
+
+    mode->kerning_mode = 1;
+    mode->kerning_degree = 0;
+    mode->center = (FT_Fixed)(center * (1 << 16));
+    mode->vertical = (FT_Byte)vertical;
+    mode->hinted = (FT_Byte)1;
+    mode->autohint = 0;
+    mode->antialias = (FT_Byte)antialias;
+    mode->matrix = NULL;
+
+    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->matrix = &mode->_rotation_matrix;
+    }
+}
+
 FT_Face
 _PGFT_GetFaceSized(FreeTypeInstance *ft,
     PyFreeTypeFont *font,
 int
 _PGFT_LoadGlyph(FreeTypeInstance *ft, 
     PyFreeTypeFont *font,
-    int do_render,
+    int load_flags,
     FTC_Scaler scale, 
     int character, 
     FT_Glyph *glyph, 
     FT_Error error = 0;
     FT_UInt32 char_index;
 
-    FT_ULong render_mode = do_render ? 
-        (FT_ULong)FT_LOAD_RENDER : 
-        (FT_ULong)FT_LOAD_DEFAULT;
-
     char_index = FTC_CMapCache_Lookup(
         ft->cache_charmap, 
             (FTC_FaceID)(&font->id),
         error = FTC_ImageCache_LookupScaler(
             ft->cache_img,
                 scale,
-                render_mode,
+                load_flags,
                 char_index,
                 glyph, NULL);
     }
         locked = 1;
     }
 
-    font_text = PGFT_BuildFontText(ft, font, text, font_size);
+    /*
+     * Setup render mode
+     * TODO: get render mode from FT instance
+     */
+    _PGFT_BuildRenderMode(&render_mode, 0.0f, FONT_RENDER_HORIZONTAL, 1, 45);
+
+    /* build font text */
+    font_text = PGFT_BuildFontText(ft, font, text, font_size, &render_mode);
 
     if (!font_text)
     {
     }
 
     /*
-     * Setup render mode
-     * TODO: get render mode from FT instance
-     */
-    render_mode.kerning_mode = 0;
-    render_mode.center = 0; //(1L << 15); /* FIXME: Center by default? */
-    render_mode.vertical = 0;
-    render_mode.matrix = NULL;
-    render_mode.hinted = 1;
-
-    /*
      * Setup target surface struct
      */
     font_surf.buffer = surface->pixels;
             FT_Bitmap*  source;
             FT_BitmapGlyph  bitmap;
 
-            assert(image->format == FT_GLYPH_FORMAT_BITMAP);
+            if (image->format == FT_GLYPH_FORMAT_OUTLINE)
+            {
+                FT_Render_Mode render_mode = 
+                    render->antialias ?
+                    FT_RENDER_MODE_NORMAL :
+                    FT_RENDER_MODE_MONO;
+
+                /* render the glyph to a bitmap, don't destroy original */
+                error = FT_Glyph_To_Bitmap(&image, render_mode, NULL, 0);
+                if (error)
+                    return error;
+            }
+
+            if (image->format != FT_GLYPH_FORMAT_BITMAP)
+                fprintf(stderr, "Format is not bitmap!\n");
 
             bitmap = (FT_BitmapGlyph)image;
             source = &bitmap->bitmap;

File src/freetype/ft_wrap.h

 
 typedef struct __rendermode
 {
-    int         kerning_mode;
     int         kerning_degree;
     FT_Fixed    center;            /* 0..1 */
-    int         vertical;          /* displayed vertically? */
     FT_Matrix*  matrix;            /* string transformation */
-    int         hinted;
+
+    FT_Matrix   _rotation_matrix;
+
+    FT_Byte     hinted;
+    FT_Byte     vertical;
+    FT_Byte     antialias;
+    FT_Byte     kerning_mode;
+    FT_Byte     autohint;
 } FontRenderMode;
 
 typedef struct  FontGlyph_
     int *_width, int *_height, int x, int y, PyColor *py_fgcolor);
 
 FontText *PGFT_BuildFontText(FreeTypeInstance *ft, PyFreeTypeFont *font, 
-    PyObject *text, int pt_size);
+    PyObject *text, int pt_sizem, FontRenderMode *mode);
 
 
 #endif