Commits

Lenard Lindstrom  committed 64e5028

freetype: more features for compatibility with font.Font. To fix: freetype.Font crashes under Python 3.2 when reading an open python file

  • Participants
  • Parent commits fb61189

Comments (0)

Files changed (8)

File docs/reST/ref/freetype.rst

       calculations unless overriden specifically in the \`render()` or
       \`get_size()` calls, via the 'style' parameter.
 
+   .. attribute:: wide
+
+      | :sl:`Gets or sets the font's wide style`
+      | :sg:`wide -> bool`
+
+      Gets or sets whether the font will be stretched horizontally
+      when drawing text. It produces a result simular to font.Font's
+      bold. This style is only available for unrotated text.
+
    .. attribute:: fixed_width
 
       | :sl:`Gets whether the font is fixed-width`

File docs/ref/freetype.html

 <td>—</td>
 <td>Gets or sets the font&#8217;s oblique style</td>
 </tr>
+<tr><td><a class="toc reference external" href="freetype.html#pygame.freetype.Font.wide">pygame.freetype.Font.wide</a></td>
+<td>—</td>
+<td>Gets or sets the font&#8217;s wide style</td>
+</tr>
 <tr><td><a class="toc reference external" href="freetype.html#pygame.freetype.Font.fixed_width">pygame.freetype.Font.fixed_width</a></td>
 <td>—</td>
 <td>Gets whether the font is fixed-width</td>
 </dd></dl>
 
 <dl class="definition attribute">
+<dt class="title" id="pygame.freetype.Font.wide">
+<tt class="descname">wide</tt><a class="headerlink" href="#pygame.freetype.Font.wide" title="Permalink to this definition">¶</a></dt>
+<dd><div class="line-block">
+<div class="line"><span class="summaryline">Gets or sets the font&#8217;s wide style</span></div>
+<div class="line"><span class="signature">wide -&gt; bool</span></div>
+</div>
+<p>Gets or sets whether the font will be stretched horizontally
+when drawing text. It produces a result simular to font.Font&#8217;s
+bold. This style is only available for unrotated text.</p>
+</dd></dl>
+
+<dl class="definition attribute">
 <dt class="title" id="pygame.freetype.Font.fixed_width">
 <tt class="descname">fixed_width</tt><a class="headerlink" href="#pygame.freetype.Font.fixed_width" title="Permalink to this definition">¶</a></dt>
 <dd><div class="line-block">

File src/doc/freetype_doc.h

 
 #define DOC_FONTOBLIQUE "oblique -> bool\nGets or sets the font's oblique style"
 
+#define DOC_FONTWIDE "wide -> bool\nGets or sets the font's wide style"
+
 #define DOC_FONTFIXEDWIDTH "fixed_width -> bool\nGets whether the font is fixed-width"
 
 #define DOC_FONTANTIALIASED "antialiased -> bool\nFont antialiasing mode"
  oblique -> bool
 Gets or sets the font's oblique style
 
+pygame.freetype.Font.wide
+ wide -> bool
+Gets or sets the font's wide style
+
 pygame.freetype.Font.fixed_width
  fixed_width -> bool
 Gets whether the font is fixed-width

File src/freetype.c

         (void *)FT_STYLE_UNDERSCORE
     },
     {
+        "wide",
+        _ftfont_getstyle_flag,
+        _ftfont_setstyle_flag,
+        DOC_FONTWIDE,
+        (void *)FT_STYLE_WIDE
+    },
+    {
         "ucs4",
         _ftfont_getucs4,
         _ftfont_setucs4,
     DEC_CONST(STYLE_OBLIQUE);
     DEC_CONST(STYLE_UNDERLINE);
     DEC_CONST(STYLE_UNDERSCORE);
+    DEC_CONST(STYLE_WIDE);
 
     DEC_CONST(BBOX_EXACT);
     DEC_CONST(BBOX_EXACT_GRIDFIT);

File src/freetype.h

 #define FT_STYLE_OBLIQUE    0x02
 #define FT_STYLE_UNDERLINE  0x04
 #define FT_STYLE_UNDERSCORE 0x08
+#define FT_STYLE_WIDE       0x10
 #define FT_STYLE_DEFAULT    0xFF
 
 /* Bounding box modes */

File src/freetype/ft_render.c

         FT_STYLE_BOLD   |
         FT_STYLE_OBLIQUE |
         FT_STYLE_UNDERLINE |
-        FT_STYLE_UNDERSCORE;
+        FT_STYLE_UNDERSCORE |
+        FT_STYLE_WIDE;
 
     return (style > max_style);
 }
         mode->render_flags |= FT_RFLAG_TRANSFORM;
     mode->transform = font->transform;
 
+    if (mode->rotation_angle != 0)
+    {
+        if (mode->style & FT_STYLE_WIDE)
+        {
+            RAISE(PyExc_ValueError,
+                  "the wide style is unsupported for rotated text");
+            return -1;
+        }
+        if (mode->style & FT_STYLE_UNDERLINE)
+        {
+            RAISE(PyExc_ValueError,
+                  "the underline style is unsupported for rotated text");
+            return -1;
+        }
+        if (mode->style & FT_STYLE_UNDERSCORE)
+        {
+            RAISE(PyExc_ValueError,
+                  "the underscore style is unsupported for rotated text");
+            return -1;
+        }
+        if (mode->render_flags & FT_RFLAG_PAD) 
+        {
+            RAISE(PyExc_ValueError,
+                  "padding is unsupported for rotated text");
+            return -1;
+        }
+    }
+
+    if (mode->render_flags & FT_RFLAG_VERTICAL)
+    {
+        if (mode->style & FT_STYLE_UNDERLINE)
+        {
+            RAISE(PyExc_ValueError,
+                  "the underline style is unsupported for vertical text");
+            return -1;
+        }
+        if (mode->style & FT_STYLE_UNDERSCORE)
+        {
+            RAISE(PyExc_ValueError,
+                  "the underscore style is unsupported for vertical text");
+            return -1;
+        }
+    }
+
     return 0;
 }
 

File src/freetype/ft_text.c

 #define FX6_ONE 64
 #define FX16_ONE 65536
 
+/* Multiply the face's x ppem by this factor to get the x strength
+ * factor in 16.16 Fixed.
+ */
+#define FX16_WIDE_FACTOR (FX16_ONE / 12)
+
 #define SLANT_FACTOR    0.22
 static FT_Matrix PGFT_SlantMatrix = 
 {
     FT_Matrix transform;
 } FontTextContext;
 
+#if 0
 #define BOLD_STRENGTH_D (0.65)
 #define PIXEL_SIZE ((FT_Fixed)64)
 #define BOLD_STRENGTH ((FT_Fixed)(BOLD_STRENGTH_D * PIXEL_SIZE))
 #define BOLD_ADVANCE (BOLD_STRENGTH * (FT_Fixed)4)
+#endif
+#define FX16_BOLD_FACTOR (FX16_ONE / 36)
 #define UNICODE_SPACE ((PGFT_char)' ')
 
 static FT_UInt32 GetLoadFlags(const FontRenderMode *);
     FT_Pos      text_width;
     FT_Pos      text_height;
     FT_Pos      top = PGFT_MIN_6;
-    FT_Fixed    bold_str = render->style & FT_STYLE_BOLD ? BOLD_STRENGTH : 0;
 
     FT_Error    error = 0;
 
         ++next_pos;
     }
 
-    if (pad && rotation_angle == 0)
+    if (pad)
     {
         FT_Size_Metrics *sz_metrics = &face->size->metrics;
 
                 min_y = -ascender;
             if (max_y <= -descender)
                 max_y = -descender + /* underscore allowance */ FX6_ONE;
-            else
-            {
-                ftext->descender = -max_y;
-                max_y += FX6_ONE;
-            }
+            /* else */
+            /* { */
+            /*     ftext->descender = -max_y + /\* underscore allowance *\/ FX6_ONE; */
+            /*     max_y += FX6_ONE; */
+            /* } */
         }
     }
-    else if (render->style & FT_STYLE_UNDERSCORE && !vertical &&
-             rotation_angle == 0)
+    else if (render->style & FT_STYLE_UNDERSCORE)
     {
         if (-ftext->descender >= max_y)
             max_y = -ftext->descender + /* underscore allowance */ FX6_ONE;
-        else
-            ftext->descender = -max_y;
+        /* else */
+        /*     ftext->descender = -max_y + /\* underscore allowance *\/ FX6_ONE; */
     }
 
-    if (render->style & FT_STYLE_UNDERLINE && !vertical && rotation_angle == 0)
+    if (render->style & FT_STYLE_UNDERLINE)
     {
         FT_Fixed scale = face->size->metrics.y_scale;
         FT_Fixed underline_pos;
         FT_Fixed underline_size;
         FT_Fixed max_y_underline;
-        
+
         underline_pos = -FT_MulFix(face->underline_position, scale) / 4; /*(1)*/
-        underline_size = FT_MulFix(face->underline_thickness, scale) + bold_str;
+        underline_size = FT_MulFix(face->underline_thickness, scale);
         max_y_underline = underline_pos + underline_size / 2;
         if (max_y_underline > max_y)
         {
 {
     static FT_Vector delta = {0, 0};
 
-    int embolden = render->style & FT_STYLE_BOLD;
     FT_Render_Mode rmode = (render->render_flags & FT_RFLAG_ANTIALIAS ?
                             FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
-    FT_Fixed bold_str = 0;
     FT_Vector bold_delta = {0, 0};
     FT_Glyph image = NULL;
 
     /*
      * Perform any outline transformations
      */
-    if (embolden)
+    if (render->style & FT_STYLE_BOLD)
     {
+        FT_UShort x_ppem = context->face->size->metrics.x_ppem;
+        FT_Fixed bold_str;
         FT_BBox before;
         FT_BBox after;
 
-        bold_str = BOLD_STRENGTH;
+        bold_str = PGFT_CEIL16_TO_6(FX16_BOLD_FACTOR * x_ppem);
         FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &before);
         if (FT_Outline_Embolden(&((FT_OutlineGlyph)image)->outline, bold_str))
             goto cleanup;
         goto cleanup;
     }
 
-    /* if (wide) */
-    /* { */
-    /*     int w = ((FT_BitmapGlyph)image)->bitmap.width; */
+    if (render->style & FT_STYLE_WIDE)
+    {
+        FT_Bitmap *bitmap = &((FT_BitmapGlyph)image)->bitmap;
+        int w = bitmap->width;
+        FT_UShort x_ppem = context->face->size->metrics.x_ppem;
+        FT_Pos x_strength;
+        
+        x_strength = PGFT_CEIL16_TO_6(x_ppem * FX16_WIDE_FACTOR);
 
-    /*     if (w) */
-    /*     { */
-    /*         error = FT_Bitmap_Embolden(context->lib, */
-    /*                                    &((FT_BitmapGlyph)image)->bitmap, */
-    /*                                    (FT_Pos)0x80, (FT_Pos)0); */
-    /*         if (error) */
-    /*         { */
-    /*             goto cleanup; */
-    /*         } */
-    /*         bold_delta.x += PGFT_INT_TO_6(((FT_BitmapGlyph)image)->bitmap.width */
-    /*                                       - w); */
-    /*     } */
-    /*     else */
-    /*     { */
-    /*         bold_delta.x += BOLD_ADVANCE; */
-    /*     } */
-    /* } */
+        /* FT_Bitmap_Embolden returns an error for a zero width bitmap */
+        if (w > 0)
+        {
+            error = FT_Bitmap_Embolden(context->lib, bitmap,
+                                       x_strength, (FT_Pos)0);
+            if (error)
+            {
+                goto cleanup;
+            }
+            bold_delta.x += PGFT_INT_TO_6(bitmap->width - w);
+        }
+        else
+        {
+            bold_delta.x += x_strength;
+        }
+    }
 
     /* Fill the glyph */
     ft_metrics = &context->face->glyph->metrics;
     glyph->image = (FT_BitmapGlyph)image;
     glyph->width = PGFT_INT_TO_6(glyph->image->bitmap.width);
     glyph->height = PGFT_INT_TO_6(glyph->image->bitmap.rows);
-    glyph->bold_strength = bold_str;
     h_bearing_rotated.x = PGFT_INT_TO_6(glyph->image->left);
     h_bearing_rotated.y = PGFT_INT_TO_6(glyph->image->top);
     fill_metrics(&glyph->h_metrics,

File src/freetype/ft_wrap.h

 
     FT_Pos      width;         /* 26.6 */
     FT_Pos      height;        /* 26.6 */
-    FT_Pos      bold_strength; /* 26.6 */
     FontMetrics h_metrics;
     FontMetrics v_metrics;
 } FontGlyph;