diff --git a/include/freetype/ftsynth.h b/include/freetype/ftsynth.h index 4c7752ae2..2424ff627 100644 --- a/include/freetype/ftsynth.h +++ b/include/freetype/ftsynth.h @@ -48,16 +48,14 @@ FT_BEGIN_HEADER /* This code is completely experimental -- use with care! */ /* It will probably be completely rewritten in the future */ /* or even integrated into the library. */ - FT_EXPORT( FT_Error ) - FT_Outline_Embolden( FT_GlyphSlot original, - FT_Outline* outline, - FT_Pos* advance ); + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); - FT_EXPORT( FT_Error ) - FT_Outline_Oblique( FT_GlyphSlot original, - FT_Outline* outline, - FT_Pos* advance ); + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ FT_END_HEADER diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index e82747be9..ae053656f 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -20,6 +20,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_CALC_H #include FT_OUTLINE_H +#include FT_TRIGONOMETRY_H #include FT_SYNTHESIS_H @@ -34,18 +35,17 @@ /*************************************************************************/ /*************************************************************************/ - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Oblique( FT_GlyphSlot original, - FT_Outline* outline, - FT_Pos* advance ) + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) { - FT_Matrix transform; + FT_Matrix transform; + FT_Outline* outline = &slot->outline; + + /* only oblique outline glyphs */ + if ( slot->format != ft_glyph_format_outline ) + return; - FT_UNUSED( original ); /* we don't touch the advance width */ - FT_UNUSED( advance ); - - /* For italic, simply apply a shear transform, with an angle */ /* of about 12 degrees. */ @@ -57,8 +57,6 @@ transform.yy = 0x10000L; FT_Outline_Transform( outline, &transform ); - - return 0; } @@ -71,97 +69,6 @@ /*************************************************************************/ - /* Compute the norm of a vector */ - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static FT_Pos - ft_norm( FT_Vector* vec ) - { - FT_Int64 t1, t2; - - - MUL_64( vec->x, vec->x, t1 ); - MUL_64( vec->y, vec->y, t2 ); - ADD_64( t1, t2, t1 ); - - return (FT_Pos)SQRT_64( t1 ); - } - -#else /* FT_CONFIG_OPTION_OLD_CALCS */ - - static FT_Pos - ft_norm( FT_Vector* vec ) - { - FT_F26Dot6 u, v, d; - FT_Int shift; - FT_ULong H, L, L2, hi, lo, med; - - - u = vec->x; if ( u < 0 ) u = -u; - v = vec->y; if ( v < 0 ) v = -v; - - if ( u < v ) - { - d = u; - u = v; - v = d; - } - - /* check that we are not trying to normalize zero! */ - if ( u == 0 ) - return 0; - - /* compute (u*u + v*v) on 64 bits with two 32-bit registers [H:L] */ - hi = (FT_ULong)u >> 16; - lo = (FT_ULong)u & 0xFFFF; - med = hi * lo; - - H = hi * hi + ( med >> 15 ); - med <<= 17; - L = lo * lo + med; - if ( L < med ) - H++; - - hi = (FT_ULong)v >> 16; - lo = (FT_ULong)v & 0xFFFF; - med = hi * lo; - - H += hi * hi + ( med >> 15 ); - med <<= 17; - L2 = lo * lo + med; - if ( L2 < med ) - H++; - - L += L2; - if ( L < L2 ) - H++; - - /* if the value is smaller than 32 bits */ - shift = 0; - if ( H == 0 ) - { - while ( ( L & 0xC0000000UL ) == 0 ) - { - L <<= 2; - shift++; - } - return ( FT_Sqrt32( L ) >> shift ); - } - else - { - while ( H ) - { - L = ( L >> 2 ) | ( H << 30 ); - H >>= 2; - shift++; - } - return ( FT_Sqrt32( L ) << shift ); - } - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - static int ft_test_extrema( FT_Outline* outline, @@ -291,28 +198,29 @@ } - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Embolden( FT_GlyphSlot original, - FT_Outline* outline, - FT_Pos* advance ) + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { - FT_Vector u, v; - FT_Vector* points; - FT_Vector cur, prev, next; - FT_Pos distance; - FT_Face face = FT_SLOT_FACE( original ); - int c, n, first, orientation; - - FT_UNUSED( advance ); + FT_Vector* points; + FT_Vector v_prev, v_first, v_next, v_cur; + FT_Pos distance; + FT_Outline* outline = &slot->outline; + FT_Face face = FT_SLOT_FACE( slot ); + FT_Angle rotate, angle_in, angle_out; + FT_Int c, n, first, orientation; + /* only embolden outline glyph images */ + if ( slot->format != ft_glyph_format_outline ) + return; /* compute control distance */ distance = FT_MulFix( face->units_per_EM / 60, face->size->metrics.y_scale ); - orientation = ft_get_orientation( &original->outline ); + orientation = ft_get_orientation( outline ); + rotate = FT_ANGLE_PI2*orientation; - points = original->outline.points; + points = outline->points; first = 0; for ( c = 0; c < outline->n_contours; c++ ) @@ -320,79 +228,50 @@ int last = outline->contours[c]; - prev = points[last]; + v_first = points[first]; + v_prev = points[last]; for ( n = first; n <= last; n++ ) { - FT_Pos norm, delta, d; + FT_Pos d; FT_Vector in, out; + FT_Fixed scale; + FT_Angle angle_diff; - cur = points[n]; - if ( n < last ) next = points[n + 1]; - else next = points[first]; + if ( n < last ) v_next = points[n + 1]; + else v_next = v_first; /* compute the in and out vectors */ - in.x = cur.x - prev.x; - in.y = cur.y - prev.y; + in.x = v_cur.x - v_prev.x; + in.y = v_cur.y - v_prev.y; - out.x = next.x - cur.x; - out.y = next.y - cur.y; + out.x = v_next.x - v_cur.x; + out.y = v_next.y - v_cur.y; - /* compute U and V */ - norm = ft_norm( &in ); - u.x = orientation * FT_DivFix( in.y, norm ); - u.y = orientation * -FT_DivFix( in.x, norm ); + angle_in = FT_Atan2( in.x, in.y ); + angle_out = FT_Atan2( out.x, out.y ); + angle_diff = FT_Angle_Diff( angle_in, angle_out ); + scale = FT_Cos( angle_diff/2 ); - norm = ft_norm( &out ); - v.x = orientation * FT_DivFix( out.y, norm ); - v.y = orientation * -FT_DivFix( out.x, norm ); + if ( scale < 0x4000L ) + scale = 0x4000L; - d = distance; + d = FT_DivFix( distance, scale ); - if ( ( outline->tags[n] & FT_Curve_Tag_On ) == 0 ) - d *= 2; + FT_Vector_From_Polar( &in, d, (angle_in+angle_out)/2 + rotate ); - /* Check discriminant for parallel vectors */ - delta = FT_MulFix( u.x, v.y ) - FT_MulFix( u.y, v.x ); - if ( delta > FT_BOLD_THRESHOLD || delta < -FT_BOLD_THRESHOLD ) - { - /* Move point -- compute A and B */ - FT_Pos x, y, A, B; + outline->points[n].x = v_cur.x + distance + in.x; + outline->points[n].y = v_cur.y + distance + in.y; - - A = d + FT_MulFix( cur.x, u.x ) + FT_MulFix( cur.y, u.y ); - B = d + FT_MulFix( cur.x, v.x ) + FT_MulFix( cur.y, v.y ); - - x = FT_MulFix( A, v.y ) - FT_MulFix( B, u.y ); - y = FT_MulFix( B, u.x ) - FT_MulFix( A, v.x ); - - outline->points[n].x = distance + FT_DivFix( x, delta ); - outline->points[n].y = distance + FT_DivFix( y, delta ); - } - else - { - /* Vectors are nearly parallel */ - FT_Pos x, y; - - - x = distance + cur.x + FT_MulFix( d, u.x + v.x ) / 2; - y = distance + cur.y + FT_MulFix( d, u.y + v.y ) / 2; - - outline->points[n].x = x; - outline->points[n].y = y; - } - - prev = cur; + v_prev = v_cur; + v_cur = v_next; } first = last + 1; } - if ( advance ) - *advance = ( *advance + distance * 4 ) & -64; - - return 0; + slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + distance*4 ) & -64; }