|
|
|
@ -908,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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -935,76 +934,94 @@ |
|
|
|
|
first = 0; |
|
|
|
|
for ( c = 0; c < outline->n_contours; c++ ) |
|
|
|
|
{ |
|
|
|
|
FT_Vector in, out, shift; |
|
|
|
|
FT_Fixed l_in, l_out, l, q, d; |
|
|
|
|
FT_Int last = outline->contours[c]; |
|
|
|
|
|
|
|
|
|
FT_Vector in, out, anchor, shift; |
|
|
|
|
FT_Fixed l_in = 0, l_out, l_anchor, l, q, d; |
|
|
|
|
FT_Int i, j, k; |
|
|
|
|
|
|
|
|
|
v_first = points[first]; |
|
|
|
|
v_prev = points[last]; |
|
|
|
|
v_cur = v_first; |
|
|
|
|
|
|
|
|
|
/* compute incoming normalized vector */ |
|
|
|
|
in.x = v_cur.x - v_prev.x; |
|
|
|
|
in.y = v_cur.y - v_prev.y; |
|
|
|
|
l_in = (FT_Fixed)FT_Vector_NormLen( &in ); |
|
|
|
|
last = outline->contours[c]; |
|
|
|
|
|
|
|
|
|
for ( n = first; n <= last; n++ ) |
|
|
|
|
/* Counter i cycles though the points; counter j advances only */ |
|
|
|
|
/* when points are moved; anchor k markes the first moved point. */ |
|
|
|
|
for ( i = last, j = first, k = -1; |
|
|
|
|
j != i && i != k; |
|
|
|
|
j = j < last ? j + 1 : first ) |
|
|
|
|
{ |
|
|
|
|
if ( n < last ) |
|
|
|
|
v_next = points[n + 1]; |
|
|
|
|
if ( j != k ) |
|
|
|
|
{ |
|
|
|
|
out.x = points[j].x - points[i].x; |
|
|
|
|
out.y = points[j].y - points[i].y; |
|
|
|
|
l_out = FT_Vector_NormLen( &out ); |
|
|
|
|
} |
|
|
|
|
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_Fixed)FT_Vector_NormLen( &out ); |
|
|
|
|
{ |
|
|
|
|
out = anchor; |
|
|
|
|
l_out = l_anchor; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y ); |
|
|
|
|
if ( l_out == 0 ) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
/* 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 along lateral bisector in appropriate 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( l, d ) ) |
|
|
|
|
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( l, d ) ) |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
points[n].x = v_cur.x + xstrength + shift.x; |
|
|
|
|
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; |
|
|
|
|