Index: third_party/freetype/src/base/ftoutln.c |
diff --git a/third_party/freetype/src/base/ftoutln.c b/third_party/freetype/src/base/ftoutln.c |
index 8749d64ce79dbc2be29fd21f2e6d49c9939e5549..35cc9f5569299b45c52e9523e9274a101fea94fe 100644 |
--- a/third_party/freetype/src/base/ftoutln.c |
+++ b/third_party/freetype/src/base/ftoutln.c |
@@ -4,7 +4,7 @@ |
/* */ |
/* FreeType outline management (body). */ |
/* */ |
-/* Copyright 1996-2008, 2010, 2012-2014 by */ |
+/* Copyright 1996-2015 by */ |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
/* */ |
/* This file is part of the FreeType project, and may only be used, */ |
@@ -52,8 +52,9 @@ |
const FT_Outline_Funcs* func_interface, |
void* user ) |
{ |
-#undef SCALED |
-#define SCALED( x ) ( ( (x) << shift ) - delta ) |
+#undef SCALED |
+#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \ |
+ : ( (x) << shift ) ) - delta ) |
FT_Vector v_last; |
FT_Vector v_control; |
@@ -279,7 +280,7 @@ |
if ( error ) |
goto Exit; |
- first = last + 1; |
+ first = (FT_UInt)last + 1; |
} |
FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); |
@@ -320,7 +321,7 @@ |
FT_NEW_ARRAY( anoutline->contours, numContours ) ) |
goto Fail; |
- anoutline->n_points = (FT_UShort)numPoints; |
+ anoutline->n_points = (FT_Short)numPoints; |
anoutline->n_contours = (FT_Short)numContours; |
anoutline->flags |= FT_OUTLINE_OWNER; |
@@ -612,7 +613,6 @@ |
FT_Raster_Params* params ) |
{ |
FT_Error error; |
- FT_Bool update = FALSE; |
FT_Renderer renderer; |
FT_ListNode node; |
@@ -646,14 +646,8 @@ |
/* format */ |
renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, |
&node ); |
- update = TRUE; |
} |
- /* if we changed the current renderer for the glyph image format */ |
- /* we need to select it as the next current one */ |
- if ( !error && update && renderer ) |
- error = FT_Set_Renderer( library, renderer, 0, 0 ); |
- |
return error; |
} |
@@ -914,8 +908,7 @@ |
FT_Pos ystrength ) |
{ |
FT_Vector* points; |
- FT_Vector v_prev, v_first, v_next, v_cur; |
- FT_Int c, n, first; |
+ FT_Int c, first, last; |
FT_Int orientation; |
@@ -941,87 +934,95 @@ |
first = 0; |
for ( c = 0; c < outline->n_contours; c++ ) |
{ |
- FT_Vector in, out, shift; |
- FT_Fixed l_in, l_out, l, q, d; |
- int last = outline->contours[c]; |
+ FT_Vector in, out, anchor, shift; |
+ FT_Fixed l_in, l_out, l_anchor = 0, l, q, d; |
+ FT_Int i, j, k; |
- v_first = points[first]; |
- v_prev = points[last]; |
- v_cur = v_first; |
+ l_in = 0; |
+ last = outline->contours[c]; |
- /* compute 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 ) |
+ /* Counter j cycles though the points; counter i advances only */ |
+ /* when points are moved; anchor k marks the first moved point. */ |
+ for ( i = last, j = first, k = -1; |
+ j != i && i != k; |
+ j = j < last ? j + 1 : first ) |
{ |
- in.x = FT_DivFix( in.x, l_in ); |
- in.y = FT_DivFix( in.y, l_in ); |
- } |
+ if ( j != k ) |
+ { |
+ out.x = points[j].x - points[i].x; |
+ out.y = points[j].y - points[i].y; |
+ l_out = (FT_Fixed)FT_Vector_NormLen( &out ); |
- for ( n = first; n <= last; n++ ) |
- { |
- if ( n < last ) |
- v_next = points[n + 1]; |
+ if ( l_out == 0 ) |
+ continue; |
+ } |
else |
- v_next = v_first; |
- |
- /* compute 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 ); |
+ out = anchor; |
+ l_out = l_anchor; |
} |
- d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); |
- |
- /* shift only if turn is less than ~160 degrees */ |
- if ( d > -0xF000L ) |
+ if ( l_in != 0 ) |
{ |
- d = d + 0x10000L; |
+ if ( k < 0 ) |
+ { |
+ k = i; |
+ anchor = in; |
+ l_anchor = l_in; |
+ } |
- /* shift components are aligned along lateral bisector */ |
- /* and directed according to the outline orientation. */ |
- shift.x = in.y + out.y; |
- shift.y = in.x + out.x; |
+ d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); |
- if ( orientation == FT_ORIENTATION_TRUETYPE ) |
- shift.x = -shift.x; |
- else |
- shift.y = -shift.y; |
+ /* shift only if turn is less than ~160 degrees */ |
+ if ( d > -0xF000L ) |
+ { |
+ d = d + 0x10000L; |
- /* restrict shift magnitude 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; |
+ /* shift components along lateral bisector in proper orientation */ |
+ shift.x = in.y + out.y; |
+ shift.y = in.x + out.x; |
- l = FT_MIN( l_in, l_out ); |
+ if ( orientation == FT_ORIENTATION_TRUETYPE ) |
+ shift.x = -shift.x; |
+ else |
+ shift.y = -shift.y; |
- /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ |
- 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 ); |
+ /* restrict shift magnitude 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 ); |
+ |
+ /* non-strict inequalities avoid divide-by-zero when q == l == 0 */ |
+ if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) ) |
+ 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 ); |
+ if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) ) |
+ shift.y = FT_MulDiv( shift.y, ystrength, d ); |
+ else |
+ shift.y = FT_MulDiv( shift.y, l, q ); |
+ } |
else |
- shift.y = FT_MulDiv( shift.y, l, q ); |
+ shift.x = shift.y = 0; |
+ |
+ for ( ; |
+ i != j; |
+ i = i < last ? i + 1 : first ) |
+ { |
+ points[i].x += xstrength + shift.x; |
+ points[i].y += ystrength + shift.y; |
+ } |
} |
else |
- shift.x = shift.y = 0; |
- |
- outline->points[n].x = v_cur.x + xstrength + shift.x; |
- outline->points[n].y = v_cur.y + ystrength + shift.y; |
+ i = j; |
- in = out; |
- l_in = l_out; |
- v_cur = v_next; |
+ in = out; |
+ l_in = l_out; |
} |
first = last + 1; |
@@ -1050,7 +1051,7 @@ |
/* We use the nonzero winding rule to find the orientation. */ |
/* Since glyph outlines behave much more `regular' than arbitrary */ |
/* cubic or quadratic curves, this test deals with the polygon */ |
- /* only which is spanned up by the control points. */ |
+ /* only that is spanned up by the control points. */ |
FT_Outline_Get_CBox( outline, &cbox ); |
@@ -1058,10 +1059,11 @@ |
if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) |
return FT_ORIENTATION_NONE; |
- xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14; |
+ xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) | |
+ FT_ABS( cbox.xMin ) ) ) - 14; |
xshift = FT_MAX( xshift, 0 ); |
- yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14; |
+ yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14; |
yshift = FT_MAX( yshift, 0 ); |
points = outline->points; |