| /* |
| * Copyright (c) 2003, 2010, 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. |
| */ |
| |
| /* |
| * This source code is provided to illustrate the usage of a given feature |
| * or technique and has been deliberately simplified. Additional steps |
| * required for a production-quality application, such as security checks, |
| * input validation and proper error handling, might not be present in |
| * this sample code. |
| */ |
| |
| |
| /* |
| * (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.Color; |
| import java.awt.Font; |
| import java.awt.Graphics; |
| import java.awt.Graphics2D; |
| import java.awt.GraphicsEnvironment; |
| import java.awt.RenderingHints; |
| import java.awt.font.NumericShaper; |
| import java.awt.font.TextAttribute; |
| import java.awt.font.FontRenderContext; |
| import java.awt.geom.AffineTransform; |
| import java.io.InputStream; |
| import java.io.BufferedReader; |
| import java.io.InputStreamReader; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import javax.swing.JComponent; |
| |
| import j2dbench.Destinations; |
| import j2dbench.Group; |
| import j2dbench.Node; |
| import j2dbench.Option; |
| import j2dbench.Option.ObjectList; |
| import j2dbench.Result; |
| import j2dbench.Test; |
| import j2dbench.TestEnvironment; |
| |
| public abstract class TextTests extends Test { |
| public static boolean hasGraphics2D; |
| |
| static { |
| try { |
| hasGraphics2D = (Graphics2D.class != null); |
| } catch (NoClassDefFoundError e) { |
| } |
| } |
| |
| // core data |
| static final int[] tlengths = { |
| 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 |
| }; |
| |
| static final String[] tscripts = { |
| // german, vietnamese, surrogate, dingbats |
| "english", "arabic", "greek", "hebrew", "hindi", "japanese", "korean", "thai", |
| "english-arabic", "english-greek", "english-hindi", "english-arabic-hindi" |
| }; |
| |
| static final float[] fsizes = { |
| 1f, 6f, 8f, 10f, 12f, 12.5f, 13f, 13.5f, 16f, 20f, 36f, 72f, 128f |
| }; |
| |
| static final float[] fintsizes = { |
| 1f, 6f, 8f, 10f, 12f, 13f, 16f, 20f, 36f, 72f, 128f |
| }; |
| |
| // utilties |
| static Float[] floatObjectList(float[] input) { |
| Float[] result = new Float[input.length]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = new Float(input[i]); |
| } |
| return result; |
| } |
| |
| static String[] floatStringList(float[] input) { |
| return floatStringList("", input, ""); |
| } |
| |
| static String[] floatStringList(float[] input, String sfx) { |
| return floatStringList("", input, sfx); |
| } |
| |
| static String[] floatStringList(String pfx, float[] input, String sfx) { |
| String[] result = new String[input.length]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = pfx + input[i] + sfx; |
| } |
| return result; |
| } |
| |
| static String[] intStringList(int[] input) { |
| return intStringList("", input, ""); |
| } |
| |
| static String[] intStringList(int[] input, String sfx) { |
| return intStringList("", input, sfx); |
| } |
| |
| static String[] intStringList(String pfx, int[] input, String sfx) { |
| String[] result = new String[input.length]; |
| for (int i = 0; i < result.length; ++i) { |
| result[i] = pfx + input[i] + sfx; |
| } |
| return result; |
| } |
| |
| static final String[] txNames; |
| static final String[] txDescNames; |
| static final AffineTransform[] txList; |
| static final Map[] maps; |
| static { |
| AffineTransform identity = new AffineTransform(); |
| AffineTransform sm_scale = AffineTransform.getScaleInstance(.5, .5); |
| AffineTransform lg_scale = AffineTransform.getScaleInstance(2, 2); |
| AffineTransform wide = AffineTransform.getScaleInstance(2, .8); |
| AffineTransform tall = AffineTransform.getScaleInstance(.8, 2); |
| AffineTransform x_trans = AffineTransform.getTranslateInstance(50, 0); |
| AffineTransform y_trans = AffineTransform.getTranslateInstance(0, -30); |
| AffineTransform xy_trans = AffineTransform.getTranslateInstance(50, -30); |
| AffineTransform sm_rot = AffineTransform.getRotateInstance(Math.PI / 3); |
| AffineTransform lg_rot = AffineTransform.getRotateInstance(Math.PI * 4 / 3); |
| AffineTransform pi2_rot = AffineTransform.getRotateInstance(Math.PI / 2); |
| AffineTransform x_shear = AffineTransform.getShearInstance(.4, 0); |
| AffineTransform y_shear = AffineTransform.getShearInstance(0, -.4); |
| AffineTransform xy_shear = AffineTransform.getShearInstance(.3, .3); |
| AffineTransform x_flip = AffineTransform.getScaleInstance(-1, 1); |
| AffineTransform y_flip = AffineTransform.getScaleInstance(1, -1); |
| AffineTransform xy_flip = AffineTransform.getScaleInstance(-1, -1); |
| AffineTransform w_rot = AffineTransform.getRotateInstance(Math.PI / 3); |
| w_rot.scale(2, .8); |
| AffineTransform w_y_shear = AffineTransform.getShearInstance(0, -.4); |
| w_y_shear.scale(2, .8); |
| AffineTransform w_r_trans = AffineTransform.getTranslateInstance(3, -7); |
| w_r_trans.rotate(Math.PI / 3); |
| w_r_trans.scale(2, .8); |
| AffineTransform w_t_rot = AffineTransform.getRotateInstance(Math.PI / 3); |
| w_t_rot.translate(3, -7); |
| w_t_rot.scale(2, .8); |
| AffineTransform w_y_s_r_trans = AffineTransform.getTranslateInstance(3, -7); |
| w_y_s_r_trans.rotate(Math.PI / 3); |
| w_y_s_r_trans.shear(0, -.4); |
| w_y_s_r_trans.scale(2, .8); |
| |
| txNames = new String[] { |
| "ident", |
| "smsc", "lgsc", "wide", "tall", |
| "xtrn", "ytrn", "xytrn", |
| "srot", "lrot", "hrot", |
| "xshr", "yshr", "xyshr", |
| "flx", "fly", "flxy", |
| "wr", "wys", "wrt", |
| "wtr", "wysrt" |
| }; |
| |
| txDescNames = new String[] { |
| "Identity", |
| "Sm Scale", "Lg Scale", "Wide", "Tall", |
| "X Trans", "Y Trans", "XY Trans", |
| "Sm Rot", "Lg Rot", "PI/2 Rot", |
| "X Shear", "Y Shear", "XY Shear", |
| "FlipX", "FlipY", "FlipXY", |
| "WRot", "WYShear", "WRTrans", |
| "WTRot", "WYSRTrans" |
| }; |
| |
| txList = new AffineTransform[] { |
| identity, |
| sm_scale, lg_scale, wide, tall, |
| x_trans, y_trans, xy_trans, |
| sm_rot, lg_rot, pi2_rot, |
| x_shear, y_shear, xy_shear, |
| x_flip, y_flip, xy_flip, |
| w_rot, w_y_shear, w_r_trans, |
| w_t_rot, w_y_s_r_trans, |
| }; |
| |
| // maps |
| HashMap fontMap = new HashMap(); |
| fontMap.put(TextAttribute.FONT, new Font("Dialog", Font.ITALIC, 18)); |
| |
| HashMap emptyMap = new HashMap(); |
| |
| HashMap simpleMap = new HashMap(); |
| simpleMap.put(TextAttribute.FAMILY, "Lucida Sans"); |
| simpleMap.put(TextAttribute.SIZE, new Float(14)); |
| simpleMap.put(TextAttribute.FOREGROUND, Color.blue); |
| |
| HashMap complexMap = new HashMap(); |
| complexMap.put(TextAttribute.FAMILY, "Serif"); |
| complexMap.put(TextAttribute.TRANSFORM, tall); |
| complexMap.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); |
| complexMap.put(TextAttribute.RUN_DIRECTION, |
| TextAttribute.RUN_DIRECTION_RTL); |
| try { |
| complexMap.put(TextAttribute.NUMERIC_SHAPING, |
| NumericShaper.getContextualShaper(NumericShaper.ALL_RANGES)); |
| } catch (NoSuchFieldError e) { |
| } |
| |
| maps = new Map[] { |
| fontMap, |
| emptyMap, |
| simpleMap, |
| complexMap, |
| }; |
| } |
| |
| static String getString(Object key, int len) { |
| String keyString = key.toString(); |
| String[] strings = new String[4]; // leave room for index == 3 to return null |
| int span = Math.min(32, len); |
| int n = keyString.indexOf('-'); |
| if (n == -1) { |
| strings[0] = getSimpleString(keyString); |
| } else { |
| strings[0] = getSimpleString(keyString.substring(0, n)); |
| int m = keyString.indexOf('-', n+1); |
| if (m == -1) { |
| strings[1] = getSimpleString(keyString.substring(n+1)); |
| // 2 to 1 ratio, short spans between 1 and 16 chars long |
| span = Math.max(1, Math.min(16, len / 3)); |
| } else { |
| strings[1] = getSimpleString(keyString.substring(n+1, m)); |
| strings[2] = getSimpleString(keyString.substring(m+1)); |
| span = Math.max(1, Math.min(16, len / 4)); |
| } |
| } |
| String s = ""; |
| int pos = 0; |
| int strx = 0; |
| while (s.length() < len) { |
| String src; |
| if (strings[strx] == null) { |
| src = strings[0]; // use strings[0] twice for each other string |
| strx = 0; |
| } else { |
| src = strings[strx++]; |
| } |
| if (pos + span > src.length()) { |
| pos = 0; // we know all strings are longer than span |
| } |
| s += src.substring(pos, pos+span); |
| pos += span; |
| } |
| return s.substring(0, len); |
| } |
| |
| |
| static HashMap strcache = new HashMap(tscripts.length); |
| private static String getSimpleString(Object key) { |
| String s = (String)strcache.get(key); |
| if (s == null) { |
| String fname = "textdata/" + key + ".ut8.txt"; |
| try { |
| InputStream is = TextTests.class.getResourceAsStream(fname); |
| if (is == null) { |
| throw new IOException("Can't load resource " + fname); |
| } |
| BufferedReader r = |
| new BufferedReader(new InputStreamReader(is, "utf8")); |
| StringBuffer buf = new StringBuffer(r.readLine()); |
| while (null != (s = r.readLine())) { |
| buf.append(" "); |
| buf.append(s); |
| } |
| s = buf.toString(); |
| if (s.charAt(0) == '\ufeff') { |
| s = s.substring(1); |
| } |
| } |
| catch (IOException e) { |
| s = "This is a dummy ascii string because " + |
| fname + " was not found."; |
| } |
| strcache.put(key, s); |
| } |
| return s; |
| } |
| |
| static Group textroot; |
| static Group txoptroot; |
| static Group txoptdataroot; |
| static Group txoptfontroot; |
| static Group txoptgraphicsroot; |
| static Group advoptsroot; |
| |
| static Option tlengthList; |
| static Option tscriptList; |
| static Option fnameList; |
| static Option fstyleList; |
| static Option fsizeList; |
| static Option ftxList; |
| static Option taaList; |
| static Option tfmTog; |
| static Option gaaTog; |
| static Option gtxList; |
| static Option gvstyList; |
| static Option tlrunList; |
| static Option tlmapList; |
| |
| // core is textlength, text script, font name/style/size/tx, frc |
| |
| // drawing |
| // drawString, drawChars, drawBytes, drawGlyphVector, TextLayout.draw, drawAttributedString |
| // length of text |
| // 1, 2, 4, 8, 16, 32, 64, 128, 256 chars |
| // script of text |
| // simple: latin-1, japanese, arabic, hebrew, indic, thai, surrogate, dingbats |
| // mixed: latin-1 + x (1, 2, 3, 4 pairs) |
| // font of text |
| // name (composite, not), style, size (6, 12, 18, 24, 30, 36, 42, 48, 54, 60), transform (full set) |
| // text rendering hints |
| // aa, fm, gaa |
| // graphics transform (full set) |
| // (gv) gtx, gpos |
| // (tl, as) num style runs |
| // |
| // querying/measuring |
| // ascent/descent/leading |
| // advance |
| // (gv) lb, vb, pb, glb, gvb, glb, gp, gjust, gmet, gtx |
| // (tl) bounds, charpos, cursor |
| // |
| // construction/layout |
| // (bidi) no controls, controls, styles |
| // (gv) createGV, layoutGV |
| // (tl) TL constructors |
| // (tm) line break |
| |
| public static void init() { |
| textroot = new Group("text", "Text Benchmarks"); |
| textroot.setTabbed(); |
| |
| txoptroot = new Group(textroot, "opts", "Text Options"); |
| txoptroot.setTabbed(); |
| |
| txoptdataroot = new Group(txoptroot, "data", "Text Data"); |
| |
| tlengthList = new Option.IntList(txoptdataroot, "tlength", |
| "Text Length", |
| tlengths, |
| intStringList(tlengths), |
| intStringList(tlengths, " chars"), |
| 0x10); |
| ((Option.ObjectList) tlengthList).setNumRows(5); |
| |
| tscriptList = new Option.ObjectList(txoptdataroot, "tscript", |
| "Text Script", |
| tscripts, |
| tscripts, |
| tscripts, |
| tscripts, |
| 0x1); |
| ((Option.ObjectList) tscriptList).setNumRows(4); |
| |
| txoptfontroot = new Group(txoptroot, "font", "Font"); |
| |
| fnameList = new FontOption(txoptfontroot, "fname", "Family Name"); |
| |
| fstyleList = new Option.IntList(txoptfontroot, "fstyle", |
| "Style", |
| new int[] { |
| Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD + Font.ITALIC, |
| }, |
| new String[] { |
| "plain", "bold", "italic", "bolditalic", |
| }, |
| new String[] { |
| "Plain", "Bold", "Italic", "Bold Italic", |
| }, |
| 0x1); |
| |
| float[] fsl = hasGraphics2D ? fsizes : fintsizes; |
| fsizeList = new Option.ObjectList(txoptfontroot, "fsize", |
| "Size", |
| floatStringList(fsl), |
| floatObjectList(fsl), |
| floatStringList(fsl), |
| floatStringList(fsl, "pt"), |
| 0x40); |
| ((Option.ObjectList) fsizeList).setNumRows(5); |
| |
| if (hasGraphics2D) { |
| ftxList = new Option.ObjectList(txoptfontroot, "ftx", |
| "Transform", |
| txDescNames, |
| txList, |
| txNames, |
| txDescNames, |
| 0x1); |
| ((Option.ObjectList) ftxList).setNumRows(6); |
| |
| txoptgraphicsroot = new Group(txoptroot, "graphics", "Graphics"); |
| |
| String[] taaNames; |
| Object[] taaHints; |
| try { |
| taaNames = new String[] { |
| "Off", "On", |
| "LCD_HRGB", "LCD_HBGR", "LCD_VRGB", "LCD_VBGR" |
| }; |
| taaHints = new Object[] { |
| RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_ON, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR, |
| }; |
| } catch (NoSuchFieldError e) { |
| taaNames = new String[] { |
| "Off", "On" |
| }; |
| taaHints = new Object[] { |
| RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, |
| RenderingHints.VALUE_TEXT_ANTIALIAS_ON, |
| }; |
| } |
| taaList = new Option.ObjectList(txoptgraphicsroot, "textaa", |
| "Text AntiAlias", |
| taaNames, taaHints, |
| taaNames, taaNames, |
| 0x1); |
| ((Option.ObjectList) taaList).setNumRows(6); |
| // add special TextAAOpt for backwards compatibility with |
| // older options files |
| new TextAAOpt(); |
| |
| tfmTog = new Option.Toggle(txoptgraphicsroot, "tfm", |
| "Fractional Metrics", Option.Toggle.Off); |
| gaaTog = new Option.Toggle(txoptgraphicsroot, "gaa", |
| "Graphics AntiAlias", Option.Toggle.Off); |
| |
| gtxList = new Option.ObjectList(txoptgraphicsroot, "gtx", |
| "Transform", |
| txDescNames, |
| txList, |
| txNames, |
| txDescNames, |
| 0x1); |
| ((Option.ObjectList) gtxList).setNumRows(6); |
| |
| advoptsroot = new Group(txoptroot, "advopts", "Advanced Options"); |
| gvstyList = new Option.IntList(advoptsroot, "gvstyle", "Style", |
| new int[] { 0, 1, 2, 3 }, |
| new String[] { "std", "wave", "twist", "circle" }, |
| new String[] { "Standard", |
| "Positions adjusted", |
| "Glyph angles adjusted", |
| "Layout to circle" |
| }, |
| 0x1); |
| |
| int[] runs = { 1, 2, 4, 8 }; |
| tlrunList = new Option.IntList(advoptsroot, "tlruns", "Attribute Runs", |
| runs, |
| intStringList(runs), |
| intStringList(runs, " runs"), |
| 0x1); |
| |
| String[] tlmapnames = new String[] { "FONT", "Empty", "Simple", "Complex" }; |
| tlmapList = new Option.ObjectList(advoptsroot, "maptype", "Map", |
| tlmapnames, |
| maps, |
| new String[] { "font", "empty", "simple", "complex" }, |
| tlmapnames, |
| 0x1); |
| } |
| } |
| |
| /** |
| * This "virtual Node" implementation is here to maintain backward |
| * compatibility with older J2DBench releases, specifically those |
| * options files that were created before we added LCD-optimized text |
| * hints in JDK 6. This class will translate the text antialias settings |
| * from the old "taa" On/Off/Both choice into the new expanded version. |
| */ |
| private static class TextAAOpt extends Node { |
| public TextAAOpt() { |
| super(txoptgraphicsroot, "taa", "Text AntiAlias"); |
| } |
| |
| public JComponent getJComponent() { |
| return null; |
| } |
| |
| public void restoreDefault() { |
| // no-op |
| } |
| |
| public void write(PrintWriter pw) { |
| // no-op (the old "taa" choice will be saved as part of the |
| // new "textaa" option) |
| } |
| |
| public String setOption(String key, String value) { |
| String opts; |
| if (value.equals("On")) { |
| opts = "On"; |
| } else if (value.equals("Off")) { |
| opts = "Off"; |
| } else if (value.equals("Both")) { |
| opts = "On,Off"; |
| } else { |
| return "Bad value"; |
| } |
| return ((Option.ObjectList)taaList).setValueFromString(opts); |
| } |
| } |
| |
| public static class Context { |
| void init(TestEnvironment env, Result result) {} |
| void cleanup(TestEnvironment env) {} |
| } |
| |
| public static class TextContext extends Context { |
| Graphics graphics; |
| String text; |
| char[] chars; |
| Font font; |
| |
| public void init(TestEnvironment env, Result result) { |
| // graphics |
| graphics = env.getGraphics(); |
| |
| // text |
| String sname = (String)env.getModifier(tscriptList); |
| int slen = env.getIntValue(tlengthList); |
| text = getString(sname, slen); |
| |
| // chars |
| chars = text.toCharArray(); |
| |
| // font |
| String fname = (String)env.getModifier(fnameList); |
| if ("Physical".equals(fname)) { |
| fname = physicalFontNameFor(sname, slen, text); |
| } |
| int fstyle = env.getIntValue(fstyleList); |
| float fsize = ((Float)env.getModifier(fsizeList)).floatValue(); |
| AffineTransform ftx = (AffineTransform)env.getModifier(ftxList); |
| font = new Font(fname, fstyle, (int)fsize); |
| if (hasGraphics2D) { |
| if (fsize != Math.floor(fsize)) { |
| font = font.deriveFont(fsize); |
| } |
| if (!ftx.isIdentity()) { |
| font = font.deriveFont(ftx); |
| } |
| } |
| |
| // graphics |
| if (hasGraphics2D) { |
| Graphics2D g2d = (Graphics2D)graphics; |
| g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, |
| env.getModifier(taaList)); |
| g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, |
| env.isEnabled(tfmTog) |
| ? RenderingHints.VALUE_FRACTIONALMETRICS_ON |
| : RenderingHints.VALUE_FRACTIONALMETRICS_OFF); |
| g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, |
| env.isEnabled(gaaTog) |
| ? RenderingHints.VALUE_ANTIALIAS_ON |
| : RenderingHints.VALUE_ANTIALIAS_OFF); |
| g2d.transform((AffineTransform)env.getModifier(gtxList)); |
| } |
| |
| // set result |
| result.setUnits(text.length()); |
| result.setUnitName("char"); |
| } |
| |
| public void cleanup(TestEnvironment env) { |
| graphics.dispose(); |
| graphics = null; |
| } |
| } |
| |
| public static class G2DContext extends TextContext { |
| Graphics2D g2d; |
| FontRenderContext frc; |
| |
| public void init(TestEnvironment env, Result results){ |
| super.init(env, results); |
| g2d = (Graphics2D)graphics; |
| frc = g2d.getFontRenderContext(); |
| } |
| } |
| |
| public TextTests(Group parent, String nodeName, String description) { |
| super(parent, nodeName, description); |
| addDependency(Destinations.destroot); |
| addDependencies(txoptroot, true); |
| } |
| |
| public Context createContext() { |
| return new TextContext(); |
| } |
| |
| public Object initTest(TestEnvironment env, Result result) { |
| Context ctx = createContext(); |
| ctx.init(env, result); |
| return ctx; |
| } |
| |
| public void cleanupTest(TestEnvironment env, Object ctx) { |
| ((Context)ctx).cleanup(env); |
| } |
| |
| static Map physicalMap = new HashMap(); |
| public static String physicalFontNameFor(String textname, int textlen, String text) { |
| Map lenMap = (Map)physicalMap.get(textname); |
| if (lenMap == null) { |
| lenMap = new HashMap(); |
| physicalMap.put(textname, lenMap); |
| } |
| Integer key = new Integer(textlen); |
| Font textfont = (Font)lenMap.get(key); |
| if (textfont == null) { |
| Font[] fontsToTry = null; |
| if (lenMap.isEmpty()) { |
| fontsToTry = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); |
| } else { |
| Set fontset = new HashSet(); |
| java.util.Iterator iter = lenMap.entrySet().iterator(); |
| while (iter.hasNext()) { |
| Map.Entry e = (Map.Entry)iter.next(); |
| fontset.add(e.getValue()); |
| } |
| fontsToTry = (Font[])fontset.toArray(new Font[fontset.size()]); |
| } |
| |
| Font bestFont = null; |
| int bestCount = 0; |
| for (int i = 0; i < fontsToTry.length; ++i) { |
| Font font = fontsToTry[i]; |
| int count = 0; |
| for (int j = 0, limit = text.length(); j < limit; ++j) { |
| if (font.canDisplay(text.charAt(j))) { |
| ++count; |
| } |
| } |
| if (count > bestCount) { |
| bestFont = font; |
| bestCount = count; |
| } |
| } |
| |
| textfont = bestFont; |
| lenMap.put(key, textfont); |
| } |
| return textfont.getName(); |
| } |
| |
| static class FontOption extends ObjectList { |
| static String[] optionnames = { |
| "default", "serif", "lucida", "physical" |
| }; |
| static String[] descnames = { |
| "Default", "Serif", "Lucida Sans", "Physical" |
| }; |
| |
| public FontOption(Group parent, String nodeName, String description) { |
| super(parent, nodeName, description, |
| optionnames, descnames, optionnames, descnames, 0xa); |
| } |
| |
| public String getValString(Object value) { |
| return value.toString(); |
| } |
| |
| public String getAbbreviatedModifierDescription(Object value) { |
| return value.toString(); |
| } |
| } |
| } |
| |