@ -668,6 +668,168 @@
}
# define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \
do { \
( first ) = ( c > 0 ) ? ( outline ) - > points + \
( outline ) - > contours [ c - 1 ] + 1 \
: ( outline ) - > points ; \
( last ) = ( outline ) - > points + ( outline ) - > contours [ c ] ; \
} while ( 0 )
/* Is a point in some contour? */
/* */
/* We treat every point of the contour as if it */
/* it is ON. That is, we allow false positive, */
/* but disallow false negative. (XXX really?) */
static FT_Bool
ft_contour_has ( FT_Outline * outline ,
FT_Short c ,
FT_Vector * point )
{
FT_Vector * first ;
FT_Vector * last ;
FT_Vector * a ;
FT_Vector * b ;
FT_UInt n = 0 ;
FT_OUTLINE_GET_CONTOUR ( outline , c , first , last ) ;
for ( a = first ; a < = last ; a + + )
{
FT_Pos x ;
FT_Int intersect ;
b = ( a = = last ) ? first : a + 1 ;
intersect = ( a - > y - point - > y ) ^ ( b - > y - point - > y ) ;
/* a and b are on the same side */
if ( intersect > = 0 )
{
if ( intersect = = 0 & & a - > y = = point - > y )
{
if ( ( a - > x < = point - > x & & b - > x > = point - > x ) | |
( a - > x > = point - > x & & b - > x < = point - > x ) )
return 1 ;
}
continue ;
}
x = a - > x + ( b - > x - a - > x ) * ( point - > y - a - > y ) / ( b - > y - a - > y ) ;
if ( x < point - > x )
n + + ;
else if ( x = = point - > x )
return 1 ;
}
return ( n % 2 ) ;
}
static FT_Bool
ft_contour_enclosed ( FT_Outline * outline ,
FT_UShort c )
{
FT_Vector * first ;
FT_Vector * last ;
FT_Short i ;
FT_OUTLINE_GET_CONTOUR ( outline , c , first , last ) ;
for ( i = 0 ; i < outline - > n_contours ; i + + )
{
if ( i ! = c & & ft_contour_has ( outline , i , first ) )
{
FT_Vector * pt ;
for ( pt = first + 1 ; pt < = last ; pt + + )
if ( ! ft_contour_has ( outline , i , pt ) )
return 0 ;
return 1 ;
}
}
return 0 ;
}
/* This version differs from the public one in that each */
/* part (contour not enclosed in another contour) of the */
/* outline is checked for orientation. This is */
/* necessary for some buggy CJK fonts. */
static FT_Orientation
ft_outline_get_orientation ( FT_Outline * outline )
{
FT_Short i ;
FT_Vector * first ;
FT_Vector * last ;
FT_Orientation orient = FT_ORIENTATION_NONE ;
first = outline - > points ;
for ( i = 0 ; i < outline - > n_contours ; i + + , first = last + 1 )
{
FT_Vector * point ;
FT_Vector * xmin_point ;
FT_Pos xmin ;
last = outline - > points + outline - > contours [ i ] ;
/* skip degenerate contours */
if ( last < first + 2 )
continue ;
if ( ft_contour_enclosed ( outline , i ) )
continue ;
xmin = first - > x ;
xmin_point = first ;
for ( point = first + 1 ; point < = last ; point + + )
{
if ( point - > x < xmin )
{
xmin = point - > x ;
xmin_point = point ;
}
}
/* check the orientation of the contour */
{
FT_Vector * prev ;
FT_Vector * next ;
FT_Orientation o ;
prev = ( xmin_point = = first ) ? last : xmin_point - 1 ;
next = ( xmin_point = = last ) ? first : xmin_point + 1 ;
if ( FT_Atan2 ( prev - > x - xmin_point - > x , prev - > y - xmin_point - > y ) >
FT_Atan2 ( next - > x - xmin_point - > x , next - > y - xmin_point - > y ) )
o = FT_ORIENTATION_POSTSCRIPT ;
else
o = FT_ORIENTATION_TRUETYPE ;
if ( orient = = FT_ORIENTATION_NONE )
orient = o ;
else if ( orient ! = o )
return FT_ORIENTATION_NONE ;
}
}
return orient ;
}
/* documentation is in ftoutln.h */
FT_EXPORT_DEF ( FT_Error )
@ -678,6 +840,7 @@
FT_Vector v_prev , v_first , v_next , v_cur ;
FT_Angle rotate , angle_in , angle_out ;
FT_Int c , n , first ;
FT_Int orientation ;
if ( ! outline )
@ -687,7 +850,16 @@
if ( strength = = 0 )
return FT_Err_Ok ;
if ( FT_Outline_Get_Orientation ( outline ) = = FT_ORIENTATION_TRUETYPE )
orientation = ft_outline_get_orientation ( outline ) ;
if ( orientation = = FT_ORIENTATION_NONE )
{
if ( outline - > n_contours )
return FT_Err_Invalid_Argument ;
else
return FT_Err_Ok ;
}
if ( orientation = = FT_ORIENTATION_TRUETYPE )
rotate = - FT_ANGLE_PI2 ;
else
rotate = FT_ANGLE_PI2 ;