1 /*
2 Ming, an SWF output library
3 Copyright (C) 2002 Opaque Industries - http://www.opaque.net/
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <math.h>
21 #include <stdlib.h>
22
23 #include "ming.h"
24 #include "shape_util.h"
25 #include "blocks/character.h"
26 #include "blocks/shape.h"
27 #include "blocks/matrix.h"
28 #include "movie.h"
29 #include "fill.h"
30 #include "libming.h"
31
32
33 /* This function returns a characters width.
34 * The characters width is return in px. If a character has no bounds
35 * -1 is returned.
36 */
37 float SWFCharacter_getWidth(SWFCharacter character)
38 {
39 if(character->bounds == NULL)
40 return -1;
41
42 return SWFCharacter_getScaledWidth(character) / Ming_scale;
43 }
44
45 /* This function returns a characters height.
46 * The characters height is return in px. If a character has no bounds
47 * -1 is returned.
48 */
49 float SWFCharacter_getHeight(SWFCharacter character)
50 {
51 if(character->bounds == NULL)
52 return -1;
53
destroySWFMovieClip(SWFMovieClip movieClip)54 return SWFCharacter_getScaledHeight(character) / Ming_scale;
55 }
56
57
58 /*
59 * set line width and line color
60 *
61 * set line width in px
62 * set line color as {r, g, b, a}
63 *
64 */
65 void SWFShape_setLine(SWFShape shape, unsigned short width,
66 byte r, byte g, byte b, byte a)
67 {
68 SWFShape_setLineStyle_internal(shape, width * Ming_scale, r, g, b, a);
69 }
70
71 /*
72 * set Linestyle2 introduce with SWF 8.
73 *
newSWFMovieClip()74 * set line width in pixel
75 * set color {r, g, b, a}
76 *
77 * Linestyle2 extends Linestyle1 with some extra flags:
78 *
79 * Line cap style: select one of the following flags (default is round cap style)
80 * SWF_LINESTYLE_CAP_ROUND
81 * SWF_LINESTYLE_CAP_NONE
82 * SWF_LINESTYLE_CAP_SQUARE
83 *
84 * Line join style: select one of the following flags (default is round join style)
85 * SWF_LINESTYLE_JOIN_ROUND
86 * SWF_LINESTYLE_JOIN_BEVEL
87 * SWF_LINESTYLE_JOIN_MITER
88 *
89 * Scaling flags: disable horizontal / vertical scaling
90 * SWF_LINESTYLE_FLAG_NOHSCALE
91 * SWF_LINESTYLE_FLAG_NOVSCALE
92 *
93 * Enable pixel hinting to correct blurry vertical / horizontal lines
94 * -> all anchors will be aligned to full pixels
95 * SWF_LINESTYLE_FLAG_HINTING
96 *
97 * Disable stroke closure: if no-close flag is set caps will be applied
98 * instead of joins
99 * SWF_LINESTYLE_FLAG_NOCLOSE
100 *
101 * End-cap style: default round
102 * SWF_LINESTYLE_FLAG_ENDCAP_ROUND
103 * SWF_LINESTYLE_FLAG_ENDCAP_NONE
104 * SWF_LINESTYLE_FLAG_ENDCAP_SQUARE
105 *
106 * If join style is SWF_LINESTYLE_JOIN_MITER a miter limit factor
107 * must be set. Miter max length is then calculated as:
108 * max miter len = miter limit * width.
109 * If join style is not miter, this value will be ignored.
110 */
111 void SWFShape_setLine2(SWFShape shape, unsigned short width,
112 byte r, byte g, byte b, byte a,
113 int flags, float miterLimit)
114 {
115 SWFShape_setLineStyle2_internal(shape, width * Ming_scale,
116 r, g, b, a, flags, miterLimit);
117 }
118
119 /*
120 * set filled Linestyle2 introduce with SWF 8.
121 *
122 * set line width in pixel
123 *
124 * Instead of providing a fill color, a FillStyle can be applied
125 * to a line.
126 *
127 * Linestyle2 also extends Linestyle1 with some extra flags:
128 *
129 * Line cap style: select one of the following flags (default is round cap style)
130 * SWF_LINESTYLE_CAP_ROUND
131 * SWF_LINESTYLE_CAP_NONE
132 * SWF_LINESTYLE_CAP_SQUARE
133 *
SWFMovieClip_setSoundStream(SWFMovieClip clip,SWFSoundStream sound,float rate)134 * Line join style: select one of the following flags (default is round join style)
135 * SWF_LINESTYLE_JOIN_ROUND
136 * SWF_LINESTYLE_JOIN_BEVEL
137 * SWF_LINESTYLE_JOIN_MITER
138 *
139 * Scaling flags: disable horizontal / vertical scaling
140 * SWF_LINESTYLE_FLAG_NOHSCALE
141 * SWF_LINESTYLE_FLAG_NOVSCALE
142 *
143 * Enable pixel hinting to correct blurry vertical / horizontal lines
144 * -> all anchors will be aligned to full pixels
145 * SWF_LINESTYLE_FLAG_HINTING
146 *
147 * Disable stroke closure: if no-close flag is set caps will be applied
148 * instead of joins
149 * SWF_LINESTYLE_FLAG_NOCLOSE
150 *
151 * End-cap style: default round
152 * SWF_LINESTYLE_FLAG_ENDCAP_ROUND
153 * SWF_LINESTYLE_FLAG_ENDCAP_NONE
154 * SWF_LINESTYLE_FLAG_ENDCAP_SQUARE
155 *
156 * If join style is SWF_LINESTYLE_JOIN_MITER a miter limit factor
157 * must be set. Miter max length is then calculated as:
158 * max miter len = miter limit * width.
159 * If join style is not miter, this value will be ignored.
160 */
161 void SWFShape_setLine2Filled(SWFShape shape, unsigned short width,
162 SWFFillStyle fill,
163 int flags, float miterLimit)
164 {
165 SWFShape_setLineStyle2filled_internal(shape, width * Ming_scale,
166 fill, flags, miterLimit);
167 }
168
169 SWFFill SWFShape_addSolidFill(SWFShape shape, byte r, byte g, byte b, byte a)
170 {
171 return newSWFFill(SWFShape_addSolidFillStyle(shape, r, g, b, a));
172 }
173
174
175 SWFFill SWFShape_addGradientFill(SWFShape shape, SWFGradient gradient,
176 byte flags)
177 {
SWFMovieClip_add(SWFMovieClip clip,SWFBlock block)178 return newSWFFill(SWFShape_addGradientFillStyle(shape, gradient, flags));
179 }
180
181
182 SWFFill SWFShape_addBitmapFill(SWFShape shape, SWFBitmap bitmap, byte flags)
183 {
184 SWFFill fill =
185 newSWFFill(SWFShape_addBitmapFillStyle(shape, bitmap, flags));
186
187 return fill;
188 }
189
190
191 void SWFShape_setLeftFill(SWFShape shape, SWFFill fill)
192 {
193 SWFShape_setLeftFillStyle(shape, fill==NULL ? NULL : SWFFill_getFillStyle(fill));
194 }
195
196
197 void SWFShape_setRightFill(SWFShape shape, SWFFill fill)
198 {
199 SWFShape_setRightFillStyle(shape, fill==NULL ? NULL : SWFFill_getFillStyle(fill));
200 }
201
202
203 void SWFShape_drawCharacterBounds(SWFShape shape, SWFCharacter character)
204 {
205 SWFShape_drawLine(shape, SWFCharacter_getWidth(character), 0);
206 SWFShape_drawLine(shape, 0, SWFCharacter_getHeight(character));
207 SWFShape_drawLine(shape, -SWFCharacter_getWidth(character), 0);
208 SWFShape_drawLine(shape, 0, -SWFCharacter_getHeight(character));
209 }
210
211
212 void SWFShape_drawCircle(SWFShape shape, double r)
213 {
214 SWFShape_drawArc(shape, r, 0, 360);
215 }
SWFMovieClip_remove(SWFMovieClip clip,SWFDisplayItem item)216
217
218 /* draw an arc of radius r, centered at (x,y), from angle startAngle to angle
219 endAngle (measured in degrees clockwise from due north) */
220
221 void SWFShape_drawArc(SWFShape shape, double r, double startAngle, double endAngle)
222 {
223 int i, nSegs;
224 double controlx, controly, anchorx, anchory, x, y;
225 double angle, subangle, controlRadius;
226
227 // Normalize the angles
228 double delta = endAngle - startAngle;
229 if ( ((delta>0)?delta:(-delta)) >= 360)
230 delta = 360;
231 else if (delta < 0)
232 delta += 360;
233 else if (delta == 0)
234 return;
235 startAngle = fmod(startAngle, 360);
236
237 /* first determine number of segments, 8 at most */
238 nSegs = 1 + (int)rint(7 * (delta / 360));
239
240 /* subangle is half the angle of each segment */
241 subangle = M_PI * delta / nSegs / 360;
242
243 angle = M_PI * startAngle / 180;
244
245 x = r * sin(angle);
246 y = -r * cos(angle);
247
248 SWFShape_movePen(shape, x, y);
249
250 controlRadius = r / cos(subangle);
251
252 for ( i=0; i<nSegs; ++i )
253 {
254 angle += subangle;
255 controlx = controlRadius * sin(angle);
256 controly = -controlRadius * cos(angle);
257 angle += subangle;
258 anchorx = (r*sin(angle));
259 anchory = (-r*cos(angle));
260
261 SWFShape_drawCurve(shape, controlx-x, controly-y,
262 anchorx-controlx, anchory-controly);
263
264 x = anchorx;
265 y = anchory;
266 }
267 }
268
269
270 /* x,y relative to shape origin */
271
SWFMovieClip_removeScalingGrid(SWFMovieClip clip)272 void SWFShape_movePenTo(SWFShape shape, double x, double y)
273 {
274 SWFShape_moveScaledPenTo(shape, (int)rint(x*Ming_scale),
275 (int)rint(y*Ming_scale));
276 }
277
278
279 void SWFShape_movePen(SWFShape shape, double dx, double dy)
280 {
281 SWFShape_moveScaledPen(shape, (int)rint(dx*Ming_scale),
282 (int)rint(dy*Ming_scale));
283 }
284
285 double SWFShape_getPenX(SWFShape shape)
286 {
287 return SWFShape_getScaledPenX(shape)/Ming_scale;
SWFMovieClip_addInitAction(SWFMovieClip clip,SWFAction action)288 }
289
290 double SWFShape_getPenY(SWFShape shape)
291 {
292 return SWFShape_getScaledPenY(shape)/Ming_scale;
293 }
294
295
296
297 void SWFShape_getPen(SWFShape shape, double* penX, double* penY)
298 {
299 *penX = SWFShape_getScaledPenX(shape)/ Ming_scale;
300 *penY = SWFShape_getScaledPenY(shape)/ Ming_scale;
301 }
302
303
304 void SWFShape_drawLineTo(SWFShape shape, double x, double y)
305 {
306 SWFShape_drawScaledLineTo(shape, (int)rint(x*Ming_scale),
307 (int)rint(y*Ming_scale));
308 }
309
310
311 void SWFShape_drawLine(SWFShape shape, double dx, double dy)
312 {
313 SWFShape_drawScaledLine(shape, (int)rint(dx*Ming_scale),
314 (int)rint(dy*Ming_scale));
315 }
316
317
318 void SWFShape_drawCurveTo(SWFShape shape, double controlx, double controly,
319 double anchorx, double anchory)
320 {
321 SWFShape_drawScaledCurveTo(shape,
322 (int)rint(controlx*Ming_scale),
323 (int)rint(controly*Ming_scale),
324 (int)rint(anchorx*Ming_scale),
325 (int)rint(anchory*Ming_scale));
326 }
327
328
329 void SWFShape_drawCurve(SWFShape shape, double controldx, double controldy,
330 double anchordx, double anchordy)
331 {
332 SWFShape_drawScaledCurve(shape,
333 (int)rint(controldx*Ming_scale),
334 (int)rint(controldy*Ming_scale),
335 (int)rint(anchordx*Ming_scale),
336 (int)rint(anchordy*Ming_scale));
337 }
338
339
340 void SWFShape_drawGlyph(SWFShape shape, SWFFont font, unsigned short c)
341 {
342 SWFShape_drawScaledGlyph(shape, font, c, 1024);
343 }
344
345
346 void SWFShape_drawSizedGlyph(SWFShape shape,
347 SWFFont font, unsigned short c, int size)
348 {
349 if(size == 0)
350 SWFShape_drawScaledGlyph(shape, font, c, 1024);
351 else
352 SWFShape_drawScaledGlyph(shape, font, c, (int)(size*Ming_scale));
353 }
354
355
356 /*
357 * Local variables:
358 * tab-width: 2
359 * c-basic-offset: 2
360 * End:
361 */
362