freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] [PATCH 2/2] Improve FT_GlyphSlot_Embolden to match more with


From: Byeongsik Jeon
Subject: [ft-devel] [PATCH 2/2] Improve FT_GlyphSlot_Embolden to match more with Microsoft Windows looks.
Date: Fri, 5 Oct 2018 03:45:59 +0900
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

---
 src/base/ftsynth.c | 92 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 22 deletions(-)

diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index ec7b93510..7d599c118 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -22,6 +22,7 @@
 #include FT_INTERNAL_OBJECTS_H
 #include FT_OUTLINE_H
 #include FT_BITMAP_H
+#include FT_TRUETYPE_TABLES_H
     /**************************************************************************
@@ -92,7 +93,7 @@
     FT_Library  library;
     FT_Face     face;
     FT_Error    error;
-    FT_Pos      xstr, ystr;
+    FT_Pos      xstr, ystr, ppem;
       if ( !slot )
@@ -105,22 +106,68 @@
          slot->format != FT_GLYPH_FORMAT_BITMAP  )
       return;
 -    /* some reasonable strength */
-    xstr = FT_MulFix( face->units_per_EM,
-                      face->size->metrics.y_scale ) / 24;
-    ystr = xstr;
+    /* the value that matches the MS Windows embolden looks.
+       the larger strength value, the more unintended artifacts increase.
+       using the integer pixel strength inhibits the blurred outlines.
+     */
+    ppem = face->size->metrics.y_ppem;
+    ystr = (( ppem - 1 ) / 50 ) << 6;
+    xstr = ystr + 64;
+
+    /* match to the MS.
+       the important factor that reduces the text layout difference. */
+    slot->metrics.horiAdvance += 1 << 6;
+    slot->linearHoriAdvance   += 1 << 16;
      if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
-      FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
+    {
+      error = FT_Outline_EmboldenXY( &slot->outline, xstr, ystr);
+      if ( error )
+        return;
+#if 1
+      /* MS Windows DirectWrite looks. */
+
+      slot->metrics.width        += xstr;
+      slot->metrics.height       += ystr;
+      slot->metrics.horiBearingY += ystr;
+#else
+      /* MS Windows GDI looks. */
 +      if ( ystr != 0 ) /* ppem > 50px */
+      {
+        TT_Header *head_table;
+        FT_Matrix scale = { 1 << 16, 0, 0, 1 << 16 };
+
+        /* Elboldened EM square box only increase the width of one pixel.
+           ( ppem, ppem ) -> embolden -> scale -> ( ppem + 1px, ppem )
+
+           ( ppem + xstr ) * scale.xx = ppem + 1px
+           ( ppem + ystr ) * scale.yy = ppem
+         */
+        ppem = ppem << 6;
+        scale.xx = FT_MulDiv( 1 << 16, ppem + 64, ppem + xstr );
+        scale.yy = FT_MulDiv( 1 << 16, ppem     , ppem + ystr );
+        FT_Outline_Transform( &slot->outline, &scale );
+
+        /* Undocumented behavior in truetype spec. */
+        head_table = FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
+        if ( head_table && head_table->Flags & ( 1 << 4 | 1 << 2 ) )
+          slot->metrics.horiAdvance =
+            FT_MulFix( slot->metrics.horiAdvance, scale.xx );
+      }
+
+      {
+        FT_BBox bbox;
+        FT_Outline_Get_CBox( &slot->outline, &bbox );
+        slot->metrics.width        = bbox.xMax - bbox.xMin;
+        slot->metrics.height       = bbox.yMax - bbox.yMin;
+        slot->metrics.horiBearingX = bbox.xMin;
+        slot->metrics.horiBearingY = bbox.yMax;
+      }
+#endif
+    }
     else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
     {
-      /* round to full pixels */
-      xstr &= ~63;
-      if ( xstr == 0 )
-        xstr = 1 << 6;
-      ystr &= ~63;
-
       /*
        * XXX: overflow check for 16-bit system, for compatibility
        *      with FT_GlyphSlot_Embolden() since FreeType 2.1.10.
@@ -140,23 +187,24 @@
       error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );
       if ( error )
         return;
+
+      slot->metrics.width        += xstr;
+      slot->metrics.height       += ystr;
+      slot->metrics.horiBearingY += ystr;
+
+      /* XXX: 16-bit overflow case must be excluded before here */
+      slot->bitmap_top += (FT_Int)( ystr >> 6 );
     }
 +    /* XXX: FT_Set_Transform, FT_GlyphSlot_Embolden combination can
+            produce different results from intention. Recommend the
+            FT_Outline_Transform and a manual metrics modification.
+     */
     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.horiAdvance  += xstr;
-    slot->metrics.vertAdvance  += ystr;
-    slot->metrics.horiBearingY += ystr;
-
-    /* XXX: 16-bit overflow case must be excluded before here */
-    if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
-      slot->bitmap_top += (FT_Int)( ystr >> 6 );
   }
  -- 2.19.0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]