Skip to content

Commit 5451896

Browse files
committed
Added pipeline (quad and glyph) from https://github.com/adbrown85/jogl (sgothel/jogl#47)
1 parent 33da50f commit 5451896

15 files changed

+2712
-0
lines changed

src/main/java/net/opengrabeso/opengl/pipeline/AbstractGlyphRenderer.java

Lines changed: 415 additions & 0 deletions
Large diffs are not rendered by default.

src/main/java/net/opengrabeso/opengl/pipeline/AbstractQuadPipeline.java

Lines changed: 417 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
/*
2+
* Copyright 2012 JogAmp Community. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without modification, are
5+
* permitted provided that the following conditions are met:
6+
*
7+
* 1. Redistributions of source code must retain the above copyright notice, this list of
8+
* conditions and the following disclaimer.
9+
*
10+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
11+
* of conditions and the following disclaimer in the documentation and/or other materials
12+
* provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22+
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
*
24+
* The views and conclusions contained in the software and documentation are those of the
25+
* authors and should not be interpreted as representing official policies, either expressed
26+
* or implied, of JogAmp Community.
27+
*/
28+
package net.opengrabeso.opengl.pipeline;
29+
30+
import net.opengrabeso.opengl.util.packrect.Rect;
31+
import net.opengrabeso.opengl.util.texture.TextureCoords;
32+
33+
import java.awt.font.GlyphVector;
34+
import java.awt.geom.Rectangle2D;
35+
36+
37+
/**
38+
* Representation of one or multiple unicode characters to be drawn.
39+
*
40+
* <p>
41+
* The reason for the dual behavior is so that we can take in a sequence of unicode characters and
42+
* partition them into runs of individual glyphs, but if we encounter complex text and/or unicode
43+
* sequences we don't understand, we can render them using the string-by-string method.
44+
*
45+
* <h1>Positioning</h1>
46+
*
47+
* <p>
48+
* In an effort to make positioning glyphs more intuitive for both Java2D's and OpenGL's coordinate
49+
* systems, {@code Glyph} now stores its measurements differently. This new way is patterned off
50+
* of HTML's box model.
51+
*
52+
* <p>
53+
* Of course, as expected each glyph maintains its width and height. For spacing however, rather
54+
* than storing positions in Java2D space that must be manipulated on a case-by-case basis,
55+
* {@code Glyph} stores two separate pre-computed boundaries representing space around the text.
56+
* Each of the boundaries has separate top, bottom, left, and right components. These components
57+
* should generally be considered positive, but negative values are sometimes necessary in rare
58+
* situations.
59+
*
60+
* <p>
61+
* The first boundary is called <i>padding</i>. Padding is the space between the actual glyph
62+
* itself and its border. It is included in the width and height of the glyph. The second
63+
* boundary that a glyph stores is called <i>margin</i>, which is extra space around the glyph's
64+
* border. The margin is generally used for separating the glyph from other glyphs when it's
65+
* stored.
66+
*
67+
* <p>
68+
* The diagram below shows the boundaries of a glyph and how they relate to its width and height.
69+
* The inner rectangle is the glyph's boundary, and the outer rectangle is the edge of the margin.
70+
*
71+
* <pre>
72+
* +--------------------------------------+
73+
* | top margin |
74+
* | |
75+
* | |------ WIDTH -------| |
76+
* | - +--------------------+ |
77+
* | | | top padding | |
78+
* | | | l ________ r | |
79+
* | l | | e / \ i | r |
80+
* | e | f | | g | i |
81+
* | f H | t | | h | g |
82+
* | t E | | | t | h |
83+
* | I | p | _____ | t |
84+
* | m G | a | | p | |
85+
* | a H | d | | a | m |
86+
* | r T | d | | d | a |
87+
* | g | i | | d | r |
88+
* | i | | n | | i | g |
89+
* | n | | g \________/ n | i |
90+
* | | | g | n |
91+
* | | | bottom padding | |
92+
* | - +--------------------+ |
93+
* | |
94+
* | |
95+
* | bottom margin |
96+
* +--------------------------------------+
97+
* </pre>
98+
*
99+
* <p>
100+
* In addition, {@code Glyph} also keeps a few other measurements useful for positioning.
101+
* <i>Ascent</i> is the distance between the baseline and the top border, while <i>descent</i> is
102+
* the distance between the baseline and the bottom border. <i>Kerning</i> is the distance between
103+
* the vertical baseline and the left border. Note that in some cases some of these fields can
104+
* match up with padding components, but in general they should be considered separate.
105+
*
106+
* <p>
107+
* Below is a diagram showing ascent, descent, and kerning.
108+
*
109+
* <pre>
110+
* +--------------------+ -
111+
* | | |
112+
* | ________ | |
113+
* | / \ | |
114+
* | | | | |
115+
* | | | | |
116+
* | | | | |
117+
* | | _____ | | ascent
118+
* | | | | |
119+
* | | | | |
120+
* | | | | |
121+
* | | | | |
122+
* | | | | |
123+
* | \________/ | -
124+
* | | |
125+
* | | | descent
126+
* +--------------------+ -
127+
*
128+
* |--| kerning
129+
* </pre>
130+
*/
131+
/*@NotThreadSafe*/
132+
public final class Glyph {
133+
134+
// TODO: Create separate Glyph implementations -- one for character one for string?
135+
136+
/**
137+
* Unicode ID if this glyph represents a single character, otherwise -1.
138+
*/
139+
/*@CheckForSigned*/
140+
final int id;
141+
142+
/**
143+
* String if this glyph represents multiple characters, otherwise null.
144+
*/
145+
/*@CheckForNull*/
146+
final String str;
147+
148+
/**
149+
* Font's identifier of glyph.
150+
*/
151+
final int code;
152+
153+
/**
154+
* Distance to next glyph.
155+
*/
156+
final float advance;
157+
158+
/**
159+
* Java2D shape of glyph.
160+
*/
161+
/*@Nonnull*/
162+
final GlyphVector glyphVector;
163+
164+
/**
165+
* Actual character if this glyph represents a single character, otherwise NUL.
166+
*/
167+
final char character;
168+
169+
/**
170+
* Width of text with inner padding.
171+
*/
172+
/*@VisibleForTesting*/
173+
public float width;
174+
175+
/**
176+
* Height of text with inner padding.
177+
*/
178+
/*@VisibleForTesting*/
179+
public float height;
180+
181+
/**
182+
* Length from baseline to top border.
183+
*/
184+
float ascent;
185+
186+
/**
187+
* Length from baseline to bottom border.
188+
*/
189+
float descent;
190+
191+
/**
192+
* Length from baseline to left padding.
193+
*/
194+
float kerning;
195+
196+
/**
197+
* Outer boundary excluded from size.
198+
*/
199+
/*@CheckForNull*/
200+
Boundary margin;
201+
202+
/**
203+
* Inner boundary included in size.
204+
*/
205+
/*@CheckForNull*/
206+
Boundary padding;
207+
208+
/**
209+
* Position of this glyph in texture.
210+
*/
211+
/*@CheckForNull*/
212+
public Rect location;
213+
214+
/**
215+
* Coordinates of this glyph in texture.
216+
*/
217+
/*@CheckForNull*/
218+
TextureCoords coordinates;
219+
220+
/**
221+
* Cached bounding box of glyph.
222+
*/
223+
/*@CheckForNull*/
224+
Rectangle2D bounds;
225+
226+
/**
227+
* Constructs a {@link Glyph} representing an individual Unicode character.
228+
*
229+
* @param id Unicode ID of character
230+
* @param gv Vector shape of character
231+
* @throws IllegalArgumentException if ID is negative
232+
* @throws NullPointerException if glyph is null
233+
*/
234+
public Glyph(/*@Nonnegative*/ final int id, /*@Nonnull*/ final GlyphVector gv) {
235+
236+
this.id = id;
237+
this.str = null;
238+
this.code = gv.getGlyphCode(0);
239+
this.advance = gv.getGlyphMetrics(0).getAdvance();
240+
this.glyphVector = gv;
241+
this.character = (char) id;
242+
}
243+
244+
/**
245+
* Constructs a {@link Glyph} representing a sequence of characters.
246+
*
247+
* @param str Sequence of characters
248+
* @param gv Vector shape of sequence
249+
* @throws NullPointerException if string or glyph vector is null
250+
*/
251+
public Glyph(/*@Nonnull*/ final String str, /*@Nonnull*/ final GlyphVector gv) {
252+
253+
this.id = -1;
254+
this.str = str;
255+
this.code = -1;
256+
this.advance = 0;
257+
this.glyphVector = gv;
258+
this.character = '\0';
259+
}
260+
261+
/*@Nonnull*/
262+
@Override
263+
public String toString() {
264+
return (str != null) ? str : Character.toString(character);
265+
}
266+
267+
/**
268+
* Space around a rectangle.
269+
*/
270+
/*@Immutable*/
271+
static final class Boundary {
272+
273+
/**
274+
* Space above rectangle.
275+
*/
276+
final int top;
277+
278+
/**
279+
* Space below rectangle.
280+
*/
281+
final int bottom;
282+
283+
/**
284+
* Space beside rectangle to left.
285+
*/
286+
final int left;
287+
288+
/**
289+
* Space beside rectangle to right.
290+
*/
291+
final int right;
292+
293+
/**
294+
* Constructs a {@link Boundary} by computing the distances between two rectangles.
295+
*
296+
* @param large Outer rectangle
297+
* @param small Inner rectangle
298+
* @throws NullPointerException if either rectangle is null
299+
*/
300+
Boundary(/*@Nonnull*/ final Rectangle2D large, /*@Nonnull*/ final Rectangle2D small) {
301+
302+
top = (int) (large.getMinY() - small.getMinY()) * -1;
303+
left = (int) (large.getMinX() - small.getMinX()) * -1;
304+
bottom = (int) (large.getMaxY() - small.getMaxY());
305+
right = (int) (large.getMaxX() - small.getMaxX());
306+
}
307+
}
308+
}

0 commit comments

Comments
 (0)