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