b54a0e4d1ddc1ced32d96ebc226208416cd928de
[swftools.git] / lib / modules / swfdraw.c
1 // swfdraw.c
2
3 typedef struct _SWFSHAPEDRAWER
4 {
5     SHAPE*shape;
6     TAG*tag;
7     int tagfree;
8     SCOORD lastx;
9     SCOORD lasty;
10     SRECT bbox;
11     char isfinished;
12 } SWFSHAPEDRAWER;
13
14 static void swf_ShapeDrawerSetLineStyle(drawer_t*draw, void*style);
15 static void swf_ShapeDrawerSetFillStyle(drawer_t*draw, void*style);
16 static void swf_ShapeDrawerMoveTo(drawer_t*draw, FPOINT * to);
17 static void swf_ShapeDrawerLineTo(drawer_t*draw, FPOINT * to);
18 static void swf_ShapeDrawerSplineTo(drawer_t*draw, FPOINT * c1, FPOINT*  to);
19 static void swf_ShapeDrawerFinish(drawer_t*draw);
20 static void swf_ShapeDrawerClear(drawer_t*draw);
21
22 static void swf_ShapeDrawerInit(drawer_t*draw, TAG*tag, int fillstylebits, int linestylebits)
23 {
24     SWFSHAPEDRAWER*sdraw = malloc(sizeof(SWFSHAPEDRAWER));
25     memset(sdraw, 0, sizeof(SWFSHAPEDRAWER));
26     draw->internal = sdraw;
27
28     draw->setLineStyle = swf_ShapeDrawerSetLineStyle;
29     draw->setFillStyle = swf_ShapeDrawerSetFillStyle;
30     draw->moveTo = swf_ShapeDrawerMoveTo;
31     draw->lineTo = swf_ShapeDrawerLineTo;
32     draw->splineTo = swf_ShapeDrawerSplineTo;
33     draw->finish = swf_ShapeDrawerFinish;
34     draw->dealloc = swf_ShapeDrawerClear;
35     
36     sdraw->tagfree = 0;
37     if(tag == 0) {
38         tag = swf_InsertTag(0, ST_DEFINESHAPE);
39         sdraw->tagfree = 1;
40     }
41     sdraw->tag = tag;
42     swf_ShapeNew(&sdraw->shape);
43     draw->pos.x = 0;
44     draw->pos.y = 0;
45
46     swf_SetU8(sdraw->tag,0);
47     sdraw->shape->bits.fill = fillstylebits;
48     sdraw->shape->bits.line = linestylebits;
49     
50     sdraw->bbox.xmin = sdraw->bbox.ymin = SCOORD_MAX;
51     sdraw->bbox.xmax = sdraw->bbox.ymax = SCOORD_MIN;
52
53     sdraw->isfinished = 0;
54
55     swf_ShapeSetStyle(sdraw->tag,sdraw->shape,linestylebits?1:0,fillstylebits?1:0,0/*?*/);
56 }
57
58 void swf_Shape01DrawerInit(drawer_t*draw, TAG*tag)
59 {
60     swf_ShapeDrawerInit(draw, tag, 1, 0);
61 }
62
63 void swf_Shape11DrawerInit(drawer_t*draw, TAG*tag)
64 {
65     swf_ShapeDrawerInit(draw, tag, 1, 1);
66 }
67
68 static void swf_ShapeDrawerSetLineStyle(drawer_t*draw, void*style)
69 {
70     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
71 }
72 static void swf_ShapeDrawerSetFillStyle(drawer_t*draw, void*style)
73 {
74     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
75 }
76 static void swf_ShapeDrawerMoveTo(drawer_t*draw, FPOINT * to)
77 {
78     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
79     int x = to->x*20;
80     int y = to->y*20;
81     swf_ShapeSetMove(sdraw->tag,sdraw->shape,x,y);
82     sdraw->lastx = x;
83     sdraw->lasty = y;
84     draw->pos = *to;
85 }
86 static void swf_ShapeDrawerLineTo(drawer_t*draw, FPOINT * to)
87 {
88     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
89     int x = to->x*20;
90     int y = to->y*20;
91     if(sdraw->lastx < sdraw->bbox.xmin) sdraw->bbox.xmin = sdraw->lastx;
92     if(sdraw->lasty < sdraw->bbox.ymin) sdraw->bbox.ymin = sdraw->lasty;
93     if(sdraw->lastx > sdraw->bbox.xmax) sdraw->bbox.xmax = sdraw->lastx;
94     if(sdraw->lasty > sdraw->bbox.ymax) sdraw->bbox.ymax = sdraw->lasty;
95     if(x < sdraw->bbox.xmin) sdraw->bbox.xmin = x;
96     if(y < sdraw->bbox.ymin) sdraw->bbox.ymin = y;
97     if(x > sdraw->bbox.xmax) sdraw->bbox.xmax = x;
98     if(y > sdraw->bbox.ymax) sdraw->bbox.ymax = y;
99     swf_ShapeSetLine(sdraw->tag,sdraw->shape,x-sdraw->lastx,y-sdraw->lasty);
100     sdraw->lastx = x;
101     sdraw->lasty = y;
102     draw->pos = *to;
103 }
104 static void swf_ShapeDrawerSplineTo(drawer_t*draw, FPOINT * c1, FPOINT*  to)
105 {
106     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
107     int tx = c1->x*20;
108     int ty = c1->y*20;
109     int x = to->x*20;
110     int y = to->y*20;
111     if(sdraw->lastx < sdraw->bbox.xmin) sdraw->bbox.xmin = sdraw->lastx;
112     if(sdraw->lasty < sdraw->bbox.ymin) sdraw->bbox.ymin = sdraw->lasty;
113     if(sdraw->lastx > sdraw->bbox.xmax) sdraw->bbox.xmax = sdraw->lastx;
114     if(sdraw->lasty > sdraw->bbox.ymax) sdraw->bbox.ymax = sdraw->lasty;
115     if(x < sdraw->bbox.xmin) sdraw->bbox.xmin = x;
116     if(y < sdraw->bbox.ymin) sdraw->bbox.ymin = y;
117     if(x > sdraw->bbox.xmax) sdraw->bbox.xmax = x;
118     if(y > sdraw->bbox.ymax) sdraw->bbox.ymax = y;
119     if(tx < sdraw->bbox.xmin) sdraw->bbox.xmin = tx;
120     if(ty < sdraw->bbox.ymin) sdraw->bbox.ymin = ty;
121     if(tx > sdraw->bbox.xmax) sdraw->bbox.xmax = tx;
122     if(ty > sdraw->bbox.ymax) sdraw->bbox.ymax = ty;
123     swf_ShapeSetCurve(sdraw->tag,sdraw->shape, tx-sdraw->lastx,ty-sdraw->lasty, x-tx,y-ty);
124     sdraw->lastx = x;
125     sdraw->lasty = y;
126     draw->pos = *to;
127 }
128 static void swf_ShapeDrawerFinish(drawer_t*draw)
129 {
130     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
131     if(sdraw->bbox.xmin == SCOORD_MAX) {
132         /* no points at all -> empty bounding box */
133         sdraw->bbox.xmin = sdraw->bbox.ymin = 
134         sdraw->bbox.xmax = sdraw->bbox.ymax = 0;
135     }
136     sdraw->isfinished = 1;
137     swf_ShapeSetEnd(sdraw->tag);
138 }
139
140 static void swf_ShapeDrawerClear(drawer_t*draw)
141 {
142     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
143     if(sdraw->tagfree) {
144         swf_DeleteTag(sdraw->tag);
145         sdraw->tag = 0;
146     }
147     swf_ShapeFree(sdraw->shape);
148     sdraw->shape = 0;
149
150     free(draw->internal);
151     draw->internal = 0;
152 }
153
154 SRECT swf_ShapeDrawerGetBBox(drawer_t*draw)
155 {
156     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
157     return sdraw->bbox;
158 }
159
160 SHAPE* swf_ShapeDrawerToShape(drawer_t*draw)
161 {
162     SWFSHAPEDRAWER*sdraw = (SWFSHAPEDRAWER*)draw->internal;
163     SHAPE* shape = malloc(sizeof(SHAPE));
164     if(!sdraw->isfinished) {
165         fprintf(stderr, "Warning: you should Finish() your drawer before calling DrawerToShape");
166         swf_ShapeDrawerFinish(draw);
167     }
168     memcpy(shape, sdraw->shape, sizeof(SHAPE));
169     shape->bitlen = (sdraw->tag->len-1)*8;
170     shape->data = (U8*)malloc(sdraw->tag->len-1);
171     memcpy(shape->data, &sdraw->tag->data[1], sdraw->tag->len-1);
172     return shape;
173 }