propane 2.7.2-java → 2.8.0.pre-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -0
  3. data/CHANGELOG.md +1 -1
  4. data/README.md +10 -8
  5. data/Rakefile +1 -1
  6. data/lib/propane/app.rb +3 -3
  7. data/lib/propane/version.rb +1 -1
  8. data/lib/{processing-core.jar → propane-2.8.0.jar} +0 -0
  9. data/library/control_panel/control_panel.rb +3 -2
  10. data/pom.rb +89 -88
  11. data/pom.xml +75 -46
  12. data/propane.gemspec +1 -2
  13. data/src/main/java/japplemenubar/JAppleMenuBar.java +88 -0
  14. data/src/main/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  15. data/src/{monkstone → main/java/monkstone}/ColorUtil.java +0 -0
  16. data/src/{monkstone → main/java/monkstone}/MathToolModule.java +0 -0
  17. data/src/{monkstone → main/java/monkstone}/PropaneLibrary.java +0 -0
  18. data/src/{monkstone → main/java/monkstone}/core/LibraryProxy.java +0 -0
  19. data/src/{monkstone → main/java/monkstone}/fastmath/Deglut.java +0 -0
  20. data/src/{monkstone → main/java/monkstone}/fastmath/package-info.java +0 -0
  21. data/src/{monkstone → main/java/monkstone}/filechooser/Chooser.java +0 -0
  22. data/src/{monkstone → main/java/monkstone}/noise/SimplexNoise.java +0 -0
  23. data/src/{monkstone → main/java/monkstone}/slider/CustomHorizontalSlider.java +0 -0
  24. data/src/{monkstone → main/java/monkstone}/slider/CustomVerticalSlider.java +0 -0
  25. data/src/{monkstone → main/java/monkstone}/slider/SimpleHorizontalSlider.java +0 -0
  26. data/src/{monkstone → main/java/monkstone}/slider/SimpleSlider.java +0 -0
  27. data/src/{monkstone → main/java/monkstone}/slider/SimpleVerticalSlider.java +0 -0
  28. data/src/{monkstone → main/java/monkstone}/slider/Slider.java +0 -0
  29. data/src/{monkstone → main/java/monkstone}/slider/SliderBar.java +0 -0
  30. data/src/{monkstone → main/java/monkstone}/slider/SliderGroup.java +0 -0
  31. data/src/{monkstone → main/java/monkstone}/slider/WheelHandler.java +0 -0
  32. data/src/{monkstone → main/java/monkstone}/vecmath/AppRender.java +0 -0
  33. data/src/{monkstone → main/java/monkstone}/vecmath/JRender.java +0 -0
  34. data/src/{monkstone → main/java/monkstone}/vecmath/ShapeRender.java +0 -0
  35. data/src/{monkstone → main/java/monkstone}/vecmath/package-info.java +0 -0
  36. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/Vec2.java +0 -0
  37. data/src/{monkstone → main/java/monkstone}/vecmath/vec2/package-info.java +0 -0
  38. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/Vec3.java +0 -0
  39. data/src/{monkstone → main/java/monkstone}/vecmath/vec3/package-info.java +0 -0
  40. data/src/{monkstone → main/java/monkstone}/videoevent/VideoInterface.java +0 -0
  41. data/src/{monkstone → main/java/monkstone}/videoevent/package-info.java +0 -0
  42. data/src/main/java/processing/awt/PGraphicsJava2D.java +3029 -0
  43. data/src/main/java/processing/awt/PShapeJava2D.java +377 -0
  44. data/src/main/java/processing/awt/PSurfaceAWT.java +1567 -0
  45. data/src/main/java/processing/core/PApplet.java +15709 -0
  46. data/src/main/java/processing/core/PConstants.java +527 -0
  47. data/src/main/java/processing/core/PFont.java +1098 -0
  48. data/src/main/java/processing/core/PGraphics.java +8467 -0
  49. data/src/main/java/processing/core/PImage.java +3438 -0
  50. data/src/main/java/processing/core/PMatrix.java +208 -0
  51. data/src/main/java/processing/core/PMatrix2D.java +534 -0
  52. data/src/main/java/processing/core/PMatrix3D.java +877 -0
  53. data/src/main/java/processing/core/PShape.java +3445 -0
  54. data/src/main/java/processing/core/PShapeOBJ.java +469 -0
  55. data/src/main/java/processing/core/PShapeSVG.java +1787 -0
  56. data/src/main/java/processing/core/PStyle.java +63 -0
  57. data/src/main/java/processing/core/PSurface.java +161 -0
  58. data/src/main/java/processing/core/PSurfaceNone.java +374 -0
  59. data/src/main/java/processing/core/PVector.java +1063 -0
  60. data/src/main/java/processing/data/FloatDict.java +829 -0
  61. data/src/main/java/processing/data/FloatList.java +912 -0
  62. data/src/main/java/processing/data/IntDict.java +796 -0
  63. data/src/main/java/processing/data/IntList.java +913 -0
  64. data/src/main/java/processing/data/JSONArray.java +1260 -0
  65. data/src/main/java/processing/data/JSONObject.java +2282 -0
  66. data/src/main/java/processing/data/JSONTokener.java +435 -0
  67. data/src/main/java/processing/data/Sort.java +46 -0
  68. data/src/main/java/processing/data/StringDict.java +601 -0
  69. data/src/main/java/processing/data/StringList.java +775 -0
  70. data/src/main/java/processing/data/Table.java +4923 -0
  71. data/src/main/java/processing/data/TableRow.java +198 -0
  72. data/src/main/java/processing/data/XML.java +1149 -0
  73. data/src/main/java/processing/event/Event.java +125 -0
  74. data/src/main/java/processing/event/KeyEvent.java +70 -0
  75. data/src/main/java/processing/event/MouseEvent.java +149 -0
  76. data/src/main/java/processing/event/TouchEvent.java +57 -0
  77. data/src/main/java/processing/opengl/FontTexture.java +379 -0
  78. data/src/main/java/processing/opengl/FrameBuffer.java +503 -0
  79. data/src/main/java/processing/opengl/LinePath.java +623 -0
  80. data/src/main/java/processing/opengl/LineStroker.java +685 -0
  81. data/src/main/java/processing/opengl/PGL.java +3366 -0
  82. data/src/main/java/processing/opengl/PGraphics2D.java +615 -0
  83. data/src/main/java/processing/opengl/PGraphics3D.java +281 -0
  84. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13634 -0
  85. data/src/main/java/processing/opengl/PJOGL.java +1966 -0
  86. data/src/main/java/processing/opengl/PShader.java +1478 -0
  87. data/src/main/java/processing/opengl/PShapeOpenGL.java +5234 -0
  88. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1315 -0
  89. data/src/main/java/processing/opengl/Texture.java +1670 -0
  90. data/src/main/java/processing/opengl/VertexBuffer.java +88 -0
  91. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  92. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  93. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  94. data/src/main/java/processing/opengl/cursors/license.txt +27 -0
  95. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  96. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  97. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  98. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  99. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  100. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  101. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +154 -0
  102. data/src/main/java/processing/opengl/shaders/LightVert.glsl +151 -0
  103. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  104. data/src/main/java/processing/opengl/shaders/LineVert.glsl +100 -0
  105. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  106. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  107. data/src/main/java/processing/opengl/shaders/PointVert.glsl +56 -0
  108. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  109. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  110. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +160 -0
  111. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  112. data/src/main/java/processing/opengl/shaders/TexVert.glsl +38 -0
  113. data/src/main/resources/icon/icon-1024.png +0 -0
  114. data/src/main/resources/icon/icon-128.png +0 -0
  115. data/src/main/resources/icon/icon-16.png +0 -0
  116. data/src/main/resources/icon/icon-256.png +0 -0
  117. data/src/main/resources/icon/icon-32.png +0 -0
  118. data/src/main/resources/icon/icon-48.png +0 -0
  119. data/src/main/resources/icon/icon-512.png +0 -0
  120. data/src/main/resources/icon/icon-64.png +0 -0
  121. data/src/main/resources/license.txt +508 -0
  122. data/vendors/Rakefile +5 -20
  123. metadata +115 -33
  124. data/lib/propane.jar +0 -0
@@ -0,0 +1,1098 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012-15 The Processing Foundation
7
+ Copyright (c) 2004-12 Ben Fry & Casey Reas
8
+ Copyright (c) 2001-04 Massachusetts Institute of Technology
9
+
10
+ This library is free software; you can redistribute it and/or
11
+ modify it under the terms of version 2.01 of the GNU Lesser General
12
+ Public License as published by the Free Software Foundation.
13
+
14
+ This library is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ Lesser General Public License for more details.
18
+
19
+ You should have received a copy of the GNU Lesser General
20
+ Public License along with this library; if not, write to the
21
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
+ Boston, MA 02111-1307 USA
23
+ */
24
+
25
+ package processing.core;
26
+
27
+ import java.awt.*;
28
+ import java.awt.font.FontRenderContext;
29
+ import java.awt.font.GlyphVector;
30
+ import java.awt.geom.PathIterator;
31
+ import java.awt.image.*;
32
+ import java.io.*;
33
+ import java.util.Arrays;
34
+ import java.util.HashMap;
35
+
36
+
37
+ /**
38
+ * Grayscale bitmap font class used by Processing.
39
+ * <P>
40
+ * Awful (and by that, I mean awesome) ASCII (non-)art for how this works:
41
+ * <PRE>
42
+ * |
43
+ * | height is the full used height of the image
44
+ * |
45
+ * | ..XX.. }
46
+ * | ..XX.. }
47
+ * | ...... }
48
+ * | XXXX.. } topExtent (top y is baseline - topExtent)
49
+ * | ..XX.. }
50
+ * | ..XX.. } dotted areas are where the image data
51
+ * | ..XX.. } is actually located for the character
52
+ * +---XXXXXX---- } (it extends to the right and down
53
+ * | for power of two texture sizes)
54
+ * ^^^^ leftExtent (amount to move over before drawing the image
55
+ *
56
+ * ^^^^^^^^^^^^^^ setWidth (width displaced by char)
57
+ * </PRE>
58
+ * @webref typography
59
+ * @see PApplet#loadFont(String)
60
+ * @see PApplet#createFont(String, float, boolean, char[])
61
+ * @see PGraphics#textFont(PFont)
62
+ */
63
+ public class PFont implements PConstants {
64
+
65
+ /** Number of character glyphs in this font. */
66
+ protected int glyphCount;
67
+
68
+ /**
69
+ * Actual glyph data. The length of this array won't necessarily be the
70
+ * same size as glyphCount, in cases where lazy font loading is in use.
71
+ */
72
+ protected Glyph[] glyphs;
73
+
74
+ /**
75
+ * Name of the font as seen by Java when it was created.
76
+ * If the font is available, the native version will be used.
77
+ */
78
+ protected String name;
79
+
80
+ /**
81
+ * Postscript name of the font that this bitmap was created from.
82
+ */
83
+ protected String psname;
84
+
85
+ /**
86
+ * The original size of the font when it was first created
87
+ */
88
+ protected int size;
89
+
90
+ /** Default density set to 1 for backwards compatibility with loadFont(). */
91
+ protected int density = 1;
92
+
93
+ /** true if smoothing was enabled for this font, used for native impl */
94
+ protected boolean smooth;
95
+
96
+ /**
97
+ * The ascent of the font. If the 'd' character is present in this PFont,
98
+ * this value is replaced with its pixel height, because the values returned
99
+ * by FontMetrics.getAscent() seem to be terrible.
100
+ */
101
+ protected int ascent;
102
+
103
+ /**
104
+ * The descent of the font. If the 'p' character is present in this PFont,
105
+ * this value is replaced with its lowest pixel height, because the values
106
+ * returned by FontMetrics.getDescent() are gross.
107
+ */
108
+ protected int descent;
109
+
110
+ /**
111
+ * A more efficient array lookup for straight ASCII characters. For Unicode
112
+ * characters, a QuickSort-style search is used.
113
+ */
114
+ protected int[] ascii;
115
+
116
+ /**
117
+ * True if this font is set to load dynamically. This is the default when
118
+ * createFont() method is called without a character set. Bitmap versions of
119
+ * characters are only created when prompted by an index() call.
120
+ */
121
+ protected boolean lazy;
122
+
123
+ /**
124
+ * Native Java version of the font. If possible, this allows the
125
+ * PGraphics subclass to just use Java's font rendering stuff
126
+ * in situations where that's faster.
127
+ */
128
+ protected Font font;
129
+
130
+ /**
131
+ * True if this font was loaded from an InputStream, rather than by name
132
+ * from the OS. It's best to use the native version of a font loaded from
133
+ * a TTF file, since that will ensure that the font is available when the
134
+ * sketch is exported.
135
+ */
136
+ protected boolean stream;
137
+
138
+ /**
139
+ * True if this font should return 'null' for getFont(), so that the native
140
+ * font will be used to create a subset, but the native version of the font
141
+ * will not be used.
142
+ */
143
+ protected boolean subsetting;
144
+
145
+ /** True if already tried to find the native AWT version of this font. */
146
+ protected boolean fontSearched;
147
+
148
+ /**
149
+ * Array of the native system fonts. Used to lookup native fonts by their
150
+ * PostScript name. This is a workaround for a several year old Apple Java
151
+ * bug that they can't be bothered to fix.
152
+ */
153
+ static protected Font[] fonts;
154
+ static protected HashMap<String,Font> fontDifferent;
155
+
156
+ // /**
157
+ // * If not null, this font is set to load dynamically. This is the default
158
+ // * when createFont() method is called without a character set. Bitmap
159
+ // * versions of characters are only created when prompted by an index() call.
160
+ // */
161
+ // protected Font lazyFont;
162
+ protected BufferedImage lazyImage;
163
+ protected Graphics2D lazyGraphics;
164
+ protected FontMetrics lazyMetrics;
165
+ protected int[] lazySamples;
166
+
167
+
168
+ /** for subclasses that need to store metadata about the font */
169
+ // protected HashMap<PGraphics, Object> cacheMap;
170
+
171
+ /**
172
+ * @nowebref
173
+ */
174
+ public PFont() { } // for subclasses
175
+
176
+
177
+ /**
178
+ * ( begin auto-generated from PFont.xml )
179
+ *
180
+ * PFont is the font class for Processing. To create a font to use with
181
+ * Processing, select "Create Font..." from the Tools menu. This will
182
+ * create a font in the format Processing requires and also adds it to the
183
+ * current sketch's data directory. Processing displays fonts using the
184
+ * .vlw font format, which uses images for each letter, rather than
185
+ * defining them through vector data. The <b>loadFont()</b> function
186
+ * constructs a new font and <b>textFont()</b> makes a font active. The
187
+ * <b>list()</b> method creates a list of the fonts installed on the
188
+ * computer, which is useful information to use with the
189
+ * <b>createFont()</b> function for dynamically converting fonts into a
190
+ * format to use with Processing.
191
+ *
192
+ * ( end auto-generated )
193
+ *
194
+ * @nowebref
195
+ * @param font font the font object to create from
196
+ * @param smooth smooth true to enable smoothing/anti-aliasing
197
+ */
198
+ public PFont(Font font, boolean smooth) {
199
+ this(font, smooth, null);
200
+ }
201
+
202
+
203
+ /**
204
+ * Create a new image-based font on the fly. If charset is set to null,
205
+ * the characters will only be created as bitmaps when they're drawn.
206
+ *
207
+ * @nowebref
208
+ * @param charset array of all unicode chars that should be included
209
+ */
210
+ public PFont(Font font, boolean smooth, char charset[]) {
211
+ // save this so that we can use the native version
212
+ this.font = font;
213
+ this.smooth = smooth;
214
+
215
+ name = font.getName();
216
+ psname = font.getPSName();
217
+ size = font.getSize();
218
+
219
+ // no, i'm not interested in getting off the couch
220
+ //lazy = true;
221
+ // not sure what else to do here
222
+ //mbox2 = 0;
223
+
224
+ int initialCount = 10;
225
+ glyphs = new Glyph[initialCount];
226
+
227
+ ascii = new int[128];
228
+ Arrays.fill(ascii, -1);
229
+
230
+ int mbox3 = size * 3;
231
+
232
+ lazyImage = new BufferedImage(mbox3, mbox3, BufferedImage.TYPE_INT_RGB);
233
+ lazyGraphics = (Graphics2D) lazyImage.getGraphics();
234
+ lazyGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
235
+ smooth ?
236
+ RenderingHints.VALUE_ANTIALIAS_ON :
237
+ RenderingHints.VALUE_ANTIALIAS_OFF);
238
+ // adding this for post-1.0.9
239
+ lazyGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
240
+ smooth ?
241
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON :
242
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
243
+
244
+ lazyGraphics.setFont(font);
245
+ lazyMetrics = lazyGraphics.getFontMetrics();
246
+ lazySamples = new int[mbox3 * mbox3];
247
+
248
+ // These values are terrible/unusable. Verified again for Processing 1.1.
249
+ // They vary widely per-platform and per-font, so instead we'll use the
250
+ // calculate-by-hand method of measuring pixels in characters.
251
+ //ascent = lazyMetrics.getAscent();
252
+ //descent = lazyMetrics.getDescent();
253
+
254
+ if (charset == null) {
255
+ lazy = true;
256
+ // lazyFont = font;
257
+
258
+ } else {
259
+ // charset needs to be sorted to make index lookup run more quickly
260
+ // http://dev.processing.org/bugs/show_bug.cgi?id=494
261
+ Arrays.sort(charset);
262
+
263
+ glyphs = new Glyph[charset.length];
264
+
265
+ glyphCount = 0;
266
+ for (char c : charset) {
267
+ if (font.canDisplay(c)) {
268
+ Glyph glyf = new Glyph(c);
269
+ if (glyf.value < 128) {
270
+ ascii[glyf.value] = glyphCount;
271
+ }
272
+ glyf.index = glyphCount;
273
+ glyphs[glyphCount++] = glyf;
274
+ }
275
+ }
276
+
277
+ // shorten the array if necessary
278
+ if (glyphCount != charset.length) {
279
+ glyphs = (Glyph[]) PApplet.subset(glyphs, 0, glyphCount);
280
+ }
281
+
282
+ // foreign font, so just make ascent the max topExtent
283
+ // for > 1.0.9, not doing this anymore.
284
+ // instead using getAscent() and getDescent() values for these cases.
285
+ // if ((ascent == 0) && (descent == 0)) {
286
+ // //for (int i = 0; i < charCount; i++) {
287
+ // for (Glyph glyph : glyphs) {
288
+ // char cc = (char) glyph.value;
289
+ // //char cc = (char) glyphs[i].value;
290
+ // if (Character.isWhitespace(cc) ||
291
+ // (cc == '\u00A0') || (cc == '\u2007') || (cc == '\u202F')) {
292
+ // continue;
293
+ // }
294
+ // if (glyph.topExtent > ascent) {
295
+ // ascent = glyph.topExtent;
296
+ // }
297
+ // int d = -glyph.topExtent + glyph.height;
298
+ // if (d > descent) {
299
+ // descent = d;
300
+ // }
301
+ // }
302
+ // }
303
+ }
304
+
305
+ // If not already created, just create these two characters to calculate
306
+ // the ascent and descent values for the font. This was tested to only
307
+ // require 5-10 ms on a 2.4 GHz MacBook Pro.
308
+ // In versions 1.0.9 and earlier, fonts that could not display d or p
309
+ // used the max up/down values as calculated by looking through the font.
310
+ // That's no longer valid with the auto-generating fonts, so we'll just
311
+ // use getAscent() and getDescent() in such (minor) cases.
312
+ if (ascent == 0) {
313
+ if (font.canDisplay('d')) {
314
+ new Glyph('d');
315
+ } else {
316
+ ascent = lazyMetrics.getAscent();
317
+ }
318
+ }
319
+ if (descent == 0) {
320
+ if (font.canDisplay('p')) {
321
+ new Glyph('p');
322
+ } else {
323
+ descent = lazyMetrics.getDescent();
324
+ }
325
+ }
326
+ }
327
+
328
+
329
+ /**
330
+ * Adds an additional parameter that indicates the font came from a file,
331
+ * not a built-in OS font.
332
+ *
333
+ * @nowebref
334
+ */
335
+ public PFont(Font font, boolean smooth, char charset[],
336
+ boolean stream, int density) {
337
+ this(font, smooth, charset);
338
+ this.stream = stream;
339
+ this.density = density;
340
+ }
341
+
342
+ /**
343
+ * @nowebref
344
+ * @param input InputStream
345
+ */
346
+ public PFont(InputStream input) throws IOException {
347
+ DataInputStream is = new DataInputStream(input);
348
+
349
+ // number of character images stored in this font
350
+ glyphCount = is.readInt();
351
+
352
+ // used to be the bitCount, but now used for version number.
353
+ // version 8 is any font before 69, so 9 is anything from 83+
354
+ // 9 was buggy so gonna increment to 10.
355
+ int version = is.readInt();
356
+
357
+ // this was formerly ignored, now it's the actual font size
358
+ //mbox = is.readInt();
359
+ size = is.readInt();
360
+
361
+ // this was formerly mboxY, the one that was used
362
+ // this will make new fonts downward compatible
363
+ is.readInt(); // ignore the other mbox attribute
364
+
365
+ ascent = is.readInt(); // formerly baseHt (zero/ignored)
366
+ descent = is.readInt(); // formerly ignored struct padding
367
+
368
+ // allocate enough space for the character info
369
+ glyphs = new Glyph[glyphCount];
370
+
371
+ ascii = new int[128];
372
+ Arrays.fill(ascii, -1);
373
+
374
+ // read the information about the individual characters
375
+ for (int i = 0; i < glyphCount; i++) {
376
+ Glyph glyph = new Glyph(is);
377
+ // cache locations of the ascii charset
378
+ if (glyph.value < 128) {
379
+ ascii[glyph.value] = i;
380
+ }
381
+ glyph.index = i;
382
+ glyphs[i] = glyph;
383
+ }
384
+
385
+ // not a roman font, so throw an error and ask to re-build.
386
+ // that way can avoid a bunch of error checking hacks in here.
387
+ if ((ascent == 0) && (descent == 0)) {
388
+ throw new RuntimeException("Please use \"Create Font\" to " +
389
+ "re-create this font.");
390
+ }
391
+
392
+ for (Glyph glyph : glyphs) {
393
+ glyph.readBitmap(is);
394
+ }
395
+
396
+ if (version >= 10) { // includes the font name at the end of the file
397
+ name = is.readUTF();
398
+ psname = is.readUTF();
399
+ }
400
+ if (version == 11) {
401
+ smooth = is.readBoolean();
402
+ }
403
+ // See if there's a native version of this font that can be used,
404
+ // in case that's of interest later.
405
+ // findNative();
406
+ }
407
+
408
+
409
+ /**
410
+ * Write this PFont to an OutputStream.
411
+ * <p>
412
+ * This is used by the Create Font tool, or whatever anyone else dreams
413
+ * up for messing with fonts themselves.
414
+ * <p>
415
+ * It is assumed that the calling class will handle closing
416
+ * the stream when finished.
417
+ */
418
+ public void save(OutputStream output) throws IOException {
419
+ DataOutputStream os = new DataOutputStream(output);
420
+
421
+ os.writeInt(glyphCount);
422
+
423
+ if ((name == null) || (psname == null)) {
424
+ name = "";
425
+ psname = "";
426
+ }
427
+
428
+ os.writeInt(11); // formerly numBits, now used for version number
429
+ os.writeInt(size); // formerly mboxX (was 64, now 48)
430
+ os.writeInt(0); // formerly mboxY, now ignored
431
+ os.writeInt(ascent); // formerly baseHt (was ignored)
432
+ os.writeInt(descent); // formerly struct padding for c version
433
+
434
+ for (int i = 0; i < glyphCount; i++) {
435
+ glyphs[i].writeHeader(os);
436
+ }
437
+
438
+ for (int i = 0; i < glyphCount; i++) {
439
+ glyphs[i].writeBitmap(os);
440
+ }
441
+
442
+ // version 11
443
+ os.writeUTF(name);
444
+ os.writeUTF(psname);
445
+ os.writeBoolean(smooth);
446
+
447
+ os.flush();
448
+ }
449
+
450
+
451
+ /**
452
+ * Create a new glyph, and add the character to the current font.
453
+ * @param c character to create an image for.
454
+ */
455
+ protected void addGlyph(char c) {
456
+ Glyph glyph = new Glyph(c);
457
+
458
+ if (glyphCount == glyphs.length) {
459
+ glyphs = (Glyph[]) PApplet.expand(glyphs);
460
+ }
461
+ if (glyphCount == 0) {
462
+ glyph.index = 0;
463
+ glyphs[glyphCount] = glyph;
464
+ if (glyph.value < 128) {
465
+ ascii[glyph.value] = 0;
466
+ }
467
+
468
+ } else if (glyphs[glyphCount-1].value < glyph.value) {
469
+ glyphs[glyphCount] = glyph;
470
+ if (glyph.value < 128) {
471
+ ascii[glyph.value] = glyphCount;
472
+ }
473
+
474
+ } else {
475
+ for (int i = 0; i < glyphCount; i++) {
476
+ if (glyphs[i].value > c) {
477
+ for (int j = glyphCount; j > i; --j) {
478
+ glyphs[j] = glyphs[j-1];
479
+ if (glyphs[j].value < 128) {
480
+ ascii[glyphs[j].value] = j;
481
+ }
482
+ }
483
+ glyph.index = i;
484
+ glyphs[i] = glyph;
485
+ // cache locations of the ascii charset
486
+ if (c < 128) ascii[c] = i;
487
+ break;
488
+ }
489
+ }
490
+ }
491
+ glyphCount++;
492
+ }
493
+
494
+
495
+ public String getName() {
496
+ return name;
497
+ }
498
+
499
+
500
+ public String getPostScriptName() {
501
+ return psname;
502
+ }
503
+
504
+
505
+ /**
506
+ * Set the native complement of this font. Might be set internally via the
507
+ * findFont() function, or externally by a deriveFont() call if the font
508
+ * is resized by PGraphicsJava2D.
509
+ */
510
+ public void setNative(Object font) {
511
+ this.font = (Font) font;
512
+ }
513
+
514
+
515
+ /**
516
+ * Use the getNative() method instead, which allows library interfaces to be
517
+ * written in a cross-platform fashion for desktop, Android, and others.
518
+ */
519
+ @Deprecated
520
+ public Font getFont() {
521
+ return font;
522
+ }
523
+
524
+
525
+ /**
526
+ * Return the native java.awt.Font associated with this PFont (if any).
527
+ */
528
+ public Object getNative() {
529
+ if (subsetting) {
530
+ return null; // don't return the font for use
531
+ }
532
+ return font;
533
+ }
534
+
535
+
536
+ /**
537
+ * Return size of this font.
538
+ */
539
+ public int getSize() {
540
+ return size;
541
+ }
542
+
543
+
544
+ // public void setDefaultSize(int size) {
545
+ // defaultSize = size;
546
+ // }
547
+
548
+
549
+ /**
550
+ * Returns the size that will be used when textFont(font) is called.
551
+ * When drawing with 2x pixel density, bitmap fonts in OpenGL need to be
552
+ * created (behind the scenes) at double the requested size. This ensures
553
+ * that they're shown at half on displays (so folks don't have to change
554
+ * their sketch code).
555
+ */
556
+ public int getDefaultSize() {
557
+ //return defaultSize;
558
+ return size / density;
559
+ }
560
+
561
+
562
+ public boolean isSmooth() {
563
+ return smooth;
564
+ }
565
+
566
+
567
+ public boolean isStream() {
568
+ return stream;
569
+ }
570
+
571
+
572
+ public void setSubsetting() {
573
+ subsetting = true;
574
+ }
575
+
576
+
577
+ /**
578
+ * Attempt to find the native version of this font.
579
+ * (Public so that it can be used by OpenGL or other renderers.)
580
+ */
581
+ public Object findNative() {
582
+ if (font == null) {
583
+ if (!fontSearched) {
584
+ // this font may or may not be installed
585
+ font = new Font(name, Font.PLAIN, size);
586
+ // if the ps name matches, then we're in fine shape
587
+ if (!font.getPSName().equals(psname)) {
588
+ // on osx java 1.4 (not 1.3.. ugh), you can specify the ps name
589
+ // of the font, so try that in case this .vlw font was created on pc
590
+ // and the name is different, but the ps name is found on the
591
+ // java 1.4 mac that's currently running this sketch.
592
+ font = new Font(psname, Font.PLAIN, size);
593
+ }
594
+ // check again, and if still bad, screw em
595
+ if (!font.getPSName().equals(psname)) {
596
+ font = null;
597
+ }
598
+ fontSearched = true;
599
+ }
600
+ }
601
+ return font;
602
+ }
603
+
604
+
605
+ public Glyph getGlyph(char c) {
606
+ int index = index(c);
607
+ return (index == -1) ? null : glyphs[index];
608
+ }
609
+
610
+
611
+ /**
612
+ * Get index for the character.
613
+ * @return index into arrays or -1 if not found
614
+ */
615
+ protected int index(char c) {
616
+ if (lazy) {
617
+ int index = indexActual(c);
618
+ if (index != -1) {
619
+ return index;
620
+ }
621
+ if (font != null && font.canDisplay(c)) {
622
+ // create the glyph
623
+ addGlyph(c);
624
+ // now where did i put that?
625
+ return indexActual(c);
626
+
627
+ } else {
628
+ return -1;
629
+ }
630
+
631
+ } else {
632
+ return indexActual(c);
633
+ }
634
+ }
635
+
636
+
637
+ protected int indexActual(char c) {
638
+ // degenerate case, but the find function will have trouble
639
+ // if there are somehow zero chars in the lookup
640
+ //if (value.length == 0) return -1;
641
+ if (glyphCount == 0) return -1;
642
+
643
+ // quicker lookup for the ascii fellers
644
+ if (c < 128) return ascii[c];
645
+
646
+ // some other unicode char, hunt it out
647
+ //return index_hunt(c, 0, value.length-1);
648
+ return indexHunt(c, 0, glyphCount-1);
649
+ }
650
+
651
+
652
+ protected int indexHunt(int c, int start, int stop) {
653
+ int pivot = (start + stop) / 2;
654
+
655
+ // if this is the char, then return it
656
+ if (c == glyphs[pivot].value) return pivot;
657
+
658
+ // char doesn't exist, otherwise would have been the pivot
659
+ //if (start == stop) return -1;
660
+ if (start >= stop) return -1;
661
+
662
+ // if it's in the lower half, continue searching that
663
+ if (c < glyphs[pivot].value) return indexHunt(c, start, pivot-1);
664
+
665
+ // if it's in the upper half, continue there
666
+ return indexHunt(c, pivot+1, stop);
667
+ }
668
+
669
+
670
+ /**
671
+ * Currently un-implemented for .vlw fonts,
672
+ * but honored for layout in case subclasses use it.
673
+ */
674
+ public float kern(char a, char b) {
675
+ return 0;
676
+ }
677
+
678
+
679
+ /**
680
+ * Returns the ascent of this font from the baseline.
681
+ * The value is based on a font of size 1.
682
+ */
683
+ public float ascent() {
684
+ return ((float) ascent / (float) size);
685
+ }
686
+
687
+
688
+ /**
689
+ * Returns how far this font descends from the baseline.
690
+ * The value is based on a font size of 1.
691
+ */
692
+ public float descent() {
693
+ return ((float) descent / (float) size);
694
+ }
695
+
696
+
697
+ /**
698
+ * Width of this character for a font of size 1.
699
+ */
700
+ public float width(char c) {
701
+ if (c == 32) return width('i');
702
+
703
+ int cc = index(c);
704
+ if (cc == -1) return 0;
705
+
706
+ return ((float) glyphs[cc].setWidth / (float) size);
707
+ }
708
+
709
+
710
+ //////////////////////////////////////////////////////////////
711
+
712
+
713
+ public int getGlyphCount() {
714
+ return glyphCount;
715
+ }
716
+
717
+
718
+ public Glyph getGlyph(int i) {
719
+ return glyphs[i];
720
+ }
721
+
722
+
723
+ public PShape getShape(char ch) {
724
+ return getShape(ch, 0);
725
+ }
726
+
727
+
728
+ public PShape getShape(char ch, float detail) {
729
+ Font font = (Font) getNative();
730
+ if (font == null) {
731
+ throw new IllegalArgumentException("getShape() only works on fonts loaded with createFont()");
732
+ }
733
+
734
+ PShape s = new PShape(PShape.PATH);
735
+
736
+ // six element array received from the Java2D path iterator
737
+ float[] iterPoints = new float[6];
738
+ // array passed to createGylphVector
739
+ char[] textArray = new char[] { ch };
740
+
741
+ //Graphics2D graphics = (Graphics2D) this.getGraphics();
742
+ //FontRenderContext frc = graphics.getFontRenderContext();
743
+ @SuppressWarnings("deprecation")
744
+ FontRenderContext frc =
745
+ Toolkit.getDefaultToolkit().getFontMetrics(font).getFontRenderContext();
746
+ GlyphVector gv = font.createGlyphVector(frc, textArray);
747
+ Shape shp = gv.getOutline();
748
+ // make everything into moveto and lineto
749
+ PathIterator iter = (detail == 0) ?
750
+ shp.getPathIterator(null) : // maintain curves
751
+ shp.getPathIterator(null, detail); // convert to line segments
752
+
753
+ int contours = 0;
754
+ //boolean outer = true;
755
+ // boolean contour = false;
756
+ while (!iter.isDone()) {
757
+ int type = iter.currentSegment(iterPoints);
758
+ switch (type) {
759
+ case PathIterator.SEG_MOVETO: // 1 point (2 vars) in textPoints
760
+ // System.out.println("moveto");
761
+ // if (!contour) {
762
+ if (contours == 0) {
763
+ s.beginShape();
764
+ } else {
765
+ s.beginContour();
766
+ // contour = true;
767
+ }
768
+ contours++;
769
+ s.vertex(iterPoints[0], iterPoints[1]);
770
+ break;
771
+
772
+ case PathIterator.SEG_LINETO: // 1 point
773
+ // System.out.println("lineto");
774
+ // PApplet.println(PApplet.subset(iterPoints, 0, 2));
775
+ s.vertex(iterPoints[0], iterPoints[1]);
776
+ break;
777
+
778
+ case PathIterator.SEG_QUADTO: // 2 points
779
+ // System.out.println("quadto");
780
+ // PApplet.println(PApplet.subset(iterPoints, 0, 4));
781
+ s.quadraticVertex(iterPoints[0], iterPoints[1],
782
+ iterPoints[2], iterPoints[3]);
783
+ break;
784
+
785
+ case PathIterator.SEG_CUBICTO: // 3 points
786
+ // System.out.println("cubicto");
787
+ // PApplet.println(iterPoints);
788
+ s.quadraticVertex(iterPoints[0], iterPoints[1],
789
+ iterPoints[2], iterPoints[3],
790
+ iterPoints[4], iterPoints[5]);
791
+ break;
792
+
793
+ case PathIterator.SEG_CLOSE:
794
+ // System.out.println("close");
795
+ if (contours > 1) {
796
+ // contours--;
797
+ // if (contours == 0) {
798
+ //// s.endShape();
799
+ // } else {
800
+ s.endContour();
801
+ }
802
+ break;
803
+ }
804
+ // PApplet.println(iterPoints);
805
+ iter.next();
806
+ }
807
+ s.endShape(CLOSE);
808
+ return s;
809
+ }
810
+
811
+
812
+ //////////////////////////////////////////////////////////////
813
+
814
+
815
+ static final char[] EXTRA_CHARS = {
816
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
817
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
818
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
819
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
820
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
821
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
822
+ 0x00B0, 0x00B1, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00BA,
823
+ 0x00BB, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5,
824
+ 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD,
825
+ 0x00CE, 0x00CF, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6,
826
+ 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DF,
827
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
828
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
829
+ 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8,
830
+ 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FF, 0x0102, 0x0103,
831
+ 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D, 0x010E, 0x010F,
832
+ 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B, 0x0131, 0x0139,
833
+ 0x013A, 0x013D, 0x013E, 0x0141, 0x0142, 0x0143, 0x0144, 0x0147,
834
+ 0x0148, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0158,
835
+ 0x0159, 0x015A, 0x015B, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162,
836
+ 0x0163, 0x0164, 0x0165, 0x016E, 0x016F, 0x0170, 0x0171, 0x0178,
837
+ 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x0192, 0x02C6,
838
+ 0x02C7, 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x03A9,
839
+ 0x03C0, 0x2013, 0x2014, 0x2018, 0x2019, 0x201A, 0x201C, 0x201D,
840
+ 0x201E, 0x2020, 0x2021, 0x2022, 0x2026, 0x2030, 0x2039, 0x203A,
841
+ 0x2044, 0x20AC, 0x2122, 0x2202, 0x2206, 0x220F, 0x2211, 0x221A,
842
+ 0x221E, 0x222B, 0x2248, 0x2260, 0x2264, 0x2265, 0x25CA, 0xF8FF,
843
+ 0xFB01, 0xFB02
844
+ };
845
+
846
+
847
+ /**
848
+ * The default Processing character set.
849
+ * <P>
850
+ * This is the union of the Mac Roman and Windows ANSI (CP1250)
851
+ * character sets. ISO 8859-1 Latin 1 is Unicode characters 0x80 -> 0xFF,
852
+ * and would seem a good standard, but in practice, most P5 users would
853
+ * rather have characters that they expect from their platform's fonts.
854
+ * <P>
855
+ * This is more of an interim solution until a much better
856
+ * font solution can be determined. (i.e. create fonts on
857
+ * the fly from some sort of vector format).
858
+ * <P>
859
+ * Not that I expect that to happen.
860
+ */
861
+ static public char[] CHARSET;
862
+ static {
863
+ CHARSET = new char[126-33+1 + EXTRA_CHARS.length];
864
+ int index = 0;
865
+ for (int i = 33; i <= 126; i++) {
866
+ CHARSET[index++] = (char)i;
867
+ }
868
+ for (int i = 0; i < EXTRA_CHARS.length; i++) {
869
+ CHARSET[index++] = EXTRA_CHARS[i];
870
+ }
871
+ };
872
+
873
+
874
+ /**
875
+ * ( begin auto-generated from PFont_list.xml )
876
+ *
877
+ * Gets a list of the fonts installed on the system. The data is returned
878
+ * as a String array. This list provides the names of each font for input
879
+ * into <b>createFont()</b>, which allows Processing to dynamically format
880
+ * fonts. This function is meant as a tool for programming local
881
+ * applications and is not recommended for use in applets.
882
+ *
883
+ * ( end auto-generated )
884
+ *
885
+ * @webref pfont
886
+ * @usage application
887
+ * @brief Gets a list of the fonts installed on the system
888
+ */
889
+ static public String[] list() {
890
+ loadFonts();
891
+ String list[] = new String[fonts.length];
892
+ for (int i = 0; i < list.length; i++) {
893
+ list[i] = fonts[i].getName();
894
+ }
895
+ return list;
896
+ }
897
+
898
+
899
+ static public void loadFonts() {
900
+ if (fonts == null) {
901
+ GraphicsEnvironment ge =
902
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
903
+ fonts = ge.getAllFonts();
904
+ if (PApplet.platform == PConstants.MACOSX) {
905
+ fontDifferent = new HashMap<String,Font>();
906
+ for (Font font : fonts) {
907
+ // getName() returns the PostScript name on OS X 10.6 w/ Java 6.
908
+ fontDifferent.put(font.getName(), font);
909
+ //fontDifferent.put(font.getPSName(), font);
910
+ }
911
+ }
912
+ }
913
+ }
914
+
915
+
916
+ /**
917
+ * Starting with Java 1.5, Apple broke the ability to specify most fonts.
918
+ * This bug was filed years ago as #4769141 at bugreporter.apple.com. More:
919
+ * <a href="http://dev.processing.org/bugs/show_bug.cgi?id=407">Bug 407</a>.
920
+ */
921
+ static public Font findFont(String name) {
922
+ loadFonts();
923
+ if (PApplet.platform == PConstants.MACOSX) {
924
+ Font maybe = fontDifferent.get(name);
925
+ if (maybe != null) {
926
+ return maybe;
927
+ }
928
+ // for (int i = 0; i < fonts.length; i++) {
929
+ // if (name.equals(fonts[i].getName())) {
930
+ // return fonts[i];
931
+ // }
932
+ // }
933
+ }
934
+ return new Font(name, Font.PLAIN, 1);
935
+ }
936
+
937
+
938
+ //////////////////////////////////////////////////////////////
939
+
940
+
941
+ /**
942
+ * A single character, and its visage.
943
+ */
944
+ public class Glyph {
945
+ public PImage image;
946
+ public int value;
947
+ public int height;
948
+ public int width;
949
+ public int index;
950
+ public int setWidth;
951
+ public int topExtent;
952
+ public int leftExtent;
953
+
954
+
955
+ public Glyph() {
956
+ index = -1;
957
+ // used when reading from a stream or for subclasses
958
+ }
959
+
960
+
961
+ public Glyph(DataInputStream is) throws IOException {
962
+ index = -1;
963
+ readHeader(is);
964
+ }
965
+
966
+
967
+ protected void readHeader(DataInputStream is) throws IOException {
968
+ value = is.readInt();
969
+ height = is.readInt();
970
+ width = is.readInt();
971
+ setWidth = is.readInt();
972
+ topExtent = is.readInt();
973
+ leftExtent = is.readInt();
974
+
975
+ // pointer from a struct in the c version, ignored
976
+ is.readInt();
977
+
978
+ // the values for getAscent() and getDescent() from FontMetrics
979
+ // seem to be way too large.. perhaps they're the max?
980
+ // as such, use a more traditional marker for ascent/descent
981
+ if (value == 'd') {
982
+ if (ascent == 0) ascent = topExtent;
983
+ }
984
+ if (value == 'p') {
985
+ if (descent == 0) descent = -topExtent + height;
986
+ }
987
+ }
988
+
989
+
990
+ protected void writeHeader(DataOutputStream os) throws IOException {
991
+ os.writeInt(value);
992
+ os.writeInt(height);
993
+ os.writeInt(width);
994
+ os.writeInt(setWidth);
995
+ os.writeInt(topExtent);
996
+ os.writeInt(leftExtent);
997
+ os.writeInt(0); // padding
998
+ }
999
+
1000
+
1001
+ protected void readBitmap(DataInputStream is) throws IOException {
1002
+ image = new PImage(width, height, ALPHA);
1003
+ int bitmapSize = width * height;
1004
+
1005
+ byte[] temp = new byte[bitmapSize];
1006
+ is.readFully(temp);
1007
+
1008
+ // convert the bitmap to an alpha channel
1009
+ int w = width;
1010
+ int h = height;
1011
+ int[] pixels = image.pixels;
1012
+ for (int y = 0; y < h; y++) {
1013
+ for (int x = 0; x < w; x++) {
1014
+ pixels[y * width + x] = temp[y*w + x] & 0xff;
1015
+ // System.out.print((image.pixels[y*64+x] > 128) ? "*" : ".");
1016
+ }
1017
+ // System.out.println();
1018
+ }
1019
+ // System.out.println();
1020
+ }
1021
+
1022
+
1023
+ protected void writeBitmap(DataOutputStream os) throws IOException {
1024
+ int[] pixels = image.pixels;
1025
+ for (int y = 0; y < height; y++) {
1026
+ for (int x = 0; x < width; x++) {
1027
+ os.write(pixels[y * width + x] & 0xff);
1028
+ }
1029
+ }
1030
+ }
1031
+
1032
+
1033
+ protected Glyph(char c) {
1034
+ int mbox3 = size * 3;
1035
+ lazyGraphics.setColor(Color.white);
1036
+ lazyGraphics.fillRect(0, 0, mbox3, mbox3);
1037
+ lazyGraphics.setColor(Color.black);
1038
+ lazyGraphics.drawString(String.valueOf(c), size, size * 2);
1039
+
1040
+ WritableRaster raster = lazyImage.getRaster();
1041
+ raster.getDataElements(0, 0, mbox3, mbox3, lazySamples);
1042
+
1043
+ int minX = 1000, maxX = 0;
1044
+ int minY = 1000, maxY = 0;
1045
+ boolean pixelFound = false;
1046
+
1047
+ for (int y = 0; y < mbox3; y++) {
1048
+ for (int x = 0; x < mbox3; x++) {
1049
+ int sample = lazySamples[y * mbox3 + x] & 0xff;
1050
+ if (sample != 255) {
1051
+ if (x < minX) minX = x;
1052
+ if (y < minY) minY = y;
1053
+ if (x > maxX) maxX = x;
1054
+ if (y > maxY) maxY = y;
1055
+ pixelFound = true;
1056
+ }
1057
+ }
1058
+ }
1059
+
1060
+ if (!pixelFound) {
1061
+ minX = minY = 0;
1062
+ maxX = maxY = 0;
1063
+ // this will create a 1 pixel white (clear) character..
1064
+ // maybe better to set one to -1 so nothing is added?
1065
+ }
1066
+
1067
+ value = c;
1068
+ height = (maxY - minY) + 1;
1069
+ width = (maxX - minX) + 1;
1070
+ setWidth = lazyMetrics.charWidth(c);
1071
+
1072
+ // offset from vertical location of baseline
1073
+ // of where the char was drawn (size*2)
1074
+ topExtent = size*2 - minY;
1075
+
1076
+ // offset from left of where coord was drawn
1077
+ leftExtent = minX - size;
1078
+
1079
+ image = new PImage(width, height, ALPHA);
1080
+ int[] pixels = image.pixels;
1081
+ for (int y = minY; y <= maxY; y++) {
1082
+ for (int x = minX; x <= maxX; x++) {
1083
+ int val = 255 - (lazySamples[y * mbox3 + x] & 0xff);
1084
+ int pindex = (y - minY) * width + (x - minX);
1085
+ pixels[pindex] = val;
1086
+ }
1087
+ }
1088
+
1089
+ // replace the ascent/descent values with something.. err, decent.
1090
+ if (value == 'd') {
1091
+ if (ascent == 0) ascent = topExtent;
1092
+ }
1093
+ if (value == 'p') {
1094
+ if (descent == 0) descent = -topExtent + height;
1095
+ }
1096
+ }
1097
+ }
1098
+ }