@ -135,8 +135,10 @@
# include <string.h>
# include <setjmp.h>
# include <limits.h>
# define FT_UINT_MAX UINT_MAX
# define FT_INT_MAX INT_MAX
# define FT_CHAR_BIT CHAR_BIT
# define FT_UINT_MAX UINT_MAX
# define FT_INT_MAX INT_MAX
# define FT_ULONG_MAX ULONG_MAX
# define ft_memset memset
@ -366,6 +368,15 @@ typedef ptrdiff_t FT_PtrDist;
# endif /* __arm__ */
/* These macros speed up repetitive divisions by replacing them */
/* with multiplications and right shifts. */
# define FT_UDIVPREP( b ) \
long b # # _r = ( long ) ( FT_ULONG_MAX > > PIXEL_BITS ) / ( b )
# define FT_UDIV( a, b ) \
( ( ( unsigned long ) ( a ) * ( unsigned long ) ( b # # _r ) ) > > \
( sizeof ( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
/*************************************************************************/
/* */
/* TYPE DEFINITIONS */
@ -678,6 +689,7 @@ typedef ptrdiff_t FT_PtrDist;
gray_set_cell ( RAS_VAR_ ex , ey ) ;
}
#if 0
/*************************************************************************/
/* */
@ -910,6 +922,143 @@ typedef ptrdiff_t FT_PtrDist;
ras . y = to_y ;
}
# else
/*************************************************************************/
/* */
/* Render a straight line across multiple cells in any direction. */
/* */
static void
gray_render_line ( RAS_ARG_ TPos to_x ,
TPos to_y )
{
TPos dx , dy , fx1 , fy1 , fx2 , fy2 ;
TCoord ex1 , ex2 , ey1 , ey2 ;
ex1 = TRUNC ( ras . x ) ;
ex2 = TRUNC ( to_x ) ;
ey1 = TRUNC ( ras . y ) ;
ey2 = TRUNC ( to_y ) ;
/* perform vertical clipping */
if ( ( ey1 > = ras . max_ey & & ey2 > = ras . max_ey ) | |
( ey1 < ras . min_ey & & ey2 < ras . min_ey ) )
goto End ;
dx = to_x - ras . x ;
dy = to_y - ras . y ;
fx1 = ras . x - SUBPIXELS ( ex1 ) ;
fy1 = ras . y - SUBPIXELS ( ey1 ) ;
if ( ex1 = = ex2 & & ey1 = = ey2 ) /* inside one cell */
;
else if ( dy = = 0 ) /* ex1 != ex2 */ /* any horizontal line */
{
ex1 = ex2 ;
gray_set_cell ( RAS_VAR_ ex1 , ey1 ) ;
}
else if ( dx = = 0 )
{
if ( dy > 0 ) /* vertical line up */
do
{
fy2 = ONE_PIXEL ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * fx1 * 2 ;
fy1 = 0 ;
ey1 + + ;
gray_set_cell ( RAS_VAR_ ex1 , ey1 ) ;
} while ( ey1 ! = ey2 ) ;
else /* vertical line down */
do
{
fy2 = 0 ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * fx1 * 2 ;
fy1 = ONE_PIXEL ;
ey1 - - ;
gray_set_cell ( RAS_VAR_ ex1 , ey1 ) ;
} while ( ey1 ! = ey2 ) ;
}
else /* any other line */
{
TArea prod = dx * fy1 - dy * fx1 ;
FT_UDIVPREP ( dx ) ;
FT_UDIVPREP ( dy ) ;
/* The fundamental value `prod' determines which side and the */
/* exact coordinate where the line exits current cell. It is */
/* also easily updated when moving from one cell to the next. */
do
{
if ( prod < = 0 & &
prod - dx * ONE_PIXEL > 0 ) /* left */
{
fx2 = 0 ;
fy2 = ( TPos ) FT_UDIV ( - prod , - dx ) ;
prod - = dy * ONE_PIXEL ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * ( fx1 + fx2 ) ;
fx1 = ONE_PIXEL ;
fy1 = fy2 ;
ex1 - - ;
}
else if ( prod - dx * ONE_PIXEL < = 0 & &
prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */
{
prod - = dx * ONE_PIXEL ;
fx2 = ( TPos ) FT_UDIV ( - prod , dy ) ;
fy2 = ONE_PIXEL ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * ( fx1 + fx2 ) ;
fx1 = fx2 ;
fy1 = 0 ;
ey1 + + ;
}
else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL < = 0 & &
prod + dy * ONE_PIXEL > = 0 ) /* right */
{
prod + = dy * ONE_PIXEL ;
fx2 = ONE_PIXEL ;
fy2 = ( TPos ) FT_UDIV ( prod , dx ) ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * ( fx1 + fx2 ) ;
fx1 = 0 ;
fy1 = fy2 ;
ex1 + + ;
}
else /* ( prod + dy * ONE_PIXEL < 0 &&
prod > 0 ) down */
{
fx2 = ( TPos ) FT_UDIV ( prod , - dy ) ;
fy2 = 0 ;
prod + = dx * ONE_PIXEL ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * ( fx1 + fx2 ) ;
fx1 = fx2 ;
fy1 = ONE_PIXEL ;
ey1 - - ;
}
gray_set_cell ( RAS_VAR_ ex1 , ey1 ) ;
} while ( ex1 ! = ex2 | | ey1 ! = ey2 ) ;
}
fx2 = to_x - SUBPIXELS ( ex2 ) ;
fy2 = to_y - SUBPIXELS ( ey2 ) ;
ras . cover + = ( fy2 - fy1 ) ;
ras . area + = ( fy2 - fy1 ) * ( fx1 + fx2 ) ;
End :
ras . x = to_x ;
ras . y = to_y ;
}
# endif
static void
gray_split_conic ( FT_Vector * base )