< 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 >