blob: 51fb97561c5f5203bc938568d6f9397b2f68a8b2 [file] [log] [blame]
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - 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.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER 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.
*/
/*
* (C) Copyright IBM Corp. 2003, All Rights Reserved.
* This technology is protected by multiple US and International
* patents. This notice and attribution to IBM may not be removed.
*/
package j2dbench.tests.text;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.text.Bidi;
import java.util.ArrayList;
import j2dbench.Group;
import j2dbench.Result;
import j2dbench.TestEnvironment;
public abstract class TextMeasureTests extends TextTests {
static Group measureroot;
static Group measuretestroot;
public static void init() {
measureroot = new Group(textroot, "Measuring", "Measuring Benchmarks");
measuretestroot = new Group(measureroot, "tests", "Measuring Tests");
new StringWidth();
new StringBounds();
new CharsWidth();
new CharsBounds();
new FontCanDisplay();
if (hasGraphics2D) {
new GVWidth();
new GVLogicalBounds();
new GVVisualBounds();
new GVPixelBounds();
new GVOutline();
new GVGlyphLogicalBounds();
new GVGlyphVisualBounds();
new GVGlyphPixelBounds();
new GVGlyphOutline();
new GVGlyphTransform();
new GVGlyphMetrics();
new TLAdvance();
new TLAscent();
new TLBounds();
new TLGetCaretInfo();
new TLGetNextHit();
new TLGetCaretShape();
new TLGetLogicalHighlightShape();
new TLHitTest();
new TLOutline();
/*
new FontLineMetrics();
new FontStringBounds();
*/
}
}
public TextMeasureTests(Group parent, String nodeName, String description) {
super(parent, nodeName, description);
}
static class SWContext extends TextContext {
FontMetrics fm;
public void init(TestEnvironment env, Result results) {
super.init(env, results);
fm = graphics.getFontMetrics(font);
}
}
public Context createContext() {
return new SWContext();
}
public static class StringWidth extends TextMeasureTests {
public StringWidth() {
super(measuretestroot, "stringWidth", "Measuring String Width");
}
public void runTest(Object ctx, int numReps) {
SWContext swctx = (SWContext)ctx;
String text = swctx.text;
FontMetrics fm = swctx.fm;
int wid = 0;
do {
wid += fm.stringWidth(text);
} while (--numReps >= 0);
}
}
public static class StringBounds extends TextMeasureTests {
public StringBounds() {
super(measuretestroot, "stringBounds", "Measuring String Bounds");
}
public void runTest(Object ctx, int numReps) {
SWContext swctx = (SWContext)ctx;
String text = swctx.text;
FontMetrics fm = swctx.fm;
int wid = 0;
Rectangle r = null;
do {
r = null;
int dx = fm.stringWidth(text);
int dy = fm.getAscent() + fm.getDescent() + fm.getLeading();
int x = 0;
int y = -fm.getAscent();
r = new Rectangle(x, y, dx, dy);
} while (--numReps >= 0);
}
}
public static class CharsWidth extends TextMeasureTests {
public CharsWidth() {
super(measuretestroot, "charsWidth", "Measuring Chars Width");
}
public void runTest(Object ctx, int numReps) {
SWContext swctx = (SWContext)ctx;
FontMetrics fm = swctx.fm;
char[] chars = swctx.chars;
int wid = 0;
do {
wid += fm.charsWidth(chars, 0, chars.length);
} while (--numReps >= 0);
}
}
public static class CharsBounds extends TextMeasureTests {
public CharsBounds() {
super(measuretestroot, "charsBounds", "Measuring Chars Bounds");
}
public void runTest(Object ctx, int numReps) {
SWContext swctx = (SWContext)ctx;
FontMetrics fm = swctx.fm;
char[] chars = swctx.chars;
int wid = 0;
Rectangle r = null;
do {
r = null;
int dx = fm.charsWidth(chars, 0, chars.length);
int dy = fm.getAscent() + fm.getDescent() + fm.getLeading();
int x = 0;
int y = -fm.getAscent();
r = new Rectangle(x, y, dx, dy);
} while (--numReps >= 0);
}
}
public static class FontCanDisplay extends TextMeasureTests {
public FontCanDisplay() {
super(measuretestroot, "fontcandisplay", "Font canDisplay(char)");
}
public void runTest(Object ctx, int numReps) {
Font font = ((TextContext)ctx).font;
boolean b = false;
do {
for (int i = 0; i < 0x10000; i += 0x64) {
b ^= font.canDisplay((char)i);
}
} while (--numReps >= 0);
}
}
public static class GVContext extends G2DContext {
GlyphVector gv;
public void init(TestEnvironment env, Result results) {
super.init(env, results);
int flags = Font.LAYOUT_LEFT_TO_RIGHT;
if (Bidi.requiresBidi(chars, 0, chars.length)) { // assume rtl
flags = Font.LAYOUT_RIGHT_TO_LEFT;
}
gv = font.layoutGlyphVector(frc, chars, 0, chars.length, flags);
// gv options
}
}
public static abstract class GVMeasureTest extends TextMeasureTests {
protected GVMeasureTest(Group parent, String nodeName, String description) {
super(parent, nodeName, description);
}
public Context createContext() {
return new GVContext();
}
}
public static class GVWidth extends GVMeasureTest {
public GVWidth() {
super(measuretestroot, "gvWidth", "Measuring GV Width");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
double wid = 0;
do {
wid += gv.getGlyphPosition(gv.getNumGlyphs()).getX();
} while (--numReps >= 0);
}
}
public static class GVLogicalBounds extends GVMeasureTest {
public GVLogicalBounds() {
super(measuretestroot, "gvLogicalBounds", "Measuring GV Logical Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getLogicalBounds();
} while (--numReps >= 0);
}
}
public static class GVVisualBounds extends GVMeasureTest {
public GVVisualBounds() {
super(measuretestroot, "gvVisualBounds", "Measuring GV Visual Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getVisualBounds();
} while (--numReps >= 0);
}
}
public static class GVPixelBounds extends GVMeasureTest {
public GVPixelBounds() {
super(measuretestroot, "gvPixelBounds", "Measuring GV Pixel Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
r = gv.getPixelBounds(null, 0, 0); // !!! add opt to provide different frc?
} while (--numReps >= 0);
}
}
public static class GVOutline extends GVMeasureTest {
public GVOutline() {
super(measuretestroot, "gvOutline", "Getting GV Outline");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Shape s;
do {
s = gv.getOutline();
} while (--numReps >= 0);
}
}
public static class GVGlyphLogicalBounds extends GVMeasureTest {
public GVGlyphLogicalBounds() {
super(measuretestroot, "gvGlyphLogicalBounds", "Measuring GV Glyph Logical Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Shape s;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
s = gv.getGlyphLogicalBounds(i);
}
} while (--numReps >= 0);
}
}
public static class GVGlyphVisualBounds extends GVMeasureTest {
public GVGlyphVisualBounds() {
super(measuretestroot, "gvGlyphVisualBounds", "Measuring GV Glyph Visual Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Shape s;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
s = gv.getGlyphVisualBounds(i);
}
} while (--numReps >= 0);
}
}
public static class GVGlyphPixelBounds extends GVMeasureTest {
public GVGlyphPixelBounds() {
super(measuretestroot, "gvGlyphPixelBounds", "Measuring GV Glyph Pixel Bounds");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Rectangle2D r;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
r = gv.getGlyphPixelBounds(i, null, 0, 0); // !!! add opt to provide different frc?
}
} while (--numReps >= 0);
}
}
public static class GVGlyphOutline extends GVMeasureTest {
public GVGlyphOutline() {
super(measuretestroot, "gvGlyphOutline", "Getting GV Glyph Outline");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
Shape s;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
s = gv.getGlyphOutline(i);
}
} while (--numReps >= 0);
}
}
public static class GVGlyphTransform extends GVMeasureTest {
public GVGlyphTransform() {
super(measuretestroot, "gvGlyphTransform", "Getting GV Glyph Transform");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
AffineTransform tx;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
tx = gv.getGlyphTransform(i);
}
} while (--numReps >= 0);
}
}
public static class GVGlyphMetrics extends GVMeasureTest {
public GVGlyphMetrics() {
super(measuretestroot, "gvGlyphMetrics", "Getting GV Glyph Metrics");
}
public void runTest(Object ctx, int numReps) {
GVContext gvctx = (GVContext)ctx;
GlyphVector gv = gvctx.gv;
GlyphMetrics gm;
do {
for (int i = 0, e = gv.getNumGlyphs(); i < e; ++i) {
gm = gv.getGlyphMetrics(i);
}
} while (--numReps >= 0);
}
}
public static class TLContext extends G2DContext {
TextLayout tl;
public void init(TestEnvironment env, Result results) {
super.init(env, results);
// need more tl options here
tl = new TextLayout(text, font, frc);
}
}
public static abstract class TLMeasureTest extends TextMeasureTests {
protected TLMeasureTest(Group parent, String nodeName, String description) {
super(parent, nodeName, description);
}
public Context createContext() {
return new TLContext();
}
}
public static class TLAdvance extends TLMeasureTest {
public TLAdvance() {
super(measuretestroot, "tlAdvance", "Measuring TL advance");
}
public void runTest(Object ctx, int numReps) {
TLContext tlctx = (TLContext)ctx;
TextLayout tl = tlctx.tl;
double wid = 0;
do {
wid += tl.getAdvance();
} while (--numReps >= 0);
}
}
public static class TLAscent extends TLMeasureTest {
public TLAscent() {
super(measuretestroot, "tlAscent", "Measuring TL ascent");
}
public void runTest(Object ctx, int numReps) {
TLContext tlctx = (TLContext)ctx;
TextLayout tl = tlctx.tl;
float ht = 0;
do {
ht += tl.getAscent();
} while (--numReps >= 0);
}
}
public static class TLBounds extends TLMeasureTest {
public TLBounds() {
super(measuretestroot, "tlBounds", "Measuring TL advance");
}
public void runTest(Object ctx, int numReps) {
TLContext tlctx = (TLContext)ctx;
TextLayout tl = tlctx.tl;
Rectangle2D r;
do {
r = tl.getBounds();
} while (--numReps >= 0);
}
}
static class TLExContext extends TLContext {
TextHitInfo[] hits;
Rectangle2D lb;
public void init(TestEnvironment env, Result results) {
super.init(env, results);
ArrayList list = new ArrayList(text.length() * 2 + 2);
TextHitInfo hit = TextHitInfo.trailing(-1);
do {
list.add(hit);
hit = tl.getNextRightHit(hit);
} while (hit != null);
hits = (TextHitInfo[])list.toArray(new TextHitInfo[list.size()]);
lb = tl.getBounds();
lb.setRect(lb.getMinX() - 10, lb.getMinY(), lb.getWidth() + 20, lb.getHeight());
}
}
public static abstract class TLExtendedMeasureTest extends TLMeasureTest {
protected TLExtendedMeasureTest(Group parent, String nodeName, String description) {
super(parent, nodeName, description);
}
public Context createContext() {
return new TLExContext();
}
}
public static class TLGetCaretInfo extends TLExtendedMeasureTest {
public TLGetCaretInfo() {
super(measuretestroot, "tlGetCaretInfo", "Measuring TL caret info");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
TextHitInfo[] hits = tlctx.hits;
do {
for (int i = 0; i < hits.length; ++i) {
tl.getCaretInfo(hits[i]);
}
} while (--numReps >= 0);
}
}
public static class TLGetNextHit extends TLExtendedMeasureTest {
public TLGetNextHit() {
super(measuretestroot, "tlGetNextHit", "Measuring TL getNextRight/LeftHit");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
TextHitInfo[] hits = tlctx.hits;
TextHitInfo hit;
do {
for (int i = 0; i < hits.length; ++i) {
hit = tl.getNextLeftHit(hits[i]);
}
} while (--numReps >= 0);
}
}
public static class TLGetCaretShape extends TLExtendedMeasureTest {
public TLGetCaretShape() {
super(measuretestroot, "tlGetCaretShape", "Measuring TL getCaretShape");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
TextHitInfo[] hits = tlctx.hits;
Shape s;
do {
for (int i = 0; i < hits.length; ++i) {
s = tl.getCaretShape(hits[i]);
}
} while (--numReps >= 0);
}
}
public static class TLGetLogicalHighlightShape extends TLExtendedMeasureTest {
public TLGetLogicalHighlightShape() {
super(measuretestroot, "tlGetLogicalHighlightShape", "Measuring TL getLogicalHighlightShape");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
int len = tlctx.text.length();
Rectangle2D lb = tlctx.lb;
Shape s;
if (len < 3) {
do {
s = tl.getLogicalHighlightShape(0, len, lb);
} while (--numReps >= 0);
} else {
do {
for (int i = 3; i < len; ++i) {
s = tl.getLogicalHighlightShape(i-3, i, lb);
}
} while (--numReps >= 0);
}
}
}
public static class TLGetVisualHighlightShape extends TLExtendedMeasureTest {
public TLGetVisualHighlightShape() {
super(measuretestroot, "tlGetVisualHighlightShape", "Measuring TL getVisualHighlightShape");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
TextHitInfo[] hits = tlctx.hits;
Rectangle2D lb = tlctx.lb;
Shape s;
if (hits.length < 3) {
do {
s = tl.getVisualHighlightShape(hits[0], hits[hits.length - 1], lb);
} while (--numReps >= 0);
} else {
do {
for (int i = 3; i < hits.length; ++i) {
s = tl.getVisualHighlightShape(hits[i-3], hits[i], lb);
}
} while (--numReps >= 0);
}
}
}
public static class TLHitTest extends TLExtendedMeasureTest {
public TLHitTest() {
super(measuretestroot, "tlHitTest", "Measuring TL hitTest");
}
public void runTest(Object ctx, int numReps) {
TLExContext tlctx = (TLExContext)ctx;
TextLayout tl = tlctx.tl;
int numhits = tlctx.hits.length;
Rectangle2D lb = tlctx.lb;
TextHitInfo hit;
for (int i = 0; i <= numhits; ++i) {
float x = (float)(lb.getMinX() + lb.getWidth() * i / numhits);
float y = (float)(lb.getMinY() + lb.getHeight() * i / numhits);
hit = tl.hitTestChar(x, y, lb);
}
}
}
public static class TLOutline extends TLMeasureTest {
public TLOutline() {
super(measuretestroot, "tlOutline", "Measuring TL outline");
}
public void runTest(Object ctx, int numReps) {
TLContext tlctx = (TLContext)ctx;
TextLayout tl = tlctx.tl;
Shape s;
do {
s = tl.getOutline(null);
} while (--numReps >= 0);
}
}
}