JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
Label.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2023 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 */
28package com.jogamp.graph.ui.shapes;
29
30import com.jogamp.opengl.GL2ES2;
31import com.jogamp.opengl.GLProfile;
32import com.jogamp.opengl.util.texture.TextureSequence;
33import com.jogamp.graph.curve.OutlineShape;
34import com.jogamp.graph.curve.Region;
35import com.jogamp.graph.curve.opengl.GLRegion;
36import com.jogamp.graph.curve.opengl.RegionRenderer;
37import com.jogamp.graph.curve.opengl.TextRegionUtil;
38import com.jogamp.graph.font.Font;
39import com.jogamp.graph.font.Font.Glyph;
40import com.jogamp.graph.ui.GraphShape;
41import com.jogamp.math.geom.AABBox;
42import com.jogamp.math.geom.plane.AffineTransform;
43
44/**
45 * A GraphUI text label {@link GraphShape}
46 * <p>
47 * GraphUI is GPU based and resolution independent.
48 * </p>
49 */
50public class Label extends GraphShape {
51 private Font font;
52 private float fontScale;
53 private CharSequence text;
54
55 /**
56 * Label ctor using a separate {@code fontScale} to scale the em-sized type glyphs.
57 * <p>
58 * If possible, try using {@link Label#Label(int, Font, CharSequence)} and {@link #scale(float, float, float)}.
59 * </p>
60 * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
61 * @param font {@link Font} for this label
62 * @param fontScale font-scale factor, by which the em-sized type glyphs shall be scaled
63 * @param text the label text
64 * @see #Label(int, Font, CharSequence)
65 */
66 public Label(final int renderModes, final Font font, final float fontScale, final CharSequence text) {
67 super(renderModes);
68 this.font = font;
69 this.fontScale = fontScale;
70 this.text = text;
71 }
72
73 /**
74 * Label ctor using em-size type glyphs
75 * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
76 * @param font {@link Font} for this label
77 * @param text the label text
78 * @see #Label(int, Font, float, CharSequence)
79 */
80 public Label(final int renderModes, final Font font, final CharSequence text) {
81 this(renderModes, font, 1f, text);
82 }
83
84 /** Returns the label text. */
85 public CharSequence getText() {
86 return text;
87 }
88
89 /**
90 * Set the text to be rendered. Shape update is pending until next {@link #draw(GL2ES2, RegionRenderer)} or {@link #validate(GL2ES2)}.
91 * @param text the text to be set.
92 * @return true if text has been updated, false if unchanged.
93 */
94 public boolean setText(final CharSequence text) {
95 if( !this.text.equals(text) ) {
96 this.text = text;
98 return true;
99 } else {
100 return false;
101 }
102 }
103
104 /**
105 * Set the text to be rendered and immediately updates the shape if necessary.
106 * @param gl {@link GL2ES2} to issue {@link #validate(GL2ES2)} in case text changed to immediately update shape and {@link #getBounds()}
107 * @param text the text to be set.
108 * @return true if text has been updated, false if unchanged.
109 */
110 public boolean setText(final GL2ES2 gl, final CharSequence text) {
111 if( setText(text) ) {
112 validate(gl);
113 return true;
114 } else {
115 return false;
116 }
117 }
118
119 /**
120 * Set the text to be rendered and immediately updates the shape if necessary.
121 * @param glp {@link GLProfile} to issue {@link #validate(GLProfile)} in case text changed to immediately update shape and {@link #getBounds()}
122 * @param text the text to be set.
123 * @return true if text has been updated, false if unchanged.
124 */
125 public boolean setText(final GLProfile glp, final CharSequence text) {
126 if( setText(text) ) {
127 validate(glp);
128 return true;
129 } else {
130 return false;
131 }
132 }
133
134 /**
135 * Returns the {@link Font} used to render the text
136 */
137 public Font getFont() {
138 return font;
139 }
140
141 /**
142 * Set the {@link Font} used to render the text
143 * @param font the font to be set.
144 * @return true if font has been updated, false if unchanged.
145 */
146 public boolean setFont(final Font font) {
147 if( !this.font.equals(font) ) {
148 this.font = font;
150 return true;
151 } else {
152 return false;
153 }
154 }
155
156 /**
157 * Returns the font-scale factor, by which the em-sized type glyphs shall be scaled.
158 */
159 public float getFontScale() {
160 return fontScale;
161 }
162
163 /** Returns {@link Font#getLineHeight()} * {@link #getFontScale()}. */
164 public float getLineHeight() {
165 return fontScale * font.getLineHeight();
166 }
167
168 /** Returns {@link Font#getLineHeight()} * {@link #getFontScale()} * {@link #getScaleY()}. */
169 public float getScaledLineHeight() {
170 return getScale().y() * fontScale * font.getLineHeight();
171 }
172
173 /**
174 * Sets the font-scale factor, by which the em-sized type glyphs shall be scaled.
175 * <p>
176 * This will lead to a recreate the shape's region in case fontScale differs.
177 * </p>
178 * <p>
179 * Use {@link #scale(float, float, float)} for non-expensive shape scaling.
180 * </p>
181 * @param fontScale font-scale factor, by which the em-sized type glyphs shall be scaled
182 * @return true if font-scale has been updated, false if unchanged.
183 */
184 public boolean setFontScale(final float fontScale) {
185 if( this.fontScale != fontScale ) {
186 this.fontScale = fontScale;
188 return true;
189 } else {
190 return false;
191 }
192 }
193
194 /** Convenient shortcut to {@link Font#getGlyphBounds(CharSequence, AffineTransform, AffineTransform)}. */
195 public static AABBox getUnscaledGlyphBounds(final Font font, final CharSequence text) {
196 return font.getGlyphBounds(text);
197 }
198 /** Convenient shortcut to {@link Font#getGlyphBounds(CharSequence, AffineTransform, AffineTransform)} using {@link #getFont()} and {@link #getText()}. */
200 return getUnscaledGlyphBounds(font, text);
201 }
202
203 private final Font.GlyphVisitor glyphVisitor = new Font.GlyphVisitor() {
204 @Override
205 public void visit(final Glyph glyph, final AffineTransform t) {
206 if( !glyph.isNonContour() ) {
207 final OutlineShape shape = glyph.getShape();
210 }
211 }
212 };
213
214 @Override
215 protected void addShapeToRegion(final GLProfile glp, final GL2ES2 gl) {
216 final AffineTransform tempT1 = new AffineTransform();
217 final AffineTransform tempT2 = new AffineTransform();
218 final AffineTransform tempT3 = new AffineTransform();
219
220 final int[] vertIndCount = TextRegionUtil.countStringRegion(font, text, new int[2]);
221 resetGLRegion(glp, gl, null, vertIndCount[0], vertIndCount[1]);
222
223 AABBox fbox = font.getGlyphBounds(text, tempT2, tempT3);
224 tempT1.setToScale(fontScale, fontScale);
225 tempT1.translate(-fbox.getMinX(), -fbox.getMinY(), tempT2); // enforce bottom-left origin @ 0/0 for good drag-zoom experience
226 fbox = font.processString(glyphVisitor, tempT1, text, tempT2, tempT3);
227 setRotationPivot( fbox.getCenter() );
228 box.copy(fbox);
229 }
230
231 @Override
232 public String getSubString() {
233 final int m = Math.min(text.length(), 8);
234 return super.getSubString()+", fscale " + fontScale + ", '" + text.subSequence(0, m)+"'";
235 }
236}
A Generic shape objects which is defined by a list of Outlines.
final void setSharpness(final float s)
Sets sharpness, defaults to DEFAULT_SHARPNESS.
final void addOutlineShape(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor)
Add the given OutlineShape to this region with the given optional AffineTransform.
Definition: Region.java:616
Text Type Rendering Utility Class adding the Font.Glyphs OutlineShape to a GLRegion.
static int[] countStringRegion(final Font font, final CharSequence str, final int[] vertIndexCount)
Count required number of vertices and indices adding to given int[2] vertIndexCount array.
Graph based GLRegion Shape.
Definition: GraphShape.java:55
final void resetGLRegion(final GLProfile glp, final GL2ES2 gl, final TextureSequence colorTexSeq, int vertexCount, int indexCount)
Reset the GLRegion and reserving its buffers to have a free capacity for vertexCount and indexCount e...
final Vec3f getScale()
Returns scale Vec3f reference.
Definition: Shape.java:682
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
Definition: Shape.java:850
final void markShapeDirty()
Marks the shape dirty, causing next draw() to recreate the Graph shape and reset the region.
Definition: Shape.java:688
final Vec4f rgbaColor
Default base-color w/o color channel, will be modulated w/ pressed- and toggle color.
Definition: Shape.java:261
final Shape setRotationPivot(final float px, final float py, final float pz)
Set unscaled rotation origin, aka pivot.
Definition: Shape.java:620
A GraphUI text label GraphShape.
Definition: Label.java:50
float getFontScale()
Returns the font-scale factor, by which the em-sized type glyphs shall be scaled.
Definition: Label.java:159
float getLineHeight()
Returns Font#getLineHeight() * getFontScale().
Definition: Label.java:164
Font getFont()
Returns the Font used to render the text.
Definition: Label.java:137
static AABBox getUnscaledGlyphBounds(final Font font, final CharSequence text)
Convenient shortcut to Font#getGlyphBounds(CharSequence, AffineTransform, AffineTransform).
Definition: Label.java:195
boolean setFontScale(final float fontScale)
Sets the font-scale factor, by which the em-sized type glyphs shall be scaled.
Definition: Label.java:184
boolean setText(final GL2ES2 gl, final CharSequence text)
Set the text to be rendered and immediately updates the shape if necessary.
Definition: Label.java:110
void addShapeToRegion(final GLProfile glp, final GL2ES2 gl)
Definition: Label.java:215
boolean setText(final CharSequence text)
Set the text to be rendered.
Definition: Label.java:94
float getScaledLineHeight()
Returns Font#getLineHeight() * getFontScale() * getScaleY().
Definition: Label.java:169
boolean setText(final GLProfile glp, final CharSequence text)
Set the text to be rendered and immediately updates the shape if necessary.
Definition: Label.java:125
Label(final int renderModes, final Font font, final float fontScale, final CharSequence text)
Label ctor using a separate fontScale to scale the em-sized type glyphs.
Definition: Label.java:66
boolean setFont(final Font font)
Set the Font used to render the text.
Definition: Label.java:146
AABBox getUnscaledGlyphBounds()
Convenient shortcut to Font#getGlyphBounds(CharSequence, AffineTransform, AffineTransform) using getF...
Definition: Label.java:199
CharSequence getText()
Returns the label text.
Definition: Label.java:85
Label(final int renderModes, final Font font, final CharSequence text)
Label ctor using em-size type glyphs.
Definition: Label.java:80
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final AABBox copy(final AABBox src)
Copy given AABBox 'src' values to this AABBox.
Definition: AABBox.java:158
final Vec3f getCenter()
Returns computed center of this AABBox of getLow() and getHigh().
Definition: AABBox.java:737
final AffineTransform translate(final float mx, final float my, final AffineTransform tmp)
final AffineTransform setToScale(final float scx, final float scy)
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
General purpose Font.Glyph visitor.
Definition: Font.java:298
boolean isNonContour()
Returns true if isWhitespace() or isUndefined().
Interface wrapper for font implementation.
Definition: Font.java:60
float getLineHeight()
Returns line height, baseline-to-baseline in em-size [0..1], composed from ‘hhea’ table entries.
AABBox getGlyphBounds(final CharSequence string)
Try using getGlyphBounds(CharSequence, AffineTransform, AffineTransform) to reuse AffineTransform ins...
AABBox processString(final Font.GlyphVisitor visitor, final AffineTransform transform, final CharSequence string)
Try using processString(GlyphVisitor, AffineTransform, CharSequence, AffineTransform,...
boolean equals(final Object o)
Returns true if other instance is of same type and NAME_UNIQUNAME is equal.