swfmill 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/.swfmill +240 -0
  4. data/LICENSE +340 -0
  5. data/README.rdoc +37 -0
  6. data/Rakefile +59 -0
  7. data/VERSION +1 -0
  8. data/ext/.gitignore +5 -0
  9. data/ext/extconf.rb +86 -0
  10. data/ext/swfmill/.gitignore +27 -0
  11. data/ext/swfmill/AUTHORS +9 -0
  12. data/ext/swfmill/COPYING +340 -0
  13. data/ext/swfmill/Makefile.am +14 -0
  14. data/ext/swfmill/Makefile.in +635 -0
  15. data/ext/swfmill/NEWS +189 -0
  16. data/ext/swfmill/README +170 -0
  17. data/ext/swfmill/TODO +33 -0
  18. data/ext/swfmill/aclocal.m4 +7712 -0
  19. data/ext/swfmill/autogen.sh +7 -0
  20. data/ext/swfmill/compile +142 -0
  21. data/ext/swfmill/config.guess +1516 -0
  22. data/ext/swfmill/config.sub +1626 -0
  23. data/ext/swfmill/configure +21868 -0
  24. data/ext/swfmill/configure.ac +55 -0
  25. data/ext/swfmill/depcomp +589 -0
  26. data/ext/swfmill/install-sh +519 -0
  27. data/ext/swfmill/ltmain.sh +6964 -0
  28. data/ext/swfmill/missing +367 -0
  29. data/ext/swfmill/src/Geom.cpp +107 -0
  30. data/ext/swfmill/src/Geom.h +100 -0
  31. data/ext/swfmill/src/Makefile.am +86 -0
  32. data/ext/swfmill/src/Makefile.in +1025 -0
  33. data/ext/swfmill/src/SWF.h +11941 -0
  34. data/ext/swfmill/src/SWFAction.cpp +41 -0
  35. data/ext/swfmill/src/SWFAction.h +19 -0
  36. data/ext/swfmill/src/SWFBasic.h +7 -0
  37. data/ext/swfmill/src/SWFFile.cpp +406 -0
  38. data/ext/swfmill/src/SWFFile.h +34 -0
  39. data/ext/swfmill/src/SWFFilter.cpp +25 -0
  40. data/ext/swfmill/src/SWFFilter.h +15 -0
  41. data/ext/swfmill/src/SWFGlyphList.cpp +262 -0
  42. data/ext/swfmill/src/SWFGlyphList.h +34 -0
  43. data/ext/swfmill/src/SWFIdItem.h +85 -0
  44. data/ext/swfmill/src/SWFIdItems.h +16 -0
  45. data/ext/swfmill/src/SWFItem.cpp +235 -0
  46. data/ext/swfmill/src/SWFItem.h +60 -0
  47. data/ext/swfmill/src/SWFList.h +179 -0
  48. data/ext/swfmill/src/SWFReader.cpp +352 -0
  49. data/ext/swfmill/src/SWFReader.h +73 -0
  50. data/ext/swfmill/src/SWFShapeItem.cpp +220 -0
  51. data/ext/swfmill/src/SWFShapeItem.h +45 -0
  52. data/ext/swfmill/src/SWFShapeMaker.cpp +401 -0
  53. data/ext/swfmill/src/SWFShapeMaker.h +128 -0
  54. data/ext/swfmill/src/SWFTag.cpp +49 -0
  55. data/ext/swfmill/src/SWFTag.h +20 -0
  56. data/ext/swfmill/src/SWFTrait.cpp +35 -0
  57. data/ext/swfmill/src/SWFTrait.h +22 -0
  58. data/ext/swfmill/src/SWFWriter.cpp +312 -0
  59. data/ext/swfmill/src/SWFWriter.h +84 -0
  60. data/ext/swfmill/src/base64.c +110 -0
  61. data/ext/swfmill/src/base64.h +15 -0
  62. data/ext/swfmill/src/codegen/Makefile.am +15 -0
  63. data/ext/swfmill/src/codegen/Makefile.in +346 -0
  64. data/ext/swfmill/src/codegen/basic.xsl +45 -0
  65. data/ext/swfmill/src/codegen/basics.xsl +235 -0
  66. data/ext/swfmill/src/codegen/dumper.xsl +109 -0
  67. data/ext/swfmill/src/codegen/header.xsl +131 -0
  68. data/ext/swfmill/src/codegen/mk.xsl +26 -0
  69. data/ext/swfmill/src/codegen/parser.xsl +196 -0
  70. data/ext/swfmill/src/codegen/parsexml.xsl +312 -0
  71. data/ext/swfmill/src/codegen/size.xsl +189 -0
  72. data/ext/swfmill/src/codegen/source.xml +2197 -0
  73. data/ext/swfmill/src/codegen/writer.xsl +190 -0
  74. data/ext/swfmill/src/codegen/writexml.xsl +138 -0
  75. data/ext/swfmill/src/swfmill.cpp +482 -0
  76. data/ext/swfmill/src/swft/Makefile.am +55 -0
  77. data/ext/swfmill/src/swft/Makefile.in +717 -0
  78. data/ext/swfmill/src/swft/Parser.cpp +76 -0
  79. data/ext/swfmill/src/swft/Parser.h +37 -0
  80. data/ext/swfmill/src/swft/SVGAttributeParser.cpp +78 -0
  81. data/ext/swfmill/src/swft/SVGAttributeParser.h +35 -0
  82. data/ext/swfmill/src/swft/SVGColor.cpp +116 -0
  83. data/ext/swfmill/src/swft/SVGColor.h +37 -0
  84. data/ext/swfmill/src/swft/SVGColors.h +167 -0
  85. data/ext/swfmill/src/swft/SVGGradient.cpp +258 -0
  86. data/ext/swfmill/src/swft/SVGGradient.h +81 -0
  87. data/ext/swfmill/src/swft/SVGPathParser.cpp +155 -0
  88. data/ext/swfmill/src/swft/SVGPathParser.h +126 -0
  89. data/ext/swfmill/src/swft/SVGPointsParser.cpp +51 -0
  90. data/ext/swfmill/src/swft/SVGPointsParser.h +25 -0
  91. data/ext/swfmill/src/swft/SVGStyle.cpp +181 -0
  92. data/ext/swfmill/src/swft/SVGStyle.h +80 -0
  93. data/ext/swfmill/src/swft/SVGTransformParser.cpp +72 -0
  94. data/ext/swfmill/src/swft/SVGTransformParser.h +32 -0
  95. data/ext/swfmill/src/swft/readpng.c +305 -0
  96. data/ext/swfmill/src/swft/readpng.h +92 -0
  97. data/ext/swfmill/src/swft/swft.cpp +251 -0
  98. data/ext/swfmill/src/swft/swft.h +64 -0
  99. data/ext/swfmill/src/swft/swft_document.cpp +57 -0
  100. data/ext/swfmill/src/swft/swft_import.cpp +38 -0
  101. data/ext/swfmill/src/swft/swft_import_binary.cpp +82 -0
  102. data/ext/swfmill/src/swft/swft_import_jpeg.cpp +255 -0
  103. data/ext/swfmill/src/swft/swft_import_mp3.cpp +268 -0
  104. data/ext/swfmill/src/swft/swft_import_png.cpp +231 -0
  105. data/ext/swfmill/src/swft/swft_import_ttf.cpp +519 -0
  106. data/ext/swfmill/src/swft/swft_import_wav.cpp +255 -0
  107. data/ext/swfmill/src/swft/swft_path.cpp +178 -0
  108. data/ext/swfmill/src/xslt/Makefile.am +51 -0
  109. data/ext/swfmill/src/xslt/Makefile.in +536 -0
  110. data/ext/swfmill/src/xslt/README +19 -0
  111. data/ext/swfmill/src/xslt/assemble.xsl +38 -0
  112. data/ext/swfmill/src/xslt/simple-deprecated.xslt +62 -0
  113. data/ext/swfmill/src/xslt/simple-elements.xslt +627 -0
  114. data/ext/swfmill/src/xslt/simple-import.xslt +565 -0
  115. data/ext/swfmill/src/xslt/simple-svg.xslt +383 -0
  116. data/ext/swfmill/src/xslt/simple-tools.xslt +255 -0
  117. data/ext/swfmill/src/xslt/simple.cpp +1686 -0
  118. data/ext/swfmill/src/xslt/simple.xml +7 -0
  119. data/ext/swfmill/src/xslt/xslt.h +7 -0
  120. data/ext/swfmill/test/Makefile.am +1 -0
  121. data/ext/swfmill/test/Makefile.in +490 -0
  122. data/ext/swfmill/test/xml/Makefile.am +20 -0
  123. data/ext/swfmill/test/xml/Makefile.in +353 -0
  124. data/ext/swfmill/test/xml/test-xml +21 -0
  125. data/ext/swfmill_ext.cc +375 -0
  126. data/lib/swfmill.rb +30 -0
  127. data/spec/data/swfmill-banner1.swf +0 -0
  128. data/spec/spec.opts +1 -0
  129. data/spec/spec_helper.rb +14 -0
  130. data/spec/swfmill_spec.rb +125 -0
  131. metadata +206 -0
@@ -0,0 +1,45 @@
1
+ #ifndef SWF_SHAPEITEM_H
2
+ #define SWF_SHAPEITEM_H
3
+
4
+ #include <SWFItem.h>
5
+
6
+ namespace SWF {
7
+
8
+ class ShapeItem : public Item {
9
+ public:
10
+ ShapeItem();
11
+ void setType( unsigned char t ) { type = t; }
12
+ unsigned char type;
13
+
14
+ int getHeaderSize( int size );
15
+ void writeHeader( Writer *w, Context *ctx, size_t len );
16
+
17
+ bool isEnd();
18
+
19
+ // static stuff
20
+ public:
21
+ static ShapeItem* get( Reader *r, int end, Context *ctx );
22
+ static ShapeItem* getByName( const char *name );
23
+ };
24
+
25
+ class LineTo : public ShapeItem {
26
+ /* plain edges are a bit hairy, so we do them manually */
27
+ public:
28
+ LineTo();
29
+ virtual bool parse( Reader *r, int end, Context *ctx );
30
+ virtual void dump( int indent, Context *ctx );
31
+ virtual size_t calcSize( Context *ctx, int start_at );
32
+ virtual void write( Writer *w, Context *ctx );
33
+ virtual void writeXML( xmlNodePtr node, Context *ctx );
34
+ virtual void parseXML( xmlNodePtr node, Context *ctx );
35
+
36
+ void setx( int x );
37
+ void sety( int y );
38
+
39
+ protected:
40
+ int bits;
41
+ int x, y;
42
+ };
43
+
44
+ }
45
+ #endif
@@ -0,0 +1,401 @@
1
+ #include "SWFShapeMaker.h"
2
+ #include <stdarg.h>
3
+ #include "SWFShapeItem.h"
4
+ #include "SWFItem.h"
5
+ #include "SWF.h"
6
+
7
+ #define TMP_STRLEN 0xFF
8
+
9
+ namespace SWF {
10
+
11
+ // TODO assure bits is representable in 4 bits!
12
+ ShapeMaker::ShapeMaker( List<ShapeItem>* e, double fx, double fy, double ofsx, double ofsy ) {
13
+ edges = e;
14
+ factorx = fx;
15
+ factory = fy;
16
+ offsetx = ofsx;
17
+ offsety = ofsy;
18
+ diffx = diffy = 0;
19
+ lastx = lasty = 0;
20
+ smoothx = smoothy = 0;
21
+ have_first = false;
22
+
23
+ fillStyle0 = lineStyle = fillStyle1 = -1;
24
+
25
+ roundReset();
26
+ }
27
+
28
+ void ShapeMaker::doSetup( double _x, double _y, bool hasMoveTo, int _fillStyle0, int _fillStyle1, int _lineStyle ) {
29
+ // append shapesetup (whithout styles, this is glyph only for now)
30
+ ShapeSetup *setup = new ShapeSetup;
31
+
32
+
33
+ if( _fillStyle0 != -1 ) {
34
+ setup->setfillStyle0( _fillStyle0 );
35
+ setup->sethasFillStyle0( 1 );
36
+ }
37
+ if( _fillStyle1 != -1 ) {
38
+ setup->setfillStyle1( _fillStyle1 );
39
+ setup->sethasFillStyle1( 1 );
40
+ }
41
+ if( _lineStyle != -1 ) {
42
+ setup->setlineStyle( _lineStyle );
43
+ setup->sethasLineStyle( 1 );
44
+ }
45
+
46
+ if( hasMoveTo ) {
47
+ roundReset();
48
+ int x = roundX(factorx * ( _x ) );
49
+ int y = roundY(factory * ( _y ) );
50
+
51
+ diffx = diffy = 0;
52
+
53
+ setup->setxybits( SWFMaxBitsNeeded( true, 2, x, y ) );
54
+
55
+ setup->sethasMoveTo( 1 );
56
+ setup->setx( x );
57
+ setup->sety( y );
58
+
59
+ minmax( x, y );
60
+
61
+ lastx = _x; lasty = _y;
62
+ lastsetupx = _x; lastsetupy = _y;
63
+ }
64
+
65
+ edges->append( setup );
66
+
67
+ // fprintf(stderr,"setup %i/%i\n", x, y );
68
+ }
69
+
70
+ void ShapeMaker::lineToR( double _x, double _y ) {
71
+ int x = roundX(factorx * ( _x ) );
72
+ int y = roundY(factory * ( _y ) );
73
+
74
+ diffx += x; diffy += y;
75
+
76
+ SWF::LineTo *segment = new SWF::LineTo;
77
+ segment->setType(1);
78
+ //segment->setbits( maxBitsNeeded( true, 2, x, y ) );
79
+ segment->setx( x );
80
+ segment->sety( y );
81
+ edges->append( segment );
82
+ minmax( x+(lastx*factorx), y+(lasty*factory) );
83
+
84
+ lastx += _x; lasty += _y;
85
+ }
86
+
87
+ void ShapeMaker::curveToR( double _cx, double _cy, double ax, double ay ) {
88
+ int cx = roundX(factorx * ( _cx ) );
89
+ int cy = roundY(factory * ( _cy ) );
90
+ int x = roundX(factorx * ( ax - _cx ) );
91
+ int y = roundY(factory * ( ay - _cy) );
92
+
93
+ smoothx = lastx + _cx;
94
+ smoothy = lasty + _cy;
95
+
96
+ diffx += cx + x; diffy += cy + y;
97
+
98
+ CurveTo *segment = new CurveTo;
99
+ segment->setType(2);
100
+ segment->setbits( SWFMaxBitsNeeded( true, 4, x, y, cx, cy ) );
101
+ segment->setx1( cx );
102
+ segment->sety1( cy );
103
+ segment->setx2( x );
104
+ segment->sety2( y );
105
+ edges->append( segment );
106
+ minmax( x+cx+(lastx*factorx), y+cy+(lasty*factory) );
107
+
108
+ lastx += ax; lasty += ay;
109
+
110
+ smoothx = ax - _cx;
111
+ smoothy = ay - _cy;
112
+ }
113
+
114
+ void ShapeMaker::curveTo( double cx, double cy, double ax, double ay ) {
115
+ curveToR( cx - lastx, cy - lasty, ax - lastx, ay - lasty );
116
+ }
117
+
118
+ void ShapeMaker::smoothCurveToR( double ax, double ay ) {
119
+ curveToR( smoothx, smoothy, ax, ay );
120
+
121
+ }
122
+
123
+ void ShapeMaker::smoothCurveTo( double ax, double ay ) {
124
+ curveTo( lastx + smoothx, lasty + smoothy, ax, ay );
125
+ }
126
+
127
+ // cubic to quadratic bezier functions
128
+ // thanks to Robert Penner
129
+
130
+ Point intersectLines( Point p1, Point p2, Point p3, Point p4 ) {
131
+ double x1 = p1.x, y1 = p1.y;
132
+ double x4 = p4.x, y4 = p4.y;
133
+ double dx1 = p2.x-x1;
134
+ double dx2 = p3.x-x4;
135
+ if( dx1 == 0 && dx2 == 0 ) return Point(p1.x + ((p4.x-p1.x)/2), p1.y + ((p4.y-p1.y)/2));
136
+ double m1 = (p2.y-y1)/dx1;
137
+ double m2 = (p3.y-y4)/dx2;
138
+
139
+ if( !dx1 ) {
140
+ return Point( x1, (m2*(x1-x4))+y4 );
141
+ } else if( !dx2 ) {
142
+ return Point( x4, (m1*(x4-x1))+y1 );
143
+ } else if( fabs( m1-m2 ) < .001 ) {
144
+ return Point( x4, (m1*(x4-x1))+y1 );
145
+ }
146
+ double x = ((-m2 * x4) + y4 + (m1 * x1) - y1) / (m1-m2);
147
+ Point p( x, (m1 * (x-x1)) + y1 );
148
+
149
+ /*
150
+ if( fabs(p.y) > 100 ) {
151
+ fprintf(stderr,"p1/2: %f/%f %f/%f %f/%f %f/%f\n", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y );
152
+ fprintf(stderr,"S: %f/%f m1/2: %f/%f\n", p.x, p.y, m1, m2 );
153
+ }
154
+ */
155
+ return p;
156
+ }
157
+
158
+ Point midLine( const Point& a, const Point& b ) {
159
+ Point p( ((a.x+b.x)/2), ((a.y+b.y)/2) );
160
+ return p;
161
+ }
162
+
163
+ void bezierSplit( const Bezier& b, Bezier* b0, Bezier* b1 ) {
164
+ Point p01 = midLine( b.p0, b.p1 );
165
+ Point p12 = midLine( b.p1, b.p2 );
166
+ Point p23 = midLine( b.p2, b.p3 );
167
+ Point p02 = midLine( p01, p12 );
168
+ Point p13 = midLine( p12, p23 );
169
+ Point p03 = midLine( p02, p13 );
170
+
171
+ b0->set( b.p0, p01, p02, p03 );
172
+ b1->set( p03, p13, p23, b.p3 );
173
+ }
174
+
175
+ void ShapeMaker::cubicToRec( const Point& a, const Point& b, const Point& c, const Point& d, double k, int iteration ) {
176
+ Point s = intersectLines( a, b, c, d );
177
+ double dx = (a.x+d.x+s.x*4-(b.x+c.x)*3)*.125;
178
+ double dy = (a.y+d.y+s.y*4-(b.y+c.y)*3)*.125;
179
+ Bezier bz( a, b, c, d );
180
+ Bezier b0, b1;
181
+ if( dx*dx + dy*dy > k && iteration<10 ) {
182
+ // fprintf(stderr,"[%03i] split: %f\n", iteration, dx*dx + dy*dy);
183
+ bezierSplit( bz, &b0, &b1 );
184
+ // recurse
185
+ iteration++;
186
+ cubicToRec( a, b0.p1, b0.p2, b0.p3, k, iteration );
187
+ //lineTo( b0.p3.x, b0.p3.y );
188
+
189
+ cubicToRec( b1.p0, b1.p1, b1.p2, d, k, iteration );
190
+ //lineTo( b1.p1.x, b1.p1.y );
191
+ //lineTo( b1.p2.x, b1.p2.y );
192
+ //lineTo( d.x, d.y );
193
+ } else {
194
+ // fprintf(stderr,"#### %i %i %i %i\n", (int)s.x, (int)s.y, (int)d.x, (int)d.y );
195
+ //lineTo( (int)s.x, (int)s.y );
196
+ //lineTo( (int)d.x, (int)d.y );
197
+ curveTo( s.x, s.y, d.x, d.y );
198
+ }
199
+ }
200
+
201
+ void ShapeMaker::cubicTo( double x1, double y1, double x2, double y2, double ax, double ay ) {
202
+ Point a(lastx,lasty);
203
+ Point b(x1,y1);
204
+ Point c(x2,y2);
205
+ Point d(ax,ay);
206
+
207
+ cubicToRec( a, b, c, d, .01 );
208
+
209
+ lastx = ax; lasty = ay;
210
+ smoothx = ax - x2;
211
+ smoothy = ay - y2;
212
+ }
213
+
214
+ void ShapeMaker::cubicToR( double x1, double y1, double x2, double y2, double ax, double ay ) {
215
+ cubicTo(lastx + x1, lasty + y1,
216
+ lastx + x2, lasty + y2,
217
+ lastx + ax, lasty + ay);
218
+ }
219
+
220
+ void ShapeMaker::smoothCubicTo( double x2, double y2, double ax, double ay ) {
221
+ cubicTo( lastx + smoothx, lasty + smoothy, x2, y2, ax, ay );
222
+
223
+ }
224
+
225
+ void ShapeMaker::smoothCubicToR( double x2, double y2, double ax, double ay ) {
226
+ cubicToR( smoothx, smoothy, x2, y2, ax, ay );
227
+ }
228
+
229
+ void ShapeMaker::close(bool stroke) {
230
+ // diffx/diffy captures rounding errors. they can accumulate a bit! FIXME
231
+
232
+ if( diffx || diffy ) {
233
+ /*fprintf(stderr,"WARNING: shape not closed; closing (%f/%f).\n", diffx, diffy);
234
+ fprintf(stderr,"DEBUG: accumulated rounding error (%f/%f).\n", roundx, roundy);*/
235
+
236
+ if(!stroke) {
237
+ doSetup( 0, 0, false, -1, -1, 0 );
238
+ }
239
+
240
+ // closing line
241
+ LineTo *segment = new LineTo;
242
+ segment->setType(1);
243
+ //segment->setbits( maxBitsNeeded( true, 2, x, y ) );
244
+ segment->setx( (int)-diffx );
245
+ segment->sety( (int)-diffy );
246
+ edges->append( segment );
247
+
248
+ if(!stroke) {
249
+ doSetup( 0, 0, false, -1, -1, lineStyle );
250
+ }
251
+
252
+ diffx = diffy = 0;
253
+ if(stroke) {
254
+ lastx = lastsetupx; lasty = lastsetupy;
255
+ }
256
+ }
257
+ }
258
+
259
+ void ShapeMaker::finish() {
260
+ // end shape
261
+ ShapeSetup *setup = new ShapeSetup;
262
+ edges->append( setup );
263
+ }
264
+
265
+ void ShapeMaker::setupR( double x, double y ) {
266
+ x += lastx; y += lasty;
267
+ doSetup( x, y, true, fillStyle0, fillStyle1, lineStyle );
268
+ }
269
+
270
+ void ShapeMaker::setup( double x, double y ) {
271
+ x += offsetx; y += offsety;
272
+ doSetup( x, y, true, fillStyle0, fillStyle1, lineStyle );
273
+ }
274
+
275
+ void ShapeMaker::lineTo( double x, double y ) {
276
+ x += offsetx; y += offsety;
277
+ lineToR( x - lastx, y - lasty );
278
+ }
279
+
280
+ void ShapeMaker::rect( double x, double y, double w, double h, double rx, double ry ) {
281
+ if(rx > 0 || ry > 0) {
282
+ setup(x + rx, y);
283
+ lineTo(x + w - rx, y);
284
+ arcTo(rx, ry, 0, false, true, x + w, y + ry);
285
+ lineTo(x + w, y + h - ry);
286
+ arcTo(rx, ry, 0, false, true, x + w - rx, y + h);
287
+ lineTo(x + rx, y + h);
288
+ arcTo(rx, ry, 0, false, true, x, y + h - ry);
289
+ lineTo(x, y + ry);
290
+ arcTo(rx, ry, 0, false, true, x + rx, y);
291
+ close();
292
+ } else {
293
+ setup(x, y);
294
+ lineToR(0, h);
295
+ lineToR(w, 0);
296
+ lineToR(0, -h);
297
+ lineToR(-w, 0);
298
+ close();
299
+ }
300
+ }
301
+
302
+ #define ELLIPSE_SEGMENTS 8
303
+ #define ELLIPSE_ANGLE ( M_PI * 2 / ELLIPSE_SEGMENTS )
304
+
305
+ void ShapeMaker::ellipseSegment( double cx, double cy, double rx, double ry, double phi, double theta, double dTheta) {
306
+ double a1 = theta + dTheta / 2;
307
+ double a2 = theta + dTheta;
308
+ double f = cos(dTheta / 2);
309
+
310
+ Point p1(cos(a1) * rx / f, sin(a1) * ry / f);
311
+ Point p2(cos(a2) * rx, sin(a2) * ry);
312
+ p1.rotate(phi);
313
+ p2.rotate(phi);
314
+
315
+ curveTo(cx + p1.x, cy + p1.y, cx + p2.x, cy + p2.y);
316
+ }
317
+
318
+ void ShapeMaker::ellipse( double cx, double cy, double rx, double ry ) {
319
+ setup(cx + rx, cy);
320
+ for(int i = 0; i < ELLIPSE_SEGMENTS; i++) {
321
+ ellipseSegment(cx, cy, rx, ry, 0, ELLIPSE_ANGLE * i, ELLIPSE_ANGLE);
322
+ }
323
+ close();
324
+ }
325
+
326
+ void ShapeMaker::arcTo( double rx, double ry, double rotation, bool largeArcFlag, bool sweepFlag, double x, double y ) {
327
+ double a, f, lambda, theta, dTheta;
328
+
329
+ a = rotation / 180 * M_PI;
330
+
331
+ Point A(lastx, lasty);
332
+ Point B(x, y);
333
+
334
+ Point P = (A - B) / 2;
335
+ P.rotate(-a);
336
+
337
+ lambda = pow(P.x, 2) / pow(rx, 2) + pow(P.y, 2) / pow(ry, 2);
338
+ if(lambda > 1) {
339
+ rx *= sqrt(lambda);
340
+ ry *= sqrt(lambda);
341
+ }
342
+
343
+ f = (pow(rx, 2)*pow(ry, 2)-pow(rx, 2)*pow(P.y, 2)-pow(ry, 2)*pow(P.x, 2))/(pow(rx, 2)*pow(P.y, 2)+pow(ry, 2)*pow(P.x, 2));
344
+ if(f < 0) {
345
+ f = 0;
346
+ } else {
347
+ f = sqrt(f);
348
+ }
349
+ if(largeArcFlag == sweepFlag) f *= -1;
350
+
351
+ Point C_(rx / ry * P.y, -ry / rx * P.x);
352
+ C_ = C_ * f;
353
+
354
+ Point C = C_;
355
+ C.rotate(a);
356
+ C = C + (A + B) / 2;
357
+
358
+ theta = atan2((P.y-C_.y)/ry, (P.x-C_.x)/rx);
359
+ dTheta = atan2((-P.y-C_.y)/ry, (-P.x-C_.x)/rx) - theta;
360
+
361
+ if(sweepFlag && dTheta < 0)
362
+ dTheta += 2 * M_PI;
363
+
364
+ if(!sweepFlag && dTheta > 0)
365
+ dTheta -= 2 * M_PI;
366
+
367
+ double dThetaAbs = (dTheta < 0 ? -dTheta : dTheta);
368
+ int segments = (int)ceil(dThetaAbs / ELLIPSE_ANGLE);
369
+
370
+ for(int i = 0; i < segments; i++) {
371
+ ellipseSegment(C.x, C.y, rx, ry, a, dTheta / segments * i + theta, dTheta / segments);
372
+ }
373
+ }
374
+
375
+ void ShapeMaker::arcToR( double rx, double ry, double rotation, bool largeArcFlag, bool sweepFlag, double x, double y ) {
376
+ arcTo(rx, ry, rotation, largeArcFlag, sweepFlag, lastx + x, lasty + y);
377
+ }
378
+
379
+ void ShapeMaker::boundsWriteXML( xmlNodePtr parent, double border ) {
380
+ char tmp[TMP_STRLEN];
381
+ xmlNodePtr node;
382
+
383
+ if(border >= 0) {
384
+ node = xmlNewChild(parent, NULL, (const xmlChar *)"bounds", NULL);
385
+ } else {
386
+ node = xmlNewChild(parent, NULL, (const xmlChar *)"strokeBounds", NULL);
387
+ border = 0;
388
+ }
389
+
390
+ node = xmlNewChild(node, NULL, (const xmlChar *)"Rectangle", NULL);
391
+ snprintf(tmp, TMP_STRLEN, "%f", minx - border * 20);
392
+ xmlSetProp(node, (const xmlChar *)"left", (const xmlChar *)&tmp);
393
+ snprintf(tmp, TMP_STRLEN,"%f", miny - border * 20);
394
+ xmlSetProp(node, (const xmlChar *)"top", (const xmlChar *)&tmp);
395
+ snprintf(tmp,TMP_STRLEN,"%f", maxx + border * 20);
396
+ xmlSetProp(node, (const xmlChar *)"right", (const xmlChar *)&tmp);
397
+ snprintf(tmp,TMP_STRLEN,"%f", maxy + border * 20);
398
+ xmlSetProp(node, (const xmlChar *)"bottom", (const xmlChar *)&tmp);
399
+ }
400
+
401
+ }
@@ -0,0 +1,128 @@
1
+ #ifndef SWF_SHAPEMAKER_H
2
+ #define SWF_SHAPEMAKER_H
3
+
4
+ #include "Geom.h"
5
+ #include <cstdio>
6
+ #include <libxml/tree.h>
7
+ #include <cmath>
8
+
9
+ namespace SWF {
10
+
11
+ class ShapeItem;
12
+ template <class T> class List;
13
+
14
+ class Bezier {
15
+ public:
16
+ Point p0, p1, p2, p3;
17
+ Bezier() { ; }
18
+ Bezier( const Point& _p0, const Point& _p1, const Point& _p2, const Point& _p3 )
19
+ : p0(_p0), p1(_p1), p2(_p2), p3(_p3) { ; }
20
+ Bezier &set( const Point& _p0, const Point& _p1, const Point& _p2, const Point& _p3 ) {
21
+ p0 = _p0; p1 = _p1; p2 = _p2; p3 = _p3;
22
+ return *this;
23
+ }
24
+ };
25
+
26
+ class ShapeMaker {
27
+ public:
28
+ ShapeMaker( List<ShapeItem>* edges, double fx = 1, double fy = 1, double ofsx = 0, double ofsy = 0 );
29
+
30
+ void setStyle( int _fillStyle0=-1, int _fillStyle1=-1, int _lineStyle=-1 ) {
31
+ fillStyle0 = _fillStyle0;
32
+ fillStyle1 = _fillStyle1;
33
+ lineStyle = _lineStyle;
34
+ }
35
+
36
+ void setup( double x = 0, double y = 0 );
37
+ void setupR( double x = 0, double y = 0 );
38
+
39
+ void lineTo( double x, double y );
40
+ void lineToR( double x, double y );
41
+
42
+ void curveTo( double cx, double cy, double ax, double ay );
43
+ void curveToR( double cx, double cy, double ax, double ay );
44
+
45
+ void smoothCurveTo( double ax, double ay );
46
+ void smoothCurveToR( double ax, double ay );
47
+
48
+ void cubicTo( double x1, double y1, double x2, double y2, double ax, double ay );
49
+ void cubicToR( double x1, double y1, double x2, double y2, double ax, double ay );
50
+
51
+ void smoothCubicTo( double x2, double y2, double ax, double ay );
52
+ void smoothCubicToR( double x2, double y2, double ax, double ay );
53
+
54
+ void close(bool stroke = true);
55
+ void finish();
56
+
57
+ void rect( double x, double y, double width, double height, double rx = 0, double ry = 0 );
58
+ void ellipse( double cx, double cy, double rx, double ry );
59
+
60
+ void arcTo( double rx, double ry, double rotation, bool largeArcFlag, bool sweepFlag, double x, double y );
61
+ void arcToR( double rx, double ry, double rotation, bool largeArcFlag, bool sweepFlag, double x, double y );
62
+
63
+ void boundsWriteXML( xmlNodePtr node, double border = -1 );
64
+
65
+ double getLastX() { return lastx; }
66
+ double getLastY() { return lasty; }
67
+
68
+ double getSmoothX() { return smoothx; }
69
+ double getSmoothY() { return smoothy; }
70
+
71
+ Rect getBounds() { return Rect(minx, miny, maxx, maxy); }
72
+
73
+ protected:
74
+ void cubicToRec( const Point& a, const Point& b, const Point& c, const Point& d, double k, int iteration=0 );
75
+
76
+ void doSetup( double _x=0, double _y=0, bool hasMoveTo=true, int _fillStyle0=-1, int _fillStyle1=-1, int _lineStyle=-1);
77
+
78
+ void ellipseSegment( double cx, double cy, double rx, double ry, double phi, double theta, double dTheta);
79
+
80
+ void minmax( double x, double y ) {
81
+ if( !have_first ) {
82
+ have_first = true;
83
+ minx = x; maxx=x; miny=y; maxy=y;
84
+ } else {
85
+ if( x < minx ) minx=x;
86
+ if( y < miny ) miny=y;
87
+ if( x > maxx ) maxx=x;
88
+ if( y > maxy ) maxy=y;
89
+ }
90
+ }
91
+
92
+ List<ShapeItem>* edges;
93
+ double factorx, factory;
94
+ double offsetx, offsety;
95
+ double diffx, diffy;
96
+ double lastx, lasty;
97
+ double lastsetupx, lastsetupy;
98
+ double minx, miny, maxx, maxy;
99
+ double smoothx, smoothy;
100
+ bool have_first;
101
+
102
+ int fillStyle0, fillStyle1, lineStyle;
103
+
104
+ // rounding error accumulation compensation
105
+ double roundx, roundy;
106
+ int roundX( double x ) { return round( x, &roundx ); }
107
+ int roundY( double y ) { return round( y, &roundy ); }
108
+ int round( double v, double *acc ) {
109
+ int r = (int)v;
110
+ *acc += v-(double)r;
111
+ while( *acc >= .5 ) {
112
+ *acc -= 1.0;
113
+ r++;
114
+ }
115
+ while( *acc <= -.5 ) {
116
+ *acc += 1.0;
117
+ r--;
118
+ }
119
+ return r;
120
+ }
121
+ void roundReset() {
122
+ roundx = roundy = 0;
123
+ }
124
+ };
125
+
126
+
127
+ }
128
+ #endif