geomerative 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/LICENSE +662 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +2 -0
  6. data/Rakefile +37 -0
  7. data/examples/README.md +7 -0
  8. data/examples/data/FreeSans.ttf +0 -0
  9. data/examples/data/ReplicaBold.ttf +0 -0
  10. data/examples/data/bot1.svg +160 -0
  11. data/examples/hello_svg_to_pdf.rb +26 -0
  12. data/examples/hello_world.rb +23 -0
  13. data/examples/physics_type.rb +77 -0
  14. data/examples/rotate_first_letter.rb +28 -0
  15. data/geomerative.gemspec +32 -0
  16. data/lib/geomerative.rb +12 -0
  17. data/lib/geomerative/version.rb +3 -0
  18. data/pom.xml +110 -0
  19. data/src/geomerative/FastRClip.java +2715 -0
  20. data/src/geomerative/RClip.java +2892 -0
  21. data/src/geomerative/RClosest.java +64 -0
  22. data/src/geomerative/RCommand.java +1941 -0
  23. data/src/geomerative/RContour.java +348 -0
  24. data/src/geomerative/RFont.java +583 -0
  25. data/src/geomerative/RG.java +753 -0
  26. data/src/geomerative/RGeomElem.java +1075 -0
  27. data/src/geomerative/RGroup.java +888 -0
  28. data/src/geomerative/RMatrix.java +401 -0
  29. data/src/geomerative/RMesh.java +420 -0
  30. data/src/geomerative/RPath.java +1095 -0
  31. data/src/geomerative/RPoint.java +419 -0
  32. data/src/geomerative/RPolygon.java +1110 -0
  33. data/src/geomerative/RRectangle.java +91 -0
  34. data/src/geomerative/RSVG.java +976 -0
  35. data/src/geomerative/RShape.java +2045 -0
  36. data/src/geomerative/RStrip.java +221 -0
  37. data/src/geomerative/RStyle.java +469 -0
  38. data/src/org/apache/batik/svggen/font/.SVGFont.java.swp +0 -0
  39. data/src/org/apache/batik/svggen/font/Font.java +188 -0
  40. data/src/org/apache/batik/svggen/font/Glyph.java +113 -0
  41. data/src/org/apache/batik/svggen/font/Messages.java.bak +72 -0
  42. data/src/org/apache/batik/svggen/font/Point.java +38 -0
  43. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +15 -0
  44. data/src/org/apache/batik/svggen/font/table/ClassDef.java +42 -0
  45. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +55 -0
  46. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +49 -0
  47. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +81 -0
  48. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +60 -0
  49. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +48 -0
  50. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +147 -0
  51. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +60 -0
  52. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +84 -0
  53. data/src/org/apache/batik/svggen/font/table/CmapTable.java +87 -0
  54. data/src/org/apache/batik/svggen/font/table/Coverage.java +50 -0
  55. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +59 -0
  56. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +56 -0
  57. data/src/org/apache/batik/svggen/font/table/CvtTable.java +48 -0
  58. data/src/org/apache/batik/svggen/font/table/Device.java +63 -0
  59. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +73 -0
  60. data/src/org/apache/batik/svggen/font/table/Feature.java +56 -0
  61. data/src/org/apache/batik/svggen/font/table/FeatureList.java +70 -0
  62. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +52 -0
  63. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +30 -0
  64. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +38 -0
  65. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +165 -0
  66. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +160 -0
  67. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +79 -0
  68. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +155 -0
  69. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +111 -0
  70. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +39 -0
  71. data/src/org/apache/batik/svggen/font/table/GposTable.java +80 -0
  72. data/src/org/apache/batik/svggen/font/table/GsubTable.java +118 -0
  73. data/src/org/apache/batik/svggen/font/table/HeadTable.java +159 -0
  74. data/src/org/apache/batik/svggen/font/table/HheaTable.java +109 -0
  75. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +99 -0
  76. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +58 -0
  77. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +65 -0
  78. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +56 -0
  79. data/src/org/apache/batik/svggen/font/table/KernTable.java +64 -0
  80. data/src/org/apache/batik/svggen/font/table/KerningPair.java +53 -0
  81. data/src/org/apache/batik/svggen/font/table/LangSys.java +58 -0
  82. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +52 -0
  83. data/src/org/apache/batik/svggen/font/table/Ligature.java +57 -0
  84. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +55 -0
  85. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +40 -0
  86. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +63 -0
  87. data/src/org/apache/batik/svggen/font/table/LocaTable.java +72 -0
  88. data/src/org/apache/batik/svggen/font/table/Lookup.java +77 -0
  89. data/src/org/apache/batik/svggen/font/table/LookupList.java +68 -0
  90. data/src/org/apache/batik/svggen/font/table/LookupSubtable.java +27 -0
  91. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +31 -0
  92. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +124 -0
  93. data/src/org/apache/batik/svggen/font/table/NameRecord.java +98 -0
  94. data/src/org/apache/batik/svggen/font/table/NameTable.java +67 -0
  95. data/src/org/apache/batik/svggen/font/table/Os2Table.java +232 -0
  96. data/src/org/apache/batik/svggen/font/table/Panose.java +108 -0
  97. data/src/org/apache/batik/svggen/font/table/PostTable.java +379 -0
  98. data/src/org/apache/batik/svggen/font/table/PrepTable.java +38 -0
  99. data/src/org/apache/batik/svggen/font/table/Program.java +49 -0
  100. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +57 -0
  101. data/src/org/apache/batik/svggen/font/table/Script.java +72 -0
  102. data/src/org/apache/batik/svggen/font/table/ScriptList.java +78 -0
  103. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +52 -0
  104. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +28 -0
  105. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +47 -0
  106. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +67 -0
  107. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +67 -0
  108. data/src/org/apache/batik/svggen/font/table/Table.java +204 -0
  109. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +94 -0
  110. data/src/org/apache/batik/svggen/font/table/TableFactory.java +121 -0
  111. metadata +206 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
3
+
4
+ This file is part of Geomerative.
5
+
6
+ Geomerative is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Geomerative is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ package geomerative ;
21
+
22
+ public class RRectangle
23
+ {
24
+ RPoint topLeft;
25
+ RPoint bottomRight;
26
+
27
+ public RRectangle()
28
+ {
29
+ topLeft = new RPoint();
30
+ bottomRight = new RPoint();
31
+ }
32
+
33
+ public RRectangle(float x,float y,float w,float h)
34
+ {
35
+ topLeft = new RPoint(x,y);
36
+ bottomRight = new RPoint(x+w,y+h);
37
+
38
+ }
39
+
40
+ public RRectangle(RPoint _topLeft,RPoint _bottomRight)
41
+ {
42
+ this.topLeft = _topLeft;
43
+ this.bottomRight = _bottomRight;
44
+ }
45
+
46
+ RPoint[] getPoints() {
47
+ RPoint[] ps = new RPoint[4];
48
+
49
+ ps[0] = new RPoint(topLeft);
50
+
51
+ ps[1] = new RPoint(topLeft);
52
+ ps[1].x = bottomRight.x;
53
+
54
+ ps[2] = new RPoint(bottomRight);
55
+
56
+ ps[3] = new RPoint(bottomRight);
57
+ ps[3].x = topLeft.x;
58
+
59
+ return ps;
60
+ }
61
+
62
+ float getMaxX()
63
+ {
64
+ //return (topLeft.x > bottomRight.x) ? topLeft.x : bottomRight.x;
65
+ return bottomRight.x;
66
+ }
67
+
68
+ float getMaxY()
69
+ {
70
+ //return (topLeft.y > bottomRight.y) ? topLeft.y : bottomRight.y;
71
+ return bottomRight.y;
72
+ }
73
+
74
+ float getMinX()
75
+ {
76
+ //return (topLeft.x < bottomRight.x) ? topLeft.x : bottomRight.x;
77
+ return topLeft.x;
78
+ }
79
+
80
+ float getMinY()
81
+ {
82
+ //return (topLeft.y < bottomRight.y) ? topLeft.y : bottomRight.y;
83
+ return topLeft.y;
84
+ }
85
+
86
+ @Override
87
+ public String toString()
88
+ {
89
+ return "";
90
+ }
91
+ }
@@ -0,0 +1,976 @@
1
+ /**
2
+ Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
3
+
4
+ This file is part of Geomerative.
5
+
6
+ Geomerative is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Geomerative is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ package geomerative;
21
+
22
+ import processing.core.*;
23
+ import processing.data.*;
24
+
25
+ /**
26
+ * @extended
27
+ */
28
+ public class RSVG
29
+ {
30
+ public void draw(String filename, PGraphics g)
31
+ {
32
+ this.toGroup(filename).draw(g);
33
+ }
34
+
35
+ public void draw(String filename, PApplet p)
36
+ {
37
+ this.toGroup(filename).draw(p);
38
+ }
39
+
40
+ public void draw(String filename)
41
+ {
42
+ this.toGroup(filename).draw();
43
+ }
44
+
45
+ public void saveShape(String filename, RShape shp) {
46
+ String str = fromShape(shp);
47
+ String[] strs = PApplet.split(str, "\n");
48
+ RG.parent().saveStrings(filename, strs);
49
+ }
50
+
51
+ public String fromShape(RShape shape) {
52
+ String header = "<?xml version=\"1.0\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
53
+
54
+ return header + shapeToString(shape) + "</svg>";
55
+ }
56
+
57
+ public void saveGroup(String filename, RGroup grp) {
58
+ String str = fromGroup(grp);
59
+ String[] strs = PApplet.split(str, "\n");
60
+ RG.parent().saveStrings(filename, strs);
61
+ }
62
+
63
+ public String fromGroup(RGroup group) {
64
+ String header = "<?xml version=\"1.0\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
65
+
66
+ return header + groupToString(group) + "</svg>";
67
+ }
68
+
69
+
70
+
71
+ public RGroup toGroup(String filename)
72
+ {
73
+ XML svg;
74
+
75
+ svg = RG.parent().loadXML(filename);
76
+
77
+
78
+ if (svg == null) return new RGroup();
79
+
80
+ if (!svg.getName().equals("svg")) {
81
+ throw new RuntimeException("root is not <svg>, it's <" + svg.getName() + ">");
82
+ }
83
+
84
+ return elemToGroup(svg);
85
+ }
86
+
87
+ public float unitsToPixels(String units, float originalPxSize) {
88
+ // TODO: check if it is possible to know the dpi of a given PGraphics or device
89
+ return unitsToPixels(units, originalPxSize, 72.0f/*Toolkit.getDefaultToolkit().getScreenResolution()*/);
90
+ }
91
+
92
+ public float unitsToPixels(String units, float originalPxSize, float dpi) {
93
+ int chars = 0;
94
+ float multiplier = 1.0f;
95
+
96
+ if (units.endsWith("em")) {
97
+ chars = 2;
98
+ multiplier = 1.0f;
99
+ } else if (units.endsWith("ex")) {
100
+ chars = 2;
101
+ multiplier = 1.0f;
102
+ } else if (units.endsWith("px")) {
103
+ chars = 2;
104
+ multiplier = 1.0f;
105
+ } else if (units.endsWith("pt")) {
106
+ chars = 2;
107
+ multiplier = 1.25f;
108
+ } else if (units.endsWith("pc")) {
109
+ chars = 2;
110
+ multiplier = 15f;
111
+ } else if (units.endsWith("cm")) {
112
+ chars = 2;
113
+ multiplier = 35.43307f / 90.0f * dpi;
114
+ } else if (units.endsWith("mm")) {
115
+ chars = 2;
116
+ multiplier = 3.543307f / 90.0f * dpi;
117
+ } else if (units.endsWith("in")) {
118
+ chars = 2;
119
+ multiplier = dpi;
120
+ } else if (units.endsWith("%")) {
121
+ chars = 1;
122
+ multiplier = originalPxSize / 100.0f;
123
+ } else {
124
+ chars = 0;
125
+ multiplier = 1.0f;
126
+ }
127
+
128
+ return Float.parseFloat(units.substring(0, units.length()-chars)) * multiplier;
129
+ }
130
+
131
+ public RShape toShape(String filename)
132
+ {
133
+ XML svg;
134
+
135
+ svg = RG.parent().loadXML(filename);
136
+
137
+
138
+ if (svg == null) return new RShape();
139
+
140
+ if ( !svg.getName().equals("svg") )
141
+ {
142
+ throw new RuntimeException("root is not <svg>, it's <" + svg.getName() + ">");
143
+ }
144
+
145
+ RShape result = elemToCompositeShape(svg);
146
+
147
+ result.origWidth = result.getWidth();
148
+ result.origHeight = result.getHeight();
149
+
150
+ if (svg.hasAttribute("width") && svg.hasAttribute("height")) {
151
+ String widthStr = svg.getString("width").trim();
152
+ String heightStr = svg.getString("height").trim();
153
+
154
+ result.width = unitsToPixels(widthStr, result.origWidth);
155
+ result.height = unitsToPixels(heightStr, result.origHeight);
156
+ } else {
157
+ result.width = result.origWidth;
158
+ result.height = result.origHeight;
159
+ }
160
+
161
+ return result;
162
+ }
163
+
164
+ public RPolygon toPolygon(String filename)
165
+ {
166
+ return toGroup(filename).toPolygon();
167
+ }
168
+
169
+ public RMesh toMesh(String filename)
170
+ {
171
+ return toGroup(filename).toMesh();
172
+ }
173
+
174
+ public String groupToString(RGroup grp) {
175
+ String result = "";
176
+ result += "<g ";
177
+ result += styleToString(grp.getStyle());
178
+ result += ">\n";
179
+
180
+ for(int i=0;i<grp.countElements();i++) {
181
+ switch(grp.elements[i].getType()){
182
+ case RGeomElem.GROUP:
183
+ result += groupToString((RGroup)grp.elements[i]);
184
+ break;
185
+
186
+ case RGeomElem.POLYGON:
187
+ result += polygonToString((RPolygon)grp.elements[i]);
188
+ break;
189
+
190
+ case RGeomElem.SHAPE:
191
+ result += shapeToString((RShape)grp.elements[i]);
192
+ break;
193
+
194
+ }
195
+ }
196
+
197
+ result += "</g>\n";
198
+ return result;
199
+ }
200
+
201
+ public String polygonToString(RPolygon poly) {
202
+ String result = "";
203
+ result += shapeToString(poly.toShape());
204
+ return result;
205
+ }
206
+
207
+ public String shapeToString(RShape shp) {
208
+ String result = "";
209
+
210
+ // If it has children it is a group
211
+ result += "<g ";
212
+ result += styleToString(shp.getStyle());
213
+ result += ">\n";
214
+
215
+ if (shp.countPaths() > 0) {
216
+ result += "<path ";
217
+ result += "d=\"";
218
+
219
+ for(int i=0; i<shp.countPaths(); i++) {
220
+ RPath sushp = shp.paths[i];
221
+ boolean init = true;
222
+ for ( int j = 0; j < sushp.countCommands(); j++ ) {
223
+ RCommand cmd = sushp.commands[j];
224
+
225
+ if (init) {
226
+ result += "M" + cmd.startPoint.x + " " + cmd.startPoint.y + " ";
227
+ init = false;
228
+ }
229
+
230
+ switch( cmd.getCommandType() )
231
+ {
232
+ case RCommand.LINETO:
233
+ result += "L" + cmd.endPoint.x + " " + cmd.endPoint.y + " ";
234
+ break;
235
+
236
+ case RCommand.QUADBEZIERTO:
237
+ result += "Q" + cmd.controlPoints[0].x + " " + cmd.controlPoints[0].y + cmd.endPoint.x + " " + cmd.endPoint.y + " ";
238
+ break;
239
+
240
+ case RCommand.CUBICBEZIERTO:
241
+ result += "C" + cmd.controlPoints[0].x + " " + cmd.controlPoints[0].y + " " + cmd.controlPoints[1].x + " " + cmd.controlPoints[1].y + " " + cmd.endPoint.x + " " + cmd.endPoint.y + " ";
242
+ break;
243
+ }
244
+ }
245
+
246
+ if (sushp.closed) {
247
+ result += "Z ";
248
+ }
249
+ }
250
+
251
+ result += "\"/>\n";
252
+ }
253
+
254
+ for (int i=0; i<shp.countChildren(); i++) {
255
+ result+=shapeToString(shp.children[i]);
256
+ }
257
+
258
+ result += "</g>\n";
259
+ return result;
260
+ }
261
+
262
+ public String styleToString(RStyle style) {
263
+ String result = " style=\"";
264
+
265
+ if (style.fillDef) {
266
+ if (!style.fill) {
267
+ result += "fill:none;";
268
+ } else {
269
+ result += "fill:#" + PApplet.hex(style.fillColor, 6) + ";";
270
+ }
271
+ }
272
+
273
+ if (style.fillAlphaDef) {
274
+ result += "fill-opacity:" + style.fillAlpha/255.0f + ";";
275
+ }
276
+
277
+ if (style.strokeDef) {
278
+ if (!style.stroke) {
279
+ result += "stroke:none;";
280
+ } else {
281
+ result += "stroke:#" + PApplet.hex(style.strokeColor, 6) + ";";
282
+ }
283
+ }
284
+
285
+ if (style.strokeAlphaDef) {
286
+ result += "stroke-opacity:" + style.strokeAlpha/255.0f + ";";
287
+ }
288
+
289
+ if (style.strokeWeightDef) {
290
+ result += "stroke-width:" + style.strokeWeight + ";";
291
+ }
292
+
293
+
294
+ if(style.strokeCapDef) {
295
+ result += "stroke-linecap:";
296
+
297
+ switch (style.strokeCap) {
298
+ case RG.PROJECT:
299
+ result += "butt";
300
+ break;
301
+ case RG.ROUND:
302
+ result += "round";
303
+ break;
304
+ case RG.SQUARE:
305
+ result += "square";
306
+ break;
307
+
308
+ default:
309
+ break;
310
+ }
311
+
312
+ result += ";";
313
+ }
314
+
315
+ if(style.strokeJoinDef) {
316
+ result += "stroke-linejoin:";
317
+
318
+ switch (style.strokeJoin) {
319
+ case RG.MITER:
320
+ result += "miter";
321
+ break;
322
+ case RG.ROUND:
323
+ result += "round";
324
+ break;
325
+ case RG.BEVEL:
326
+ result += "bevel";
327
+ break;
328
+
329
+ default:
330
+ break;
331
+ }
332
+
333
+ result += ";";
334
+ }
335
+
336
+ result += "\" ";
337
+ return result;
338
+ }
339
+
340
+ /**
341
+ * @param elem
342
+ * @return
343
+ * @invisible
344
+ */
345
+ public RGroup elemToGroup(XML elem)
346
+ {
347
+ RGroup grp = new RGroup();
348
+
349
+ // Set the defaults SVG styles for the root
350
+ if(elem.getName().toLowerCase().equals("svg")){
351
+ grp.setFill(0); // By default in SVG it's black
352
+ grp.setFillAlpha(255); // By default in SVG it's 1
353
+ grp.setStroke(false); // By default in SVG it's none
354
+ grp.setStrokeWeight(1F); // By default in SVG it's none
355
+ grp.setStrokeCap("butt"); // By default in SVG it's 'butt'
356
+ grp.setStrokeJoin("miter"); // By default in SVG it's 'miter'
357
+ grp.setStrokeAlpha(255); // By default in SVG it's 1
358
+ grp.setAlpha(255); // By default in SVG it's 1F
359
+ }
360
+
361
+ XML elems[] = elem.getChildren();
362
+ for (XML elem1 : elems) {
363
+ String name = elem1.getName().toLowerCase();
364
+ XML element = elem1;
365
+ // Parse and create the geometrical element
366
+ RGeomElem geomElem = null;
367
+ switch (name) {
368
+ case "g":
369
+ geomElem = elemToGroup(element);
370
+ break;
371
+ case "path":
372
+ geomElem = elemToShape(element);
373
+ break;
374
+ case "polygon":
375
+ geomElem = elemToPolygon(element);
376
+ break;
377
+ case "polyline":
378
+ geomElem = elemToPolyline(element);
379
+ break;
380
+ case "circle":
381
+ geomElem = elemToCircle(element);
382
+ break;
383
+ case "ellipse":
384
+ geomElem = elemToEllipse(element);
385
+ break;
386
+ case "rect":
387
+ geomElem = elemToRect(element);
388
+ break;
389
+ case "line":
390
+ geomElem = elemToLine(element);
391
+ break;
392
+ case "defs":
393
+ break;
394
+ default:
395
+ PApplet.println("Element '" + name + "' not know. Ignoring it.");
396
+ break; // If the geometrical element has been correctly created
397
+ }
398
+ if((geomElem != null)){
399
+ // Transform geometrical element
400
+ if(element.hasAttribute("transform")){
401
+ String transformString = element.getString("transform");
402
+ RMatrix transf = new RMatrix(transformString);
403
+ geomElem.transform(transf);
404
+ }
405
+
406
+ // Get the id for the geometrical element
407
+ if(element.hasAttribute("id")){
408
+ geomElem.name = element.getString("id");
409
+ }
410
+
411
+ // Get the style for the geometrical element
412
+ if(element.hasAttribute("style")){
413
+ geomElem.setStyle(element.getString("style"));
414
+ }
415
+
416
+ // Get the fill for the geometrical element
417
+ if(element.hasAttribute("fill")){
418
+ geomElem.setFill(element.getString("fill"));
419
+ }
420
+
421
+ // Get the fill-linejoin for the geometrical element
422
+ if(element.hasAttribute("fill-opacity")){
423
+ geomElem.setFillAlpha(element.getString("fill-opacity"));
424
+ }
425
+
426
+ // Get the stroke for the geometrical element
427
+ if(element.hasAttribute("stroke")){
428
+ geomElem.setStroke(element.getString("stroke"));
429
+ }
430
+
431
+ // Get the stroke-width for the geometrical element
432
+ if(element.hasAttribute("stroke-width")){
433
+ geomElem.setStrokeWeight(element.getString("stroke-width"));
434
+ }
435
+
436
+ // Get the stroke-linecap for the geometrical element
437
+ if(element.hasAttribute("stroke-linecap")){
438
+ geomElem.setStrokeCap(element.getString("stroke-linecap"));
439
+ }
440
+
441
+ // Get the stroke-linejoin for the geometrical element
442
+ if(element.hasAttribute("stroke-linejoin")){
443
+ geomElem.setStrokeJoin(element.getString("stroke-linejoin"));
444
+ }
445
+
446
+ // Get the stroke-linejoin for the geometrical element
447
+ if(element.hasAttribute("stroke-opacity")){
448
+ geomElem.setStrokeAlpha(element.getString("stroke-opacity"));
449
+ }
450
+
451
+ // Get the opacity for the geometrical element
452
+ if(element.hasAttribute("opacity")){
453
+ geomElem.setAlpha(element.getString("opacity"));
454
+ }
455
+
456
+ // Get the style for the geometrical element
457
+ grp.addElement(geomElem);
458
+ }
459
+ }
460
+
461
+ // Set the original width and height
462
+ grp.updateOrigParams();
463
+
464
+ return grp;
465
+ }
466
+
467
+ /**
468
+ * @param elem
469
+ * @return
470
+ * @invisible
471
+ */
472
+ public RShape elemToCompositeShape( XML elem )
473
+ {
474
+ RShape shp = new RShape();
475
+
476
+ // Set the defaults SVG styles for the root
477
+ if (elem.getName().toLowerCase().equals("svg"))
478
+ {
479
+ shp.setFill(0); // By default in SVG it's black
480
+ shp.setFillAlpha(255); // By default in SVG it's 1
481
+ shp.setStroke(false); // By default in SVG it's none
482
+ shp.setStrokeWeight(1F); // By default in SVG it's none
483
+ shp.setStrokeCap("butt"); // By default in SVG it's 'butt'
484
+ shp.setStrokeJoin("miter"); // By default in SVG it's 'miter'
485
+ shp.setStrokeAlpha(255); // By default in SVG it's 1
486
+ shp.setAlpha(255); // By default in SVG it's 1F
487
+ }
488
+
489
+ XML elems[] = elem.getChildren();
490
+
491
+ for (XML elem1 : elems) {
492
+ String name = elem1.getName();
493
+ if ( name == null ) continue;
494
+ name = name.toLowerCase();
495
+ XML element = elem1;
496
+ // Parse and create the geometrical element
497
+ RShape geomElem = null;
498
+ switch (name) {
499
+ case "g":
500
+ geomElem = elemToCompositeShape(element);
501
+ break;
502
+ case "path":
503
+ geomElem = elemToShape(element);
504
+ break;
505
+ case "polygon":
506
+ geomElem = elemToPolygon(element);
507
+ break;
508
+ case "polyline":
509
+ geomElem = elemToPolyline(element);
510
+ break;
511
+ case "circle":
512
+ geomElem = elemToCircle(element);
513
+ break;
514
+ case "ellipse":
515
+ geomElem = elemToEllipse(element);
516
+ break;
517
+ case "rect":
518
+ geomElem = elemToRect(element);
519
+ break;
520
+ case "line":
521
+ geomElem = elemToLine(element);
522
+ break;
523
+ case "defs":
524
+ break;
525
+ default:
526
+ PApplet.println("Element '" + name + "' not know. Ignoring it.");
527
+ break; // If the geometrical element has been correctly created
528
+ }
529
+ if((geomElem != null)){
530
+ // Transform geometrical element
531
+ if(element.hasAttribute("transform")){
532
+ String transformString = element.getString("transform");
533
+ RMatrix transf = new RMatrix(transformString);
534
+ geomElem.transform(transf);
535
+ }
536
+
537
+ // Get the id for the geometrical element
538
+ if(element.hasAttribute("id")){
539
+ geomElem.name = element.getString("id");
540
+ }
541
+
542
+ // Get the style for the geometrical element
543
+ if(element.hasAttribute("style")){
544
+ geomElem.setStyle(element.getString("style"));
545
+ }
546
+
547
+ // Get the fill for the geometrical element
548
+ if(element.hasAttribute("fill")){
549
+ geomElem.setFill(element.getString("fill"));
550
+ }
551
+
552
+ // Get the fill-linejoin for the geometrical element
553
+ if(element.hasAttribute("fill-opacity")){
554
+ geomElem.setFillAlpha(element.getString("fill-opacity"));
555
+ }
556
+
557
+ // Get the stroke for the geometrical element
558
+ if(element.hasAttribute("stroke")){
559
+ geomElem.setStroke(element.getString("stroke"));
560
+ }
561
+
562
+ // Get the stroke-width for the geometrical element
563
+ if(element.hasAttribute("stroke-width")){
564
+ geomElem.setStrokeWeight(element.getString("stroke-width"));
565
+ }
566
+
567
+ // Get the stroke-linecap for the geometrical element
568
+ if(element.hasAttribute("stroke-linecap")){
569
+ geomElem.setStrokeCap(element.getString("stroke-linecap"));
570
+ }
571
+
572
+ // Get the stroke-linejoin for the geometrical element
573
+ if(element.hasAttribute("stroke-linejoin")){
574
+ geomElem.setStrokeJoin(element.getString("stroke-linejoin"));
575
+ }
576
+
577
+ // Get the stroke-linejoin for the geometrical element
578
+ if(element.hasAttribute("stroke-opacity")){
579
+ geomElem.setStrokeAlpha(element.getString("stroke-opacity"));
580
+ }
581
+
582
+ // Get the opacity for the geometrical element
583
+ if(element.hasAttribute("opacity")){
584
+ geomElem.setAlpha(element.getString("opacity"));
585
+ }
586
+
587
+ // Get the style for the geometrical element
588
+ shp.addChild(geomElem);
589
+ }
590
+ }
591
+
592
+ shp.updateOrigParams();
593
+
594
+ return shp;
595
+ }
596
+
597
+ /**
598
+ * @param elem
599
+ * @return
600
+ * @invisible
601
+ */
602
+ public RShape elemToPolyline(XML elem)
603
+ {
604
+ RShape shp = getPolyline(elem.getString("points").trim());
605
+
606
+ shp.updateOrigParams();
607
+
608
+ return shp;
609
+ }
610
+
611
+ /**
612
+ * @param elem
613
+ * @return
614
+ * @invisible
615
+ */
616
+ public RShape elemToPolygon(XML elem)
617
+ {
618
+ RShape poly = elemToPolyline(elem);
619
+
620
+ poly.addClose();
621
+
622
+ poly.updateOrigParams();
623
+
624
+ return poly;
625
+ }
626
+
627
+ /**
628
+ * @param elem
629
+ * @return
630
+ * @invisible
631
+ */
632
+ public RShape elemToRect(XML elem)
633
+ {
634
+
635
+ RShape shp = getRect(elem.getFloat("x"), elem.getFloat("y"), elem.getFloat("width"), elem.getFloat("height"));
636
+
637
+ shp.updateOrigParams();
638
+
639
+ return shp;
640
+ }
641
+
642
+ /**
643
+ * @param elem
644
+ * @return
645
+ * @invisible
646
+ */
647
+ public RShape elemToLine(XML elem)
648
+ {
649
+ RShape shp = getLine(elem.getFloat("x1"), elem.getFloat("y1"), elem.getFloat("x2"), elem.getFloat("y2"));
650
+
651
+ shp.updateOrigParams();
652
+
653
+ return shp;
654
+ }
655
+
656
+
657
+ /**
658
+ * @param elem
659
+ * @return
660
+ * @invisible
661
+ */
662
+ public RShape elemToEllipse(XML elem)
663
+ {
664
+ RShape shp = getEllipse(elem.getFloat("cx"), elem.getFloat("cy"), elem.getFloat("rx"), elem.getFloat("ry"));
665
+
666
+ shp.updateOrigParams();
667
+
668
+ return shp;
669
+ }
670
+
671
+
672
+ /**
673
+ * @param elem
674
+ * @return
675
+ * @invisible
676
+ */
677
+ public RShape elemToCircle(XML elem)
678
+ {
679
+ float r = elem.getFloat("r");
680
+ RShape shp = getEllipse(elem.getFloat("cx"), elem.getFloat("cy"), r, r);
681
+
682
+ shp.updateOrigParams();
683
+
684
+ return shp;
685
+ }
686
+
687
+ /**
688
+ * @param elem
689
+ * @return
690
+ * @invisible
691
+ */
692
+ public RShape elemToShape(XML elem)
693
+ {
694
+ RShape shp = getShape(elem.getString("d"));
695
+
696
+ shp.updateOrigParams();
697
+
698
+ return shp;
699
+ }
700
+
701
+ /**
702
+ * @invisible
703
+ */
704
+ private RShape getRect(float x, float y, float w, float h)
705
+ {
706
+ RShape shp = RShape.createRectangle(x, y, w, h);
707
+
708
+ shp.updateOrigParams();
709
+
710
+ return shp;
711
+ }
712
+
713
+ /**
714
+ * @invisible
715
+ */
716
+ private RShape getLine(float x1, float y1, float x2, float y2)
717
+ {
718
+ RShape shp = new RShape();
719
+
720
+ shp.addMoveTo(x1, y1);
721
+ shp.addLineTo(x2, y2);
722
+
723
+ return shp;
724
+ }
725
+
726
+
727
+ /**
728
+ * @invisible
729
+ */
730
+ private RShape getEllipse(float cx, float cy, float rx, float ry)
731
+ {
732
+ // RShape createEllipse takes as input the width and height of the ellipses
733
+ return RShape.createEllipse(cx, cy, rx*2F, ry*2F);
734
+ }
735
+
736
+ /**
737
+ * @invisible
738
+ */
739
+ private RShape getPolyline(String s)
740
+ {
741
+ RShape poly = new RShape();
742
+ boolean first = true;
743
+
744
+ //format string to usable format
745
+ char charline[]=s.toCharArray();
746
+ for(int i=0;i<charline.length;i++)
747
+ {
748
+ switch(charline[i])
749
+ {
750
+ case '-':
751
+ if(charline[i-1] != 'e' && charline[i-1] != 'E'){
752
+ charline=PApplet.splice(charline,' ',i);
753
+ i++;
754
+ }
755
+ break;
756
+ case ',':
757
+ case '\n':
758
+ case '\r':
759
+ case '\t':
760
+ charline[i]=' ';
761
+ break;
762
+ }
763
+ }
764
+ String formatted=new String(charline);
765
+ String tags[]=PApplet.splitTokens(formatted,", ");
766
+ for(int i=0;i<tags.length;i++){
767
+ float x = PApplet.parseFloat(tags[i]);
768
+ float y = PApplet.parseFloat(tags[i+1]);
769
+ i++;
770
+ if(first){
771
+ poly.addMoveTo(x,y);
772
+ first = false;
773
+ }else{
774
+ poly.addLineTo(x,y);
775
+ }
776
+ }
777
+ return poly;
778
+ }
779
+
780
+ /**
781
+ * @invisible
782
+ */
783
+ private RShape getShape(String s)
784
+ {
785
+ RShape shp = new RShape();
786
+
787
+ if(s == null){
788
+ return shp;
789
+ }
790
+
791
+ //format string to usable format
792
+ char charline[] = s.toCharArray();
793
+ for( int i = 0 ; i < charline.length ; i++)
794
+ {
795
+ switch(charline[i])
796
+ {
797
+ case 'M':
798
+ case 'm':
799
+ case 'Z':
800
+ case 'z':
801
+ case 'C':
802
+ case 'c':
803
+ case 'S':
804
+ case 's':
805
+ case 'L':
806
+ case 'l':
807
+ case 'H':
808
+ case 'h':
809
+ case 'V':
810
+ case 'v':
811
+ charline = PApplet.splice(charline,' ',i);
812
+ i ++;
813
+ charline = PApplet.splice(charline,' ',i+1);
814
+ i ++;
815
+ break;
816
+
817
+ case '-':
818
+ if(i>0 && charline[i-1] != 'e' && charline[i-1] != 'E'){
819
+ charline=PApplet.splice(charline,' ',i);
820
+ i++;
821
+ }
822
+ break;
823
+ case ',':
824
+ case '\n':
825
+ case '\r':
826
+ case '\t':
827
+ charline[i] = ' ';
828
+ break;
829
+
830
+ }
831
+ }
832
+ String formatted = new String(charline);
833
+ String[] tags = PApplet.splitTokens(formatted);
834
+
835
+ //PApplet.println("formatted: " + formatted);
836
+ //PApplet.println("tags: ");
837
+ //PApplet.println(tags);
838
+
839
+ //build points
840
+ RPoint curp = new RPoint();
841
+ RPoint relp = new RPoint();
842
+ RPoint refp = new RPoint();
843
+ RPoint strp = new RPoint();
844
+
845
+ char command = 'a';
846
+
847
+ for (int i=0;i<tags.length;i++)
848
+ {
849
+ char nextChar = tags[i].charAt(0);
850
+ switch(nextChar)
851
+ {
852
+ case 'm':
853
+ case 'M':
854
+ case 'c':
855
+ case 'C':
856
+ case 's':
857
+ case 'S':
858
+ case 'l':
859
+ case 'L':
860
+ case 'h':
861
+ case 'H':
862
+ case 'v':
863
+ case 'V':
864
+ i += 1;
865
+ case 'z':
866
+ case 'Z':
867
+ command = nextChar;
868
+ break;
869
+ default:
870
+ if (command == 'm') {
871
+ command = 'l';
872
+ } else if (command == 'M') {
873
+ command = 'L';
874
+ }
875
+ }
876
+
877
+ relp.setLocation(0F, 0F);
878
+
879
+ switch(command)
880
+ {
881
+ case 'm':
882
+ relp.setLocation(curp.x, curp.y);
883
+ case 'M':
884
+ i = move(shp, curp, relp, refp, strp, tags, i);
885
+ break;
886
+
887
+ case 'z':
888
+ relp.setLocation(curp.x, curp.y);
889
+ case 'Z':
890
+ shp.addClose();
891
+ break;
892
+
893
+ case 'c':
894
+ relp.setLocation(curp.x, curp.y);
895
+ case 'C':
896
+ i = curve(shp, curp, relp, refp, strp, tags, i);
897
+ break;
898
+
899
+ case 's':
900
+ relp.setLocation(curp.x, curp.y);
901
+ case 'S':
902
+ i = smooth(shp, curp, relp, refp, strp, tags, i);
903
+ break;
904
+
905
+ case 'l':
906
+ relp.setLocation(curp.x, curp.y);
907
+ case 'L':
908
+ i = line(shp, curp, relp, refp, strp, tags, i);
909
+ break;
910
+
911
+ case 'h':
912
+ relp.setLocation(curp.x, curp.y);
913
+ case 'H':
914
+ i = horizontal(shp, curp, relp, refp, strp, tags, i);
915
+ break;
916
+
917
+ case 'v':
918
+ relp.setLocation(curp.x, curp.y);
919
+ case 'V':
920
+ i = vertical(shp, curp, relp, refp, strp, tags, i);
921
+ break;
922
+ }
923
+ }
924
+ return shp;
925
+ }
926
+
927
+ private int move(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
928
+ shp.addMoveTo(PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y);
929
+
930
+ curp.setLocation(PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y);
931
+ refp.setLocation(curp.x,curp.y);
932
+ strp.setLocation(curp.x,curp.y);
933
+ //relp.setLocation(0F, 0F);
934
+ return i + 1;
935
+ }
936
+
937
+ private int curve(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
938
+ shp.addBezierTo(PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y, PApplet.parseFloat(tags[i+2])+relp.x, PApplet.parseFloat(tags[i+3])+relp.y, PApplet.parseFloat(tags[i+4])+relp.x, PApplet.parseFloat(tags[i+5])+relp.y);
939
+
940
+ curp.setLocation(PApplet.parseFloat(tags[i+4])+relp.x, PApplet.parseFloat(tags[i+5])+relp.y);
941
+ refp.setLocation(2.0f*curp.x-(PApplet.parseFloat(tags[i+2])+relp.x), 2.0f*curp.y-(PApplet.parseFloat(tags[i+3])+relp.y));
942
+ return i + 5;
943
+ }
944
+
945
+ private int smooth(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
946
+ shp.addBezierTo(refp.x, refp.y, PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y, PApplet.parseFloat(tags[i+2])+relp.x, PApplet.parseFloat(tags[i+3])+relp.y);
947
+
948
+ curp.setLocation(PApplet.parseFloat(tags[i+2])+relp.x, PApplet.parseFloat(tags[i+3])+relp.y);
949
+ refp.setLocation(2.0f*curp.x-(PApplet.parseFloat(tags[i])+relp.x), 2.0f*curp.y-(PApplet.parseFloat(tags[i+1])+relp.y));
950
+ return i + 3;
951
+ }
952
+
953
+ private int line(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
954
+ shp.addLineTo(PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y);
955
+
956
+ curp.setLocation(PApplet.parseFloat(tags[i])+relp.x, PApplet.parseFloat(tags[i+1])+relp.y);
957
+ refp.setLocation(curp.x, curp.y);
958
+ return i + 1;
959
+ }
960
+
961
+ private int horizontal(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
962
+ shp.addLineTo(PApplet.parseFloat(tags[i])+relp.x, curp.y);
963
+
964
+ curp.setLocation(PApplet.parseFloat(tags[i])+relp.x, curp.y);
965
+ refp.setLocation(curp.x, curp.y);
966
+ return i;
967
+ }
968
+
969
+ private int vertical(RShape shp, RPoint curp, RPoint relp, RPoint refp, RPoint strp, String[] tags, int i){
970
+ shp.addLineTo(curp.x, PApplet.parseFloat(tags[i])+relp.y);
971
+
972
+ curp.setLocation(curp.x, PApplet.parseFloat(tags[i])+relp.y);
973
+ refp.setLocation(curp.x, curp.y);
974
+ return i;
975
+ }
976
+ }