From 629d7df9111674207610e6c96ab43bd28ef0f514 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 11 Jul 2004 21:09:06 +0000 Subject: [PATCH] * src/base/ftstroke.c: fixed a bug that prevented the stroker to correctly generate stroked paths from closed paths, i.e. nearly all glyphs in vectorial fonts :-) The code is still _very_ buggy though, treat with special care. --- ChangeLog | 8 +++++ src/base/ftstroke.c | 78 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 429fe1ba9..17752515d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-07-11 David Turner + + * src/base/ftstroke.c: fixed a bug that prevented the stroker to + correctly generate stroked paths from closed paths, i.e. nearly + all glyphs in vectorial fonts :-) + + The code is still _very_ buggy though, treat with special care. + 2004-06-26 Peter Kovar * src/truetype/ttgload.c (load_truetype_glyph): Fix typo. diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index 10aad2db8..a4d92162e 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -234,6 +234,7 @@ } FT_StrokeTags; +#define FT_STROKE_TAG_BEGIN_END (FT_STROKE_TAG_BEGIN|FT_STROKE_TAG_END) typedef struct FT_StrokeBorderRec_ { @@ -626,6 +627,54 @@ } + static void + ft_stroke_border_reverse( FT_StrokeBorder border ) + { + FT_Vector* point1 = border->points + border->start; + FT_Vector* point2 = border->points + border->num_points-1; + FT_Byte* tag1 = border->tags + border->start; + FT_Byte* tag2 = border->tags + border->num_points-1; + + while ( point1 < point2 ) + { + FT_Vector tpoint; + FT_Byte ttag1, ttag2, ttag; + + /* swap the points + */ + tpoint = *point1; + *point1 = *point2; + *point2 = tpoint; + + /* swap the tags + */ + ttag1 = *tag1; + ttag2 = *tag2; + +#if 0 + ttag = ttag1 & FT_STROKE_TAG_BEGIN_END; + if ( ttag == FT_STROKE_TAG_BEGIN || + ttag == FT_STROKE_TAG_END ) + ttag1 ^= FT_STROKE_TAG_BEGIN_END; + + ttag = ttag2 & FT_STROKE_TAG_BEGIN_END; + if ( ttag == FT_STROKE_TAG_BEGIN || + ttag == FT_STROKE_TAG_END ) + ttag2 ^= FT_STROKE_TAG_BEGIN_END; +#endif + + *tag1 = ttag2; + *tag2 = ttag1; + + point1++; + point2--; + tag1++; + tag2--; + } + } + + + /***************************************************************************/ /***************************************************************************/ /***** *****/ @@ -805,7 +854,7 @@ { FT_StrokeBorder border = stroker->borders + side; FT_Angle phi, theta, rotate; - FT_Fixed length, thcos, sigma; + FT_Fixed length, thcos; FT_Vector delta; FT_Error error = 0; @@ -822,9 +871,10 @@ phi = stroker->angle_in + theta; thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); - if ( sigma < 0x10000L ) + /* TODO: find better criterion + */ + if ( thcos < 0x4000 ) { FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); @@ -1351,12 +1401,18 @@ *dst_tag = *src_tag; if ( open ) - dst_tag[0] &= ~( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); + dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; else { + FT_Byte ttag = dst_tag[0] & FT_STROKE_TAG_BEGIN_END; + /* switch begin/end tags if necessary.. */ - if ( dst_tag[0] & ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ) ) - dst_tag[0] ^= ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); + if ( ttag == FT_STROKE_TAG_BEGIN || + ttag == FT_STROKE_TAG_END ) + { + dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END; + } + } src_point--; @@ -1440,11 +1496,9 @@ if ( turn < 0 ) inside_side = 1; - /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE! */ - /* process the inside side */ - /* error = ft_stroker_inside( stroker, inside_side ); */ - /* if ( error ) */ - /* goto Exit; */ + error = ft_stroker_inside( stroker, inside_side ); + if ( error ) + goto Exit; /* process the outside side */ error = ft_stroker_outside( stroker, 1 - inside_side ); @@ -1452,6 +1506,8 @@ goto Exit; } + ft_stroke_border_reverse( stroker->borders+0 ); + /* then end our two subpaths */ ft_stroke_border_close( stroker->borders + 0 ); ft_stroke_border_close( stroker->borders + 1 );