* 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
diff --git a/ChangeLog b/ChangeLog
index 429fe1b..1775251 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-07-11 David Turner <david@freetype.org>
+
+ * 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 <peter.kovar@r3.roburnet.sk>
* src/truetype/ttgload.c (load_truetype_glyph): Fix typo.
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 10aad2d..a4d9216 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 );