From 76e18c86c8def6df7c0acbf9a8c82d667d16ed25 Mon Sep 17 00:00:00 2001
From: Hin-Tak Leung <htl10@users.sourceforge.net>
Date: Sat, 19 Jan 2013 05:50:37 +0000
Subject: [PATCH] candidate fix for over flow


Signed-off-by: Hin-Tak Leung <htl10@users.sourceforge.net>
---
 include/freetype/internal/ftcalc.h |  8 +++++++-
 src/base/ftcalc.c                  | 36 ++++++++++++++++++++++++++++++++++++
 src/base/ftoutln.c                 | 13 ++++++++++++-
 src/base/fttrigon.c                | 32 ++------------------------------
 4 files changed, 57 insertions(+), 32 deletions(-)

diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 56aa07c..e4924d0 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -125,7 +125,6 @@ FT_BEGIN_HEADER
    *  A variant of FT_Vector_Transform.  See comments for
    *  FT_Matrix_Multiply_Scaled.
    */
-
   FT_BASE( void )
   FT_Vector_Transform_Scaled( FT_Vector*        vector,
                               const FT_Matrix*  matrix,
@@ -156,6 +155,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 )
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 2aeea04..4122fda 100644
--- a/src/base/ftcalc.c
+++ b/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 */
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 27aba01..875968c 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -1009,6 +1009,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;
@@ -1023,6 +1025,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;
@@ -1036,7 +1046,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;
       }
 
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 4bd4320..e8cc3e3 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -118,42 +118,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     = FT_ABS( x ) | FT_ABS( y );
-    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;
-    }
+    shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) );
 
     if ( shift <= FT_TRIG_SAFE_MSB )
     {
-- 
1.8.1

