kdtree code cleanup
[swftools.git] / lib / modules / swfdraw.c
blobba601a3c4bc6557362bf660e0f8bca9535a15f27
1 // swfdraw.c
3 #include "../rfxswf.h"
5 typedef struct _SWFSHAPEDRAWER
7 SHAPE*shape;
8 TAG*tag;
9 int tagfree;
10 SCOORD firstx;
11 SCOORD firsty;
12 SCOORD lastx;
13 SCOORD lasty;
14 SRECT bbox;
15 char isfinished;
16 } 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;
39 sdraw->tagfree = 0;
40 if(tag == 0) {
41 tag = swf_InsertTag(0, ST_DEFINESHAPE);
42 sdraw->tagfree = 1;
44 sdraw->tag = tag;
45 swf_ShapeNew(&sdraw->shape);
46 draw->pos.x = 0;
47 draw->pos.y = 0;
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 */
90 FPOINT to;
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. */
106 if(!x&&!y)
107 x++;
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
112 be seperate
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) {
118 fixEndPoint(draw);
119 swf_ShapeSetMove(sdraw->tag,sdraw->shape,x,y);
120 sdraw->firstx = sdraw->lastx = x;
121 sdraw->firsty = sdraw->lasty = y;
122 draw->pos = *to;
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);
130 if(!x&&!y)
131 x++;
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);
141 sdraw->lastx = x;
142 sdraw->lasty = y;
143 draw->pos = *to;
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);
152 if(!x&&!y)
153 x++;
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);
167 sdraw->lastx = x;
168 sdraw->lasty = y;
169 draw->pos = *to;
171 static void swf_ShapeDrawerFinish(drawer_t*draw)
173 SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
174 if(sdraw->isfinished)
175 return;
177 fixEndPoint(draw);
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;
191 if(sdraw->tagfree) {
192 swf_DeleteTag(0, sdraw->tag);
193 sdraw->tag = 0;
195 swf_ShapeFree(sdraw->shape);
196 sdraw->shape = 0;
198 rfx_free(draw->internal);
199 draw->internal = 0;
202 SRECT swf_ShapeDrawerGetBBox(drawer_t*draw)
204 SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
205 return sdraw->bbox;
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);
220 return shape;