ref: 58ad559a34e06c1021b15876795417ae4a668fe7
parent: 0d73b0c49abc97cb89d05bb5295769f289d271e2
author: David Turner <[email protected]>
date: Mon Jul 1 17:33:48 EDT 2002
* include/freetype/ftsynth.h, src/base/ftsynth.c: rewriting the automatic style synthesis functions, now renamed to FT_GlyphSlot_Oblique and FT_GlyphSlot_Embolden
--- a/include/freetype/ftsynth.h
+++ b/include/freetype/ftsynth.h
@@ -48,16 +48,14 @@
/* 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
--- 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,19 +35,18 @@
/*************************************************************************/
/*************************************************************************/
- 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;
- FT_UNUSED( original );
+ /* only oblique outline glyphs */
+ if ( slot->format != ft_glyph_format_outline )
+ return;
+
/* 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,98 +69,7 @@
/*************************************************************************/
- /* 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,
int n )
@@ -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_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;
- FT_UNUSED( advance );
+ /* 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;
}