[base] Fix integer overflow. * src/base/ftoutln.c (FT_Outline_EmboldenXY): Normalize incoming and outgoing vectors and use fixed point arithmetic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/ChangeLog b/ChangeLog
index 7b2767a..f361519 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,13 @@
[base] Fix integer overflow.
+ * src/base/ftoutln.c (FT_Outline_EmboldenXY): Normalize incoming and
+ outgoing vectors and use fixed point arithmetic.
+
+2013-01-23 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ [base] Fix integer overflow.
+
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Scale the
coordinates down to avoid overflow.
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 875968c..a23b8a3 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -937,10 +937,12 @@
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 );
+ in.x = FT_DivFix( in.x, l_in );
+ in.y = FT_DivFix( in.y, l_in );
for ( n = first; n <= last; n++ )
{
@@ -949,20 +951,24 @@
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 );
+ 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 )
{
+ d = d + 0x10000L;
+
/* shift components are aligned along bisector */
/* and directed according to the outline orientation. */
- shift.x = l_out * in.y + l_in * out.y;
- shift.y = l_out * in.x + l_in * out.x;
+ shift.x = in.y + out.y;
+ shift.y = in.x + out.x;
if ( orientation == FT_ORIENTATION_TRUETYPE )
shift.x = -shift.x;
@@ -970,18 +976,19 @@
shift.y = -shift.y;
/* threshold strength to better handle collapsing segments */
- l = FT_MIN( l_in, l_out );
- q = out.x * in.y - out.y * in.x;
+ q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
if ( orientation == FT_ORIENTATION_TRUETYPE )
q = -q;
- if ( FT_MulDiv( xstrength, q, l ) < d )
+ 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_MulDiv( ystrength, q, l ) < d )
+ 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 );