swfmill 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,258 @@
1
+ #include "SVGGradient.h"
2
+ #include "SVGTransformParser.h"
3
+ #include <cstring>
4
+
5
+ #define TMP_STRLEN 0xFF
6
+
7
+ using namespace std;
8
+
9
+ namespace SWF {
10
+
11
+ /* SVGGradient */
12
+
13
+ SVGGradient::SVGGradient() {
14
+ spreadMethod = PAD;
15
+ }
16
+
17
+ void SVGGradient::parse(xmlNodePtr node) {
18
+ attribs.parseNode(node);
19
+
20
+ const char *tmp = attribs["gradientUnits"];
21
+ if(tmp) {
22
+ if(!strcmp(tmp, "userSpaceOnUse")) {
23
+ userSpace = true;
24
+ } else {
25
+ userSpace = false;
26
+ }
27
+ } else {
28
+ userSpace = false;
29
+ }
30
+
31
+ parseGradient();
32
+ parseSpreadMethod();
33
+ parseTransform();
34
+ parseStops(node);
35
+ }
36
+
37
+ void SVGGradient::parseStops(xmlNodePtr parent) {
38
+ for(xmlNodePtr node = parent->children; node; node = node->next) {
39
+ if(!xmlStrcmp(node->name, (const xmlChar *)"stop"))
40
+ parseStop(node);
41
+ }
42
+ }
43
+
44
+ void SVGGradient::parseStop(xmlNodePtr node) {
45
+ SVGGradientStop stop;
46
+ AttributeParser stopAttribs;
47
+
48
+ stopAttribs.parseNode(node);
49
+
50
+ double offset = stopAttribs.getDouble("offset");
51
+
52
+ const char *tmp = stopAttribs["stop-color"];
53
+ if(tmp) {
54
+ stop.setColor(tmp);
55
+ }
56
+
57
+ stop.setAlpha(stopAttribs.getDouble("stop-opacity", 1));
58
+
59
+ stops[offset] = stop;
60
+ }
61
+
62
+ void SVGGradient::parseTransform() {
63
+ const char *tmp = attribs["gradientTransform"];
64
+ if(tmp) {
65
+ TransformParser parser;
66
+ parser.parse(tmp);
67
+ transform = parser.getMatrix();
68
+ }
69
+
70
+ }
71
+
72
+ void SVGGradient::parseSpreadMethod() {
73
+ const char *tmp = attribs["spreadMethod"];
74
+ if(tmp) {
75
+ if(!strcmp(tmp, "pad")) {
76
+ spreadMethod = PAD;
77
+ } else if(!strcmp(tmp, "reflect")) {
78
+ spreadMethod = REFLECT;
79
+ } else if(!strcmp(tmp, "repeat")) {
80
+ spreadMethod = REPEAT;
81
+ } else {
82
+ spreadMethod = PAD;
83
+ }
84
+ }
85
+ }
86
+
87
+ void SVGGradient::writeCommonXML(xmlNodePtr parentNode, Matrix& m, bool hasModes) {
88
+ char tmp[TMP_STRLEN];
89
+ xmlNodePtr node;
90
+
91
+ if(hasModes) {
92
+ xmlSetProp(parentNode, (const xmlChar *)"interpolationMode", (const xmlChar *)"0");
93
+
94
+ snprintf(tmp, TMP_STRLEN, "%i", spreadMethod);
95
+ xmlSetProp(parentNode, (const xmlChar *)"spreadMode", (const xmlChar *)&tmp);
96
+ } else {
97
+ xmlSetProp(parentNode, (const xmlChar *)"reserved", (const xmlChar *)"0");
98
+ }
99
+
100
+ node = xmlNewChild(parentNode, NULL, (const xmlChar *)"matrix", NULL);
101
+ node = xmlNewChild(node, NULL, (const xmlChar *)"Transform", NULL);
102
+ m.setXMLProps(node);
103
+
104
+ node = xmlNewChild(parentNode, NULL, (const xmlChar *)"gradientColors", NULL);
105
+
106
+ for(map<double, SVGGradientStop>::iterator i = stops.begin(); i != stops.end(); i++) {
107
+ (*i).second.writeXML(node, (*i).first);
108
+ }
109
+ }
110
+
111
+ /* SVGLinearGradient */
112
+
113
+ void SVGLinearGradient::parseGradient() {
114
+ x1 = attribs.getDouble("x1", 0);
115
+ y1 = attribs.getDouble("y1", 0);
116
+ x2 = attribs.getDouble("x2", 1);
117
+ y2 = attribs.getDouble("y2", 0);
118
+ }
119
+
120
+ void SVGLinearGradient::writeXML(xmlNodePtr node, Rect& bounds, bool hadModes) {
121
+ double w = bounds.right - bounds.left;
122
+ double h = bounds.bottom - bounds.top;
123
+
124
+ Matrix m;
125
+
126
+ if(userSpace) {
127
+ double lx = x2 - x1;
128
+ double ly = y2 - y1;
129
+
130
+ double dx = x2 - x1;
131
+ double dy = y2 - y1;
132
+ double d = sqrt(dx * dx + dy * dy);
133
+ double a = atan2(dy, dx);
134
+
135
+ m *= transform;
136
+ m.translate((x1 + x2) / 2 * 20, (y1 + y2) / 2 * 20);
137
+ m.rotate(a);
138
+ m.scale(d * 20 / 32768);
139
+ } else {
140
+ double sx, sy;
141
+
142
+ double _x1 = bounds.left + x1 * w;
143
+ double _y1 = bounds.top + y1 * h;
144
+ double _x2 = bounds.left + x2 * w;
145
+ double _y2 = bounds.top + y2 * h;
146
+
147
+ if(x1 != x2) {
148
+ sx = (_x2 - _x1) / 32768.0;
149
+ } else {
150
+ sx = 1;
151
+ }
152
+
153
+ if(y1 != y2) {
154
+ sy = (_y2 - _y1) / 32768.0;
155
+ } else {
156
+ sy = 1;
157
+ }
158
+
159
+ double dx = x2 - x1;
160
+ double dy = y2 - y1;
161
+ double d = sqrt(dx * dx + dy * dy);
162
+ double a = atan2(dy, dx);
163
+
164
+ m.translate((_x1 + _x2) / 2, (_y1 + _y2) / 2);
165
+ m.scale(sx, sy);
166
+ m.rotate(a);
167
+ m.scale(d);
168
+ }
169
+
170
+ xmlNodePtr topNode = xmlNewChild(node, NULL, (const xmlChar *)"LinearGradient", NULL);
171
+ writeCommonXML(topNode, m, hadModes);
172
+ }
173
+
174
+ /* SVGRadialGradient */
175
+
176
+ void SVGRadialGradient::parseGradient() {
177
+ cx = attribs.getDouble("cx", .5);
178
+ cy = attribs.getDouble("cy", .5);
179
+ r = attribs.getDouble("r", .5);
180
+
181
+ if(attribs["fx"] || attribs["fy"]) {
182
+ hasFocalPoint = true;
183
+ fx = attribs.getDouble("fx", cx);
184
+ fy = attribs.getDouble("fy", cy);
185
+
186
+ if(fx == cx && fy == cy) {
187
+ hasFocalPoint = false;
188
+ }
189
+ } else {
190
+ hasFocalPoint = false;
191
+ }
192
+ }
193
+
194
+ void SVGRadialGradient::writeXML(xmlNodePtr node, Rect& bounds, bool hasModes) {
195
+ Matrix m;
196
+
197
+ double w = bounds.right - bounds.left;
198
+ double h = bounds.bottom - bounds.top;
199
+ double shift = 0;
200
+
201
+ if(userSpace) {
202
+ m *= transform;
203
+ m.translate(cx * 20, cy * 20);
204
+
205
+ if(hasFocalPoint) {
206
+ double dx = fx - cx;
207
+ double dy = fy - cy;
208
+ m.rotate(atan2(dy, dx));
209
+ shift = sqrt(pow(dx, 2) + pow(dy, 2)) / r;
210
+ }
211
+
212
+ m.scale(r * 20 / 16348.0, r * 20 / 16384.0);
213
+ } else {
214
+ double _cx = bounds.left + cx * w;
215
+ double _cy = bounds.top + cy * h;
216
+
217
+ m.translate(_cx, _cy);
218
+
219
+ m.scale(r * w / 16348.0, r * h / 16384.0);
220
+
221
+ if(hasFocalPoint) {
222
+ double _fx = bounds.left + fx * w;
223
+ double _fy = bounds.top + fy * h;
224
+
225
+ double dx = _fx - _cx;
226
+ double dy = _fy - _cy;
227
+
228
+ m.rotate(atan2(dy, dx));
229
+ shift = sqrt(pow(dx, 2) + pow(dy, 2)) / (r * sqrt(pow(w, 2) + pow(h, 2)) / sqrt(2));
230
+ }
231
+ }
232
+
233
+ xmlNodePtr topNode;
234
+ if(hasFocalPoint) {
235
+ topNode = xmlNewChild(node, NULL, (const xmlChar *)"ShiftedRadialGradient", NULL);
236
+
237
+ char tmp[TMP_STRLEN];
238
+ snprintf(tmp, TMP_STRLEN, "%f", shift);
239
+ xmlSetProp(topNode, (const xmlChar *)"shift", (const xmlChar *)tmp);
240
+ } else {
241
+ topNode = xmlNewChild(node, NULL, (const xmlChar *)"RadialGradient", NULL);
242
+ }
243
+ writeCommonXML(topNode, m, hasModes);
244
+ }
245
+
246
+ /* SVGGradientStop */
247
+
248
+ void SVGGradientStop::writeXML(xmlNodePtr node, double offset) {
249
+ char tmp[TMP_STRLEN];
250
+
251
+ node = xmlNewChild(node, NULL, (const xmlChar *)"GradientItem", NULL);
252
+ snprintf(tmp, TMP_STRLEN, "%i", (int)(offset * 255));
253
+ xmlSetProp(node, (const xmlChar *)"position", (const xmlChar *)&tmp);
254
+ node = xmlNewChild(node, NULL, (const xmlChar *)"color", NULL);
255
+ color.writeXML(node);
256
+ }
257
+
258
+ }
@@ -0,0 +1,81 @@
1
+ #ifndef SVG_GRADIENT_H
2
+ #define SVG_GRADIENT_H
3
+
4
+ #include <iostream>
5
+ #include <map>
6
+ #include <libxml/tree.h>
7
+ #include "Geom.h"
8
+ #include "SVGColor.h"
9
+ #include "SVGAttributeParser.h"
10
+ #include "SWFShapeMaker.h"
11
+
12
+
13
+
14
+ namespace SWF {
15
+
16
+ class SVGGradientStop;
17
+
18
+ class SVGGradient {
19
+ public:
20
+ SVGGradient();
21
+
22
+ virtual void parse(xmlNodePtr node);
23
+ virtual void writeXML(xmlNodePtr node, Rect &bounds, bool hadModes) = 0;
24
+
25
+ enum SpreadMethod {
26
+ PAD,
27
+ REFLECT,
28
+ REPEAT
29
+ };
30
+
31
+ protected:
32
+ virtual void parseGradient() = 0;
33
+ void parseStops(xmlNodePtr parent);
34
+ void parseStop(xmlNodePtr node);
35
+ void parseTransform();
36
+ void parseSpreadMethod();
37
+ void writeCommonXML(xmlNodePtr node, Matrix& m, bool hasModes);
38
+
39
+ std::map<double, SVGGradientStop> stops;
40
+ Matrix transform;
41
+ AttributeParser attribs;
42
+ SpreadMethod spreadMethod;
43
+
44
+ bool userSpace;
45
+ };
46
+
47
+ class SVGLinearGradient : public SVGGradient {
48
+ public:
49
+ void writeXML(xmlNodePtr node, Rect &bounds, bool hasModes);
50
+
51
+ protected:
52
+ void parseGradient();
53
+
54
+ double x1, x2, y1, y2;
55
+ };
56
+
57
+ class SVGRadialGradient : public SVGGradient {
58
+ public:
59
+ void writeXML(xmlNodePtr node, Rect &bounds, bool hasModes);
60
+
61
+ protected:
62
+ void parseGradient();
63
+
64
+ double cx, cy, fx, fy, r;
65
+ bool hasFocalPoint;
66
+ };
67
+
68
+ class SVGGradientStop {
69
+ public:
70
+ void setColor(const char *c) { color.parse(c); }
71
+ void setAlpha(unsigned char alpha) { color.setAlpha(alpha); }
72
+ void setAlpha(double alpha) { color.setAlpha(alpha); }
73
+ void writeXML(xmlNodePtr node, double offset);
74
+
75
+ private:
76
+ SVGColor color;
77
+ };
78
+
79
+ }
80
+
81
+ #endif
@@ -0,0 +1,155 @@
1
+ #include "SVGPathParser.h"
2
+
3
+ using namespace std;
4
+
5
+ namespace SWF {
6
+
7
+ PathParser::PathParser(ShapeMaker *shapeMaker) {
8
+ shaper = shapeMaker;
9
+ }
10
+
11
+ void PathParser::parse(const char *path) {
12
+ char currentChar, currentCmd = 0;
13
+ CharType charType;
14
+ bool repeated = false;
15
+
16
+ //use <= strlen() to make sure the last parameter is parsed correctly
17
+ for(size_t i = 0; i <= strlen(path); i++) {
18
+ currentChar = path[i];
19
+ charType = getCharType(currentChar);
20
+
21
+ if(charType != OTHER) {
22
+ if(params.size() != 0 && params.size() == getParameterCount(currentCmd)) {
23
+ executeCommand(currentCmd, repeated);
24
+ params.clear();
25
+
26
+ repeated = true;
27
+ }
28
+
29
+ if(charType == COMMAND_ABSOLUTE || charType == COMMAND_RELATIVE) {
30
+ if(params.size() > 0) {
31
+ cerr << "WARNING: too much parameters in SVG path" << endl;
32
+ params.clear();
33
+ }
34
+
35
+ currentCmd = currentChar;
36
+
37
+ if(getParameterCount(currentCmd) == 0) {
38
+ executeCommand(currentCmd, repeated);
39
+ }
40
+
41
+ repeated = false;
42
+ }
43
+ } else {
44
+ char *str = (char*)path + i;
45
+ char *tailPtr;
46
+
47
+ params.push_back(strtod(str, &tailPtr));
48
+ i += tailPtr - str - 1;
49
+ }
50
+
51
+ }
52
+ if(params.size() > 0) {
53
+ cerr << "WARNING: too much parameters in SVG path" << endl;
54
+ params.clear();
55
+ }
56
+ shaper->close(false);
57
+ shaper->finish();
58
+ }
59
+
60
+ void PathParser::executeCommand(char command, bool repeated) {
61
+ switch(command) {
62
+ case 'Q':
63
+ shaper->curveTo(params[0], params[1], params[2], params[3]);
64
+ break;
65
+
66
+ case 'q':
67
+ shaper->curveToR(params[0], params[1], params[2], params[3]);
68
+ break;
69
+
70
+ case 'T':
71
+ shaper->smoothCurveTo(params[0], params[1]);
72
+ break;
73
+
74
+ case 't':
75
+ shaper->smoothCurveToR(params[0], params[1]);
76
+ break;
77
+
78
+ case 'C':
79
+ shaper->cubicTo(params[0], params[1], params[2], params[3], params[4], params[5]);
80
+ break;
81
+
82
+ case 'c':
83
+ shaper->cubicToR(params[0], params[1], params[2], params[3], params[4], params[5]);
84
+ break;
85
+
86
+ case 'S':
87
+ shaper->smoothCubicTo(params[0], params[1], params[2], params[3]);
88
+ break;
89
+
90
+ case 's':
91
+ shaper->smoothCubicToR(params[0], params[1], params[2], params[3]);
92
+ break;
93
+
94
+ case 'L':
95
+ shaper->lineTo(params[0], params[1]);
96
+ break;
97
+
98
+ case 'l':
99
+ shaper->lineToR(params[0], params[1]);
100
+ break;
101
+
102
+ case 'M':
103
+ if(repeated) {
104
+ shaper->lineTo(params[0], params[1]);
105
+ } else {
106
+ shaper->close(false);
107
+ shaper->setup(params[0], params[1]);
108
+ }
109
+ break;
110
+
111
+ case 'm':
112
+ if(repeated) {
113
+ shaper->lineToR(params[0], params[1]);
114
+ } else {
115
+ shaper->close(false);
116
+ shaper->setupR(params[0], params[1]);
117
+ }
118
+ break;
119
+
120
+ case 'H':
121
+ shaper->lineTo(params[0], shaper->getLastY());
122
+ break;
123
+
124
+ case 'h':
125
+ shaper->lineToR(params[0], 0);
126
+ break;
127
+
128
+ case 'V':
129
+ shaper->lineTo(shaper->getLastX(), params[0]);
130
+ break;
131
+
132
+ case 'v':
133
+ shaper->lineToR(0, params[0]);
134
+ break;
135
+
136
+ case 'A':
137
+ shaper->arcTo(params[0], params[1], params[2], (params[3] == 1), (params[4] == 1), params[5], params[6]);
138
+ break;
139
+
140
+ case 'a':
141
+ shaper->arcToR(params[0], params[1], params[2], (params[3] == 1), (params[4] == 1), params[5], params[6]);
142
+ break;
143
+
144
+ case 'Z':
145
+ case 'z':
146
+ shaper->close();
147
+ break;
148
+
149
+ default:
150
+ cerr << "WARNING: SVG path command not implemented (" << command << ")" << endl;
151
+ break;
152
+ }
153
+ }
154
+
155
+ }