propane 3.4.2-java → 3.5.0-java

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