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,348 @@
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 it under
7
+ * the terms of the GNU General Public License as published by the Free Software
8
+ * Foundation, either version 3 of the License, or (at your option) any later
9
+ * version.
10
+ *
11
+ * Geomerative is distributed in the hope that it will be useful, but WITHOUT
12
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
+ * details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License along with
17
+ * Geomerative. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+ package geomerative;
20
+
21
+ import processing.core.*;
22
+
23
+ import java.util.List;
24
+
25
+ /**
26
+ * RContour is a reduced interface for creating, holding and drawing contours.
27
+ * Contours are ordered lists of points (RPoint) which define the outlines of
28
+ * polygons. Contours can be self-intersecting.
29
+ *
30
+ * @eexample RContour
31
+ * @usage Geometry
32
+ * @related RPoint
33
+ * @related RPolygon
34
+ * @extended
35
+ */
36
+ public class RContour extends RGeomElem {
37
+
38
+ /**
39
+ * @invisible
40
+ */
41
+ public int type = RGeomElem.CONTOUR;
42
+
43
+ /**
44
+ * Array of RPoint objects holding the points of the contour.
45
+ *
46
+ * @eexample points
47
+ * @related RPoint
48
+ * @related countPoints ( )
49
+ * @related addPoint ( )
50
+ */
51
+ public RPoint[] points;
52
+ boolean isContributing = true;
53
+ boolean isHole = false;
54
+ boolean closed = true;
55
+
56
+ /**
57
+ * Use this method to count the number of points in the contour.
58
+ *
59
+ * @eexample countPoints
60
+ * @return int, the number points in the contour
61
+ */
62
+ public int countPoints() {
63
+ if (this.points == null) {
64
+ return 0;
65
+ }
66
+
67
+ return this.points.length;
68
+ }
69
+
70
+ /**
71
+ * Create a countour given an array of points.
72
+ *
73
+ * @param contourpoints the points of the new contour
74
+ * @invisible
75
+ */
76
+ public RContour(RPoint[] contourpoints) {
77
+ this.points = contourpoints;
78
+ }
79
+
80
+ public RContour() {
81
+ }
82
+
83
+ public RContour(RContour c) {
84
+ for (int i = 0; i < c.countPoints(); i++) {
85
+ this.append(new RPoint(c.points[i]));
86
+ }
87
+ isHole = c.isHole;
88
+ isContributing = c.isContributing;
89
+
90
+ setStyle(c);
91
+ }
92
+
93
+ /**
94
+ * Use this method to draw the contour.
95
+ *
96
+ * @eexample drawContour
97
+ * @param g PGraphics, the graphics object on which to draw the contour
98
+ */
99
+ @Override
100
+ public void draw(PGraphics g) {
101
+ int numPoints = countPoints();
102
+ boolean beforeFill = g.fill;
103
+ g.noFill();
104
+ g.beginShape();
105
+ for (int i = 0; i < numPoints; i++) {
106
+ g.vertex(points[i].x, points[i].y);
107
+ }
108
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
109
+ if (beforeFill) {
110
+ g.fill(g.fillColor);
111
+ }
112
+ }
113
+
114
+ @Override
115
+ public void draw(PApplet g) {
116
+ int numPoints = countPoints();
117
+ boolean beforeFill = g.g.fill;
118
+ g.noFill();
119
+ g.beginShape();
120
+ for (int i = 0; i < numPoints; i++) {
121
+ g.vertex(points[i].x, points[i].y);
122
+ }
123
+ g.endShape(closed ? PConstants.CLOSE : PConstants.OPEN);
124
+ if (beforeFill) {
125
+ g.fill(g.g.fillColor);
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Use this method to add new points to the contour.
131
+ *
132
+ * @param p
133
+ * @eexample addPoint ( )
134
+ */
135
+ public void addPoint(RPoint p) {
136
+ this.append(p);
137
+ }
138
+
139
+ public void addPoint(float x, float y) {
140
+ this.append(new RPoint(x, y));
141
+ }
142
+
143
+ /**
144
+ * Efficiently add an array of points to the contour.
145
+ *
146
+ * @param morePoints
147
+ */
148
+ public void addPoints(RPoint[] morePoints) {
149
+ if (points == null) {
150
+ this.points = morePoints;
151
+ } else {
152
+ RPoint[] newPoints = new RPoint[this.points.length + morePoints.length];
153
+ System.arraycopy(this.points, 0, newPoints, 0, this.points.length);
154
+ System.arraycopy(morePoints, 0, newPoints, this.points.length, morePoints.length);
155
+ this.points = newPoints;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Efficiently add a list of points to the contour.
161
+ *
162
+ * @param morePoints
163
+ */
164
+ public void addPoints(List<RPoint> morePoints) {
165
+ int start = 0;
166
+ if (points == null) {
167
+ this.points = new RPoint[morePoints.size()];
168
+ } else {
169
+ RPoint[] newPoints = new RPoint[this.points.length + morePoints.size()];
170
+ System.arraycopy(this.points, 0, newPoints, 0, this.points.length);
171
+ this.points = newPoints;
172
+ start = morePoints.size();
173
+ }
174
+ // it would be nice to be able to access the ArrayList's internal array!
175
+ for (int i = start, j = 0; i < points.length; i++) {
176
+ points[i] = morePoints.get(j);
177
+ j++;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Use this to return the points of the contour. It returns the points in
183
+ * the way of an array of RPoint.
184
+ *
185
+ * @eexample RContour_getHandles
186
+ * @return RPoint[], the points returned in an array.
187
+ *
188
+ */
189
+ @Override
190
+ public RPoint[] getHandles() {
191
+ return points;
192
+ }
193
+
194
+ /**
195
+ * Use this to return the points of the contour. It returns the points in
196
+ * the way of an array of RPoint.
197
+ *
198
+ * @eexample RContour_getPoints
199
+ * @return RPoint[], the points returned in an array.
200
+ *
201
+ */
202
+ @Override
203
+ public RPoint[] getPoints() {
204
+ return points;
205
+ }
206
+
207
+ /**
208
+ *
209
+ * @param t
210
+ * @return
211
+ */
212
+ @Override
213
+ public RPoint getPoint(float t) {
214
+ PApplet.println("Feature not yet implemented for this class.");
215
+ return null;
216
+ }
217
+
218
+ @Override
219
+ public RPoint getTangent(float t) {
220
+ PApplet.println("Feature not yet implemented for this class.");
221
+ return null;
222
+ }
223
+
224
+ @Override
225
+ public RPoint[] getTangents() {
226
+ PApplet.println("Feature not yet implemented for this class.");
227
+ return null;
228
+ }
229
+
230
+ @Override
231
+ public RPoint[][] getPointsInPaths() {
232
+ PApplet.println("Feature not yet implemented for this class.");
233
+ return null;
234
+ }
235
+
236
+ /**
237
+ *
238
+ * @return
239
+ */
240
+ @Override
241
+ public RPoint[][] getHandlesInPaths() {
242
+ PApplet.println("Feature not yet implemented for this class.");
243
+ return null;
244
+ }
245
+
246
+ @Override
247
+ public RPoint[][] getTangentsInPaths() {
248
+ PApplet.println("Feature not yet implemented for this class.");
249
+ return null;
250
+ }
251
+
252
+ /**
253
+ *
254
+ * @param p
255
+ * @return
256
+ */
257
+ @Override
258
+ public boolean contains(RPoint p) {
259
+ PApplet.println("Feature not yet implemented for this class.");
260
+ return false;
261
+ }
262
+
263
+ /**
264
+ * Use this method to know if the contour is a hole. Remember to use the
265
+ * method update() on the polygon before using this method.
266
+ *
267
+ * @eexample RPolygon_isHole
268
+ * @return boolean, true if it is a hole
269
+ * @related update ( )
270
+ */
271
+ public boolean isHole() {
272
+ return isHole;
273
+ }
274
+
275
+ /**
276
+ *
277
+ */
278
+ @Override
279
+ public void print() {
280
+ System.out.println("contour: ");
281
+ for (int i = 0; i < countPoints(); i++) {
282
+ System.out.println("--- point " + i + " ---");
283
+ points[i].print();
284
+ System.out.println("---------------");
285
+ }
286
+ }
287
+
288
+ public void addClose() {
289
+ if (points == null) {
290
+ return;
291
+ }
292
+
293
+ if ((points[0].x == points[points.length - 1].x) && (points[0].y == points[points.length - 1].y)) {
294
+ return;
295
+ }
296
+
297
+ addPoint(new RPoint(points[0].x, points[0].y));
298
+ closed = true;
299
+ }
300
+
301
+ /**
302
+ * @return @invisible
303
+ */
304
+ @Override
305
+ public RPolygon toPolygon() {
306
+ return new RPolygon(this);
307
+ }
308
+
309
+ /**
310
+ * @return @invisible
311
+ */
312
+ @Override
313
+ public RShape toShape() throws RuntimeException {
314
+ throw new RuntimeException("Transforming a Contour to a Shape is not yet implemented.");
315
+ }
316
+
317
+ /**
318
+ * @return @invisible
319
+ */
320
+ @Override
321
+ public RMesh toMesh() {
322
+ return this.toPolygon().toMesh();
323
+ }
324
+
325
+ /**
326
+ * Use this method to get the type of element this is.
327
+ *
328
+ * @eexample RPolygon_getType
329
+ * @return int, will allways return RGeomElem.POLYGON
330
+ */
331
+ @Override
332
+ public int getType() {
333
+ return type;
334
+ }
335
+
336
+ final void append(RPoint nextpoint) {
337
+ RPoint[] newpoints;
338
+ if (points == null) {
339
+ newpoints = new RPoint[1];
340
+ newpoints[0] = nextpoint;
341
+ } else {
342
+ newpoints = new RPoint[this.points.length + 1];
343
+ System.arraycopy(this.points, 0, newpoints, 0, this.points.length);
344
+ newpoints[this.points.length] = nextpoint;
345
+ }
346
+ this.points = newpoints;
347
+ }
348
+ }
@@ -0,0 +1,583 @@
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
+ import processing.core.*;
22
+
23
+ import org.apache.batik.svggen.font.*;
24
+ import org.apache.batik.svggen.font.table.*;
25
+
26
+ /**
27
+ * RShape is a reduced interface for creating, holding and drawing text from TrueType Font files. It's a basic interpreter of TrueType fonts enabling to access any String in the form of a group of shapes. Enabling us in this way to access their geometry.
28
+ * @eexample RFont
29
+ * @usage Geometry
30
+ * @related RGroup
31
+ *
32
+ * @extended
33
+ */
34
+ public class RFont implements PConstants{
35
+ Font f;
36
+ float scaleFactor = 0.2F;
37
+ //int scaleFactorFixed = 1;
38
+
39
+ /**
40
+ * The point size of the font.
41
+ * @eexample size
42
+ * @related setSize ( )
43
+ * @related RFont
44
+ */
45
+ public int size = DEFAULT_SIZE;
46
+
47
+ /**
48
+ * The alignment of the font. This property can take the following values: RFont.LEFT, RFont.CENTER and RFont.RIGHT
49
+ * @eexample align
50
+ * @related setAlign ( )
51
+ * @related RFont
52
+ */
53
+ public int align = DEFAULT_ALIGN;
54
+
55
+ final static int DEFAULT_SIZE = 48;
56
+ final static int DEFAULT_RESOLUTION = 72;
57
+ final static int DEFAULT_ALIGN = RFont.LEFT;
58
+
59
+ /**
60
+ * Should we try to use ASCII, rather than Unicode?
61
+ */
62
+ public boolean forceAscii = false;
63
+
64
+
65
+ /**
66
+ * The constructor of the RFont object. Use this in order to create a font with which we will be able to draw and obtain outlines of text.
67
+ * @eexample RFont
68
+ * @param fontPath String, the name of the TrueType Font file which should be situated in the data folder of the sketch.
69
+ * @param size int, the point size of the font in points.
70
+ * @param align int, this can only take the following values: RFont.LEFT, RFont.CENTER and RFont.RIGHT.
71
+ * @related toGroup ( )
72
+ * @related toShape ( )
73
+ * @related toPolygon ( )
74
+ * @related toMesh ( )
75
+ * @related draw ( )
76
+ */
77
+ public RFont(String fontPath, int size, int align) throws RuntimeException{
78
+ // Try to find the font as font path
79
+ byte[] bs = RG.parent().loadBytes(fontPath);
80
+ f = Font.create(bs);
81
+
82
+ setSize(size);
83
+ setAlign(align);
84
+ }
85
+
86
+ public RFont(String fontPath, int size) throws RuntimeException{
87
+ this(fontPath, size, DEFAULT_ALIGN);
88
+ }
89
+
90
+ public RFont(String fontPath) throws RuntimeException{
91
+ this(fontPath, DEFAULT_SIZE, DEFAULT_ALIGN);
92
+ }
93
+
94
+ /**
95
+ * Use this method to reset the point size of the font.
96
+ * @eexample setSize
97
+ * @param size int, the point size of the font in points.
98
+ * @related size
99
+ * @related RFont
100
+ */
101
+ public void setSize(int size){
102
+ short unitsPerEm = f.getHeadTable().getUnitsPerEm();
103
+ int resolution = RG.dpi();
104
+ this.scaleFactor = ((float)size * (float)resolution) / (72F * (float)unitsPerEm);
105
+ //this.scaleFactorFixed = (int)(this.scaleFactor * 65536F);
106
+ //System.out.println(scaleFactor);
107
+ //System.out.println(scaleFactorFixed);
108
+ }
109
+
110
+ public float getLineSpacing() {
111
+ // More info at:
112
+ // http://fontforge.sourceforge.net/faq.html#linespace
113
+ // http://typophile.com/node/13081
114
+ short unitsPerEm = f.getHeadTable().getUnitsPerEm();
115
+ System.out.println("UnitsPerEm (emsize): " + unitsPerEm);
116
+
117
+ // HHEA table method:
118
+ float hheaLineGap = (f.getHheaTable().getAscender() - f.getHheaTable().getDescender() + f.getHheaTable().getLineGap()) * this.scaleFactor;
119
+ System.out.println("HHEA lineGap: " + hheaLineGap);
120
+
121
+ // OS2 table typographic line gap method:
122
+ float os2TypoLineGap = (f.getOS2Table().getTypoAscender() - f.getOS2Table().getTypoDescender() + f.getOS2Table().getTypoLineGap()) * this.scaleFactor;
123
+ System.out.println("Os2 Typo lineGap: " + os2TypoLineGap);
124
+
125
+ // OS2 table win line gap method:
126
+ float os2WinLineGap = (f.getOS2Table().getWinAscent() + f.getOS2Table().getWinDescent()) * this.scaleFactor;
127
+ System.out.println("Os2 Win lineGap: " + os2WinLineGap);
128
+
129
+ // Automatic calculation
130
+ float autoLineGap = f.getHeadTable().getUnitsPerEm() * 1.25f * this.scaleFactor;
131
+ System.out.println("Automatic lineGap: " + autoLineGap);
132
+
133
+ return hheaLineGap;
134
+ }
135
+
136
+ /**
137
+ * Use this method to reset the alignment of the font. This property can take the following values: RFont.LEFT, RFont.CENTER and RFont.RIGHT
138
+ * @eexample setAlign
139
+ * @param align int, this can only take the following values: RFont.LEFT, RFont.CENTER and RFont.RIGHT.
140
+ * @related align
141
+ * @related RFont
142
+ */
143
+ public void setAlign(int align) throws RuntimeException{
144
+ if(align!=LEFT && align!=CENTER && align!=RIGHT){
145
+ throw new RuntimeException("Alignment unknown. The only accepted values are: RFont.LEFT, RFont.CENTER and RFont.RIGHT");
146
+ }
147
+ this.align = align;
148
+ }
149
+
150
+ /**
151
+ * @invisible
152
+ **/
153
+ public String getFamily(){
154
+ return f.getNameTable().getRecord(org.apache.batik.svggen.font.table.Table.nameFontFamilyName);
155
+ }
156
+
157
+ /**
158
+ * Use this method to get the outlines of a character in the form of an RShape.
159
+ * @eexample RFont_toShape
160
+ * @param character char, the character we want the outline from.
161
+ * @return RShape, the outline of the character.
162
+ * @related toGroup ( )
163
+ * @related toPolygon ( )
164
+ * @related draw ( )
165
+ */
166
+ public RShape toShape(char character){
167
+ RGroup grp = toGroup(Character.toString(character));
168
+ if(grp.countElements()>0) return (RShape)(grp.elements[0]);
169
+ return new RShape();
170
+ }
171
+
172
+ /**
173
+ * Use this method to get the outlines of a character in the form of an RPolygon.
174
+ * @eexample RFont_toPolygon
175
+ * @param character char, the character we want the outline from.
176
+ * @return RPolygon, the outline of the character.
177
+ * @related toGroup ( )
178
+ * @related toShape ( )
179
+ * @related draw ( )
180
+ */
181
+ public RPolygon toPolygon(char character) {
182
+ return toShape(character).toPolygon();
183
+ }
184
+
185
+
186
+ private CmapFormat getCmapFormat() {
187
+ if (forceAscii) {
188
+ // We've been asked to use the ASCII/Macintosh cmap format
189
+ return f.getCmapTable().getCmapFormat(
190
+ org.apache.batik.svggen.font.table.Table.platformMacintosh,
191
+ org.apache.batik.svggen.font.table.Table.encodingRoman );
192
+ } else {
193
+ short[] platforms = new short[] {
194
+ org.apache.batik.svggen.font.table.Table.platformMicrosoft,
195
+ org.apache.batik.svggen.font.table.Table.platformAppleUnicode,
196
+ org.apache.batik.svggen.font.table.Table.platformMacintosh
197
+ };
198
+ short[] encodings = new short[] {
199
+ org.apache.batik.svggen.font.table.Table.encodingUGL,
200
+ org.apache.batik.svggen.font.table.Table.encodingKorean,
201
+ org.apache.batik.svggen.font.table.Table.encodingHebrew,
202
+ org.apache.batik.svggen.font.table.Table.encodingUndefined
203
+ };
204
+
205
+ CmapFormat cmapFmt;
206
+ for(int i = 0; i < encodings.length; i++) {
207
+ for(int j = 0; j < platforms.length; j++) {
208
+
209
+ cmapFmt = f.getCmapTable().getCmapFormat(platforms[j], encodings[i]);
210
+ if (cmapFmt != null) {
211
+ return cmapFmt;
212
+ }
213
+ }
214
+ }
215
+ return null;
216
+ }
217
+ }
218
+
219
+
220
+ /**
221
+ * Use this method to get the outlines of a string in the form of an RGroup. All the elements of the group will be RShapes.
222
+ * @eexample RFont_toGroup
223
+ * @param text String, the string we want the outlines from.
224
+ * @return RGroup, the group of outlines of the character. All the elements are RShapes.
225
+ * @related toShape ( )
226
+ * @related draw ( )
227
+ */
228
+ public RGroup toGroup(String text) throws RuntimeException{
229
+ RGroup result = new RGroup();
230
+
231
+ // Decide upon a cmap table to use for our character to glyph look-up
232
+ CmapFormat cmapFmt = getCmapFormat();
233
+
234
+ if (cmapFmt == null) {
235
+ throw new RuntimeException("Cannot find a suitable cmap table");
236
+ }
237
+
238
+ // If this font includes arabic script, we want to specify
239
+ // substitutions for initial, medial, terminal & isolated
240
+ // cases.
241
+ /*
242
+ GsubTable gsub = (GsubTable) f.getTable(Table.GSUB);
243
+ SingleSubst initialSubst = null;
244
+ SingleSubst medialSubst = null;
245
+ SingleSubst terminalSubst = null;
246
+ if (gsub != null) {
247
+ Script s = gsub.getScriptList().findScript(ScriptTags.SCRIPT_TAG_ARAB);
248
+ if (s != null) {
249
+ LangSys ls = s.getDefaultLangSys();
250
+ if (ls != null) {
251
+ Feature init = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_INIT);
252
+ Feature medi = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_MEDI);
253
+ Feature fina = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_FINA);
254
+
255
+ initialSubst = (SingleSubst)
256
+ gsub.getLookupList().getLookup(init, 0).getSubtable(0);
257
+ medialSubst = (SingleSubst)
258
+ gsub.getLookupList().getLookup(medi, 0).getSubtable(0);
259
+ terminalSubst = (SingleSubst)
260
+ gsub.getLookupList().getLookup(fina, 0).getSubtable(0);
261
+ }
262
+ }
263
+ }*/
264
+
265
+ int x = 0;
266
+ for (short i = 0; i < text.length(); i++) {
267
+ int glyphIndex = cmapFmt.mapCharCode(text.charAt(i));
268
+ Glyph glyph = f.getGlyph(glyphIndex);
269
+ int default_advance_x = f.getHmtxTable().getAdvanceWidth(glyphIndex);
270
+ if (glyph != null) {
271
+ glyph.scale(scaleFactor);
272
+ // Add the Glyph to the Shape with an horizontal offset of x
273
+ result.addElement(getGlyphAsShape(f,glyph, glyphIndex,x));
274
+ x += glyph.getAdvanceWidth();
275
+ }else{
276
+ x += (int)((float)default_advance_x*scaleFactor);
277
+ }
278
+
279
+ }
280
+
281
+ if(align!=LEFT && align!=CENTER && align!=RIGHT){
282
+ throw new RuntimeException("Alignment unknown. The only accepted values are: RFont.LEFT, RFont.CENTER and RFont.RIGHT");
283
+ }
284
+
285
+ RRectangle r;
286
+ RMatrix mattrans;
287
+
288
+ switch(this.align){
289
+ case RFont.CENTER:
290
+ r = result.getBounds();
291
+ mattrans = new RMatrix();
292
+ mattrans.translate((r.getMinX()-r.getMaxX())/2,0);
293
+ result.transform(mattrans);
294
+ break;
295
+ case RFont.RIGHT:
296
+ r = result.getBounds();
297
+ mattrans = new RMatrix();
298
+ mattrans.translate((r.getMinX()-r.getMaxX()),0);
299
+ result.transform(mattrans);
300
+ break;
301
+ case RFont.LEFT:
302
+ break;
303
+ }
304
+ return result;
305
+ }
306
+
307
+ public RShape toShape(String text) throws RuntimeException{
308
+ RShape result = new RShape();
309
+
310
+ // Decide upon a cmap table to use for our character to glyph look-up
311
+ CmapFormat cmapFmt = getCmapFormat();
312
+
313
+ if (cmapFmt == null) {
314
+ throw new RuntimeException("Cannot find a suitable cmap table");
315
+ }
316
+
317
+ // If this font includes arabic script, we want to specify
318
+ // substitutions for initial, medial, terminal & isolated
319
+ // cases.
320
+ /*
321
+ GsubTable gsub = (GsubTable) f.getTable(Table.GSUB);
322
+ SingleSubst initialSubst = null;
323
+ SingleSubst medialSubst = null;
324
+ SingleSubst terminalSubst = null;
325
+ if (gsub != null) {
326
+ Script s = gsub.getScriptList().findScript(ScriptTags.SCRIPT_TAG_ARAB);
327
+ if (s != null) {
328
+ LangSys ls = s.getDefaultLangSys();
329
+ if (ls != null) {
330
+ Feature init = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_INIT);
331
+ Feature medi = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_MEDI);
332
+ Feature fina = gsub.getFeatureList().findFeature(ls, FeatureTags.FEATURE_TAG_FINA);
333
+
334
+ initialSubst = (SingleSubst)
335
+ gsub.getLookupList().getLookup(init, 0).getSubtable(0);
336
+ medialSubst = (SingleSubst)
337
+ gsub.getLookupList().getLookup(medi, 0).getSubtable(0);
338
+ terminalSubst = (SingleSubst)
339
+ gsub.getLookupList().getLookup(fina, 0).getSubtable(0);
340
+ }
341
+ }
342
+ }*/
343
+
344
+ int x = 0;
345
+ for (short i = 0; i < text.length(); i++) {
346
+ int glyphIndex = cmapFmt.mapCharCode(text.charAt(i));
347
+ Glyph glyph = f.getGlyph(glyphIndex);
348
+ int default_advance_x = f.getHmtxTable().getAdvanceWidth(glyphIndex);
349
+ if (glyph != null) {
350
+ glyph.scale(scaleFactor);
351
+ // Add the Glyph to the Shape with an horizontal offset of x
352
+ result.addChild(getGlyphAsShape(f,glyph, glyphIndex,x));
353
+ x += glyph.getAdvanceWidth();
354
+ }else{
355
+ x += (int)((float)default_advance_x*scaleFactor);
356
+ }
357
+
358
+ }
359
+
360
+ if(align!=LEFT && align!=CENTER && align!=RIGHT){
361
+ throw new RuntimeException("Alignment unknown. The only accepted values are: RFont.LEFT, RFont.CENTER and RFont.RIGHT");
362
+ }
363
+
364
+ RRectangle r;
365
+ RMatrix mattrans;
366
+
367
+ switch(this.align){
368
+ case RFont.CENTER:
369
+ r = result.getBounds();
370
+ mattrans = new RMatrix();
371
+ mattrans.translate((r.getMinX()-r.getMaxX())/2,0);
372
+ result.transform(mattrans);
373
+ break;
374
+ case RFont.RIGHT:
375
+ r = result.getBounds();
376
+ mattrans = new RMatrix();
377
+ mattrans.translate((r.getMinX()-r.getMaxX()),0);
378
+ result.transform(mattrans);
379
+ break;
380
+ case RFont.LEFT:
381
+ break;
382
+ }
383
+ return result;
384
+ }
385
+
386
+ /**
387
+ * Use this method to draw a character on a certain canvas.
388
+ * @eexample RFont_draw
389
+ * @param character the character to be drawn
390
+ * @param g the canvas where to draw
391
+ * @related toShape ( )
392
+ * @related toGroup ( )
393
+ */
394
+ public void draw(char character, PGraphics g) throws RuntimeException{
395
+ this.toShape(character).draw(g);
396
+ }
397
+
398
+ /**
399
+ * Use this method to draw a character on a certain canvas.
400
+ * @eexample RFont_draw
401
+ * @param text the string to be drawn
402
+ * @param g the canvas where to draw
403
+ * @related toShape ( )
404
+ * @related toGroup ( )
405
+ */
406
+ public void draw(String text, PGraphics g) throws RuntimeException{
407
+ this.toGroup(text).draw(g);
408
+ }
409
+
410
+ /**
411
+ * Use this method to draw a character on a certain canvas.
412
+ * @eexample RFont_draw
413
+ * @param character char, the character to be drawn
414
+ * @param g the canvas where to draw
415
+ * @related toShape ( )
416
+ * @related toGroup ( )
417
+ */
418
+ public void draw(char character, PApplet g) throws RuntimeException{
419
+ this.toShape(character).draw(g);
420
+ }
421
+
422
+ /**
423
+ * Use this method to draw a character on a certain canvas.
424
+ * @eexample RFont_draw
425
+ * @param text the string to be drawn
426
+ * @param g the canvas where to draw
427
+ * @related toShape ( )
428
+ * @related toGroup ( )
429
+ */
430
+ public void draw(String text, PApplet g) throws RuntimeException{
431
+ this.toGroup(text).draw(g);
432
+ }
433
+
434
+ public void draw(String text) throws RuntimeException{
435
+ this.toGroup(text).draw();
436
+ }
437
+
438
+ public void draw(char character) throws RuntimeException{
439
+ this.toShape(character).draw();
440
+ }
441
+
442
+
443
+
444
+ private static float midValue(float a, float b) {
445
+ return a + (b - a)/2;
446
+ }
447
+
448
+ protected static RShape getContourAsShape(Glyph glyph, int startIndex, int count) {
449
+ return getContourAsShape(glyph, startIndex, count, 0);
450
+ }
451
+
452
+ protected static RShape getContourAsShape(Glyph glyph, int startIndex, int count, float xadv) {
453
+
454
+ // If this is a single point on it's own, weSystem.out.println("Value of pointx: "+pointx); can't do anything with it
455
+ if (glyph.getPoint(startIndex).endOfContour) {
456
+ return new RShape();
457
+ }
458
+
459
+ RShape result = new RShape();
460
+ int offset = 0;
461
+ //float originx = 0F,originy = 0F;
462
+
463
+ while (offset < count) {
464
+ Point point = glyph.getPoint(startIndex + offset%count);
465
+ Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count);
466
+ Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count);
467
+
468
+ float pointx = ((float)point.x + xadv);
469
+ float pointy = ((float)point.y);
470
+ float point_plus1x = ((float)point_plus1.x + xadv);
471
+ float point_plus1y = ((float)point_plus1.y);
472
+ float point_plus2x = ((float)point_plus2.x + xadv);
473
+ float point_plus2y = ((float)point_plus2.y);
474
+
475
+ if (offset == 0) {
476
+ // move command
477
+ result.addMoveTo(pointx,pointy);
478
+ }
479
+
480
+ if (point.onCurve && point_plus1.onCurve) {
481
+ // line command
482
+ result.addLineTo(point_plus1x,point_plus1y);
483
+ offset++;
484
+ } else if (point.onCurve && !point_plus1.onCurve && point_plus2.onCurve) {
485
+ // This is a curve with no implied points
486
+ // quadratic bezier command
487
+ result.addQuadTo(point_plus1x, point_plus1y, point_plus2x, point_plus2y);
488
+ offset+=2;
489
+ } else if (point.onCurve && !point_plus1.onCurve && !point_plus2.onCurve) {
490
+ // This is a curve with one implied point
491
+ // quadratic bezier command avec le endPoint implicit
492
+ result.addQuadTo(point_plus1x, point_plus1y, midValue(point_plus1x, point_plus2x), midValue(point_plus1y, point_plus2y));
493
+ offset+=2;
494
+ } else if (!point.onCurve && !point_plus1.onCurve) {
495
+ // This is a curve with two implied points
496
+ // quadratic bezier with
497
+ result.addQuadTo(pointx, pointy, midValue(pointx, point_plus1x), midValue(pointy, point_plus1y));
498
+ offset++;
499
+ } else if (!point.onCurve && point_plus1.onCurve) {
500
+ // This is a curve with no implied points
501
+ result.addQuadTo(pointx, pointy, point_plus1x, point_plus1y);
502
+ offset++;
503
+ } else {
504
+ System.out.println("drawGlyph case not catered for!!");
505
+ break;
506
+ }
507
+ }
508
+ result.addClose();
509
+ return result;
510
+ }
511
+
512
+ protected static RShape getGlyphAsShape(Font font, Glyph glyph, int glyphIndex) {
513
+ return getGlyphAsShape(font,glyph,glyphIndex,0);
514
+ }
515
+
516
+ protected static RShape getGlyphAsShape(Font font, Glyph glyph, int glyphIndex,float xadv) {
517
+
518
+ RShape result = new RShape();
519
+ int firstIndex = 0;
520
+ int count = 0;
521
+ int i;
522
+
523
+ if (glyph != null) {
524
+ for (i = 0; i < glyph.getPointCount(); i++) {
525
+ count++;
526
+ if (glyph.getPoint(i).endOfContour) {
527
+ result.addShape(getContourAsShape(glyph, firstIndex, count, xadv));
528
+ firstIndex = i + 1;
529
+ count = 0;
530
+ }
531
+ }
532
+ }
533
+
534
+ return result;
535
+ }
536
+
537
+ protected static RShape getGlyphAsShape(Font font, Glyph glyph, int glyphIndex, SingleSubst arabInitSubst, SingleSubst arabMediSubst, SingleSubst arabTermSubst) {
538
+ return getGlyphAsShape(font, glyph, glyphIndex, arabInitSubst, arabMediSubst, arabTermSubst, 0);
539
+ }
540
+
541
+ protected static RShape getGlyphAsShape(Font font, Glyph glyph, int glyphIndex, SingleSubst arabInitSubst, SingleSubst arabMediSubst, SingleSubst arabTermSubst, float xadv) {
542
+
543
+ RShape result = new RShape();
544
+ boolean substituted = false;
545
+
546
+ // arabic = "initial | medial | terminal | isolated"
547
+ int arabInitGlyphIndex = glyphIndex;
548
+ int arabMediGlyphIndex = glyphIndex;
549
+ int arabTermGlyphIndex = glyphIndex;
550
+ if (arabInitSubst != null) {
551
+ arabInitGlyphIndex = arabInitSubst.substitute(glyphIndex);
552
+ }
553
+ if (arabMediSubst != null) {
554
+ arabMediGlyphIndex = arabMediSubst.substitute(glyphIndex);
555
+ }
556
+ if (arabTermSubst != null) {
557
+ arabTermGlyphIndex = arabTermSubst.substitute(glyphIndex);
558
+ }
559
+
560
+ if (arabInitGlyphIndex != glyphIndex) {
561
+ result.addShape(getGlyphAsShape(font,font.getGlyph(arabInitGlyphIndex),arabInitGlyphIndex));
562
+ substituted = true;
563
+ }
564
+
565
+ if (arabMediGlyphIndex != glyphIndex) {
566
+ result.addShape(getGlyphAsShape(font,font.getGlyph(arabMediGlyphIndex),arabMediGlyphIndex));
567
+ substituted = true;
568
+ }
569
+
570
+ if (arabTermGlyphIndex != glyphIndex) {
571
+ result.addShape(getGlyphAsShape(font,font.getGlyph(arabTermGlyphIndex),arabTermGlyphIndex));
572
+ substituted = true;
573
+ }
574
+
575
+ if (substituted) {
576
+ result.addShape(getGlyphAsShape(font,glyph,glyphIndex));
577
+ } else {
578
+ result.addShape(getGlyphAsShape(font,glyph,glyphIndex));
579
+ }
580
+
581
+ return result;
582
+ }
583
+ }