[freetype/f18] Fix emboldening

mkasik mkasik at fedoraproject.org
Tue Mar 19 16:09:20 UTC 2013


commit 7d8d4f355a6d0de955bfb80f9cdf9fb6e78dda33
Author: Marek Kasik <mkasik at redhat.com>
Date:   Tue Mar 19 16:58:30 2013 +0100

    Fix emboldening
    
    - split out MSB function
    - fix integer overflows
    - fix broken emboldening at small sizes
    - clean up emboldening code and improve comments there
    - fortify emboldening code against egregious distortions
    - Resolves: #891457

 freetype-2.4.10-fix-emboldening.patch |  263 +++++++++++++++++++++++++++++++++
 freetype.spec                         |   15 ++-
 2 files changed, 277 insertions(+), 1 deletions(-)
---
diff --git a/freetype-2.4.10-fix-emboldening.patch b/freetype-2.4.10-fix-emboldening.patch
new file mode 100644
index 0000000..bdd66a2
--- /dev/null
+++ b/freetype-2.4.10-fix-emboldening.patch
@@ -0,0 +1,263 @@
+--- freetype-2.4.10/include/freetype/internal/ftcalc.h
++++ freetype-2.4.10/include/freetype/internal/ftcalc.h
+@@ -160,6 +160,13 @@ FT_BEGIN_HEADER
+                      FT_Pos  out_y );
+ 
+ 
++  /*
++   *  Return the most significant bit index.
++   */
++  FT_BASE( FT_Int )
++  FT_MSB( FT_UInt32 z );
++
++
+ #define INT_TO_F26DOT6( x )    ( (FT_Long)(x) << 6  )
+ #define INT_TO_F2DOT14( x )    ( (FT_Long)(x) << 14 )
+ #define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )
+--- freetype-2.4.10/src/base/ftcalc.c
++++ freetype-2.4.10/src/base/ftcalc.c
+@@ -103,6 +103,42 @@
+   }
+ 
+ 
++  FT_BASE_DEF ( FT_Int )
++  FT_MSB( FT_UInt32 z )
++  {
++    FT_Int shift = 0;
++
++    /* determine msb bit index in `shift' */
++    if ( z >= ( 1L << 16 ) )
++    {
++      z     >>= 16;
++      shift  += 16;
++    }
++    if ( z >= ( 1L << 8 ) )
++    {
++      z     >>= 8;
++      shift  += 8;
++    }
++    if ( z >= ( 1L << 4 ) )
++    {
++      z     >>= 4;
++      shift  += 4;
++    }
++    if ( z >= ( 1L << 2 ) )
++    {
++      z     >>= 2;
++      shift  += 2;
++    }
++    if ( z >= ( 1L << 1 ) )
++    {
++      z     >>= 1;
++      shift  += 1;
++    }
++
++    return shift;
++  }
++
++
+ #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+ 
+   /* documentation is in ftcalc.h */
+--- freetype-2.4.10/src/base/ftoutln.c
++++ freetype-2.4.10/src/base/ftoutln.c
+@@ -922,7 +922,7 @@
+     for ( c = 0; c < outline->n_contours; c++ )
+     {
+       FT_Vector  in, out, shift;
+-      FT_Fixed   l_in, l_out, d;
++      FT_Fixed   l_in, l_out, l, q, d;
+       int        last = outline->contours[c];
+ 
+ 
+@@ -930,10 +930,15 @@
+       v_prev  = points[last];
+       v_cur   = v_first;
+ 
+-      /* compute the incoming vector and its length */
++      /* compute the incoming normalized vector */
+       in.x = v_cur.x - v_prev.x;
+       in.y = v_cur.y - v_prev.y;
+       l_in = FT_Vector_Length( &in );
++      if ( l_in )
++      {
++        in.x = FT_DivFix( in.x, l_in );
++        in.y = FT_DivFix( in.y, l_in );
++      }
+ 
+       for ( n = first; n <= last; n++ )
+       {
+@@ -942,27 +947,49 @@
+         else
+           v_next = v_first;
+ 
+-        /* compute the outgoing vector and its length */
++        /* compute the outgoing normalized vector */
+         out.x = v_next.x - v_cur.x;
+         out.y = v_next.y - v_cur.y;
+         l_out = FT_Vector_Length( &out );
++        if ( l_out )
++        {
++          out.x = FT_DivFix( out.x, l_out );
++          out.y = FT_DivFix( out.y, l_out );
++        }
+ 
+-        d = l_in * l_out + in.x * out.x + in.y * out.y;
++        d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y );
+ 
+         /* shift only if turn is less then ~160 degrees */
+-        if ( 16 * d > l_in * l_out )
++        if ( d > -0xF000L )
+         {
+-          /* shift components are rotated */
+-          shift.x = FT_DivFix( l_out * in.y + l_in * out.y, d );
+-          shift.y = FT_DivFix( l_out * in.x + l_in * out.x, d );
++          d = d + 0x10000L;
++
++          /* shift components are aligned along bisector        */
++          /* and directed according to the outline orientation. */
++          shift.x = in.y + out.y;
++          shift.y = in.x + out.x;
+ 
+           if ( orientation == FT_ORIENTATION_TRUETYPE )
+             shift.x = -shift.x;
+           else
+             shift.y = -shift.y;
+ 
+-          shift.x = FT_MulFix( xstrength, shift.x );
+-          shift.y = FT_MulFix( ystrength, shift.y );
++          /* threshold strength to better handle collapsing segments */
++          q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
++          if ( orientation == FT_ORIENTATION_TRUETYPE )
++            q = -q;
++
++          l = FT_MIN( l_in, l_out );
++
++          if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) )
++            shift.x = FT_MulDiv( shift.x, xstrength, d );
++          else
++            shift.x = FT_MulDiv( shift.x, l, q );
++
++          if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) )
++            shift.y = FT_MulDiv( shift.y, ystrength, d );
++          else
++            shift.y = FT_MulDiv( shift.y, l, q );
+         }
+         else
+           shift.x = shift.y = 0;
+@@ -987,6 +1014,8 @@
+   FT_EXPORT_DEF( FT_Orientation )
+   FT_Outline_Get_Orientation( FT_Outline*  outline )
+   {
++    FT_BBox     cbox;
++    FT_Int      xshift, yshift;
+     FT_Vector*  points;
+     FT_Vector   v_prev, v_cur;
+     FT_Int      c, n, first;
+@@ -1001,6 +1030,14 @@
+     /* cubic or quadratic curves, this test deals with the polygon    */
+     /* only which is spanned up by the control points.                */
+ 
++    FT_Outline_Get_CBox( outline, &cbox );
++
++    xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
++    xshift = FT_MAX( xshift, 0 );
++
++    yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14;
++    yshift = FT_MAX( yshift, 0 );
++
+     points = outline->points;
+ 
+     first = 0;
+@@ -1014,7 +1051,8 @@
+       for ( n = first; n <= last; n++ )
+       {
+         v_cur = points[n];
+-        area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x );
++        area += ( ( v_cur.y - v_prev.y ) >> yshift ) *
++                ( ( v_cur.x + v_prev.x ) >> xshift );
+         v_prev = v_cur;
+       }
+ 
+--- freetype-2.4.10/src/base/fttrigon.c
++++ freetype-2.4.10/src/base/fttrigon.c
+@@ -99,43 +99,14 @@
+   static FT_Int
+   ft_trig_prenorm( FT_Vector*  vec )
+   {
+-    FT_Fixed  x, y, z;
++    FT_Fixed  x, y;
+     FT_Int    shift;
+ 
+ 
+     x = vec->x;
+     y = vec->y;
+ 
+-    z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
+-    shift = 0;
+-
+-#if 1
+-    /* determine msb bit index in `shift' */
+-    if ( z >= ( 1L << 16 ) )
+-    {
+-      z     >>= 16;
+-      shift  += 16;
+-    }
+-    if ( z >= ( 1L << 8 ) )
+-    {
+-      z     >>= 8;
+-      shift  += 8;
+-    }
+-    if ( z >= ( 1L << 4 ) )
+-    {
+-      z     >>= 4;
+-      shift  += 4;
+-    }
+-    if ( z >= ( 1L << 2 ) )
+-    {
+-      z     >>= 2;
+-      shift  += 2;
+-    }
+-    if ( z >= ( 1L << 1 ) )
+-    {
+-      z    >>= 1;
+-      shift += 1;
+-    }
++    shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) );
+ 
+     if ( shift <= 27 )
+     {
+@@ -151,33 +122,6 @@
+       shift  = -shift;
+     }
+ 
+-#else /* 0 */
+-
+-    if ( z < ( 1L << 27 ) )
+-    {
+-      do
+-      {
+-        shift++;
+-        z <<= 1;
+-      } while ( z < ( 1L << 27 ) );
+-      vec->x = x << shift;
+-      vec->y = y << shift;
+-    }
+-    else if ( z > ( 1L << 28 ) )
+-    {
+-      do
+-      {
+-        shift++;
+-        z >>= 1;
+-      } while ( z > ( 1L << 28 ) );
+-
+-      vec->x = x >> shift;
+-      vec->y = y >> shift;
+-      shift  = -shift;
+-    }
+-
+-#endif /* 0 */
+-
+     return shift;
+   }
+ 
diff --git a/freetype.spec b/freetype.spec
index 6d0c46d..650a4c5 100644
--- a/freetype.spec
+++ b/freetype.spec
@@ -7,7 +7,7 @@
 Summary: A free and portable font rendering engine
 Name: freetype
 Version: 2.4.10
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: FTL or GPLv2+
 Group: System Environment/Libraries
 URL: http://www.freetype.org
@@ -28,6 +28,9 @@ Patch88:  freetype-multilib.patch
 # https://bugzilla.redhat.com/show_bug.cgi?id=903554
 Patch89:  freetype-2.4.10-CVE-2012-5669.patch
 
+# https://bugzilla.redhat.com/show_bug.cgi?id=891457
+Patch90:  freetype-2.4.10-fix-emboldening.patch
+
 Buildroot: %{_tmppath}/%{name}-%{version}-root-%(%{__id_u} -n)
 
 BuildRequires: libX11-devel
@@ -88,6 +91,7 @@ popd
 
 %patch88 -p1 -b .multilib
 %patch89 -p1 -b .CVE-2012-5669
+%patch90 -p1 -b .fix-emboldening
 
 %build
 
@@ -220,6 +224,15 @@ rm -rf $RPM_BUILD_ROOT
 %doc docs/tutorial
 
 %changelog
+* Tue Mar 19 2013 Marek Kasik <mkasik at redhat.com> - 2.4.10-4
+- Fix emboldening:
+    - split out MSB function
+    - fix integer overflows
+    - fix broken emboldening at small sizes
+    - clean up emboldening code and improve comments there
+    - fortify emboldening code against egregious distortions
+- Resolves: #891457
+
 * Thu Jan 24 2013 Marek Kasik <mkasik at redhat.com> 2.4.10-3
 - Fixes CVE-2012-5669
 - Resolves: #903554


More information about the fonts-bugs mailing list