aboutsummaryrefslogtreecommitdiffstats
path: root/src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-03-31 11:06:44 +0200
committerSven Gothel <[email protected]>2023-03-31 11:06:44 +0200
commit4f32f3aba62a73cafecec8af461cff4d0d475882 (patch)
tree58f6e7f0800a1ca8b793966520d6008cc6f2080b /src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java
parent759a381963476e2e64b7afba0d6ef2bafeb35417 (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/GlyphShape.java')
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java
new file mode 100644
index 000000000..568270073
--- /dev/null
+++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/GlyphShape.java
@@ -0,0 +1,204 @@
+/**
+ * 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 java.util.List;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.opengl.GLRegion;
+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;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.math.Vec3f;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.texture.TextureSequence;
+
+/**
+ * Representing a single {@link Font.Glyph} as a {@link GraphShape}
+ *
+ * A GlyphShape is represented in font em-size [0..1] unscaled w/ bottom-left origin at 0/0
+ * while preserving an intended position, see {@link #getOrigPos()} and {@link #getOrigPos(float)}.
+ *
+ * Scaling, if any, should be applied via {@link #setScale(float, float, float)} etc.
+ */
+public class GlyphShape extends GraphShape {
+ private final char symbol;
+ private final Glyph glyph;
+ private final Vec3f origPos;
+
+ /**
+ * Creates a new GlyphShape
+ * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
+ * @param symbol the represented character
+ * @param glyph the {@link Font.Glyph}
+ * @param x the intended unscaled X position of this Glyph, e.g. if part of a string - otherwise use zero.
+ * @param y the intended unscaled Y position of this Glyph, e.g. if part of a string - otherwise use zero.
+ * @see #processString(List, int, Font, String)
+ */
+ public GlyphShape(final int renderModes, final char symbol, final Glyph glyph, final float x, final float y) {
+ super(renderModes);
+ this.symbol = symbol;
+ this.glyph = glyph;
+ this.origPos = new Vec3f(x, y, 0f);
+ if( glyph.isWhiteSpace() || null == glyph.getShape() ) {
+ setEnabled(false);
+ }
+ }
+
+ /**
+ * Creates a new GlyphShape
+ * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
+ * @param font the {@link Font} to lookup the symbol's {@link Font.Glyph}
+ * @param symbol the represented character
+ * @param x the intended unscaled X position of this Glyph, e.g. if part of a string - otherwise use zero.
+ * @param y the intended unscaled Y position of this Glyph, e.g. if part of a string - otherwise use zero.
+ */
+ public GlyphShape(final int renderModes, final Font font, final char symbol, final float x, final float y) {
+ super(renderModes);
+ this.symbol = symbol;
+ this.glyph = font.getGlyph( font.getGlyphID(symbol) );
+ this.origPos = new Vec3f(x, y, 0f);
+ if( glyph.isWhiteSpace() || null == glyph.getShape() ) {
+ setEnabled(false);
+ }
+ }
+
+ /** Returns the char symbol to be rendered. */
+ public char getSymbol() {
+ return symbol;
+ }
+
+ /**
+ * Returns the {@link Font.Glyph} to be rendered.
+ */
+ public Glyph getGlyph() {
+ return glyph;
+ }
+
+ /**
+ * Returns the {@link Font} used to render the text
+ */
+ public Font getFont() {
+ return glyph.getFont();
+ }
+
+ /**
+ * Returns the unscaled original position of this glyph, e.g. if part of a string, otherwise zero.
+ *
+ * Method borrows and returns the internal instance.
+ *
+ * @see #processString(List, int, Font, String)
+ */
+ public Vec3f getOrigPos() { return origPos; }
+
+ /**
+ * Returns the unscaled original position of this glyph, e.g. if part of a string, otherwise zero.
+ *
+ * @param s {@link Vec3f} storage to be returned
+ * @return storage containing the unscaled original position
+ * @see #processString(List, int, Font, String)
+ */
+ public Vec3f getOrigPos(final Vec3f s) { return s.set(origPos); }
+
+ /**
+ * Returns a copy of the scaled original position of this glyph, see {@link #getOrigPos(Vec3f)}
+ * @see #processString(List, int, Font, String)
+ */
+ public Vec3f getOrigPos(final float scale) { return origPos.mul(scale); }
+
+ /**
+ * Returns the scaled original position of this glyph, see {@link #getOrigPos(float)}
+ * @param s {@link Vec3f} storage to be returned
+ * @return storage containing the scaled original position
+ * @see #processString(List, int, Font, String)
+ */
+ public Vec3f getOrigPos(final Vec3f s, final float scale) { return s.set(origPos).scale(scale); }
+
+ /** Resets this Shape's position to the scaled original position, see {@link #getOrigPos(float)}. */
+ public void resetPos(final float scale) {
+ moveTo(origPos.x() * scale, origPos.y() * scale, 0f);
+ }
+
+ /** Resets this Shape's position to the scaled original position and {@link #setScale(float, float, float) set scale}, see {@link #resetPos(float)}. */
+ public void resetPosAndScale(final float scale) {
+ moveTo(origPos.x() * scale, origPos.y() * scale, 0f);
+ setScale(scale, scale, 1f);
+ }
+
+ /** Returns {@link Font#getLineHeight()}. */
+ public float getLineHeight() {
+ return glyph.getFont().getLineHeight();
+ }
+
+ /**
+ * Process the given text resulting in a list of {@link GlyphShape}s with stored original position {@link #getOrigX()} and {@link #getOrigY()} each at font em-size [0..1].
+ * @param res storage for resulting {@link GlyphShape}s.
+ * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
+ * @param font {@link Font} used
+ * @param text text to be represented
+ * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] OutlineShape into account.
+ * @see #getOrigX()
+ * @see #getOrigY()
+ */
+ public static final AABBox processString(final List<GlyphShape> res, final int renderModes, final Font font, final String text) {
+ final Font.GlyphVisitor fgv = new Font.GlyphVisitor() {
+ @Override
+ public void visit(final char symbol, final Glyph glyph, final AffineTransform t) {
+ if( !glyph.isWhiteSpace() && null != glyph.getShape() ) {
+ res.add( new GlyphShape(renderModes, symbol, glyph, t.getTranslateX(), t.getTranslateY()) );
+ }
+ }
+ };
+ return font.processString(fgv, null, text, new AffineTransform(), new AffineTransform());
+ }
+
+ @Override
+ protected void addShapeToRegion() {
+ final OutlineShape shape = glyph.getShape();
+ box.reset();
+ if( null != shape ) {
+ final AABBox sbox = shape.getBounds();
+ final AffineTransform tmp = new AffineTransform();
+ // Enforce bottom-left origin @ 0/0 for good drag-zoom experience,
+ // but keep the underline (decline) intact!
+ tmp.setToTranslation(-sbox.getMinX(), -sbox.getMinY() + glyph.getBounds().getMinY());
+ shape.setSharpness(oshapeSharpness);
+ region.addOutlineShape(shape, tmp, rgbaColor);
+ setRotationPivot( sbox.getCenter() );
+ box.resize(tmp.transform(sbox, new AABBox()));
+ }
+ }
+
+ @Override
+ public String getSubString() {
+ return super.getSubString()+", origPos " + origPos.x() + " / " + origPos.y() + ", '" + symbol + "'";
+ }
+}