freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] master be32b16: [autofit] Don't distort (latin) glyphs too m


From: Werner LEMBERG
Subject: [freetype2] master be32b16: [autofit] Don't distort (latin) glyphs too much (#46195).
Date: Sun, 08 Nov 2015 07:39:23 +0000

branch: master
commit be32b168ac42e670e1a8c5c614cce4c3f8232829
Author: Philipp Knechtges <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [autofit] Don't distort (latin) glyphs too much (#46195).
    
    * src/autofit/aflatin.h (AF_LatinBlueRec): Add `ascender' and
    `descender' fields.
    
    * src/autofit/aflatin.c (af_latin_metrics_init_blues): Collect
    ascender and descender data for blue zones.
    (af_latin_metrics_scale_dim): Reject vertical scaling values that
    change the result by more than two pixels.
---
 ChangeLog             |   12 ++++++++
 src/autofit/aflatin.c |   75 +++++++++++++++++++++++++++++++++++++++++--------
 src/autofit/aflatin.h |    2 +
 3 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cc8ba89..28cec3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2015-11-06  Philipp Knechtges  <address@hidden>
+
+       [autofit] Don't distort (latin) glyphs too much (#46195).
+
+       * src/autofit/aflatin.h (AF_LatinBlueRec): Add `ascender' and
+       `descender' fields.
+
+       * src/autofit/aflatin.c (af_latin_metrics_init_blues): Collect
+       ascender and descender data for blue zones.
+       (af_latin_metrics_scale_dim): Reject vertical scaling values that
+       change the result by more than two pixels.
+
 2015-11-05  Werner Lemberg  <address@hidden>
 
        [sfnt] Ignore embedded bitmaps with zero size (#46379).
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 5645aaf..53851e7 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -293,6 +293,8 @@
       const char*  p = &af_blue_strings[bs->string];
       FT_Pos*      blue_ref;
       FT_Pos*      blue_shoot;
+      FT_Pos       ascender;
+      FT_Pos       descender;
 
 
 #ifdef FT_DEBUG_LEVEL_TRACE
@@ -344,6 +346,8 @@
 
       num_flats  = 0;
       num_rounds = 0;
+      ascender   = 0;
+      descender  = 0;
 
       while ( *p )
       {
@@ -405,20 +409,30 @@
             if ( AF_LATIN_IS_TOP_BLUE( bs ) )
             {
               for ( pp = first; pp <= last; pp++ )
+              {
                 if ( best_point < 0 || points[pp].y > best_y )
                 {
                   best_point = pp;
                   best_y     = points[pp].y;
+                  ascender   = FT_MAX( ascender, best_y + y_offset );
                 }
+                else
+                  descender = FT_MIN( descender, points[pp].y + y_offset );
+              }
             }
             else
             {
               for ( pp = first; pp <= last; pp++ )
+              {
                 if ( best_point < 0 || points[pp].y < best_y )
                 {
                   best_point = pp;
                   best_y     = points[pp].y;
+                  descender  = FT_MIN( descender, best_y + y_offset );
                 }
+                else
+                  ascender = FT_MAX( ascender, points[pp].y + y_offset );
+              }
             }
 
             if ( best_point != old_best_point )
@@ -791,6 +805,9 @@
         }
       }
 
+      blue->ascender  = ascender;
+      blue->descender = descender;
+
       blue->flags = 0;
       if ( AF_LATIN_IS_TOP_BLUE( bs ) )
         blue->flags |= AF_LATIN_BLUE_TOP;
@@ -973,18 +990,52 @@
 #endif
           if ( dim == AF_DIMENSION_VERT )
           {
-            scale = FT_MulDiv( scale, fitted, scaled );
-
-            FT_TRACE5((
-              "af_latin_metrics_scale_dim:"
-              " x height alignment (style `%s'):\n"
-              "                           "
-              " vertical scaling changed from %.4f to %.4f (by %d%%)\n"
-              "\n",
-              af_style_names[metrics->root.style_class->style],
-              axis->org_scale / 65536.0,
-              scale / 65536.0,
-              ( fitted - scaled ) * 100 / scaled ));
+            FT_Pos    max_height;
+            FT_Pos    dist;
+            FT_Fixed  new_scale;
+
+
+            new_scale = FT_MulDiv( scale, fitted, scaled );
+
+            /* the scaling should not change the result by more than two 
pixels */
+            max_height = metrics->units_per_em;
+
+            for ( nn = 0; nn < Axis->blue_count; nn++ )
+            {
+              max_height = FT_MAX( max_height, Axis->blues[nn].ascender );
+              max_height = FT_MAX( max_height, -Axis->blues[nn].descender );
+            }
+
+            dist  = FT_ABS( FT_MulFix( max_height, new_scale - scale ) );
+            dist &= ~127;
+
+            if ( dist == 0 )
+            {
+              scale = new_scale;
+
+              FT_TRACE5((
+                "af_latin_metrics_scale_dim:"
+                " x height alignment (style `%s'):\n"
+                "                           "
+                " vertical scaling changed from %.4f to %.4f (by %d%%)\n"
+                "\n",
+                af_style_names[metrics->root.style_class->style],
+                axis->org_scale / 65536.0,
+                scale / 65536.0,
+                ( fitted - scaled ) * 100 / scaled ));
+            }
+#ifdef FT_DEBUG_LEVEL_TRACE
+            else
+            {
+              FT_TRACE5((
+                "af_latin_metrics_scale_dim:"
+                " x height alignment (style `%s'):\n"
+                "                           "
+                " excessive vertical scaling abandoned\n"
+                "\n",
+                af_style_names[metrics->root.style_class->style] ));
+            }
+#endif
           }
         }
       }
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 6855492..dd75ef3 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -74,6 +74,8 @@ FT_BEGIN_HEADER
   {
     AF_WidthRec  ref;
     AF_WidthRec  shoot;
+    FT_Pos       ascender;
+    FT_Pos       descender;
     FT_UInt      flags;
 
   } AF_LatinBlueRec, *AF_LatinBlue;



reply via email to

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