Commits

Lenard Lindstrom  committed 1d7d6b8

freetype: Some identifier refactoring. The strength of the strong and wide styles is now adjustable

  • Participants
  • Parent commits 6425e68

Comments (0)

Files changed (11)

File docs/reST/ref/freetype.rst

       when drawing text. It produces a result simular to font.Font's
       bold. This style is only available for unrotated text.
 
+   .. attribute:: strength
+
+      | :sl:`Gets or sets the strength of the strong or wide styles`
+      | :sg:`strength -> float`
+
+      The amount by which a face glyph's size is enlarged for the
+      strong or wide transformations, as a fraction of the untransformed
+      size. For the wide style only the horizontal dimension is
+      increased. For strong text both the horizontal and vertical
+      dimensions are enlarged. A wide style of strength 1/12 is
+      equivalent to the font.Font bold style. The default is 1/36.
+
    .. attribute:: fixed_width
 
       | :sl:`Gets whether the face is fixed-width`

File docs/ref/freetype.html

 <td>—</td>
 <td>Gets or sets the face&#8217;s wide style</td>
 </tr>
+<tr><td><a class="toc reference external" href="freetype.html#pygame.freetype.Face.strength">pygame.freetype.Face.strength</a></td>
+<td>—</td>
+<td>Gets or sets the strength of the strong or wide styles</td>
+</tr>
 <tr><td><a class="toc reference external" href="freetype.html#pygame.freetype.Face.fixed_width">pygame.freetype.Face.fixed_width</a></td>
 <td>—</td>
 <td>Gets whether the face is fixed-width</td>
 </dd></dl>
 
 <dl class="definition attribute">
+<dt class="title" id="pygame.freetype.Face.strength">
+<tt class="descname">strength</tt><a class="headerlink" href="#pygame.freetype.Face.strength" title="Permalink to this definition">¶</a></dt>
+<dd><div class="line-block">
+<div class="line"><span class="summaryline">Gets or sets the strength of the strong or wide styles</span></div>
+<div class="line"><span class="signature">strength -&gt; float</span></div>
+</div>
+<p>The amount by which a face glyph&#8217;s size is enlarged for the
+strong or wide transformations, as a fraction of the untransformed
+size. For the wide style only the horizontal dimension is
+increased. For strong text both the horizontal and vertical
+dimensions are enlarged. A wide style of strength 1/12 is
+equivalent to the font.Font bold style. The default is 1/36.</p>
+</dd></dl>
+
+<dl class="definition attribute">
 <dt class="title" id="pygame.freetype.Face.fixed_width">
 <tt class="descname">fixed_width</tt><a class="headerlink" href="#pygame.freetype.Face.fixed_width" title="Permalink to this definition">¶</a></dt>
 <dd><div class="line-block">

File examples/freetype_misc.py

             ptsize=148)
 
     face.render((screen, 380, 380), "...yes, this is an SDL surface", pygame.Color(0, 0, 0), None,
-            ptsize=24, style=freetype.STYLE_BOLD)
+            ptsize=24, style=freetype.STYLE_STRONG)
 
     pygame.display.flip()
 

File src/doc/freetype_doc.h

 
 #define DOC_FACEWIDE "wide -> bool\nGets or sets the face's wide style"
 
+#define DOC_FACESTRENGTH "strength -> float\nGets or sets the strength of the strong or wide styles"
+
 #define DOC_FACEFIXEDWIDTH "fixed_width -> bool\nGets whether the face is fixed-width"
 
 #define DOC_FACEANTIALIASED "antialiased -> bool\nFace antialiasing mode"
  wide -> bool
 Gets or sets the face's wide style
 
+pygame.freetype.Face.strength
+ strength -> float
+Gets or sets the strength of the strong or wide styles
+
 pygame.freetype.Face.fixed_width
  fixed_width -> bool
 Gets whether the face is fixed-width

File src/freetype.c

 static PyObject *_ftface_getname(PyObject *, void *);
 static PyObject *_ftface_getpath(PyObject *, void *);
 static PyObject *_ftface_getfixedwidth(PyObject *, void *);
+static PyObject *_ftface_getstrength(PgFaceObject *, void *);
+static int _ftface_setstrength(PgFaceObject *, PyObject *, void *);
 
 static PyObject *_ftface_getvertical(PyObject *, void *);
 static int _ftface_setvertical(PyObject *, PyObject *, void *);
 static PyGetSetDef _ftface_getsets[] = {
     {
         "style",
-        _ftface_getstyle,
-        _ftface_setstyle,
+        (getter)_ftface_getstyle,
+        (setter)_ftface_setstyle,
         DOC_FACESTYLE,
         0
     },
     {
         "height",
-        _ftface_getheight,
+        (getter)_ftface_getheight,
         0,
         DOC_FACEHEIGHT,
         0
     },
     {
         "ascender",
-        _ftface_getascender,
+        (getter)_ftface_getascender,
         0,
         DOC_FACEASCENDER,
         0
     },
     {
         "descender",
-        _ftface_getdescender,
+        (getter)_ftface_getdescender,
         0,
         DOC_FACEASCENDER,
         0
     },
     {
         "name",
-        _ftface_getname,
+        (getter)_ftface_getname,
         0,
         DOC_FACENAME,
         0
     },
     {
         "path",
-        _ftface_getpath,
+        (getter)_ftface_getpath,
         0,
         DOC_FACEPATH,
         0
     },
     {
         "fixed_width",
-        _ftface_getfixedwidth,
+        (getter)_ftface_getfixedwidth,
         0,
         DOC_FACEFIXEDWIDTH,
         0
     },
     {
         "antialiased",
-        _ftface_getantialias,
-        _ftface_setantialias,
+        (getter)_ftface_getantialias,
+        (setter)_ftface_setantialias,
         DOC_FACEANTIALIASED,
         0
     },
     {
         "kerning",
-        _ftface_getkerning,
-        _ftface_setkerning,
+        (getter)_ftface_getkerning,
+        (setter)_ftface_setkerning,
         DOC_FACEKERNING,
         0
     },
     {
         "vertical",
-        _ftface_getvertical,
-        _ftface_setvertical,
+        (getter)_ftface_getvertical,
+        (setter)_ftface_setvertical,
         DOC_FACEVERTICAL,
         0
     },
     {
         "pad",
-        _ftface_getpad,
-        _ftface_setpad,
+        (getter)_ftface_getpad,
+        (setter)_ftface_setpad,
         DOC_FACEPAD,
         0
     },
     {
         "oblique",
-        _ftface_getstyle_flag,
-        _ftface_setstyle_flag,
+        (getter)_ftface_getstyle_flag,
+        (setter)_ftface_setstyle_flag,
         DOC_FACEOBLIQUE,
         (void *)FT_STYLE_OBLIQUE
     },
     {
         "strong",
-        _ftface_getstyle_flag,
-        _ftface_setstyle_flag,
+        (getter)_ftface_getstyle_flag,
+        (setter)_ftface_setstyle_flag,
         DOC_FACESTRONG,
         (void *)FT_STYLE_STRONG
     },
     {
         "underline",
-        _ftface_getstyle_flag,
-        _ftface_setstyle_flag,
+        (getter)_ftface_getstyle_flag,
+        (setter)_ftface_setstyle_flag,
         DOC_FACEUNDERLINE,
         (void *)FT_STYLE_UNDERLINE
     },
     {
         "underscore",
-        _ftface_getstyle_flag,
-        _ftface_setstyle_flag,
+        (getter)_ftface_getstyle_flag,
+        (setter)_ftface_setstyle_flag,
         DOC_FACEUNDERSCORE,
         (void *)FT_STYLE_UNDERSCORE
     },
     {
         "wide",
-        _ftface_getstyle_flag,
-        _ftface_setstyle_flag,
+        (getter)_ftface_getstyle_flag,
+        (setter)_ftface_setstyle_flag,
         DOC_FACEWIDE,
         (void *)FT_STYLE_WIDE
     },
     {
+        "strength",
+        (getter)_ftface_getstrength,
+        (setter)_ftface_setstrength,
+        DOC_FACESTRENGTH,
+        0
+    },
+    {
         "ucs4",
-        _ftface_getucs4,
-        _ftface_setucs4,
+        (getter)_ftface_getucs4,
+        (setter)_ftface_setucs4,
         DOC_FACEUCS4,
         0
     },
     {
         "resolution",
-        _ftface_getresolution,
+        (getter)_ftface_getresolution,
         0,
         DOC_FACERESOLUTION,
         0
     },
     {
         "origin",
-        _ftface_getorigin,
-        _ftface_setorigin,
+        (getter)_ftface_getorigin,
+        (setter)_ftface_setorigin,
         DOC_FACEORIGIN,
         0
     },
 #if defined(PGFT_DEBUG_CACHE)
     {
         "_debug_cache_stats",
-        _ftface_getdebugcachestats,
+        (getter)_ftface_getdebugcachestats,
         0,
         "_debug cache fields as a tuple",
         0
         obj->_internals = 0;
         obj->ptsize = -1;
         obj->style = FT_STYLE_NORMAL;
+        obj->strength = PGFT_DBL_DEFAULT_STRENGTH;
         obj->vertical = 0;
         obj->antialias = 1;
         obj->kerning = 0;
     return fixed_width >= 0 ? PyBool_FromLong(fixed_width) : 0;
 }
 
+static PyObject *
+_ftface_getstrength(PgFaceObject *self, void *closure)
+{
+    return PyFloat_FromDouble(self->strength);
+}
+
+static int
+_ftface_setstrength(PgFaceObject *self, PyObject *value, void *closure)
+{
+    PyObject *strengthobj = PyNumber_Float(value);
+    double strength;
+
+    if (!strengthobj) {
+        return -1;
+    }
+    strength = PyFloat_AS_DOUBLE(strengthobj);
+    Py_DECREF(strengthobj);
+    if (strength < 0.0 || strength > 1.0) {
+        char msg[80];
+
+        sprintf(msg, "strength value %.4e is outside range [0, 1]", strength);
+        PyErr_SetString(PyExc_ValueError, msg);
+        return -1;
+    }
+    self->strength = strength;
+    return 0;
+}
+
 
 /** ucs4 unicode text handling attribute */
 static PyObject *
 static PyObject *
 _ftface_gettransform(PgFaceObject *self)
 {
-    const double scale_factor = 1.5259e-5; /* 1 / 65536.0 */
-
     if (!self->do_transform) {
         Py_RETURN_NONE;
     }
     return Py_BuildValue("dddd",
-                         self->transform.xx * scale_factor,
-                         self->transform.xy * scale_factor,
-                         self->transform.yx * scale_factor,
-                         self->transform.yy * scale_factor);
+                         FX16_TO_DBL(self->transform.xx),
+                         FX16_TO_DBL(self->transform.xy),
+                         FX16_TO_DBL(self->transform.yx),
+                         FX16_TO_DBL(self->transform.yy));
 }
 
 static PyObject *
 _ftface_settransform(PgFaceObject *self, PyObject *args)
 {
-    const double scale_factor = 65536.0;
     double xx;
     double xy;
     double yx;
                         "received a value outside range [-2.0,2.0]");
         return 0;
     }
-    self->transform.xx = (FT_Fixed)(xx * scale_factor);
-    self->transform.xy = (FT_Fixed)(xy * scale_factor);
-    self->transform.yx = (FT_Fixed)(yx * scale_factor);
-    self->transform.yy = (FT_Fixed)(yy * scale_factor);
+    self->transform.xx = FX16_TO_DBL(xx);
+    self->transform.xy = FX16_TO_DBL(xy);
+    self->transform.yx = FX16_TO_DBL(yx);
+    self->transform.yy = FX16_TO_DBL(yy);
     self->do_transform = 1;
     Py_RETURN_NONE;
 }

File src/freetype.h

 
     FT_Int16 ptsize;
     FT_Byte style;
+    double strength;
     FT_Byte vertical;
     FT_Byte antialias;
     FT_Byte kerning;

File src/freetype/ft_cache.c

 #include "ft_wrap.h"
 #include FT_MODULE_H
 
-/* The key is the UTF character, point size (unsigned short),
- * style flags (unsigned short), render flags (unsigned short),
- * and rotation (in whole degrees, unsigned short), transform.xx,
- * transform.xy, transform.yx, transform.yy. Byte order is little-endian.
- */
-#define MINKEYLEN (sizeof(PGFT_char) + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 4)
-#define KEYLEN ((MINKEYLEN + 3) & 0xFFFC)
+typedef struct keyfields_ {
+    PGFT_char ch;
+    unsigned short pt_size;
+    unsigned short style;
+    unsigned short render_flags;
+    unsigned short rotation;
+    FT_Fixed strength;
+    FT_Matrix transform;
+} KeyFields;
 
 typedef union cachenodekey_ {
-    FT_Byte bytes[KEYLEN];
-    FT_UInt32 dwords[KEYLEN / 4];
-} CacheNodeKey;
+    KeyFields fields;
+    FT_UInt32 dwords[(sizeof(KeyFields) + 3) / 4];
+} NodeKey;
 
 typedef struct cachenode_ {
     FaceGlyph glyph;
     struct cachenode_ *next;
-    CacheNodeKey key;
+    NodeKey key;
     FT_UInt32 hash;
 } CacheNode;
 
-static FT_UInt32 get_hash(const CacheNodeKey *);
+static FT_UInt32 get_hash(const NodeKey *);
 static CacheNode *allocate_node(FaceCache *,
                                     const FaceRenderMode *,
                                     FT_UInt, void *);
 static void free_node(FaceCache *, CacheNode *);
-static void set_node_key(CacheNodeKey *, PGFT_char, const FaceRenderMode *);
-static int equal_node_keys(const CacheNodeKey *, const CacheNodeKey *);
+static void set_node_key(NodeKey *, PGFT_char, const FaceRenderMode *);
+static int equal_node_keys(const NodeKey *, const NodeKey *);
 
 const int render_flags_mask = (FT_RFLAG_ANTIALIAS |
                                FT_RFLAG_HINTED |
                                FT_RFLAG_AUTOHINT);
 
 static void
-set_node_key(CacheNodeKey *key, PGFT_char ch, const FaceRenderMode *render)
+set_node_key(NodeKey *key, PGFT_char ch, const FaceRenderMode *mode)
 {
+    KeyFields *fields = &key->fields;
     const FT_UInt16 style_mask = ~(FT_STYLE_UNDERLINE);
     const FT_UInt16 rflag_mask = ~(FT_RFLAG_VERTICAL | FT_RFLAG_KERNING);
-    int i = 0;
-    unsigned short rot = (unsigned short)PGFT_TRUNC(render->rotation_angle);
+    unsigned short rot = (unsigned short)FX6_TRUNC(mode->rotation_angle);
 
-    key->dwords[sizeof(key->dwords) / 4 - 1] = 0;
-    key->bytes[i++] = (FT_Byte)ch;
-    ch >>= 8;
-    key->bytes[i++] = (FT_Byte)ch;
-    ch >>= 8;
-    key->bytes[i++] = (FT_Byte)ch;
-    ch >>= 8;
-    key->bytes[i++] = (FT_Byte)ch;
-    key->bytes[i++] = (FT_Byte)render->pt_size;
-    key->bytes[i++] = (FT_Byte)(render->pt_size >> 8);
-    key->bytes[i++] = (FT_Byte)(render->style & style_mask);
-    key->bytes[i++] = (FT_Byte)((render->style & style_mask) >> 8);
-    key->bytes[i++] = (FT_Byte)(render->render_flags & rflag_mask);
-    key->bytes[i++] = (FT_Byte)((render->render_flags & rflag_mask) >> 8);
-    key->bytes[i++] = (FT_Byte)rot;
-    key->bytes[i++] = (FT_Byte)(rot >> 8);
-    key->bytes[i++] = (FT_Byte)render->transform.xx;
-    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 8);
-    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 16);
-    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 24);
-    key->bytes[i++] = (FT_Byte)render->transform.xy;
-    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 8);
-    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 16);
-    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 24);
-    key->bytes[i++] = (FT_Byte)render->transform.yx;
-    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 8);
-    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 16);
-    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 24);
-    key->bytes[i++] = (FT_Byte)render->transform.yy;
-    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 8);
-    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 16);
-    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 24);
+    memset(key, 0, sizeof(key));
+    fields->ch = ch;
+    fields->pt_size = mode->pt_size;
+    fields->style = mode->style & style_mask;
+    fields->render_flags = mode->render_flags & rflag_mask;
+    fields->rotation = rot;
+    fields->strength = mode->strength;
+    fields->transform.xx = mode->transform.xx;
+    fields->transform.xy = mode->transform.xy;
+    fields->transform.yx = mode->transform.yx;
+    fields->transform.yy = mode->transform.yy;
 }
 
 static int
-equal_node_keys(const CacheNodeKey *a, const CacheNodeKey *b)
+equal_node_keys(const NodeKey *a, const NodeKey *b)
 {
     int i;
 
-    for (i = 0; i < sizeof(a->dwords) / 4; ++i) {
+    for (i = 0; i < sizeof(a->dwords) / sizeof(a->dwords[0]); ++i) {
         if (a->dwords[i] != b->dwords[i]) {
             return 0;
         }
 }
 
 static FT_UInt32
-get_hash(const CacheNodeKey *key)
+get_hash(const NodeKey *key)
 {
     /*
      * Based on the 32 bit x86 MurmurHash3, with the key size a multiple of 4.
 {
     CacheNode **nodes = cache->nodes;
     CacheNode *node, *prev;
-    CacheNodeKey key;
+    NodeKey key;
 
     FT_UInt32 hash;
     FT_UInt32 bucket;

File src/freetype/ft_render.c

 {
     const FT_UInt32 max_style =
         FT_STYLE_NORMAL |
-        FT_STYLE_STRONG   |
+        FT_STYLE_STRONG |
         FT_STYLE_OBLIQUE |
         FT_STYLE_UNDERLINE |
         FT_STYLE_UNDERSCORE |
 
         mode->style = (FT_Byte)style;
     }
+    mode->strength = DBL_TO_FX16(faceobj->strength);
 
     mode->render_flags = FT_RFLAG_DEFAULTS;
 
 
     angle = rotation % 360;
     while (angle < 0) angle += 360;
-    mode->rotation_angle = PGFT_INT_TO_16(angle);
+    mode->rotation_angle = INT_TO_FX16(angle);
 
     if (faceobj->do_transform) {
         mode->render_flags |= FT_RFLAG_TRANSFORM;
      * Setup target surface struct
      */
     font_surf.buffer = surface->pixels;
-    font_surf.offset.x = PGFT_INT_TO_6(x);
-    font_surf.offset.y = PGFT_INT_TO_6(y);
+    font_surf.offset.x = INT_TO_FX6(x);
+    font_surf.offset.y = INT_TO_FX6(y);
     if (faceobj->origin) {
-        x -= PGFT_TRUNC(PGFT_CEIL(font_text->offset.x));
-        y -= PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+        x -= FX6_TRUNC(FX6_CEIL(font_text->offset.x));
+        y -= FX6_TRUNC(FX6_CEIL(font_text->offset.y));
     }
     else {
         font_surf.offset.x += font_text->offset.x;
      */
     render(ft, font_text, mode, fgcolor, &font_surf);
 
-    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(font_text->offset.x));
-    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+    r->x = -(Sint16)FX6_TRUNC(FX6_FLOOR(font_text->offset.x));
+    r->y = (Sint16)FX6_TRUNC(FX6_CEIL(font_text->offset.y));
     r->w = (Uint16)width;
     r->h = (Uint16)height;
 
      */
     render(ft, font_text, mode, fgcolor, &font_surf);
 
-    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(font_text->offset.x));
-    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+    r->x = -(Sint16)FX6_TRUNC(FX6_FLOOR(font_text->offset.x));
+    r->y = (Sint16)FX6_TRUNC(FX6_CEIL(font_text->offset.y));
     r->w = (Uint16)width;
     r->h = (Uint16)height;
 
     top = surface->offset.y;
     for (n = 0; n < length; ++n) {
         image = glyphs[n]->image;
-        x = PGFT_TRUNC(PGFT_CEIL(left + posns[n].x));
-        y = PGFT_TRUNC(PGFT_CEIL(top + posns[n].y));
+        x = FX6_TRUNC(FX6_CEIL(left + posns[n].x));
+        y = FX6_TRUNC(FX6_CEIL(top + posns[n].y));
         if (image->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
             render_gray(x, y, surface, &(image->bitmap), fg_color);
         }
 
     if (mode->style & FT_STYLE_UNDERLINE) {
         surface->fill(
-            PGFT_TRUNC(PGFT_CEIL(left - text->offset.x)),
-            PGFT_TRUNC(PGFT_CEIL(top + text->underline_pos)),
-            text->width, PGFT_TRUNC(PGFT_CEIL(text->underline_size)),
+            FX6_TRUNC(FX6_CEIL(left - text->offset.x)),
+            FX6_TRUNC(FX6_CEIL(top + text->underline_pos)),
+            text->width, FX6_TRUNC(FX6_CEIL(text->underline_size)),
             surface, fg_color);
     }
 
     if (mode->style & FT_STYLE_UNDERSCORE) {
         surface->fill(
-            PGFT_TRUNC(PGFT_CEIL(left - text->offset.x)),
-            PGFT_TRUNC(PGFT_CEIL(top - text->descender)),
+            FX6_TRUNC(FX6_CEIL(left - text->offset.x)),
+            FX6_TRUNC(FX6_CEIL(top - text->descender)),
             text->width, 1, surface, fg_color);
     }
 }

File src/freetype/ft_text.c

 #include FT_BITMAP_H
 #include FT_CACHE_H
 
-#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.
  */
 
 FaceText *
 _PGFT_LoadFaceText(FreeTypeInstance *ft, PgFaceObject *faceobj,
-                  const FaceRenderMode *render, PGFT_String *text)
+                  const FaceRenderMode *mode, PGFT_String *text)
 {
     Py_ssize_t  string_length = PGFT_String_GET_LENGTH(text);
 
 
     FT_Vector   *next_pos;
 
-    int         vertical = render->render_flags & FT_RFLAG_VERTICAL;
+    int         vertical = mode->render_flags & FT_RFLAG_VERTICAL;
     int         use_kerning = faceobj->kerning;
-    int         pad = render->render_flags & FT_RFLAG_PAD;
+    int         pad = mode->render_flags & FT_RFLAG_PAD;
     FT_UInt     prev_glyph_index = 0;
 
     /* All these are 16.16 precision */
-    FT_Angle    rotation_angle = render->rotation_angle;
+    FT_Angle    rotation_angle = mode->rotation_angle;
 
     /* All these are 26.6 precision */
     FT_Vector   kerning;
-    FT_Pos      min_x = PGFT_MAX_6;
-    FT_Pos      max_x = PGFT_MIN_6;
-    FT_Pos      min_y = PGFT_MAX_6;
-    FT_Pos      max_y = PGFT_MIN_6;
+    FT_Pos      min_x = FX6_MAX;
+    FT_Pos      max_x = FX6_MIN;
+    FT_Pos      min_y = FX6_MAX;
+    FT_Pos      max_y = FX6_MIN;
     FT_Pos      glyph_width;
     FT_Pos      glyph_height;
     FT_Pos      text_width;
     FT_Pos      text_height;
-    FT_Pos      top = PGFT_MIN_6;
+    FT_Pos      top = FX6_MIN;
 
     FT_Error    error = 0;
 
     /* load our sized face */
-    face = _PGFT_GetFaceSized(ft, faceobj, render->pt_size);
+    face = _PGFT_GetFaceSized(ft, faceobj, mode->pt_size);
 
     if (!face) {
         PyErr_SetString(PyExc_SDLError, _PGFT_GetError(ft));
     ftext->descender = face->size->metrics.descender;
 
     /* fill it with the glyphs */
-    fill_context(&context, ft, faceobj, render, face);
+    fill_context(&context, ft, faceobj, mode, face);
     glyph_array = ftext->glyphs;
     next_pos = ftext->posns;
 
         /*
          * Load the corresponding glyph from the cache
          */
-        glyph = _PGFT_Cache_FindGlyph(*((FT_UInt32 *)ch), render,
+        glyph = _PGFT_Cache_FindGlyph(*((FT_UInt32 *)ch), mode,
                                      &ftext->glyph_cache, &context);
 
         if (!glyph) {
             if (rotation_angle != 0) {
                 FT_Vector_Rotate(&kerning, rotation_angle);
             }
-            pen.x += PGFT_ROUND(kerning.x);
-            pen.y += PGFT_ROUND(kerning.y);
+            pen.x += FX6_ROUND(kerning.x);
+            pen.y += FX6_ROUND(kerning.y);
             if (FT_Vector_Length(&pen2) > FT_Vector_Length(&pen)) {
                 pen.x = pen2.x;
                 pen.y = pen2.y;
             }
         }
     }
-    else if (render->style & FT_STYLE_UNDERSCORE) {
+    else if (mode->style & FT_STYLE_UNDERSCORE) {
         if (-ftext->descender >= max_y) {
             max_y = -ftext->descender + /* underscore allowance */ FX6_ONE;
         }
     }
 
-    if (render->style & FT_STYLE_UNDERLINE) {
+    if (mode->style & FT_STYLE_UNDERLINE) {
         FT_Fixed scale = face->size->metrics.y_scale;
         FT_Fixed underline_pos;
         FT_Fixed underline_size;
          */
     }
 
-    text_width = PGFT_CEIL(max_x) - PGFT_FLOOR(min_x);
-    ftext->width = PGFT_TRUNC(text_width);
+    text_width = FX6_CEIL(max_x) - FX6_FLOOR(min_x);
+    ftext->width = FX6_TRUNC(text_width);
     ftext->offset.x = -min_x;
     ftext->advance.x = pen.x;
-    ftext->left = PGFT_TRUNC(PGFT_FLOOR(min_x));
-    text_height = PGFT_CEIL(max_y) - PGFT_FLOOR(min_y);
-    ftext->height = PGFT_TRUNC(text_height);
+    ftext->left = FX6_TRUNC(FX6_FLOOR(min_x));
+    text_height = FX6_CEIL(max_y) - FX6_FLOOR(min_y);
+    ftext->height = FX6_TRUNC(text_height);
     ftext->offset.y = -min_y;
     ftext->advance.y = pen.y;
-    ftext->top = PGFT_TRUNC(PGFT_CEIL(top));
+    ftext->top = FX6_TRUNC(FX6_CEIL(top));
 
     return ftext;
 }
 
 int _PGFT_GetMetrics(FreeTypeInstance *ft, PgFaceObject *faceobj,
-                    PGFT_char character, const FaceRenderMode *render,
+                    PGFT_char character, const FaceRenderMode *mode,
                     FT_UInt *gindex, long *minx, long *maxx,
                     long *miny, long *maxy,
                     double *advance_x, double *advance_y)
     FT_Face     face;
 
     /* load our sized face */
-    face = _PGFT_GetFaceSized(ft, faceobj, render->pt_size);
+    face = _PGFT_GetFaceSized(ft, faceobj, mode->pt_size);
 
     if (!face) {
         return -1;
     /* cleanup the cache */
     _PGFT_Cache_Cleanup(&ftext->glyph_cache);
 
-    fill_context(&context, ft, faceobj, render, face);
-    glyph = _PGFT_Cache_FindGlyph(character, render,
+    fill_context(&context, ft, faceobj, mode, face);
+    glyph = _PGFT_Cache_FindGlyph(character, mode,
                                  &PGFT_INTERNALS(faceobj)->active_text.glyph_cache,
                                  &context);
 
 
 int
 _PGFT_GetSurfaceSize(FreeTypeInstance *ft, PgFaceObject *faceobj,
-        const FaceRenderMode *render, FaceText *text,
+        const FaceRenderMode *mode, FaceText *text,
         int *width, int *height)
 {
     *width = text->width;
 
 int
 _PGFT_GetTextRect(FreeTypeInstance *ft, PgFaceObject *faceobj,
-    const FaceRenderMode *render, PGFT_String *text, SDL_Rect *r)
+    const FaceRenderMode *mode, PGFT_String *text, SDL_Rect *r)
 {
     FaceText *face_text;
 
-    face_text = _PGFT_LoadFaceText(ft, faceobj, render, text);
+    face_text = _PGFT_LoadFaceText(ft, faceobj, mode, text);
 
     if (!face_text)
         return -1;
 
-    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(face_text->offset.x));
-    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(face_text->offset.y));
+    r->x = -(Sint16)FX6_TRUNC(FX6_FLOOR(face_text->offset.x));
+    r->y = (Sint16)FX6_TRUNC(FX6_CEIL(face_text->offset.y));
     r->w = (Uint16)face_text->width;
     r->h = (Uint16)face_text->height;
     return 0;
 }
 
 int
-_PGFT_LoadGlyph(FaceGlyph *glyph, PGFT_char character, const FaceRenderMode *render,
-               void *internal)
+_PGFT_LoadGlyph(FaceGlyph *glyph, PGFT_char character,
+                const FaceRenderMode *mode, void *internal)
 {
     static FT_Vector delta = {0, 0};
 
-    FT_Render_Mode rmode = (render->render_flags & FT_RFLAG_ANTIALIAS ?
+    FT_Render_Mode rmode = (mode->render_flags & FT_RFLAG_ANTIALIAS ?
                             FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
     FT_Vector strong_delta = {0, 0};
     FT_Glyph image = 0;
     FT_UInt32 load_flags;
     FT_UInt gindex;
 
-    FT_Fixed rotation_angle = render->rotation_angle;
+    FT_Fixed rotation_angle = mode->rotation_angle;
     /* FT_Matrix transform; */
     FT_Vector h_bearing_rotated;
     FT_Vector v_bearing_rotated;
     /*
      * Get loading information
      */
-    load_flags = get_load_flags(render);
+    load_flags = get_load_flags(mode);
 
     /*
      * Load the glyph into the glyph slot
     /*
      * Perform any outline transformations
      */
-    if (render->style & FT_STYLE_STRONG) {
+    if (mode->style & FT_STYLE_STRONG) {
         FT_UShort x_ppem = context->face->size->metrics.x_ppem;
         FT_Fixed bold_str;
         FT_BBox before;
         FT_BBox after;
 
-        bold_str = PGFT_CEIL16_TO_6(FX16_BOLD_FACTOR * x_ppem);
+        bold_str = FX16_CEIL_TO_FX6(mode->strength * x_ppem);
         FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &before);
         if (FT_Outline_Embolden(&((FT_OutlineGlyph)image)->outline, bold_str))
             goto cleanup;
         FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &after);
-        strong_delta.x += (after.xMax - after.xMin) - (before.xMax - before.xMin);
-        strong_delta.y += (after.yMax - after.yMin) - (before.yMax - before.yMin);
+        strong_delta.x += ((after.xMax - after.xMin) -
+                           (before.xMax - before.xMin));
+        strong_delta.y += ((after.yMax - after.yMin) -
+                           (before.yMax - before.yMin));
     }
 
     if (context->do_transform) {
         goto cleanup;
     }
 
-    if (render->style & FT_STYLE_WIDE) {
+    if (mode->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);
+        x_strength = FX16_CEIL_TO_FX6(mode->strength * x_ppem);
 
         /* FT_Bitmap_Embolden returns an error for a zero width bitmap */
         if (w > 0) {
             if (error) {
                 goto cleanup;
             }
-            strong_delta.x += PGFT_INT_TO_6(bitmap->width - w);
+            strong_delta.x += INT_TO_FX6(bitmap->width - w);
         }
         else {
             strong_delta.x += x_strength;
     v_advance_rotated.x = 0;
     v_advance_rotated.y = ft_metrics->vertAdvance + strong_delta.y;
     if (rotation_angle != 0) {
-        FT_Angle counter_rotation = PGFT_INT_TO_6(360) - rotation_angle;
+        FT_Angle counter_rotation = INT_TO_FX6(360) - rotation_angle;
 
         FT_Vector_Rotate(&h_advance_rotated, rotation_angle);
         FT_Vector_Rotate(&v_advance_rotated, counter_rotation);
     }
 
     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);
-    h_bearing_rotated.x = PGFT_INT_TO_6(glyph->image->left);
-    h_bearing_rotated.y = PGFT_INT_TO_6(glyph->image->top);
+    glyph->width = INT_TO_FX6(glyph->image->bitmap.width);
+    glyph->height = INT_TO_FX6(glyph->image->bitmap.rows);
+    h_bearing_rotated.x = INT_TO_FX6(glyph->image->left);
+    h_bearing_rotated.y = INT_TO_FX6(glyph->image->top);
     fill_metrics(&glyph->h_metrics,
                  ft_metrics->horiBearingX,
                  ft_metrics->horiBearingY,
 fill_context(TextContext *context,
              const FreeTypeInstance *ft,
              const PgFaceObject *faceobj,
-             const FaceRenderMode *render,
+             const FaceRenderMode *mode,
              const FT_Face face)
 {
     context->lib = ft->library;
     context->charmap = ft->cache_charmap;
     context->do_transform = 0;
 
-    if (render->style & FT_STYLE_OBLIQUE) {
+    if (mode->style & FT_STYLE_OBLIQUE) {
         context->transform = slant_matrix;
         context->do_transform = 1;
     }
         context->transform = unit_matrix;
     }
 
-    if (render->render_flags & FT_RFLAG_TRANSFORM) {
-        FT_Matrix_Multiply(&render->transform, &context->transform);
+    if (mode->render_flags & FT_RFLAG_TRANSFORM) {
+        FT_Matrix_Multiply(&mode->transform, &context->transform);
         context->do_transform = 1;
     }
 
-    if (render->rotation_angle != 0) {
+    if (mode->rotation_angle != 0) {
         FT_Vector unit;
         FT_Matrix rotate;
 
-        FT_Vector_Unit(&unit, render->rotation_angle);
+        FT_Vector_Unit(&unit, mode->rotation_angle);
         rotate.xx = unit.x;  /*  cos(angle) */
         rotate.xy = -unit.y; /* -sin(angle) */
         rotate.yx = unit.y;  /*  sin(angle) */
 }
 
 static FT_UInt32
-get_load_flags(const FaceRenderMode *render)
+get_load_flags(const FaceRenderMode *mode)
 {
     FT_UInt32 load_flags = FT_LOAD_DEFAULT;
 
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
-    if (render->render_flags & FT_RFLAG_AUTOHINT) {
+    if (mode->render_flags & FT_RFLAG_AUTOHINT) {
         load_flags |= FT_LOAD_FORCE_AUTOHINT;
     }
 
-    if (render->render_flags & FT_RFLAG_HINTED) {
+    if (mode->render_flags & FT_RFLAG_HINTED) {
         load_flags |= FT_LOAD_TARGET_NORMAL;
     }
     else {

File src/freetype/ft_wrap.c

         RAISE(PyExc_RuntimeError, _PGFT_GetError(ft));
         return 0;
     }
-    return (long)PGFT_TRUNC(PGFT_CEIL(face->size->metrics.height));
+    return (long)FX6_TRUNC(FX6_CEIL(face->size->metrics.height));
 }
 
 long
         RAISE(PyExc_RuntimeError, _PGFT_GetError(ft));
         return 0;
     }
-    return (long)PGFT_TRUNC(PGFT_CEIL(face->size->metrics.ascender));
+    return (long)FX6_TRUNC(FX6_CEIL(face->size->metrics.ascender));
 }
 
 long
         RAISE(PyExc_RuntimeError, _PGFT_GetError(ft));
         return 0;
     }
-    return (long)PGFT_TRUNC(PGFT_FLOOR(face->size->metrics.descender));
+    return (long)FX6_TRUNC(FX6_FLOOR(face->size->metrics.descender));
 }
 
 long
         return 0;
     }
     metrics = &face->size->metrics;
-    return (long)PGFT_TRUNC(PGFT_CEIL(metrics->ascender) -
-                            PGFT_FLOOR(metrics->descender)) + /* baseline */ 1;
+    return (long)FX6_TRUNC(FX6_CEIL(metrics->ascender) -
+                           FX6_FLOOR(metrics->descender)) + /* baseline */ 1;
 }
 
 

File src/freetype/ft_wrap.h

  **********************************************************/
 
 /* Fixed point (26.6) math macros */
-#define PGFT_FLOOR(x) ((x) & -64 )
-#define PGFT_CEIL(x) (((x) + 63) & -64)
-#define PGFT_ROUND(x) (((x) + 32) & -64)
-#define PGFT_TRUNC(x)  ((x) >> 6)
-#define PGFT_CEIL16_TO_6(x) (((x) + 1023) >> 10)
-#define PGFT_INT_TO_6(x) ((x) << 6)
-#define PGFT_INT_TO_16(x) ((x) << 16)
+#define FX6_ONE 64
+#define FX16_ONE 65536
+#define FX6_MIN ((FT_Pos)0x80000000)
+#define FX6_MAX ((FT_Pos)0x7FFFFFFF)
 
-#define PGFT_MIN_6 ((FT_Pos)0x80000000)
-#define PGFT_MAX_6 ((FT_Pos)0x7FFFFFFF)
+#define FX6_FLOOR(x) ((x) & -64)
+#define FX6_CEIL(x) (((x) + 63) & -64)
+#define FX6_ROUND(x) (((x) + 32) & -64)
+#define FX6_TRUNC(x)  ((x) >> 6)
+#define FX16_CEIL_TO_FX6(x) (((x) + 1023) >> 10)
+#define INT_TO_FX6(i) ((FT_Fixed)((i) << 6))
+#define INT_TO_FX16(i) ((FT_Fixed)((i) << 16))
+#define FX16_TO_DBL(x) ((x) * 1.5259e-5 /* 65536.0^-1 */)
+#define DBL_TO_FX16(d) ((FT_Fixed)((d) * 65536.0))
 
 /* Internal configuration variables */
 #define PGFT_DEFAULT_CACHE_SIZE 64
 #endif
 #define PGFT_DEFAULT_RESOLUTION 72 /* dots per inch */
 
+#define PGFT_DBL_DEFAULT_STRENGTH (1.0 / 36.0)
 
 /**********************************************************
  * Internal basic types
     FT_Angle rotation_angle;
     FT_UInt16 render_flags;
     FT_UInt16 style;
+    FT_Fixed strength;
     FT_Matrix transform;
 } FaceRenderMode;