mirror of https://github.com/freetype/freetype
* src/base/ftstroke.c (ft_stroker_outside): Speed up clipped miter.
* include/freetype/ftstroke.h: Wordsmith miter docs.
This commit is contained in:
parent
db4083fd7f
commit
432efa25b3
|
@ -1,3 +1,8 @@
|
|||
2019-09-25 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||
|
||||
* src/base/ftstroke.c (ft_stroker_outside): Speed up clipped miter.
|
||||
* include/freetype/ftstroke.h: Wordsmith miter docs.
|
||||
|
||||
2019-09-25 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/sfnt/sfwoff2.c (woff2_open_font): Check (sum of) table sizes.
|
||||
|
|
|
@ -114,22 +114,19 @@ FT_BEGIN_HEADER
|
|||
* FT_STROKER_LINEJOIN_MITER_FIXED ::
|
||||
* Used to render mitered line joins, with fixed bevels if the miter
|
||||
* limit is exceeded. The outer edges of the strokes for the two
|
||||
* segments are extended until they meet at an angle. If the segments
|
||||
* meet at too sharp an angle (such that the miter would extend from
|
||||
* the intersection of the segments a distance greater than the product
|
||||
* of the miter limit value and the border radius), then a bevel join
|
||||
* (see above) is used instead. This prevents long spikes being
|
||||
* created. `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line
|
||||
* join as used in PostScript and PDF.
|
||||
* segments are extended until they meet at an angle. A bevel join
|
||||
* (see above) is used if the segments meet at too sharp an angle and
|
||||
* the outer edges meet beyond a distance corresponding to the meter
|
||||
* limit. This prevents long spikes being created.
|
||||
* `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line join as
|
||||
* used in PostScript and PDF.
|
||||
*
|
||||
* FT_STROKER_LINEJOIN_MITER_VARIABLE ::
|
||||
* FT_STROKER_LINEJOIN_MITER ::
|
||||
* Used to render mitered line joins, with variable bevels if the miter
|
||||
* limit is exceeded. The intersection of the strokes is clipped at a
|
||||
* line perpendicular to the bisector of the angle between the strokes,
|
||||
* at the distance from the intersection of the segments equal to the
|
||||
* product of the miter limit value and the border radius. This
|
||||
* prevents long spikes being created.
|
||||
* limit is exceeded. The intersection of the strokes is clipped
|
||||
* perpendicularly to the bisector, at a distance corresponding to
|
||||
* the miter limit. This prevents long spikes being created.
|
||||
* `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join
|
||||
* as used in XPS. `FT_STROKER_LINEJOIN_MITER` is an alias for
|
||||
* `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward
|
||||
|
@ -296,13 +293,17 @@ FT_BEGIN_HEADER
|
|||
* The line join style.
|
||||
*
|
||||
* miter_limit ::
|
||||
* The miter limit for the `FT_STROKER_LINEJOIN_MITER_FIXED` and
|
||||
* `FT_STROKER_LINEJOIN_MITER_VARIABLE` line join styles, expressed as
|
||||
* 16.16 fixed-point value.
|
||||
* The maximum reciprocal sine of half-angle at the miter join,
|
||||
* expressed as 16.16 fixed point value.
|
||||
*
|
||||
* @note:
|
||||
* The radius is expressed in the same units as the outline coordinates.
|
||||
*
|
||||
* The miter limit multiplied by the radius gives the maximum size
|
||||
* of a miter spike, at which it is clipped for
|
||||
* `FT_STROKER_LINEJOIN_MITER_VARIABLE` or replaced with a bevel join for
|
||||
* `FT_STROKER_LINEJOIN_MITER_FIXED`.
|
||||
*
|
||||
* This function calls @FT_Stroker_Rewind automatically.
|
||||
*/
|
||||
FT_EXPORT( void )
|
||||
|
|
|
@ -1062,10 +1062,10 @@
|
|||
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;
|
||||
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 );
|
||||
|
@ -1076,26 +1076,20 @@
|
|||
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 );
|
||||
theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2;
|
||||
|
||||
if ( theta == FT_ANGLE_PI )
|
||||
{
|
||||
theta = rotate;
|
||||
phi = stroker->angle_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
theta /= 2;
|
||||
phi = stroker->angle_in + theta + rotate;
|
||||
}
|
||||
if ( theta == FT_ANGLE_PI2 )
|
||||
theta = -rotate;
|
||||
|
||||
thcos = FT_Cos( theta );
|
||||
sigma = FT_MulFix( stroker->miter_limit, thcos );
|
||||
phi = stroker->angle_in + theta + rotate;
|
||||
|
||||
FT_Vector_From_Polar( &sigma, stroker->miter_limit, theta );
|
||||
|
||||
/* is miter limit exceeded? */
|
||||
if ( sigma < 0x10000L )
|
||||
if ( sigma.x < 0x10000L )
|
||||
{
|
||||
/* don't create variable bevels for very small deviations; */
|
||||
/* FT_Sin(x) = 0 for x <= 57 */
|
||||
|
@ -1122,36 +1116,34 @@
|
|||
border->movable = FALSE;
|
||||
error = ft_stroke_border_lineto( border, &delta, FALSE );
|
||||
}
|
||||
else /* variable bevel */
|
||||
else /* variable bevel or clipped miter */
|
||||
{
|
||||
/* the miter is truncated */
|
||||
FT_Vector middle, delta;
|
||||
FT_Fixed length;
|
||||
FT_Fixed coef;
|
||||
|
||||
|
||||
/* compute middle point */
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
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 )
|
||||
|
@ -1178,7 +1170,7 @@
|
|||
FT_Vector delta;
|
||||
|
||||
|
||||
length = FT_DivFix( stroker->radius, thcos );
|
||||
length = FT_MulDiv( stroker->radius, stroker->miter_limit, sigma.x );
|
||||
|
||||
FT_Vector_From_Polar( &delta, length, phi );
|
||||
delta.x += stroker->center.x;
|
||||
|
|
Loading…
Reference in New Issue