| /* |
| * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /** |
| * Copyright (C) 2013-2014 IBM Corporation and Others. All Rights Reserved. |
| */ |
| |
| import java.awt.Color; |
| import java.awt.Composite; |
| import java.awt.Font; |
| import java.awt.FontFormatException; |
| import java.awt.FontMetrics; |
| import java.awt.Graphics; |
| import java.awt.Graphics2D; |
| import java.awt.GraphicsConfiguration; |
| import java.awt.Image; |
| import java.awt.Paint; |
| import java.awt.Rectangle; |
| import java.awt.RenderingHints; |
| import java.awt.RenderingHints.Key; |
| import java.awt.Shape; |
| import java.awt.Stroke; |
| import java.awt.font.FontRenderContext; |
| import java.awt.font.GlyphVector; |
| import java.awt.font.TextLayout; |
| import java.awt.geom.AffineTransform; |
| import java.awt.image.BufferedImage; |
| import java.awt.image.BufferedImageOp; |
| import java.awt.image.ImageObserver; |
| import java.awt.image.RenderedImage; |
| import java.awt.image.renderable.RenderableImage; |
| import java.io.BufferedInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.text.AttributedCharacterIterator; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.MissingResourceException; |
| import java.util.TreeMap; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * This test runs against a test XML file. It opens the fonts and attempts |
| * to shape and layout glyphs. |
| * Note that the test is highly environment dependent- you must have |
| * the same versions of the same fonts available or the test will fail. |
| * |
| * It is similar to letest which is part of ICU. |
| * For reference, here are some reference items: |
| * ICU's test file: |
| * http://source.icu-project.org/repos/icu/icu/trunk/source/test/testdata/letest.xml |
| * ICU's readme for the similar test: |
| * http://source.icu-project.org/repos/icu/icu/trunk/source/test/letest/readme.html |
| * |
| * @bug 8054203 |
| * @test |
| * @summary manual test of layout engine behavior. Takes an XML control file. |
| * @compile TestLayoutVsICU.java |
| * @author srl |
| * @run main/manual |
| */ |
| public class TestLayoutVsICU { |
| |
| public static boolean OPT_DRAW = false; |
| public static boolean OPT_VERBOSE = false; |
| public static boolean OPT_FAILMISSING = false; |
| public static boolean OPT_NOTHROW= false; // if true - don't stop on failure |
| |
| public static int docs = 0; // # docs processed |
| public static int skipped = 0; // cases skipped due to bad font |
| public static int total = 0; // cases processed |
| public static int bad = 0; // cases with errs |
| |
| public static final String XML_LAYOUT_TESTS = "layout-tests"; // top level |
| public static final String XML_TEST_CASE = "test-case"; |
| public static final String XML_TEST_FONT = "test-font"; |
| public static final String XML_TEST_TEXT = "test-text"; |
| public static final String XML_RESULT_GLYPHS = "result-glyphs"; |
| public static final String XML_ID = "id"; |
| public static final String XML_SCRIPT = "script"; |
| public static final String XML_NAME = "name"; |
| public static final String XML_VERSION = "version"; |
| public static final String XML_CHECKSUM = "checksum"; |
| public static final String XML_RESULT_INDICES = "result-indices"; |
| public static final String XML_RESULT_POSITIONS = "result-positions"; |
| |
| /** |
| * @param args |
| * @throws IOException |
| * @throws SAXException |
| * @throws ParserConfigurationException |
| */ |
| public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { |
| System.out.println("Java " + System.getProperty("java.version") + " from " + System.getProperty("java.vendor")); |
| TestLayoutVsICU tlvi = null; |
| for(String arg : args) { |
| if(arg.equals("-d")) { |
| OPT_DRAW = true; |
| } else if(arg.equals("-n")) { |
| OPT_NOTHROW = true; |
| } else if(arg.equals("-v")) { |
| OPT_VERBOSE = true; |
| } else if(arg.equals("-f")) { |
| OPT_FAILMISSING = true; |
| } else { |
| if(tlvi == null) { |
| tlvi = new TestLayoutVsICU(); |
| } |
| try { |
| tlvi.show(arg); |
| } finally { |
| if(OPT_VERBOSE) { |
| System.out.println("# done with " + arg); |
| } |
| } |
| } |
| } |
| |
| if(tlvi == null) { |
| throw new IllegalArgumentException("No XML input. Usage: " + TestLayoutVsICU.class.getSimpleName() + " [-d][-v][-f] letest.xml ..."); |
| } else { |
| System.out.println("\n\nRESULTS:\n"); |
| System.out.println(skipped+"\tskipped due to missing font"); |
| System.out.println(total+"\ttested of which:"); |
| System.out.println(bad+"\twere bad"); |
| |
| if(bad>0) { |
| throw new InternalError("One or more failure(s)"); |
| } |
| } |
| } |
| |
| String id; |
| |
| private void show(String arg) throws ParserConfigurationException, SAXException, IOException { |
| id = "<none>"; |
| File xmlFile = new File(arg); |
| if(!xmlFile.exists()) { |
| throw new FileNotFoundException("Can't open input XML file " + arg); |
| } |
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder db = dbf.newDocumentBuilder(); |
| if(OPT_VERBOSE) { |
| System.out.println("# Parsing " + xmlFile.getAbsolutePath()); |
| } |
| Document doc = db.parse(xmlFile); |
| Element e = doc.getDocumentElement(); |
| if(!XML_LAYOUT_TESTS.equals(e.getNodeName())) { |
| throw new IllegalArgumentException("Document " + xmlFile.getAbsolutePath() + " does not have <layout-tests> as its base"); |
| } |
| |
| NodeList testCases = e.getElementsByTagName(XML_TEST_CASE); |
| for(int caseNo=0;caseNo<testCases.getLength();caseNo++) { |
| final Node testCase = testCases.item(caseNo); |
| final Map<String,String> testCaseAttrs = attrs(testCase); |
| id = testCaseAttrs.get(XML_ID); |
| final String script = testCaseAttrs.get(XML_SCRIPT); |
| String testText = null; |
| Integer[] expectGlyphs = null; |
| Integer[] expectIndices = null; |
| Map<String,String> fontAttrs = null; |
| if(OPT_VERBOSE) { |
| System.out.println("#"+caseNo+" id="+id + ", script="+script); |
| } |
| NodeList children = testCase.getChildNodes(); |
| for(int sub=0;sub<children.getLength();sub++) { |
| Node n = children.item(sub); |
| if(n.getNodeType()!=Node.ELEMENT_NODE) continue; |
| String nn = n.getNodeName(); |
| if(nn.equals(XML_TEST_FONT)) { |
| fontAttrs = attrs(n); |
| } else if(nn.equals(XML_TEST_TEXT)) { |
| testText = n.getTextContent(); |
| } else if(nn.equals(XML_RESULT_GLYPHS)) { |
| String hex = n.getTextContent(); |
| expectGlyphs = parseHexArray(hex); |
| } else if(nn.equals(XML_RESULT_INDICES)) { |
| String hex = n.getTextContent(); |
| expectIndices = parseHexArray(hex); |
| } else if(OPT_VERBOSE) { |
| System.out.println("Ignoring node " + nn); |
| } |
| } |
| if(fontAttrs == null) { |
| throw new IllegalArgumentException(id + " Missing node " + XML_TEST_FONT); |
| } |
| if(testText == null) { |
| throw new IllegalArgumentException(id + " Missing node " + XML_TEST_TEXT); |
| } |
| |
| String fontName = fontAttrs.get(XML_NAME); |
| Font f = getFont(fontName, fontAttrs); |
| if(f==null) { |
| if(OPT_FAILMISSING) { |
| throw new MissingResourceException("Missing font, abort test", Font.class.getName(), fontName); |
| } |
| System.out.println("Skipping " + id + " because font is missing: " + fontName); |
| skipped++; |
| continue; |
| } |
| FontRenderContext frc = new FontRenderContext(null, true, true); |
| TextLayout tl = new TextLayout(testText,f,frc); |
| final List<GlyphVector> glyphs = new ArrayList<GlyphVector>(); |
| Graphics2D myg2 = new Graphics2D(){ |
| |
| @Override |
| public void draw(Shape s) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public boolean drawImage(Image img, AffineTransform xform, |
| ImageObserver obs) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public void drawImage(BufferedImage img, |
| BufferedImageOp op, int x, int y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawRenderedImage(RenderedImage img, |
| AffineTransform xform) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawRenderableImage(RenderableImage img, |
| AffineTransform xform) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawString(String str, int x, int y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawString(String str, float x, float y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawString( |
| AttributedCharacterIterator iterator, int x, int y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawString( |
| AttributedCharacterIterator iterator, float x, |
| float y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawGlyphVector(GlyphVector g, float x, float y) { |
| if(x!=0.0 || y!=0.0) { |
| throw new InternalError("x,y should be 0 but got " + x+","+y); |
| } |
| //System.err.println("dGV : " + g.toString() + " @ "+x+","+y); |
| glyphs.add(g); |
| } |
| |
| @Override |
| public void fill(Shape s) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public boolean hit(Rectangle rect, Shape s, boolean onStroke) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public GraphicsConfiguration getDeviceConfiguration() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setComposite(Composite comp) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setPaint(Paint paint) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setStroke(Stroke s) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setRenderingHint(Key hintKey, Object hintValue) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public Object getRenderingHint(Key hintKey) { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setRenderingHints(Map<?, ?> hints) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void addRenderingHints(Map<?, ?> hints) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public RenderingHints getRenderingHints() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void translate(int x, int y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void translate(double tx, double ty) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void rotate(double theta) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void rotate(double theta, double x, double y) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void scale(double sx, double sy) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void shear(double shx, double shy) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void transform(AffineTransform Tx) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setTransform(AffineTransform Tx) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public AffineTransform getTransform() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Paint getPaint() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Composite getComposite() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setBackground(Color color) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public Color getBackground() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Stroke getStroke() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void clip(Shape s) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public FontRenderContext getFontRenderContext() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Graphics create() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Color getColor() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setColor(Color c) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setPaintMode() { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setXORMode(Color c1) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public Font getFont() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setFont(Font font) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public FontMetrics getFontMetrics(Font f) { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public Rectangle getClipBounds() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void clipRect(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void setClip(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public Shape getClip() { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| |
| @Override |
| public void setClip(Shape clip) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void copyArea(int x, int y, int width, int height, |
| int dx, int dy) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawLine(int x1, int y1, int x2, int y2) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void fillRect(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void clearRect(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawRoundRect(int x, int y, int width, |
| int height, int arcWidth, int arcHeight) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void fillRoundRect(int x, int y, int width, |
| int height, int arcWidth, int arcHeight) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawOval(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void fillOval(int x, int y, int width, int height) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawArc(int x, int y, int width, int height, |
| int startAngle, int arcAngle) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void fillArc(int x, int y, int width, int height, |
| int startAngle, int arcAngle) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawPolyline(int[] xPoints, int[] yPoints, |
| int nPoints) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void drawPolygon(int[] xPoints, int[] yPoints, |
| int nPoints) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void fillPolygon(int[] xPoints, int[] yPoints, |
| int nPoints) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int x, int y, |
| ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int x, int y, |
| int width, int height, ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int x, int y, |
| Color bgcolor, ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int x, int y, |
| int width, int height, Color bgcolor, |
| ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int dx1, int dy1, |
| int dx2, int dy2, int sx1, int sy1, int sx2, |
| int sy2, ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean drawImage(Image img, int dx1, int dy1, |
| int dx2, int dy2, int sx1, int sy1, int sx2, |
| int sy2, Color bgcolor, ImageObserver observer) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public void dispose() { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| }; |
| tl.draw(myg2, 0, 0); |
| if(glyphs.size() != 1) { |
| err("drew " + glyphs.size() + " times - expected 1"); |
| total++; |
| bad++; |
| continue; |
| } |
| boolean isBad = false; |
| GlyphVector gv = glyphs.get(0); |
| |
| // GLYPHS |
| int gotGlyphs[] = gv.getGlyphCodes(0, gv.getNumGlyphs(), new int[gv.getNumGlyphs()]); |
| |
| int count = Math.min(gotGlyphs.length, expectGlyphs.length); // go up to this count |
| |
| for(int i=0;i<count;i++) { |
| if(gotGlyphs[i]!=expectGlyphs[i]) { |
| err("@"+i+" - got \tglyph 0x" + Integer.toHexString(gotGlyphs[i]) + " wanted 0x" + Integer.toHexString(expectGlyphs[i])); |
| isBad=true; |
| break; |
| } |
| } |
| |
| // INDICES |
| int gotIndices[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), new int[gv.getNumGlyphs()]); |
| for(int i=0;i<count;i++) { |
| if(gotIndices[i]!=expectIndices[i]) { |
| err("@"+i+" - got \tindex 0x" + Integer.toHexString(gotGlyphs[i]) + " wanted 0x" + Integer.toHexString(expectGlyphs[i])); |
| isBad=true; |
| break; |
| } |
| } |
| |
| |
| // COUNT |
| if(gotGlyphs.length != expectGlyphs.length) { |
| System.out.println("Got " + gotGlyphs.length + " wanted " + expectGlyphs.length + " glyphs"); |
| isBad=true; |
| } else { |
| if(OPT_VERBOSE) { |
| System.out.println(">> OK: " + gotGlyphs.length + " glyphs"); |
| } |
| } |
| |
| |
| if(isBad) { |
| bad++; |
| System.out.println("* FAIL: " + id + " /\t" + fontName); |
| } else { |
| System.out.println("* OK : " + id + " /\t" + fontName); |
| } |
| total++; |
| } |
| } |
| |
| |
| private boolean verifyFont(File f, Map<String, String> fontAttrs) { |
| InputStream fis = null; |
| String fontName = fontAttrs.get(XML_NAME); |
| int count=0; |
| try { |
| fis = new BufferedInputStream(new FileInputStream(f)); |
| |
| int i = 0; |
| int r; |
| try { |
| while((r=fis.read())!=-1) { |
| i+=(int)r; |
| count++; |
| } |
| } catch (IOException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| return false; |
| } |
| if(OPT_VERBOSE) { |
| System.out.println("for " + f.getAbsolutePath() + " chks = 0x" + Integer.toHexString(i) + " size=" + count); |
| } |
| String theirStr = fontAttrs.get("rchecksum"); |
| |
| String ourStr = Integer.toHexString(i).toLowerCase(); |
| |
| if(theirStr!=null) { |
| if(theirStr.startsWith("0x")) { |
| theirStr = theirStr.substring(2).toLowerCase(); |
| } else { |
| theirStr = theirStr.toLowerCase(); |
| } |
| long theirs = Integer.parseInt(theirStr, 16); |
| if(theirs != i) { |
| err("WARNING: rchecksum for " + fontName + " was " + i + " (0x"+ourStr+") "+ " but file said " + theirs +" (0x"+theirStr+") - perhaps a different font?"); |
| return false; |
| } else { |
| if(OPT_VERBOSE) { |
| System.out.println(" rchecksum for " + fontName + " OK"); |
| } |
| return true; |
| } |
| } else { |
| //if(OPT_VERBOSE) { |
| System.err.println("WARNING: rchecksum for " + fontName + " was " + i + " (0x"+ourStr+") "+ " but rchecksum was MISSING. Old ICU data?"); |
| //} |
| } |
| } catch (FileNotFoundException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| return false; |
| } finally { |
| try { |
| fis.close(); |
| } catch (IOException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| } |
| return true; |
| } |
| |
| |
| private Integer[] parseHexArray(String hex) { |
| List<Integer> ret = new ArrayList<Integer>(); |
| String items[] = hex.split("[\\s,]"); |
| for(String i : items) { |
| if(i.isEmpty()) continue; |
| if(i.startsWith("0x")) { |
| i = i.substring(2); |
| } |
| ret.add(Integer.parseInt(i, 16)); |
| } |
| return ret.toArray(new Integer[0]); |
| } |
| |
| |
| private void err(String string) { |
| if(OPT_NOTHROW) { |
| System.out.println(id+" ERROR: " + string +" (continuing due to -n)"); |
| } else { |
| throw new InternalError(id+ ": " + string); |
| } |
| } |
| |
| |
| private Font getFont(String fontName, Map<String, String> fontAttrs) { |
| Font f; |
| if(false) |
| try { |
| f = Font.getFont(fontName); |
| if(f!=null) { |
| if(OPT_VERBOSE) { |
| System.out.println("Loaded default path to " + fontName); |
| } |
| return f; |
| } |
| } catch(Throwable t) { |
| if(OPT_VERBOSE) { |
| t.printStackTrace(); |
| System.out.println("problem loading font " + fontName + " - " + t.toString()); |
| } |
| } |
| |
| File homeDir = new File(System.getProperty("user.home")); |
| File fontDir = new File(homeDir, "fonts"); |
| File fontFile = new File(fontDir, fontName); |
| //System.out.println("## trying " + fontFile.getAbsolutePath()); |
| if(fontFile.canRead()) { |
| try { |
| if(!verifyFont(fontFile,fontAttrs)) { |
| System.out.println("Warning: failed to verify " + fontName); |
| } |
| f = Font.createFont(Font.TRUETYPE_FONT, fontFile); |
| if(f!=null & OPT_VERBOSE) { |
| System.out.println("> loaded from " + fontFile.getAbsolutePath() + " - " + f.toString()); |
| } |
| return f; |
| } catch (FontFormatException e) { |
| if(OPT_VERBOSE) { |
| e.printStackTrace(); |
| System.out.println("problem loading font " + fontName + " - " + e.toString()); |
| } |
| } catch (IOException e) { |
| if(OPT_VERBOSE) { |
| e.printStackTrace(); |
| System.out.println("problem loading font " + fontName + " - " + e.toString()); |
| } |
| } |
| } |
| return null; |
| } |
| |
| |
| private static Map<String, String> attrs(Node testCase) { |
| Map<String,String> rv = new TreeMap<String,String>(); |
| NamedNodeMap nnm = testCase.getAttributes(); |
| for(int i=0;i<nnm.getLength();i++) { |
| Node n = nnm.item(i); |
| String k = n.getNodeName(); |
| String v = n.getNodeValue(); |
| rv.put(k, v); |
| } |
| return rv; |
| } |
| } |