5 typedef struct _SWFSHAPEDRAWER
18 static void swf_ShapeDrawerSetLineStyle(drawer_t
*draw
, void*style
);
19 static void swf_ShapeDrawerSetFillStyle(drawer_t
*draw
, void*style
);
20 static void swf_ShapeDrawerMoveTo(drawer_t
*draw
, FPOINT
* to
);
21 static void swf_ShapeDrawerLineTo(drawer_t
*draw
, FPOINT
* to
);
22 static void swf_ShapeDrawerSplineTo(drawer_t
*draw
, FPOINT
* c1
, FPOINT
* to
);
23 static void swf_ShapeDrawerFinish(drawer_t
*draw
);
24 static void swf_ShapeDrawerClear(drawer_t
*draw
);
26 static void swf_ShapeDrawerInit(drawer_t
*draw
, TAG
*tag
, int fillstylebits
, int linestylebits
)
28 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)rfx_calloc(sizeof(SWFSHAPEDRAWER
));
29 draw
->internal
= sdraw
;
31 draw
->setLineStyle
= swf_ShapeDrawerSetLineStyle
;
32 draw
->setFillStyle
= swf_ShapeDrawerSetFillStyle
;
33 draw
->moveTo
= swf_ShapeDrawerMoveTo
;
34 draw
->lineTo
= swf_ShapeDrawerLineTo
;
35 draw
->splineTo
= swf_ShapeDrawerSplineTo
;
36 draw
->finish
= swf_ShapeDrawerFinish
;
37 draw
->dealloc
= swf_ShapeDrawerClear
;
41 tag
= swf_InsertTag(0, ST_DEFINESHAPE
);
45 swf_ShapeNew(&sdraw
->shape
);
49 swf_SetU8(sdraw
->tag
,0);
50 sdraw
->shape
->bits
.fill
= fillstylebits
;
51 sdraw
->shape
->bits
.line
= linestylebits
;
53 sdraw
->bbox
.xmin
= sdraw
->bbox
.ymin
= SCOORD_MAX
;
54 sdraw
->bbox
.xmax
= sdraw
->bbox
.ymax
= SCOORD_MIN
;
56 sdraw
->isfinished
= 0;
58 swf_ShapeSetStyle(sdraw
->tag
,sdraw
->shape
,linestylebits
?1:0,fillstylebits
?1:0,0/*?*/);
61 void swf_Shape10DrawerInit(drawer_t
*draw
, TAG
*tag
)
63 swf_ShapeDrawerInit(draw
, tag
, 0, 1);
66 void swf_Shape01DrawerInit(drawer_t
*draw
, TAG
*tag
)
68 swf_ShapeDrawerInit(draw
, tag
, 1, 0);
71 void swf_Shape11DrawerInit(drawer_t
*draw
, TAG
*tag
)
73 swf_ShapeDrawerInit(draw
, tag
, 1, 1);
76 static void swf_ShapeDrawerSetLineStyle(drawer_t
*draw
, void*style
)
78 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
80 static void swf_ShapeDrawerSetFillStyle(drawer_t
*draw
, void*style
)
82 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
84 static void fixEndPoint(drawer_t
*draw
)
86 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
87 if( sdraw
->firstx
!= sdraw
->lastx
88 || sdraw
->firsty
!= sdraw
->lasty
) {
89 /* fix non-closing shapes */
91 to
.x
= sdraw
->firstx
/20.0;
92 to
.y
= sdraw
->firsty
/20.0;
93 if(sdraw
->shape
->bits
.fill
) // do this only if the shape is filled
94 draw
->lineTo(draw
, &to
);
97 static void swf_ShapeDrawerMoveTo(drawer_t
*draw
, FPOINT
* to
)
99 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
100 int x
= floor(to
->x
*20);
101 int y
= floor(to
->y
*20);
103 /* Flash will ignore a moveto (0,0) in glyphs. Hence, we map
104 all (0,0)s to (0.05,0)s in moveto,lineto and splineto. */
109 /* we need to write moveto always- it
110 might be that it signals the end of a polygon, otherwise
111 we would end up connecting two polygons which should
113 TODO: check if the last operation was a moveTo- if
114 yes we *can* skip it.
117 //if(sdraw->lastx != x || sdraw->lasty != y) {
119 swf_ShapeSetMove(sdraw
->tag
,sdraw
->shape
,x
,y
);
120 sdraw
->firstx
= sdraw
->lastx
= x
;
121 sdraw
->firsty
= sdraw
->lasty
= y
;
125 static void swf_ShapeDrawerLineTo(drawer_t
*draw
, FPOINT
* to
)
127 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
128 int x
= floor(to
->x
*20);
129 int y
= floor(to
->y
*20);
132 if(sdraw
->lastx
< sdraw
->bbox
.xmin
) sdraw
->bbox
.xmin
= sdraw
->lastx
;
133 if(sdraw
->lasty
< sdraw
->bbox
.ymin
) sdraw
->bbox
.ymin
= sdraw
->lasty
;
134 if(sdraw
->lastx
> sdraw
->bbox
.xmax
) sdraw
->bbox
.xmax
= sdraw
->lastx
;
135 if(sdraw
->lasty
> sdraw
->bbox
.ymax
) sdraw
->bbox
.ymax
= sdraw
->lasty
;
136 if(x
< sdraw
->bbox
.xmin
) sdraw
->bbox
.xmin
= x
;
137 if(y
< sdraw
->bbox
.ymin
) sdraw
->bbox
.ymin
= y
;
138 if(x
> sdraw
->bbox
.xmax
) sdraw
->bbox
.xmax
= x
;
139 if(y
> sdraw
->bbox
.ymax
) sdraw
->bbox
.ymax
= y
;
140 swf_ShapeSetLine(sdraw
->tag
,sdraw
->shape
,x
-sdraw
->lastx
,y
-sdraw
->lasty
);
145 static void swf_ShapeDrawerSplineTo(drawer_t
*draw
, FPOINT
* c1
, FPOINT
* to
)
147 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
148 int tx
= floor(c1
->x
*20);
149 int ty
= floor(c1
->y
*20);
150 int x
= floor(to
->x
*20);
151 int y
= floor(to
->y
*20);
154 if(sdraw
->lastx
< sdraw
->bbox
.xmin
) sdraw
->bbox
.xmin
= sdraw
->lastx
;
155 if(sdraw
->lasty
< sdraw
->bbox
.ymin
) sdraw
->bbox
.ymin
= sdraw
->lasty
;
156 if(sdraw
->lastx
> sdraw
->bbox
.xmax
) sdraw
->bbox
.xmax
= sdraw
->lastx
;
157 if(sdraw
->lasty
> sdraw
->bbox
.ymax
) sdraw
->bbox
.ymax
= sdraw
->lasty
;
158 if(x
< sdraw
->bbox
.xmin
) sdraw
->bbox
.xmin
= x
;
159 if(y
< sdraw
->bbox
.ymin
) sdraw
->bbox
.ymin
= y
;
160 if(x
> sdraw
->bbox
.xmax
) sdraw
->bbox
.xmax
= x
;
161 if(y
> sdraw
->bbox
.ymax
) sdraw
->bbox
.ymax
= y
;
162 if(tx
< sdraw
->bbox
.xmin
) sdraw
->bbox
.xmin
= tx
;
163 if(ty
< sdraw
->bbox
.ymin
) sdraw
->bbox
.ymin
= ty
;
164 if(tx
> sdraw
->bbox
.xmax
) sdraw
->bbox
.xmax
= tx
;
165 if(ty
> sdraw
->bbox
.ymax
) sdraw
->bbox
.ymax
= ty
;
166 swf_ShapeSetCurve(sdraw
->tag
,sdraw
->shape
, tx
-sdraw
->lastx
,ty
-sdraw
->lasty
, x
-tx
,y
-ty
);
171 static void swf_ShapeDrawerFinish(drawer_t
*draw
)
173 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
174 if(sdraw
->isfinished
)
179 if(sdraw
->bbox
.xmin
== SCOORD_MAX
) {
180 /* no points at all -> empty bounding box */
181 sdraw
->bbox
.xmin
= sdraw
->bbox
.ymin
=
182 sdraw
->bbox
.xmax
= sdraw
->bbox
.ymax
= 0;
184 sdraw
->isfinished
= 1;
185 swf_ShapeSetEnd(sdraw
->tag
);
188 static void swf_ShapeDrawerClear(drawer_t
*draw
)
190 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
192 swf_DeleteTag(0, sdraw
->tag
);
195 swf_ShapeFree(sdraw
->shape
);
198 rfx_free(draw
->internal
);
202 SRECT
swf_ShapeDrawerGetBBox(drawer_t
*draw
)
204 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
208 SHAPE
* swf_ShapeDrawerToShape(drawer_t
*draw
)
210 SWFSHAPEDRAWER
*sdraw
= (SWFSHAPEDRAWER
*)draw
->internal
;
211 SHAPE
* shape
= (SHAPE
*)rfx_alloc(sizeof(SHAPE
));
212 if(!sdraw
->isfinished
) {
213 fprintf(stderr
, "Warning: you should Finish() your drawer before calling DrawerToShape");
214 swf_ShapeDrawerFinish(draw
);
216 memcpy(shape
, sdraw
->shape
, sizeof(SHAPE
));
217 shape
->bitlen
= (sdraw
->tag
->len
-1)*8;
218 shape
->data
= (U8
*)rfx_alloc(sdraw
->tag
->len
-1);
219 memcpy(shape
->data
, &sdraw
->tag
->data
[1], sdraw
->tag
->len
-1);