diff options
author | Sven Gothel <[email protected]> | 2023-03-31 11:06:44 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-03-31 11:06:44 +0200 |
commit | 4f32f3aba62a73cafecec8af461cff4d0d475882 (patch) | |
tree | 58f6e7f0800a1ca8b793966520d6008cc6f2080b /src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java | |
parent | 759a381963476e2e64b7afba0d6ef2bafeb35417 (diff) |
GraphUI: Relocate com.jogamp.graph.ui.gl.* -> com.jogamp.graph.ui.*, resolve GL/VK abstraction at a later time differently
Actual GPU rendering toolkit dependency can be abstracted differently, i.e. GPU <- { GL, VK } etc.
Diffstat (limited to 'src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java')
-rw-r--r-- | src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java new file mode 100644 index 000000000..e7d89ade4 --- /dev/null +++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/Label.java @@ -0,0 +1,225 @@ +/** + * Copyright 2010-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.graph.ui.shapes; + +import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.graph.curve.OutlineShape; +import com.jogamp.graph.curve.opengl.GLRegion; +import com.jogamp.graph.curve.opengl.RegionRenderer; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.Font.Glyph; +import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.graph.ui.GraphShape; + +/** + * A GraphUI text label {@link GraphShape} + * <p> + * GraphUI is GPU based and resolution independent. + * </p> + */ +public class Label extends GraphShape { + private Font font; + private float fontScale; + private String text; + + private final AffineTransform tempT1 = new AffineTransform(); + private final AffineTransform tempT2 = new AffineTransform(); + private final AffineTransform tempT3 = new AffineTransform(); + + /** + * Label ctor using a separate {@code fontScale} to scale the em-sized type glyphs + * @param renderModes region renderModes + * @param font the font + * @param fontScale font-scale factor, by which the em-sized type glyphs shall be scaled + * @param text the text to render + */ + public Label(final int renderModes, final Font font, final float fontScale, final String text) { + super(renderModes); + this.font = font; + this.fontScale = fontScale; + this.text = text; + } + + /** + * Label ctor using em-size type glyphs + * @param renderModes region renderModes + * @param font the font + * @param text the text to render + */ + public Label(final int renderModes, final Font font, final String text) { + super(renderModes); + this.font = font; + this.fontScale = 1f; + this.text = text; + } + + /** Return the text to be rendered. */ + public String getText() { + return text; + } + + /** + * Set the text to be rendered. Shape update is pending until next {@link #draw(GL2ES2, RegionRenderer, int[])} or {@link #validate(GL2ES2)}. + * @param text the text to be set. + * @return true if text has been updated, false if unchanged. + */ + public boolean setText(final String text) { + if( !this.text.equals(text) ) { + this.text = text; + markShapeDirty(); + return true; + } else { + return false; + } + } + + /** + * Set the text to be rendered and immediately updates the shape if necessary. + * @param gl {@link GL2ES2} to issue {@link #validate(GL2ES2)} in case text changed to immediately update shape and {@link #getBounds()} + * @param text the text to be set. + * @return true if text has been updated, false if unchanged. + */ + public boolean setText(final GL2ES2 gl, final String text) { + if( setText(text) ) { + validate(gl); + return true; + } else { + return false; + } + } + + /** + * Set the text to be rendered and immediately updates the shape if necessary. + * @param glp {@link GLProfile} to issue {@link #validate(GLProfile)} in case text changed to immediately update shape and {@link #getBounds()} + * @param text the text to be set. + * @return true if text has been updated, false if unchanged. + */ + public boolean setText(final GLProfile glp, final String text) { + if( setText(text) ) { + validate(glp); + return true; + } else { + return false; + } + } + + /** + * Return the {@link Font} used to render the text + */ + public Font getFont() { + return font; + } + + /** + * Set the {@link Font} used to render the text + * @param font the font to be set. + * @return true if font has been updated, false if unchanged. + */ + public boolean setFont(final Font font) { + if( !this.font.equals(font) ) { + this.font = font; + markShapeDirty(); + return true; + } else { + return false; + } + } + + /** + * Gets the font-scale factor, by which the em-sized type glyphs shall be scaled. + */ + public float getFontScale() { + return fontScale; + } + + /** Returns {@link Font#getLineHeight()} * {@link #getFontScale()}. */ + public float getLineHeight() { + return fontScale * font.getLineHeight(); + } + + /** Returns {@link Font#getLineHeight()} * {@link #getFontScale()} * {@link #getScaleY()}. */ + public float getScaledLineHeight() { + return getScaleY() * fontScale * font.getLineHeight(); + } + + /** + * Sets the font-scale factor, by which the em-sized type glyphs shall be scaled. + * <p> + * This will lead to a recreate the shape's region in case fontScale differs. + * </p> + * <p> + * Use {@link #scale(float, float, float)} for non-expensive shape scaling. + * </p> + * @param fontScale font-scale factor, by which the em-sized type glyphs shall be scaled + * @return true if font-scale has been updated, false if unchanged. + */ + public boolean setFontScale(final float fontScale) { + if( this.fontScale != fontScale ) { + this.fontScale = fontScale; + markShapeDirty(); + return true; + } else { + return false; + } + } + + @Override + protected GLRegion createGLRegion(final GLProfile glp) { + return GLRegion.create(glp, getRenderModes(), null, font, text); + } + + private final Font.GlyphVisitor glyphVisitor = new Font.GlyphVisitor() { + @Override + public void visit(final char symbol, final Glyph glyph, final AffineTransform t) { + if( glyph.isWhiteSpace() ) { + return; + } + final OutlineShape shape = glyph.getShape(); + shape.setSharpness(oshapeSharpness); + region.addOutlineShape(shape, t, rgbaColor); + } + }; + + @Override + protected void addShapeToRegion() { + AABBox fbox = font.getGlyphBounds(text, tempT2, tempT3); + tempT1.setToScale(fontScale, fontScale); + tempT1.translate(-fbox.getMinX(), -fbox.getMinY(), tempT2); // enforce bottom-left origin @ 0/0 for good drag-zoom experience + fbox = font.processString(glyphVisitor, tempT1, text, tempT2, tempT3); + setRotationPivot( fbox.getCenter() ); + box.copy(fbox); + } + + @Override + public String getSubString() { + final int m = Math.min(text.length(), 8); + return super.getSubString()+", fscale " + fontScale + ", '" + text.substring(0, m)+"'"; + } +} |