From abc833631e0ab30a06c7aff47a39a551544fd735 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 2 Apr 2014 19:25:16 +0200 Subject: Bug 801: Reduce temp. object creation, i.e. GC load --- .../jogamp/graph/curve/opengl/TextRegionUtil.java | 54 +++++++++++----- src/jogl/classes/com/jogamp/graph/font/Font.java | 58 +++++++++-------- .../classes/com/jogamp/graph/geom/Outline.java | 44 ++++++------- .../classes/com/jogamp/graph/geom/SVertex.java | 13 +--- .../com/jogamp/opengl/math/geom/AABBox.java | 41 ++++++++---- .../javax/media/opengl/GLBufferStorage.java | 18 ++++-- .../jogamp/graph/font/typecast/TypecastFont.java | 22 +++---- .../jogamp/graph/font/typecast/TypecastGlyph.java | 67 ++++++++++---------- .../graph/font/typecast/TypecastHMetrics.java | 18 +++--- .../jogamp/graph/geom/plane/AffineTransform.java | 74 ++++++++-------------- .../jogamp/opengl/GLBufferObjectTracker.java | 44 ++++++++----- .../jogamp/opengl/util/glsl/GLSLArrayHandler.java | 12 ++-- .../test/junit/graph/TestTextRendererNEWT00.java | 24 ++++--- .../test/junit/graph/TextRendererGLELBase.java | 8 ++- .../graph/demos/GPUTextRendererListenerBase01.java | 7 +- .../opengl/test/junit/graph/demos/ui/Label.java | 4 +- .../opengl/test/junit/graph/demos/ui/Label0.java | 6 +- .../opengl/test/junit/graph/demos/ui/RIButton.java | 7 +- 18 files changed, 283 insertions(+), 238 deletions(-) diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index 16b1224bd..f944843e9 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -63,6 +63,17 @@ public class TextRegionUtil { public void visit(final OutlineShape shape, final AffineTransform t); } + public static int getCharCount(final String s, final char c) { + final int sz = s.length(); + int count = 0; + for(int i=0; i vertexFactory, - final Font font, final float pixelSize, final CharSequence str, final float[] rgbaColor) { + final Font font, final float pixelSize, final CharSequence str, final float[] rgbaColor, + final AffineTransform temp1, final AffineTransform temp2) { final ShapeVisitor visitor = new ShapeVisitor() { public final void visit(final OutlineShape shape, final AffineTransform t) { region.addOutlineShape(shape, t, region.hasColorChannel() ? rgbaColor : null); } }; - processString(visitor, null, font, pixelSize, str); + processString(visitor, null, font, pixelSize, str, temp1, temp2); } /** @@ -163,7 +179,7 @@ public class TextRegionUtil { GLRegion region = getCachedRegion(font, str, pixelSize, special); if(null == region) { region = GLRegion.create(renderModes); - addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); + addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor, tempT1, tempT2); addCachedRegion(gl, font, str, pixelSize, special, region); } region.draw(gl, renderer, sampleCount); @@ -175,7 +191,7 @@ public class TextRegionUtil { *

* In case of a multisampling region renderer, i.e. {@link Region#VBAA_RENDERING_BIT}, recreating the {@link GLRegion} * is a huge performance impact. - * In such case better use {@link #drawString3D(GL2ES2, GLRegion, RegionRenderer, Font, float, CharSequence, float[], int[])} + * In such case better use {@link #drawString3D(GL2ES2, GLRegion, RegionRenderer, Font, float, CharSequence, float[], int[], AffineTransform, AffineTransform)} * instead. *

* @param gl the current GL state @@ -186,16 +202,19 @@ public class TextRegionUtil { * @param rgbaColor if {@link Region#hasColorChannel()} RGBA color must be passed, otherwise value is ignored. * @param sampleCount desired multisampling sample count for msaa-rendering. * The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched. + * @param temp1 temporary AffineTransform storage, mandatory + * @param temp2 temporary AffineTransform storage, mandatory * @throws Exception if TextRenderer not initialized */ public static void drawString3D(final GL2ES2 gl, final int renderModes, final RegionRenderer renderer, final Font font, final float pixelSize, - final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount) { + final CharSequence str, final float[] rgbaColor, final int[/*1*/] sampleCount, + final AffineTransform temp1, final AffineTransform temp2) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } final GLRegion region = GLRegion.create(renderModes); - addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); + addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor, temp1, temp2); region.draw(gl, renderer, sampleCount); region.destroy(gl); } @@ -210,16 +229,19 @@ public class TextRegionUtil { * @param rgbaColor if {@link Region#hasColorChannel()} RGBA color must be passed, otherwise value is ignored. * @param sampleCount desired multisampling sample count for msaa-rendering. * The actual used scample-count is written back when msaa-rendering is enabled, otherwise the store is untouched. + * @param temp1 temporary AffineTransform storage, mandatory + * @param temp2 temporary AffineTransform storage, mandatory * @throws Exception if TextRenderer not initialized */ public static void drawString3D(final GL2ES2 gl, final GLRegion region, final RegionRenderer renderer, final Font font, final float pixelSize, final CharSequence str, - final float[] rgbaColor, final int[/*1*/] sampleCount) { + final float[] rgbaColor, final int[/*1*/] sampleCount, + final AffineTransform temp1, final AffineTransform temp2) { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } region.clear(gl); - addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor); + addStringToRegion(region, renderer.getRenderState().getVertexFactory(), font, pixelSize, str, rgbaColor, temp1, temp2); region.draw(gl, renderer, sampleCount); } @@ -321,6 +343,8 @@ public class TextRegionUtil { /** Default cache limit, see {@link #setCacheLimit(int)} */ public static final int DEFAULT_CACHE_LIMIT = 256; + public final AffineTransform tempT1 = new AffineTransform(); + public final AffineTransform tempT2 = new AffineTransform(); private final HashMap stringCacheMap = new HashMap(DEFAULT_CACHE_LIMIT); private final ArrayList stringCacheArray = new ArrayList(DEFAULT_CACHE_LIMIT); private int stringCacheLimit = DEFAULT_CACHE_LIMIT; diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java index 811ab9d94..92d35768b 100644 --- a/src/jogl/classes/com/jogamp/graph/font/Font.java +++ b/src/jogl/classes/com/jogamp/graph/font/Font.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. +// * Copyright 2010 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: @@ -30,7 +30,6 @@ package com.jogamp.graph.font; import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.curve.opengl.TextRegionUtil.ShapeVisitor; import com.jogamp.opengl.math.geom.AABBox; /** @@ -82,17 +81,18 @@ public interface Font { * Horizontal http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html */ public interface Metrics { - float getAscent(float pixelSize); - float getDescent(float pixelSize); - float getLineGap(float pixelSize); - float getMaxExtend(float pixelSize); - float getScale(float pixelSize); + float getAscent(final float pixelSize); + float getDescent(final float pixelSize); + float getLineGap(final float pixelSize); + float getMaxExtend(final float pixelSize); + float getScale(final float pixelSize); /** + * @param dest AABBox instance set to this metrics boundary w/ given pixelSize * @param pixelSize * @param tmpV3 caller provided temporary 3-component vector - * @return + * @return the given and set AABBox 'dest' */ - AABBox getBBox(float pixelSize, float[] tmpV3); + AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3); } /** @@ -113,28 +113,29 @@ public interface Font { public char getSymbol(); public short getID(); public AABBox getBBox(); - public float getScale(float pixelSize); + public float getScale(final float pixelSize); /** + * @param dest AABBox instance set to this metrics boundary w/ given pixelSize * @param pixelSize * @param tmpV3 caller provided temporary 3-component vector - * @return + * @return the given and set AABBox 'dest' */ - public AABBox getBBox(float pixelSize, float[] tmpV3); - public float getAdvance(float pixelSize, boolean useFrationalMetrics); + public AABBox getBBox(final AABBox dest, final float pixelSize, float[] tmpV3); + public float getAdvance(final float pixelSize, boolean useFrationalMetrics); public OutlineShape getShape(); public int hashCode(); } - public String getName(int nameIndex); - public StringBuilder getName(StringBuilder string, int nameIndex); + public String getName(final int nameIndex); + public StringBuilder getName(final StringBuilder string, final int nameIndex); /** Shall return the family and subfamily name, separated a dash. *

{@link #getName(StringBuilder, int)} w/ {@link #NAME_FAMILY} and {@link #NAME_SUBFAMILY}

*

Example: "{@code Ubuntu-Regular}"

*/ - public StringBuilder getFullFamilyName(StringBuilder buffer); + public StringBuilder getFullFamilyName(final StringBuilder buffer); - public StringBuilder getAllNames(StringBuilder string, String separator); + public StringBuilder getAllNames(final StringBuilder string, final String separator); /** *
@@ -150,36 +151,39 @@ public interface Font {
      * @param resolution display resolution in dots-per-inch
      * @return pixel-per-inch, pixelSize scale factor for font operations.
      */
-    public float getPixelSize(float fontSize /* points per inch */, float resolution);
+    public float getPixelSize(final float fontSize /* points per inch */, final float resolution);
 
-    public float getAdvanceWidth(int glyphID, float pixelSize);
+    public float getAdvanceWidth(final int glyphID, final float pixelSize);
     public Metrics getMetrics();
-    public Glyph getGlyph(char symbol);
+    public Glyph getGlyph(final char symbol);
     public int getNumGlyphs();
 
-    public float getLineHeight(float pixelSize);
-    public float getMetricWidth(CharSequence string, float pixelSize);
-    public float getMetricHeight(CharSequence string, float pixelSize);
+    public float getLineHeight(final float pixelSize);
+    public float getMetricWidth(final CharSequence string, final float pixelSize);
+    public float getMetricHeight(final CharSequence string, final float pixelSize, final AABBox tmp);
     /**
      * Return the layout bounding box as computed by each glyph's metrics.
      * The result is not pixel correct, bit reflects layout specific metrics.
      * 

- * See {@link #getPointsBounds(AffineTransform, CharSequence, float)} for pixel correct results. + * See {@link #getPointsBounds(AffineTransform, CharSequence, float, AffineTransform, AffineTransform)} for pixel correct results. *

* @param string string text * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. */ - public AABBox getMetricBounds(CharSequence string, float pixelSize); + public AABBox getMetricBounds(final CharSequence string, final float pixelSize); /** * Return the bounding box by taking each glyph's point-based bounding box into account. * @param transform optional given transform * @param string string text * @param pixelSize Use {@link Font#getPixelSize(float, float)} for resolution correct pixel-size. + * @param temp1 temporary AffineTransform storage, mandatory + * @param temp2 temporary AffineTransform storage, mandatory */ - public AABBox getPointsBounds(final AffineTransform transform, CharSequence string, float pixelSize); + public AABBox getPointsBounds(final AffineTransform transform, final CharSequence string, final float pixelSize, + final AffineTransform temp1, final AffineTransform temp2); - public boolean isPrintableChar( char c ); + public boolean isPrintableChar(final char c); /** Shall return {@link #getFullFamilyName()} */ @Override diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java index 80aea2af4..15a45b056 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java @@ -47,18 +47,35 @@ import com.jogamp.opengl.math.geom.AABBox; * * @see OutlineShape, Region */ -public class Outline implements Cloneable, Comparable { +public class Outline implements Comparable { - private ArrayList vertices = new ArrayList(3); - private boolean closed = false; - private AABBox bbox = new AABBox(); - private boolean dirtyBBox = false; + private ArrayList vertices; + private boolean closed; + private final AABBox bbox; + private boolean dirtyBBox; /**Create an outline defined by control vertices. * An outline can contain off Curve vertices which define curved * regions in the outline. */ public Outline() { + vertices = new ArrayList(3); + closed = false; + bbox = new AABBox(); + dirtyBBox = false; + } + + /** + * Copy ctor + */ + public Outline(final Outline src) { + vertices = new ArrayList(src.vertices.size()); + for(int i=0; i { } return true; } - - /** - * @return deep clone of this Outline - */ - @Override - public Outline clone() { - Outline o; - try { - o = (Outline) super.clone(); - } catch (CloneNotSupportedException e) { throw new InternalError(); } - o.bbox = bbox.clone(); - o.vertices = new ArrayList(vertices.size()); - for(int i=0; i * */ -public class AABBox implements Cloneable { +public class AABBox { private static final boolean DEBUG = FloatUtil.DEBUG; private final float[] low = new float[3]; private final float[] high = new float[3]; @@ -70,9 +70,7 @@ public class AABBox implements Cloneable { * @param src the box value to be used for the new instance */ public AABBox(AABBox src) { - System.arraycopy(src.low, 0, low, 0, 3); - System.arraycopy(src.high, 0, high, 0, 3); - System.arraycopy(src.center, 0, center, 0, 3); + copy(src); } /** @@ -90,12 +88,13 @@ public class AABBox implements Cloneable { setSize(lx, ly, lz, hx, hy, hz); } - /** Create a AABBox defining the low and high + /** + * Create a AABBox defining the low and high * @param low min xyz-coordinates * @param high max xyz-coordinates */ public AABBox(final float[] low, final float[] high) { - setSize(low[0],low[1],low[2], high[0],high[1],high[2]); + setSize(low, high); } /** @@ -143,6 +142,31 @@ public class AABBox implements Cloneable { center[2] = (high[2] + low[2])/2f; } + /** + * Copy given AABBox 'src' values to this AABBox. + * + * @param src source AABBox + * @return this AABBox for chaining + */ + public final AABBox copy(AABBox src) { + System.arraycopy(src.low, 0, low, 0, 3); + System.arraycopy(src.high, 0, high, 0, 3); + System.arraycopy(src.center, 0, center, 0, 3); + return this; + } + + /** + * Set size of the AABBox specifying the coordinates + * of the low and high. + * + * @param low min xyz-coordinates + * @param high max xyz-coordinates + * @return this AABBox for chaining + */ + public final AABBox setSize(final float[] low, final float[] high) { + return setSize(low[0],low[1],low[2], high[0],high[1],high[2]); + } + /** * Set size of the AABBox specifying the coordinates * of the low and high. @@ -509,11 +533,6 @@ public class AABBox implements Cloneable { return high[2] - low[2]; } - @Override - public final AABBox clone() { - return new AABBox(this); - } - @Override public final boolean equals(Object obj) { if( obj == this ) { diff --git a/src/jogl/classes/javax/media/opengl/GLBufferStorage.java b/src/jogl/classes/javax/media/opengl/GLBufferStorage.java index 929ecf60a..b36e87101 100644 --- a/src/jogl/classes/javax/media/opengl/GLBufferStorage.java +++ b/src/jogl/classes/javax/media/opengl/GLBufferStorage.java @@ -78,10 +78,10 @@ import java.nio.IntBuffer; */ public abstract class GLBufferStorage { private final int name; - private final long size; - private final int mutableUsage; - private final int immutableFlags; - protected ByteBuffer mappedBuffer; + private /* final */ long size; + private /* final */ int mutableUsage; + private /* final */ int immutableFlags; + private ByteBuffer mappedBuffer; protected GLBufferStorage(final int name, final long size, final int mutableUsage, final int immutableFlags) { this.name = name; @@ -91,6 +91,16 @@ public abstract class GLBufferStorage { this.mappedBuffer = null; } + protected void reset(final long size, final int mutableUsage, final int immutableFlags) { + this.size = size; + this.mutableUsage = mutableUsage; + this.immutableFlags = immutableFlags; + this.mappedBuffer = null; + } + protected void setMappedBuffer(final ByteBuffer buffer) { + this.mappedBuffer = buffer; + } + /** Return the buffer name */ public final int getName() { return name; } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index cd48cd8d6..5fb61387a 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -38,10 +38,8 @@ import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.curve.Region; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; -import com.jogamp.graph.font.Font.Glyph; import com.jogamp.graph.geom.SVertex; import com.jogamp.graph.geom.Vertex; import com.jogamp.opengl.math.geom.AABBox; @@ -251,7 +249,7 @@ class TypecastFont implements Font { if (character == '\n') { width = 0; } else { - Glyph glyph = getGlyph(character); + final Glyph glyph = getGlyph(character); width += glyph.getAdvance(pixelSize, false); } } @@ -259,14 +257,14 @@ class TypecastFont implements Font { } @Override - public float getMetricHeight(CharSequence string, float pixelSize) { + public float getMetricHeight(CharSequence string, float pixelSize, final AABBox tmp) { int height = 0; for (int i=0; i size2advance = new HashMap(); + private final IntIntHashMap size2advanceI = new IntIntHashMap(); - public Advance(Font font, float advance) + public Advance(final Font font, final float advance) { this.font = font; this.advance = advance; + size2advanceI.setKeyNotFoundValue(0); } public void reset() { - size2advance.clear(); + size2advanceI.clear(); } - public float getScale(float pixelSize) + public float getScale(final float pixelSize) { return this.font.getMetrics().getScale(pixelSize); } - public void add(float advance, float size) + public void add(final float advance, final float size) { - size2advance.put(size, advance); + size2advanceI.put(Float.floatToIntBits(size), Float.floatToIntBits(advance)); } - public float get(float size, boolean useFrationalMetrics) + public float get(final float size, final boolean useFrationalMetrics) { - final Float fo = size2advance.get(size); - if(null == fo) { - float value = (this.advance * getScale(size)); - if (useFrationalMetrics == false) { - //value = (float)Math.ceil(value); - // value = (int)value; - value = (int) ( value + 0.5f ) ; // TODO: check - } - size2advance.put(size, value); - return value; + final int sI = Float.floatToIntBits(size); + final int aI = size2advanceI.get(sI); + if( 0 != aI ) { + return Float.intBitsToFloat(aI); + } + final float a; + if ( useFrationalMetrics ) { + a = this.advance * getScale(size); + } else { + // a = Math.ceil(this.advance * getScale(size)); + a = Math.round(this.advance * getScale(size)); // TODO: check whether ceil should be used instead? } - return fo.floatValue(); + size2advanceI.put(sI, Float.floatToIntBits(a)); + return a; } @Override @@ -81,7 +83,7 @@ public class TypecastGlyph implements Font.Glyph { { return "\nAdvance:"+ "\n advance: "+this.advance+ - "\n advances: \n"+size2advance; + "\n advances: \n"+size2advanceI; } } @@ -90,7 +92,7 @@ public class TypecastGlyph implements Font.Glyph { private final AABBox bbox; private final Advance advance; - public Metrics(Font font, AABBox bbox, float advance) + public Metrics(final Font font, final AABBox bbox, final float advance) { this.bbox = bbox; this.advance = new Advance(font, advance); @@ -100,7 +102,7 @@ public class TypecastGlyph implements Font.Glyph { advance.reset(); } - public float getScale(float pixelSize) + public float getScale(final float pixelSize) { return this.advance.getScale(pixelSize); } @@ -110,12 +112,12 @@ public class TypecastGlyph implements Font.Glyph { return this.bbox; } - public void addAdvance(float advance, float size) + public void addAdvance(final float advance, final float size) { this.advance.add(advance, size); } - public float getAdvance(float size, boolean useFrationalMetrics) + public float getAdvance(final float size, final boolean useFrationalMetrics) { return this.advance.get(size, useFrationalMetrics); } @@ -139,7 +141,7 @@ public class TypecastGlyph implements Font.Glyph { private final int advance; private final Metrics metrics; - protected TypecastGlyph(Font font, char symbol, short id, AABBox bbox, int advance, OutlineShape shape) { + protected TypecastGlyph(final Font font, final char symbol, final short id, final AABBox bbox, final int advance, final OutlineShape shape) { this.font = font; this.symbol = symbol; this.shape = shape; @@ -183,24 +185,21 @@ public class TypecastGlyph implements Font.Glyph { } @Override - public final float getScale(float pixelSize) { + public final float getScale(final float pixelSize) { return this.metrics.getScale(pixelSize); } @Override - public final AABBox getBBox(float pixelSize, float[] tmpV3) { - final float size = getScale(pixelSize); - AABBox newBox = getBBox().clone(); - newBox.scale(size, tmpV3); - return newBox; + public final AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3) { + return dest.copy(getBBox()).scale(getScale(pixelSize), tmpV3); } - protected final void addAdvance(float advance, float size) { + protected final void addAdvance(final float advance, final float size) { this.metrics.addAdvance(advance, size); } @Override - public final float getAdvance(float pixelSize, boolean useFrationalMetrics) { + public final float getAdvance(final float pixelSize, final boolean useFrationalMetrics) { return this.metrics.getAdvance(pixelSize, useFrationalMetrics); } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java index 4064e6463..be8ab8f69 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java @@ -45,7 +45,7 @@ class TypecastHMetrics implements Metrics { // VheaTable (for horizontal fonts) // private final VheaTable vheaTable; - public TypecastHMetrics(TypecastFont fontImpl) { + public TypecastHMetrics(final TypecastFont fontImpl) { this.fontImpl = fontImpl; headTable = this.fontImpl.font.getHeadTable(); hheaTable = this.fontImpl.font.getHheaTable(); @@ -62,29 +62,27 @@ class TypecastHMetrics implements Metrics { } @Override - public final float getAscent(float pixelSize) { + public final float getAscent(final float pixelSize) { return getScale(pixelSize) * -hheaTable.getAscender(); // invert } @Override - public final float getDescent(float pixelSize) { + public final float getDescent(final float pixelSize) { return getScale(pixelSize) * -hheaTable.getDescender(); // invert } @Override - public final float getLineGap(float pixelSize) { + public final float getLineGap(final float pixelSize) { return getScale(pixelSize) * -hheaTable.getLineGap(); // invert } @Override - public final float getMaxExtend(float pixelSize) { + public final float getMaxExtend(final float pixelSize) { return getScale(pixelSize) * hheaTable.getXMaxExtent(); } @Override - public final float getScale(float pixelSize) { + public final float getScale(final float pixelSize) { return pixelSize * unitsPerEM_Inv; } @Override - public final AABBox getBBox(float pixelSize, float[] tmpV3) { - AABBox res = new AABBox(bbox.getLow(), bbox.getHigh()); - res.scale(getScale(pixelSize), tmpV3); - return res; + public final AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3) { + return dest.setSize(bbox.getLow(), bbox.getHigh()).scale(getScale(pixelSize), tmpV3); } } \ No newline at end of file diff --git a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java index 04b9d3bcd..2a30fa6ec 100644 --- a/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/jogamp/graph/geom/plane/AffineTransform.java @@ -208,7 +208,7 @@ public class AffineTransform implements Cloneable { return m00 * m11 - m01 * m10; } - public final void setTransform(float m00, float m10, float m01, float m11, float m02, float m12) { + public final AffineTransform setTransform(float m00, float m10, float m01, float m11, float m02, float m12) { this.type = TYPE_UNKNOWN; this.m00 = m00; this.m10 = m10; @@ -216,20 +216,23 @@ public class AffineTransform implements Cloneable { this.m11 = m11; this.m02 = m02; this.m12 = m12; + return this; } - public final void setTransform(AffineTransform t) { + public final AffineTransform setTransform(AffineTransform t) { type = t.type; setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12); + return this; } - public final void setToIdentity() { + public final AffineTransform setToIdentity() { type = TYPE_IDENTITY; m00 = m11 = 1.0f; m10 = m01 = m02 = m12 = 0.0f; + return this; } - public final void setToTranslation(float mx, float my) { + public final AffineTransform setToTranslation(float mx, float my) { m00 = m11 = 1.0f; m01 = m10 = 0.0f; m02 = mx; @@ -239,9 +242,10 @@ public class AffineTransform implements Cloneable { } else { type = TYPE_TRANSLATION; } + return this; } - public final void setToScale(float scx, float scy) { + public final AffineTransform setToScale(float scx, float scy) { m00 = scx; m11 = scy; m10 = m01 = m02 = m12 = 0.0f; @@ -250,9 +254,10 @@ public class AffineTransform implements Cloneable { } else { type = TYPE_IDENTITY; } + return this; } - public final void setToShear(float shx, float shy) { + public final AffineTransform setToShear(float shx, float shy) { m00 = m11 = 1.0f; m02 = m12 = 0.0f; m01 = shx; @@ -262,9 +267,10 @@ public class AffineTransform implements Cloneable { } else { type = TYPE_IDENTITY; } + return this; } - public final void setToRotation(float angle) { + public final AffineTransform setToRotation(float angle) { float sin = FloatUtil.sin(angle); float cos = FloatUtil.cos(angle); if (FloatUtil.abs(cos) < ZERO) { @@ -280,63 +286,35 @@ public class AffineTransform implements Cloneable { m10 = sin; m02 = m12 = 0.0f; type = TYPE_UNKNOWN; + return this; } - public final void setToRotation(float angle, float px, float py) { + public final AffineTransform setToRotation(float angle, float px, float py) { setToRotation(angle); m02 = px * (1.0f - m00) + py * m10; m12 = py * (1.0f - m00) - px * m10; type = TYPE_UNKNOWN; + return this; } - public static AffineTransform getTranslateInstance(float mx, float my) { - AffineTransform t = new AffineTransform(); - t.setToTranslation(mx, my); - return t; - } - - public static AffineTransform getScaleInstance(float scx, float scY) { - AffineTransform t = new AffineTransform(); - t.setToScale(scx, scY); - return t; - } - - public static AffineTransform getShearInstance(float shx, float shy) { - AffineTransform t = new AffineTransform(); - t.setToShear(shx, shy); - return t; - } - - public static AffineTransform getRotateInstance(float angle) { - AffineTransform t = new AffineTransform(); - t.setToRotation(angle); - return t; - } - - public static AffineTransform getRotateInstance(float angle, float x, float y) { - AffineTransform t = new AffineTransform(); - t.setToRotation(angle, x, y); - return t; - } - - public final AffineTransform translate(float mx, float my) { - return concatenate(AffineTransform.getTranslateInstance(mx, my)); + public final AffineTransform translate(float mx, float my, AffineTransform tmp) { + return concatenate(tmp.setToTranslation(mx, my)); } - public final AffineTransform scale(float scx, float scy) { - return concatenate(AffineTransform.getScaleInstance(scx, scy)); + public final AffineTransform scale(float scx, float scy, AffineTransform tmp) { + return concatenate(tmp.setToScale(scx, scy)); } - public final AffineTransform shear(float shx, float shy) { - return concatenate(AffineTransform.getShearInstance(shx, shy)); + public final AffineTransform shear(float shx, float shy, AffineTransform tmp) { + return concatenate(tmp.setToShear(shx, shy)); } - public final AffineTransform rotate(float angle) { - return concatenate(AffineTransform.getRotateInstance(angle)); + public final AffineTransform rotate(float angle, AffineTransform tmp) { + return concatenate(tmp.setToRotation(angle)); } - public final AffineTransform rotate(float angle, float px, float py) { - return concatenate(AffineTransform.getRotateInstance(angle, px, py)); + public final AffineTransform rotate(float angle, float px, float py, AffineTransform tmp) { + return concatenate(tmp.setToRotation(angle, px, py)); } /** diff --git a/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java index 2351826cb..483b9b526 100644 --- a/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java +++ b/src/jogl/classes/jogamp/opengl/GLBufferObjectTracker.java @@ -109,11 +109,11 @@ public class GLBufferObjectTracker { GLBufferStorageImpl(final int name, final long size, final int mutableUsage, final int immutableFlags) { super(name, size, mutableUsage, immutableFlags); } - final void setMappedBuffer(final ByteBuffer bb) { - if (DEBUG) { - System.err.printf("%s.GLBufferStorage.setMappedBuffer: %s: %s -> %s%n", msgClazzName, toString(true), mappedBuffer, bb); - } - mappedBuffer = bb; + protected final void reset(final long size, final int mutableUsage, final int immutableFlags) { + super.reset(size, mutableUsage, immutableFlags); + } + protected final void setMappedBuffer(final ByteBuffer buffer) { + super.setMappedBuffer(buffer); } } @@ -169,13 +169,18 @@ public class GLBufferObjectTracker { throw new GLException(String.format("GL-Error 0x%X while creating %s storage for target 0x%X -> buffer %d of size %d with data %s", glerrPost, mutableBuffer ? "mutable" : "immutable", target, bufferName, size, data)); } - final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, immutableFlags); - final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.put(bufferName, objNew); - if (DEBUG) { - System.err.printf("%s.%s target: 0x%X -> %d: %s -> %s%n", msgClazzName, msgCreateBound, target, bufferName, objOld, objNew); - } + final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.get(bufferName); if( null != objOld ) { - objOld.setMappedBuffer(null); + objOld.reset(size, mutableUsage, immutableFlags); + if (DEBUG) { + System.err.printf("%s.%s target: 0x%X -> reset %d: %s%n", msgClazzName, msgCreateBound, target, bufferName, objOld); + } + } else { + final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, immutableFlags); + bufferName2StorageMap.put(bufferName, objNew); + if (DEBUG) { + System.err.printf("%s.%s target: 0x%X -> new %d: %s%n", msgClazzName, msgCreateBound, target, bufferName, objNew); + } } } @@ -209,13 +214,18 @@ public class GLBufferObjectTracker { throw new GLException(String.format("GL-Error 0x%X while creating %s storage for buffer %d of size %d with data %s", glerrPost, "mutable", bufferName, size, data)); } - final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, 0 /* immutableFlags */); - final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.put(bufferName, objNew); - if (DEBUG) { - System.err.printf("%s.%s direct: %d: %s -> %s%n", msgClazzName, msgCreateNamed, bufferName, objOld, objNew); - } + final GLBufferStorageImpl objOld = (GLBufferStorageImpl) bufferName2StorageMap.get(bufferName); if( null != objOld ) { - objOld.setMappedBuffer(null); + objOld.reset(size, mutableUsage, immutableFlags); + if (DEBUG) { + System.err.printf("%s.%s direct: reset %d: %s%n", msgClazzName, msgCreateNamed, bufferName, objOld); + } + } else { + final GLBufferStorageImpl objNew = new GLBufferStorageImpl(bufferName, size, mutableUsage, immutableFlags); + bufferName2StorageMap.put(bufferName, objNew); + if (DEBUG) { + System.err.printf("%s.%s direct: new %d: %s%n", msgClazzName, msgCreateNamed, bufferName, objNew); + } } } diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java index 1f402f48b..e9fb91086 100644 --- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java +++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java @@ -69,6 +69,8 @@ public class GLSLArrayHandler extends GLVBOArrayHandler { } } + private final int[] tempI = new int[1]; + private final void enableShaderState(GL2ES2 glsl, boolean enable, ShaderState st) { if(enable) { /* @@ -99,9 +101,8 @@ public class GLSLArrayHandler extends GLVBOArrayHandler { } else if(st.getAttribLocation(glsl, ad) >= 0) { // didn't experience a performance hit on this query .. // (using ShaderState's location query above to validate the location) - final int[] qi = new int[1]; - glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0); - if(ad.getVBOName() != qi[0]) { + glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, tempI, 0); + if(ad.getVBOName() != tempI[0]) { glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName()); st.vertexAttribPointer(glsl, ad); glsl.glBindBuffer(ad.getVBOTarget(), 0); @@ -151,9 +152,8 @@ public class GLSLArrayHandler extends GLVBOArrayHandler { } else { // didn't experience a performance hit on this query .. // (using ShaderState's location query above to validate the location) - final int[] qi = new int[1]; - glsl.glGetVertexAttribiv(location, GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0); - if(ad.getVBOName() != qi[0]) { + glsl.glGetVertexAttribiv(location, GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, tempI, 0); + if(ad.getVBOName() != tempI[0]) { glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName()); glsl.glVertexAttribPointer(ad); glsl.glBindBuffer(ad.getVBOTarget(), 0); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java index 27e5ad90f..f9107ef3e 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java @@ -136,9 +136,12 @@ public class TestTextRendererNEWT00 extends UITestCase { } static void sleep() { + sleep(Duration); + } + static void sleep(final long d) { try { - System.err.println("** new frame ** (sleep: "+Duration+"ms)"); - Thread.sleep(Duration); + System.err.println("** new frame ** (sleep: "+d+"ms)"); + Thread.sleep(d); } catch (InterruptedException ie) {} } @@ -373,22 +376,23 @@ public class TestTextRendererNEWT00 extends UITestCase { final float pixelSizeAnim = font.getPixelSize(fontSizeAnim, dpiH); final String modeS = Region.getRenderModeString(renderModes); - final String text1 = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, %s-samples %d", - lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0, fontSizeFixed, - drawable.getChosenGLCapabilities().getNumSamples(), modeS, vbaaSampleCount[0]); - final String text1A = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, %s-samples %d", - lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0, fontSizeAnim, - drawable.getChosenGLCapabilities().getNumSamples(), modeS, vbaaSampleCount[0]); if( true ) { // renderString(drawable, font, pixelSize, "I - / H P 7 0", 0, 0, 0, 0, -1000f, true); // renderString(drawable, font, pixelSize, "A M > } ] ", 0, 0, 0, 0, -1000f, true); - renderString(drawable, font, pixelSize, "M", 0, 0, 0, 0, -1000f, true); + // renderString(drawable, font, pixelSize, "M", 0, 0, 0, 0, -1000f, true); // renderString(drawable, font, pixelSize, "0 6 9 a b O Q A M > } ] ", 0, 0, 0, 0, -1000f, true); // renderString(drawable, font, pixelSize, "012345678901234567890123456789", 0, 0, 0, -1000, true); // renderString(drawable, font, pixelSize, textX2, 0, 0, 0, 0, -1000f, true); // renderString(drawable, font, pixelSize, text1, 0, 0, 0, -1000f, regionFPS); // no-cache + final String text1 = lfps+" / "+tfps+" fps, vsync "+gl.getSwapInterval()+", elapsed "+(t1-t0)/1000.0+ + " s, fontSize "+fontSizeFixed+", msaa "+drawable.getChosenGLCapabilities().getNumSamples()+ + ", "+modeS+"-samples "+vbaaSampleCount[0]; + renderString(drawable, font, pixelSize, text1, 0, 0, 0, 0, -1000, regionFPS); // no-cache } else { + final String text1 = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s, fontSize %2.2f, msaa %d, %s-samples %d", + lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0, fontSizeFixed, + drawable.getChosenGLCapabilities().getNumSamples(), modeS, vbaaSampleCount[0]); renderString(drawable, font, pixelSize, getFontInfo(), 0, 0, 0, 0, -1000, true); renderString(drawable, font, pixelSize, "012345678901234567890123456789", 0, 0, 0, -1000, true); renderString(drawable, font, pixelSize, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0, 0, 0, -1000, true); @@ -399,7 +403,7 @@ public class TestTextRendererNEWT00 extends UITestCase { renderString(drawable, font, pixelSize, textX2, 0, 0, 0, -1000, true); renderString(drawable, font, pixelSize, text1, 0, 0, 0, -1000, regionFPS); // no-cache if( TextAnim ) { - renderString(drawable, font, pixelSizeAnim, text1A, 0, 0, 0, -1000, regionFPSAnim); // no-cache + renderString(drawable, font, pixelSizeAnim, text1, 0, 0, 0, -1000, regionFPSAnim); // no-cache } } } }; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java index 05e090886..207904f89 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java @@ -248,7 +248,7 @@ public abstract class TextRendererGLELBase implements GLEventListener { final int height = drawable.getHeight(); dy = height-ty; } - final int newLineCount = text.length() - text.replace("\n", "").length(); + final int newLineCount = TextRegionUtil.getCharCount(text, '\n'); final float lineHeight = font.getLineHeight(pixelSize); dx += pixelScale * font.getAdvanceWidth('X', pixelSize) * column; dy -= pixelScale * lineHeight * ( row + 1 ); @@ -270,9 +270,11 @@ public abstract class TextRendererGLELBase implements GLEventListener { if( cacheRegion ) { textRenderUtil.drawString3D(gl, renderer, font, pixelSize, text, null, vbaaSampleCount); } else if( null != region ) { - TextRegionUtil.drawString3D(gl, region, renderer, font, pixelSize, text, null, vbaaSampleCount); + TextRegionUtil.drawString3D(gl, region, renderer, font, pixelSize, text, null, vbaaSampleCount, + textRenderUtil.tempT1, textRenderUtil.tempT2); } else { - TextRegionUtil.drawString3D(gl, renderModes, renderer, font, pixelSize, text, null, vbaaSampleCount); + TextRegionUtil.drawString3D(gl, renderModes, renderer, font, pixelSize, text, null, vbaaSampleCount, + textRenderUtil.tempT1, textRenderUtil.tempT2); } renderer.enable(gl, false); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java index 5dcfea4a9..8b653bdfa 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java @@ -247,7 +247,8 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB pmv.glTranslatef(nearPlaneX0, nearPlaneY0+(nearPlaneS * pixelSizeFPS / 2f), nearPlaneZ0); // No cache, keep region alive! - TextRegionUtil.drawString3D(gl, regionFPS, renderer, font, nearPlaneS * pixelSizeFPS, text, null, sampleCountFPS); + TextRegionUtil.drawString3D(gl, regionFPS, renderer, font, nearPlaneS * pixelSizeFPS, text, null, sampleCountFPS, + textRegionUtil.tempT1, textRegionUtil.tempT2); } float dx = width-fontNameBox.getWidth()-2f; @@ -292,13 +293,13 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB } if(!userInput) { if( bottomTextUseFrustum ) { - TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount()); + TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount(), null, null); } else { textRegionUtil.drawString3D(gl, renderer, font, nearPlaneS * pixelSizeBottom, text2, null, getSampleCount()); } } else { if( bottomTextUseFrustum ) { - TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount()); + TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount(), null, null); } else { textRegionUtil.drawString3D(gl, renderer, font, nearPlaneS * pixelSizeBottom, userString.toString(), null, getSampleCount()); } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java index 6209bd975..4a14bb442 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java @@ -90,6 +90,8 @@ public class Label extends UIShape { } private final float[] tmpV3 = new float[3]; + private final AffineTransform tempT1 = new AffineTransform(); + private final AffineTransform tempT2 = new AffineTransform(); private final TextRegionUtil.ShapeVisitor shapeVisitor = new TextRegionUtil.ShapeVisitor() { @Override @@ -102,7 +104,7 @@ public class Label extends UIShape { @Override protected void addShapeToRegion(GL2ES2 gl, RegionRenderer renderer) { - TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text); + TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text, tempT1, tempT2); final float[] ctr = box.getCenter(); setRotationOrigin( ctr[0], ctr[1], ctr[2]); } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java index dff9cd1c7..336ce7526 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java @@ -72,11 +72,13 @@ public class Label0 { public final AABBox getBounds() { return box; } private final float[] tmpV3 = new float[3]; + private final AffineTransform tempT1 = new AffineTransform(); + private final AffineTransform tempT2 = new AffineTransform(); private final TextRegionUtil.ShapeVisitor shapeVisitor = new TextRegionUtil.ShapeVisitor() { @Override public void visit(OutlineShape shape, AffineTransform t) { - final AffineTransform t1 = new AffineTransform(tLeft).concatenate( t ); + final AffineTransform t1 = t.preConcatenate(tLeft); region.addOutlineShape(shape, t1, rgbaColor); box.resize(shape.getBounds(), t1, tmpV3); } @@ -89,7 +91,7 @@ public class Label0 { box.reset(); this.region = region; this.tLeft = tLeft; - TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text); + TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text, tempT1, tempT2); this.region = null; this.tLeft = null; return box; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java index e83097488..5315a8927 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/RIButton.java @@ -37,7 +37,6 @@ import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; -import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.geom.AABBox; /** @@ -58,6 +57,8 @@ public class RIButton extends UIShape { private float spacingX = DEFAULT_SPACING_X; private float spacingY = DEFAULT_SPACING_Y; private float corner = DEFAULT_CORNER; + private final AffineTransform tempT1 = new AffineTransform(); + private final AffineTransform tempT2 = new AffineTransform(); public RIButton(Factory factory, int renderModes, Font labelFont, String labelText, float width, float height, float labelZOffset) { super(factory, renderModes | Region.COLORCHANNEL_RENDERING_BIT); @@ -129,13 +130,13 @@ public class RIButton extends UIShape { } // Setting pixelSize based on actual text-box size - final AABBox lbox1 = label.font.getPointsBounds(null, label.text, lPixelSize1); + final AABBox lbox1 = label.font.getPointsBounds(null, label.text, lPixelSize1, tempT1, tempT2); // Center text .. (share same center w/ button) final float[] lctr = lbox1.getCenter(); final float[] ctr = box.getCenter(); final float[] ltx = new float[] { ctr[0] - lctr[0], ctr[1] - lctr[1], 0f }; - final AABBox lbox2 = label.addShapeToRegion(lPixelSize1, region, AffineTransform.getTranslateInstance(ltx[0], ltx[1])); + final AABBox lbox2 = label.addShapeToRegion(lPixelSize1, region, tempT1.setToTranslation(ltx[0], ltx[1])); if( DRAW_DEBUG_BOX ) { System.err.printf("RIButton.0: lbox1 %s%n", lbox1); System.err.printf("RIButton.0: lbox2 %s%n", lbox2); -- cgit v1.2.3