< prev index next >
src/java.desktop/share/native/libfreetype/src/base/ftstroke.c
Print this page
*** 2,12 ****
*
* ftstroke.c
*
* FreeType path stroker (body).
*
! * Copyright (C) 2002-2019 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
--- 2,12 ----
*
* ftstroke.c
*
* FreeType path stroker (body).
*
! * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
*** 538,604 ****
FT_Vector* center,
FT_Fixed radius,
FT_Angle angle_start,
FT_Angle angle_diff )
{
! FT_Angle total, angle, step, rotate, next, theta;
! FT_Vector a, b, a2, b2;
! FT_Fixed length;
FT_Error error = FT_Err_Ok;
! /* compute start point */
! FT_Vector_From_Polar( &a, radius, angle_start );
! a.x += center->x;
! a.y += center->y;
!
! total = angle_diff;
! angle = angle_start;
! rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2;
!
! while ( total != 0 )
! {
! step = total;
! if ( step > FT_ARC_CUBIC_ANGLE )
! step = FT_ARC_CUBIC_ANGLE;
!
! else if ( step < -FT_ARC_CUBIC_ANGLE )
! step = -FT_ARC_CUBIC_ANGLE;
!
! next = angle + step;
! theta = step;
! if ( theta < 0 )
! theta = -theta;
!
! theta >>= 1;
!
! /* compute end point */
! FT_Vector_From_Polar( &b, radius, next );
! b.x += center->x;
! b.y += center->y;
!
! /* compute first and second control points */
! length = FT_MulDiv( radius, FT_Sin( theta ) * 4,
! ( 0x10000L + FT_Cos( theta ) ) * 3 );
!
! FT_Vector_From_Polar( &a2, length, angle + rotate );
! a2.x += a.x;
! a2.y += a.y;
!
! FT_Vector_From_Polar( &b2, length, next - rotate );
! b2.x += b.x;
! b2.y += b.y;
/* add cubic arc */
! error = ft_stroke_border_cubicto( border, &a2, &b2, &b );
if ( error )
break;
! /* process the rest of the arc ?? */
! a = b;
! total -= step;
! angle = next;
}
return error;
}
--- 538,593 ----
FT_Vector* center,
FT_Fixed radius,
FT_Angle angle_start,
FT_Angle angle_diff )
{
! FT_Fixed coef;
! FT_Vector a0, a1, a2, a3;
! FT_Int i, arcs = 1;
FT_Error error = FT_Err_Ok;
! /* number of cubic arcs to draw */
! while ( angle_diff > FT_ARC_CUBIC_ANGLE * arcs ||
! -angle_diff > FT_ARC_CUBIC_ANGLE * arcs )
! arcs++;
!
! /* control tangents */
! coef = FT_Tan( angle_diff / ( 4 * arcs ) );
! coef += coef / 3;
!
! /* compute start and first control point */
! FT_Vector_From_Polar( &a0, radius, angle_start );
! a1.x = FT_MulFix( -a0.y, coef );
! a1.y = FT_MulFix( a0.x, coef );
!
! a0.x += center->x;
! a0.y += center->y;
! a1.x += a0.x;
! a1.y += a0.y;
!
! for ( i = 1; i <= arcs; i++ )
! {
! /* compute end and second control point */
! FT_Vector_From_Polar( &a3, radius,
! angle_start + i * angle_diff / arcs );
! a2.x = FT_MulFix( a3.y, coef );
! a2.y = FT_MulFix( -a3.x, coef );
!
! a3.x += center->x;
! a3.y += center->y;
! a2.x += a3.x;
! a2.y += a3.y;
/* add cubic arc */
! error = ft_stroke_border_cubicto( border, &a1, &a2, &a3 );
if ( error )
break;
! /* a0 = a3; */
! a1.x = a3.x - a2.x + a3.x;
! a1.y = a3.y - a2.y + a3.y;
}
return error;
}
*** 932,990 ****
stroker->angle_in = angle;
stroker->angle_out = angle + FT_ANGLE_PI;
error = ft_stroker_arcto( stroker, side );
}
! else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
{
! /* add a square cap */
! FT_Vector delta, delta2;
! FT_Angle rotate = FT_SIDE_TO_ROTATE( side );
FT_Fixed radius = stroker->radius;
FT_StrokeBorder border = stroker->borders + side;
! FT_Vector_From_Polar( &delta2, radius, angle + rotate );
! FT_Vector_From_Polar( &delta, radius, angle );
!
! delta.x += stroker->center.x + delta2.x;
! delta.y += stroker->center.y + delta2.y;
! error = ft_stroke_border_lineto( border, &delta, FALSE );
! if ( error )
! goto Exit;
!
! FT_Vector_From_Polar( &delta2, radius, angle - rotate );
! FT_Vector_From_Polar( &delta, radius, angle );
!
! delta.x += delta2.x + stroker->center.x;
! delta.y += delta2.y + stroker->center.y;
!
! error = ft_stroke_border_lineto( border, &delta, FALSE );
}
! else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT )
{
! /* add a butt ending */
! FT_Vector delta;
! FT_Angle rotate = FT_SIDE_TO_ROTATE( side );
! FT_Fixed radius = stroker->radius;
! FT_StrokeBorder border = stroker->borders + side;
!
!
! FT_Vector_From_Polar( &delta, radius, angle + rotate );
! delta.x += stroker->center.x;
! delta.y += stroker->center.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
! FT_Vector_From_Polar( &delta, radius, angle - rotate );
!
! delta.x += stroker->center.x;
! delta.y += stroker->center.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
Exit:
--- 921,964 ----
stroker->angle_in = angle;
stroker->angle_out = angle + FT_ANGLE_PI;
error = ft_stroker_arcto( stroker, side );
}
! else
{
! /* add a square or butt cap */
! FT_Vector middle, delta;
FT_Fixed radius = stroker->radius;
FT_StrokeBorder border = stroker->borders + side;
! /* compute middle point and first angle point */
! FT_Vector_From_Polar( &middle, radius, angle );
! delta.x = side ? middle.y : -middle.y;
! delta.y = side ? -middle.x : middle.x;
! if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
! {
! middle.x += stroker->center.x;
! middle.y += stroker->center.y;
}
! else /* FT_STROKER_LINECAP_BUTT */
{
! middle.x = stroker->center.x;
! middle.y = stroker->center.y;
! }
! delta.x += middle.x;
! delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
! /* compute second angle point */
! delta.x = middle.x - delta.x + middle.x;
! delta.y = middle.y - delta.y + middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
Exit:
*** 998,1009 ****
FT_Int side,
FT_Fixed line_length )
{
FT_StrokeBorder border = stroker->borders + side;
FT_Angle phi, theta, rotate;
! FT_Fixed length, thcos;
! FT_Vector delta;
FT_Error error = FT_Err_Ok;
FT_Bool intersect; /* use intersection of lines? */
rotate = FT_SIDE_TO_ROTATE( side );
--- 972,983 ----
FT_Int side,
FT_Fixed line_length )
{
FT_StrokeBorder border = stroker->borders + side;
FT_Angle phi, theta, rotate;
! FT_Fixed length;
! FT_Vector sigma, delta;
FT_Error error = FT_Err_Ok;
FT_Bool intersect; /* use intersection of lines? */
rotate = FT_SIDE_TO_ROTATE( side );
*** 1017,1029 ****
theta > 0x59C000 || theta < -0x59C000 )
intersect = FALSE;
else
{
/* compute minimum required length of lines */
! FT_Fixed min_length = ft_pos_abs( FT_MulFix( stroker->radius,
! FT_Tan( theta ) ) );
intersect = FT_BOOL( min_length &&
stroker->line_length >= min_length &&
line_length >= min_length );
}
--- 991,1006 ----
theta > 0x59C000 || theta < -0x59C000 )
intersect = FALSE;
else
{
/* compute minimum required length of lines */
! FT_Fixed min_length;
!
+ FT_Vector_Unit( &sigma, theta );
+ min_length =
+ ft_pos_abs( FT_MulDiv( stroker->radius, sigma.y, sigma.x ) );
intersect = FT_BOOL( min_length &&
stroker->line_length >= min_length &&
line_length >= min_length );
}
*** 1038,1054 ****
border->movable = FALSE;
}
else
{
/* compute median angle */
! phi = stroker->angle_in + theta;
!
! thcos = FT_Cos( theta );
! length = FT_DivFix( stroker->radius, thcos );
! FT_Vector_From_Polar( &delta, length, phi + rotate );
delta.x += stroker->center.x;
delta.y += stroker->center.y;
}
error = ft_stroke_border_lineto( border, &delta, FALSE );
--- 1015,1029 ----
border->movable = FALSE;
}
else
{
/* compute median angle */
! phi = stroker->angle_in + theta + rotate;
! length = FT_DivFix( stroker->radius, sigma.x );
! FT_Vector_From_Polar( &delta, length, phi );
delta.x += stroker->center.x;
delta.y += stroker->center.y;
}
error = ft_stroke_border_lineto( border, &delta, FALSE );
*** 1071,1083 ****
if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND )
error = ft_stroker_arcto( stroker, side );
else
{
/* this is a mitered (pointed) or beveled (truncated) corner */
! FT_Fixed sigma = 0, radius = stroker->radius;
FT_Angle theta = 0, phi = 0;
- FT_Fixed thcos = 0;
FT_Bool bevel, fixed_bevel;
rotate = FT_SIDE_TO_ROTATE( side );
--- 1046,1058 ----
if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND )
error = ft_stroker_arcto( stroker, side );
else
{
/* this is a mitered (pointed) or beveled (truncated) corner */
! FT_Fixed radius = stroker->radius;
! FT_Vector sigma;
FT_Angle theta = 0, phi = 0;
FT_Bool bevel, fixed_bevel;
rotate = FT_SIDE_TO_ROTATE( side );
*** 1085,1114 ****
FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_BEVEL );
fixed_bevel =
FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE );
if ( !bevel )
{
! theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
- if ( theta == FT_ANGLE_PI )
- {
- theta = rotate;
- phi = stroker->angle_in;
- }
- else
- {
- theta /= 2;
phi = stroker->angle_in + theta + rotate;
- }
! thcos = FT_Cos( theta );
! sigma = FT_MulFix( stroker->miter_limit, thcos );
/* is miter limit exceeded? */
! if ( sigma < 0x10000L )
{
/* don't create variable bevels for very small deviations; */
/* FT_Sin(x) = 0 for x <= 57 */
if ( fixed_bevel || ft_pos_abs( theta ) > 57 )
bevel = TRUE;
--- 1060,1083 ----
FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_BEVEL );
fixed_bevel =
FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE );
+ /* check miter limit first */
if ( !bevel )
{
! theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2;
!
! if ( theta == FT_ANGLE_PI2 )
! theta = -rotate;
phi = stroker->angle_in + theta + rotate;
! FT_Vector_From_Polar( &sigma, stroker->miter_limit, theta );
/* is miter limit exceeded? */
! if ( sigma.x < 0x10000L )
{
/* don't create variable bevels for very small deviations; */
/* FT_Sin(x) = 0 for x <= 57 */
if ( fixed_bevel || ft_pos_abs( theta ) > 57 )
bevel = TRUE;
*** 1131,1170 ****
delta.y += stroker->center.y;
border->movable = FALSE;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
! else /* variable bevel */
{
/* the miter is truncated */
FT_Vector middle, delta;
! FT_Fixed length;
! /* compute middle point */
FT_Vector_From_Polar( &middle,
FT_MulFix( radius, stroker->miter_limit ),
phi );
- middle.x += stroker->center.x;
- middle.y += stroker->center.y;
! /* compute first angle point */
! length = FT_MulDiv( radius, 0x10000L - sigma,
! ft_pos_abs( FT_Sin( theta ) ) );
! FT_Vector_From_Polar( &delta, length, phi + rotate );
delta.x += middle.x;
delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
/* compute second angle point */
! FT_Vector_From_Polar( &delta, length, phi - rotate );
! delta.x += middle.x;
! delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
--- 1100,1137 ----
delta.y += stroker->center.y;
border->movable = FALSE;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
! else /* variable bevel or clipped miter */
{
/* the miter is truncated */
FT_Vector middle, delta;
! FT_Fixed coef;
! /* compute middle point and first angle point */
FT_Vector_From_Polar( &middle,
FT_MulFix( radius, stroker->miter_limit ),
phi );
! coef = FT_DivFix( 0x10000L - sigma.x, sigma.y );
! delta.x = FT_MulFix( middle.y, coef );
! delta.y = FT_MulFix( -middle.x, coef );
! middle.x += stroker->center.x;
! middle.y += stroker->center.y;
delta.x += middle.x;
delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
/* compute second angle point */
! delta.x = middle.x - delta.x + middle.x;
! delta.y = middle.y - delta.y + middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
*** 1187,1197 ****
{
FT_Fixed length;
FT_Vector delta;
! length = FT_DivFix( stroker->radius, thcos );
FT_Vector_From_Polar( &delta, length, phi );
delta.x += stroker->center.x;
delta.y += stroker->center.y;
--- 1154,1164 ----
{
FT_Fixed length;
FT_Vector delta;
! length = FT_MulDiv( stroker->radius, stroker->miter_limit, sigma.x );
FT_Vector_From_Polar( &delta, length, phi );
delta.x += stroker->center.x;
delta.y += stroker->center.y;
< prev index next >