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,126 @@
1
+ #ifndef SVG_PATHPARSER_H
2
+ #define SVG_PATHPARSER_H
3
+
4
+ #include <string>
5
+ #include <vector>
6
+ #include <iostream>
7
+ #include <libxml/tree.h>
8
+ #include <cmath>
9
+ #include <cstdlib>
10
+ #include "SWFShapeMaker.h"
11
+ #include "SWF.h"
12
+
13
+
14
+
15
+ namespace SWF {
16
+
17
+ class PathParser {
18
+ public:
19
+ PathParser(ShapeMaker *shapeMaker);
20
+ void parse(const char *path);
21
+
22
+ private:
23
+ std::vector<double> params;
24
+ ShapeMaker *shaper;
25
+
26
+ enum CharType {
27
+ COMMAND_ABSOLUTE,
28
+ COMMAND_RELATIVE,
29
+ WHITESPACE,
30
+ OTHER
31
+ };
32
+
33
+ void executeCommand(char command, bool repeated);
34
+
35
+ CharType getCharType(char c) {
36
+ switch(c) {
37
+ case 'M':
38
+ case 'Z':
39
+ case 'L':
40
+ case 'H':
41
+ case 'V':
42
+ case 'C':
43
+ case 'S':
44
+ case 'Q':
45
+ case 'T':
46
+ case 'A':
47
+ return COMMAND_ABSOLUTE;
48
+ break;
49
+
50
+ case 'm':
51
+ case 'z':
52
+ case 'l':
53
+ case 'h':
54
+ case 'v':
55
+ case 'c':
56
+ case 's':
57
+ case 'q':
58
+ case 't':
59
+ case 'a':
60
+ return COMMAND_RELATIVE;
61
+ break;
62
+
63
+ case '\t':
64
+ case '\n':
65
+ case '\r':
66
+ case ',':
67
+ case ' ':
68
+ case 0:
69
+ return WHITESPACE;
70
+ break;
71
+
72
+ default:
73
+ return OTHER;
74
+ break;
75
+
76
+ }
77
+ }
78
+
79
+ size_t getParameterCount(char command) {
80
+ switch(command) {
81
+ case 'z':
82
+ case 'Z':
83
+ return 0;
84
+ break;
85
+
86
+ case 'h':
87
+ case 'H':
88
+ case 'v':
89
+ case 'V':
90
+ return 1;
91
+ break;
92
+
93
+ case 'm':
94
+ case 'M':
95
+ case 'l':
96
+ case 'L':
97
+ case 't':
98
+ case 'T':
99
+ return 2;
100
+ break;
101
+
102
+ case 's':
103
+ case 'S':
104
+ case 'q':
105
+ case 'Q':
106
+ return 4;
107
+ break;
108
+
109
+ case 'c':
110
+ case 'C':
111
+ return 6;
112
+ break;
113
+
114
+ case 'a':
115
+ case 'A':
116
+ return 7;
117
+ break;
118
+ }
119
+ return 0;
120
+ }
121
+
122
+ };
123
+
124
+ }
125
+
126
+ #endif
@@ -0,0 +1,51 @@
1
+ #include "SVGPointsParser.h"
2
+
3
+ #include <iostream>
4
+ #include <cstring>
5
+
6
+ using namespace std;
7
+
8
+ namespace SWF {
9
+
10
+ void PointsParser::parse(const char *points) {
11
+ string tmp;
12
+
13
+ coords.clear();
14
+
15
+ for(int i = 0; i < strlen(points); i++) {
16
+ char currentChar = points[i];
17
+
18
+ if(currentChar == ',' || currentChar == ' ') {
19
+ if(tmp.length() > 0) {
20
+ coords.push_back(atof(tmp.c_str()));
21
+ tmp.clear();
22
+ }
23
+ } else {
24
+ tmp += currentChar;
25
+ }
26
+ }
27
+
28
+ if(tmp.length() > 0) {
29
+ coords.push_back(atof(tmp.c_str()));
30
+ }
31
+
32
+ if(coords.size() % 2) {
33
+ cerr << "WARNING: odd number of coordinates in points attribute" << endl;
34
+ }
35
+ }
36
+
37
+ int PointsParser::getPointCount() {
38
+ return coords.size() / 2;
39
+ }
40
+
41
+ Point PointsParser::getPoint() {
42
+ double x = coords.front();
43
+ coords.pop_front();
44
+
45
+ double y = coords.front();
46
+ coords.pop_front();
47
+
48
+ return Point(x, y);
49
+ }
50
+
51
+ }
@@ -0,0 +1,25 @@
1
+ #ifndef SVG_POINTSPARSER_H
2
+ #define SVG_POINTSPARSER_H
3
+
4
+ #include <string>
5
+ #include <deque>
6
+ #include "Geom.h"
7
+
8
+
9
+
10
+ namespace SWF {
11
+
12
+ class PointsParser {
13
+ public:
14
+ void parse(const char *path);
15
+ Point getPoint();
16
+ int getPointCount();
17
+
18
+ private:
19
+ deque<double> coords;
20
+
21
+ };
22
+
23
+ }
24
+
25
+ #endif
@@ -0,0 +1,181 @@
1
+ #include "SVGStyle.h"
2
+ #include "SVGAttributeParser.h"
3
+ #include <cstring>
4
+
5
+ #define TMP_STRLEN 0xFF
6
+
7
+ using namespace std;
8
+
9
+ namespace SWF {
10
+
11
+ SVGStyle::SVGStyle() {
12
+ _hasFill = false;
13
+ _hasFillGradient = false;
14
+ _hasStroke = false;
15
+ _hasStrokeGradient = false;
16
+ _hasStyle = false;
17
+
18
+ _hasLineCap = false;
19
+ lineCap = CAP_BUTT;
20
+
21
+ _hasLineJoin = false;
22
+ lineJoin = JOIN_MITER;
23
+ miterLimit = 4;
24
+
25
+ strokeWidth = 1;
26
+ }
27
+
28
+ void SVGStyle::parseNode(xmlNodePtr node, map<string, SVGGradient*> &gradients) {
29
+ AttributeParser parser;
30
+ parser.parseNode(node);
31
+
32
+ map<string, string> &attributes = parser.getAttributes();
33
+ for(map<string, string>::iterator iter = attributes.begin(); iter != attributes.end(); iter++) {
34
+ const string &attribute = (*iter).first;
35
+ const string &valueStr = (*iter).second;
36
+ const char *value = valueStr.c_str();
37
+
38
+ if(attribute == "stroke") {
39
+ SVGGradient *gradient = getGradient(valueStr, gradients);
40
+ if(gradient) {
41
+ strokeGradient = gradient;
42
+ _hasStrokeGradient = true;
43
+ _hasStroke = true;
44
+ } else {
45
+ setStrokeColor(value);
46
+ }
47
+ } else if(attribute == "stroke-width") {
48
+ setStrokeWidth(atof(value));
49
+ } else if(attribute == "stroke-opacity") {
50
+ setStrokeAlpha(atof(value));
51
+ } else if(attribute == "stroke-linecap") {
52
+ setLineCap(value);
53
+ } else if(attribute == "stroke-linejoin") {
54
+ setLineJoin(value);
55
+ } else if(attribute == "stroke-miterlimit") {
56
+ setMiterLimit(atof(value));
57
+ } else if(attribute == "fill") {
58
+ SVGGradient *gradient = getGradient(valueStr, gradients);
59
+ if(gradient) {
60
+ fillGradient = gradient;
61
+ _hasFillGradient = true;
62
+ _hasFill = true;
63
+ } else {
64
+ setFillColor(value);
65
+ }
66
+ } else if(attribute == "fill-opacity") {
67
+ setFillAlpha(atof(value));
68
+ }
69
+ }
70
+ }
71
+
72
+ SVGGradient *SVGStyle::getGradient(const string &str, map<string, SVGGradient*> &gradients) {
73
+ if(str.substr(0, 4) == "url(" && str.substr(str.length() - 1) == ")") {
74
+ map<string, SVGGradient*>::iterator i;
75
+ i = gradients.find(str.substr(5, str.length() - 6));
76
+ if(i != gradients.end()) {
77
+ return (*i).second;
78
+ } else {
79
+ return NULL;
80
+ }
81
+ } else {
82
+ return NULL;
83
+ }
84
+ }
85
+
86
+ void SVGStyle::setLineCap(const char *cap) {
87
+ if(!strcmp(cap, "butt")) {
88
+ lineCap = CAP_BUTT;
89
+ _hasLineCap = true;
90
+ _hasStyle = true;
91
+ } else if(!strcmp(cap, "round")) {
92
+ lineCap = CAP_ROUND;
93
+ _hasLineCap = true;
94
+ _hasStyle = true;
95
+ } else if(!strcmp(cap, "square")) {
96
+ lineCap = CAP_SQUARE;
97
+ _hasLineCap = true;
98
+ _hasStyle = true;
99
+ }
100
+ }
101
+
102
+ void SVGStyle::setLineJoin(const char *join) {
103
+ if(!strcmp(join, "miter")) {
104
+ lineJoin = JOIN_MITER;
105
+ _hasLineJoin = true;
106
+ _hasStyle = true;
107
+ } else if(!strcmp(join, "round")) {
108
+ lineJoin = JOIN_ROUND;
109
+ _hasLineJoin = true;
110
+ _hasStyle = true;
111
+ } else if(!strcmp(join, "bevel")) {
112
+ lineJoin = JOIN_BEVEL;
113
+ _hasLineJoin = true;
114
+ _hasStyle = true;
115
+ }
116
+ }
117
+
118
+ void SVGStyle::writeXML(xmlNodePtr parent, double movieVersion) {
119
+ xmlNodePtr node, styleNode;
120
+ char tmp[TMP_STRLEN];
121
+
122
+ styleNode = xmlNewChild(parent, NULL, (const xmlChar *)"StyleList", NULL);
123
+
124
+ if(_hasFill) {
125
+ node = xmlNewChild(styleNode, NULL, (const xmlChar *)"fillStyles", NULL);
126
+ if(_hasFillGradient) {
127
+ fillGradient->writeXML(node, bounds, (movieVersion >= 8));
128
+ } else {
129
+ node = xmlNewChild(node, NULL, (const xmlChar *)"Solid", NULL);
130
+ node = xmlNewChild(node, NULL, (const xmlChar *)"color", NULL);
131
+ fill.writeXML(node);
132
+ }
133
+ }
134
+
135
+ if(_hasStroke) {
136
+ node = xmlNewChild(styleNode, NULL, (const xmlChar *)"lineStyles", NULL);
137
+
138
+ if(movieVersion >= 8) {
139
+ node = xmlNewChild(node, NULL, (const xmlChar *)"LineStyle", NULL);
140
+ snprintf(tmp,TMP_STRLEN,"%f", strokeWidth * 20);
141
+ xmlSetProp(node, (const xmlChar *)"width", (const xmlChar *)&tmp);
142
+ snprintf(tmp, TMP_STRLEN, "%i", lineCap);
143
+ xmlSetProp(node, (const xmlChar *)"startCapStyle", (const xmlChar *)&tmp);
144
+ snprintf(tmp, TMP_STRLEN, "%i", lineJoin);
145
+ xmlSetProp(node, (const xmlChar *)"jointStyle", (const xmlChar *)&tmp);
146
+ xmlSetProp(node, (const xmlChar *)"hasFill", (const xmlChar *)(_hasStrokeGradient ? "1" : "0"));
147
+ xmlSetProp(node, (const xmlChar *)"noHScale", (const xmlChar *)"0");
148
+ xmlSetProp(node, (const xmlChar *)"noVScale", (const xmlChar *)"0");
149
+ xmlSetProp(node, (const xmlChar *)"pixelHinting", (const xmlChar *)"0");
150
+ xmlSetProp(node, (const xmlChar *)"reserved", (const xmlChar *)"0");
151
+ xmlSetProp(node, (const xmlChar *)"noClose", (const xmlChar *)"0");
152
+ snprintf(tmp, TMP_STRLEN, "%i", lineCap);
153
+ xmlSetProp(node, (const xmlChar *)"endCapStyle", (const xmlChar *)&tmp);
154
+
155
+ if(lineJoin == JOIN_MITER) {
156
+ snprintf(tmp, TMP_STRLEN, "%f", miterLimit);
157
+ xmlSetProp(node, (const xmlChar *)"miterLimitFactor", (const xmlChar *)&tmp);
158
+ }
159
+
160
+ if(_hasStrokeGradient) {
161
+ node = xmlNewChild(node, NULL, (const xmlChar *)"fillStyles", NULL);
162
+ strokeGradient->writeXML(node, bounds, (movieVersion >= 8));
163
+ } else {
164
+ node = xmlNewChild(node, NULL, (const xmlChar *)"fillColor", NULL);
165
+ stroke.writeXML(node);
166
+ }
167
+ } else {
168
+ node = xmlNewChild(node, NULL, (const xmlChar *)"LineStyle", NULL);
169
+ snprintf(tmp,TMP_STRLEN,"%f", strokeWidth * 20);
170
+ xmlSetProp(node, (const xmlChar *)"width", (const xmlChar *)&tmp);
171
+ node = xmlNewChild(node, NULL, (const xmlChar *)"color", NULL);
172
+ stroke.writeXML(node);
173
+
174
+ if(_hasLineCap || _hasLineJoin) {
175
+ cerr << "WARNING: some svg features aren't supported before swf version 8" << endl;
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ }
@@ -0,0 +1,80 @@
1
+ #ifndef SVG_STYLE_H
2
+ #define SVG_STYLE_H
3
+
4
+ #include <iostream>
5
+ #include <map>
6
+ #include <libxml/tree.h>
7
+ #include "SVGColor.h"
8
+ #include "SVGGradient.h"
9
+ #include "SWFShapeMaker.h"
10
+
11
+
12
+
13
+ namespace SWF {
14
+
15
+ enum SVGLineCap {
16
+ CAP_ROUND,
17
+ CAP_BUTT,
18
+ CAP_SQUARE
19
+ };
20
+
21
+ enum SVGLineJoin {
22
+ JOIN_ROUND,
23
+ JOIN_BEVEL,
24
+ JOIN_MITER
25
+ };
26
+
27
+ class SVGStyle {
28
+ public:
29
+ SVGStyle();
30
+
31
+ void setStrokeColor(const char *color) { _hasStroke = stroke.parse(color); _hasStyle = true; }
32
+ void setStrokeWidth(const double width) { strokeWidth = width; _hasStyle = true; }
33
+ void setStrokeAlpha(const double alpha) { stroke.setAlpha(alpha); _hasStyle = true; }
34
+ void setFillColor(const char *color) { _hasFill = fill.parse(color); _hasStyle = true; }
35
+ void setFillAlpha(const double alpha) { fill.setAlpha(alpha); _hasStyle = true; }
36
+ void setLineCap(const char *cap);
37
+ void setLineJoin(const char *join);
38
+ void setMiterLimit(const double miter) { miterLimit = miter; _hasStyle = true; }
39
+
40
+ double getStrokeWidth() { return strokeWidth; }
41
+
42
+ void setBounds(Rect b) { bounds = b; }
43
+
44
+ bool hasFill() { return _hasFill; }
45
+ bool hasStroke() { return _hasStroke; }
46
+ bool hasStyle() { return _hasStyle; }
47
+
48
+ void parseNode(xmlNodePtr node, std::map<std::string, SVGGradient*> &gradients);
49
+ void writeXML(xmlNodePtr parent, double movieVersion);
50
+
51
+ private:
52
+ SVGGradient *getGradient(const std::string &str, std::map<std::string, SVGGradient*> &gradients);
53
+
54
+ bool _hasFill;
55
+ bool _hasFillGradient;
56
+ SVGColor fill;
57
+ SVGGradient *fillGradient;
58
+
59
+ bool _hasStroke;
60
+ bool _hasStrokeGradient;
61
+ SVGColor stroke;
62
+ SVGGradient *strokeGradient;
63
+
64
+ bool _hasLineCap;
65
+ SVGLineCap lineCap;
66
+
67
+ bool _hasLineJoin;
68
+ SVGLineJoin lineJoin;
69
+ double miterLimit;
70
+
71
+ bool _hasStyle;
72
+
73
+ double strokeWidth;
74
+
75
+ Rect bounds;
76
+ };
77
+
78
+ }
79
+
80
+ #endif