diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2012-04-05 16:19:19 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2012-04-05 16:19:19 +0000 |
commit | 502152b4779d4b970148a074e741754828fcc89a (patch) | |
tree | 809eb271a8251dcb69dda9679eaeb09398d232d0 /test/java/org/apache/fop | |
parent | 7c8f02c57302d672fe4d0a8fc5332af6d9f0e610 (diff) | |
parent | 73c7b4470f8793bcbf5f1ae795a72fdb7d4455b3 (diff) | |
download | xmlgraphics-fop-502152b4779d4b970148a074e741754828fcc89a.tar.gz xmlgraphics-fop-502152b4779d4b970148a074e741754828fcc89a.zip |
Merged changes from trunk up to revision 1306814
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1309921 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/java/org/apache/fop')
875 files changed, 24747 insertions, 2121 deletions
diff --git a/test/java/org/apache/fop/AbstractBasicTranscoderTestCase.java b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java index 4a65b77b5..f046ee615 100644 --- a/test/java/org/apache/fop/AbstractBasicTranscoderTestCase.java +++ b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java @@ -19,6 +19,8 @@ package org.apache.fop; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.InputStream; @@ -26,19 +28,13 @@ import org.apache.batik.transcoder.Transcoder; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.commons.io.output.ByteArrayOutputStream; +import org.junit.Test; /** * Basic runtime test for FOP's transcoders. It is used to verify that * nothing obvious is broken after compiling. */ -public abstract class AbstractBasicTranscoderTestCase extends AbstractFOPTestCase { - - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public AbstractBasicTranscoderTestCase(String name) { - super(name); - } +public abstract class AbstractBasicTranscoderTest extends AbstractFOPTest { /** * Creates the transcoder to test. @@ -51,6 +47,7 @@ public abstract class AbstractBasicTranscoderTestCase extends AbstractFOPTestCas * Without special configuration stuff. * @throws Exception if a problem occurs */ + @Test public void testGenericPDFTranscoder() throws Exception { //Create transcoder Transcoder transcoder = createTranscoder(); diff --git a/test/java/org/apache/fop/AbstractFOPTestCase.java b/test/java/org/apache/fop/AbstractFOPTest.java index 7d6fee984..eac140d31 100644 --- a/test/java/org/apache/fop/AbstractFOPTestCase.java +++ b/test/java/org/apache/fop/AbstractFOPTest.java @@ -21,31 +21,17 @@ package org.apache.fop; import java.io.File; -import junit.framework.TestCase; - /** * Abstract base test class for FOP's tests. */ -public abstract class AbstractFOPTestCase extends TestCase { - - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public AbstractFOPTestCase(String name) { - super(name); - } +public abstract class AbstractFOPTest { /** * Returns the base directory to use for the tests. * @return the base directory */ - protected File getBaseDir() { - String basedir = System.getProperty("basedir"); - if (basedir != null) { - return new File(basedir); - } else { - return new File("."); - } + protected static File getBaseDir() { + return new File("."); } } diff --git a/test/java/org/apache/fop/BasicDriverTestCase.java b/test/java/org/apache/fop/BasicDriverTestCase.java index 0ae6da048..2fc23edfd 100644 --- a/test/java/org/apache/fop/BasicDriverTestCase.java +++ b/test/java/org/apache/fop/BasicDriverTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop; +import static org.junit.Assert.assertTrue; + import java.io.File; import javax.xml.transform.Result; @@ -34,26 +36,21 @@ import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; import org.apache.fop.cli.InputHandler; +import org.junit.Test; /** * Basic runtime test for the old Fop class. It is used to verify that * nothing obvious is broken after compiling. */ -public class BasicDriverTestCase extends AbstractFOPTestCase { +public class BasicDriverTestCase extends AbstractFOPTest { private FopFactory fopFactory = FopFactory.newInstance(); /** - * @see junit.framework.TestCase#TestCase(String) - */ - public BasicDriverTestCase(String name) { - super(name); - } - - /** * Tests Fop with JAXP and OutputStream generating PDF. * @throws Exception if anything fails */ + @Test public void testFO2PDFWithJAXP() throws Exception { FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); File foFile = new File(getBaseDir(), "test/xml/bugtests/block.fo"); @@ -73,6 +70,7 @@ public class BasicDriverTestCase extends AbstractFOPTestCase { * Tests Fop with JAXP and OutputStream generating PostScript. * @throws Exception if anything fails */ + @Test public void testFO2PSWithJAXP() throws Exception { FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); File foFile = new File(getBaseDir(), "test/xml/bugtests/block.fo"); @@ -92,6 +90,7 @@ public class BasicDriverTestCase extends AbstractFOPTestCase { * Tests Fop with JAXP and OutputStream generating RTF. * @throws Exception if anything fails */ + @Test public void testFO2RTFWithJAXP() throws Exception { FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); File foFile = new File(getBaseDir(), "test/xml/bugtests/block.fo"); @@ -111,6 +110,7 @@ public class BasicDriverTestCase extends AbstractFOPTestCase { * Tests Fop with XsltInputHandler and OutputStream. * @throws Exception if anything fails */ + @Test public void testFO2PDFWithXSLTInputHandler() throws Exception { FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); File xmlFile = new File(getBaseDir(), "test/xml/1.xml"); diff --git a/test/java/org/apache/fop/BasicDriverTestSuite.java b/test/java/org/apache/fop/BasicDriverTestSuite.java index 92fb07a8d..8330a5f7f 100644 --- a/test/java/org/apache/fop/BasicDriverTestSuite.java +++ b/test/java/org/apache/fop/BasicDriverTestSuite.java @@ -19,24 +19,14 @@ package org.apache.fop; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * Test suite for basic functionality of FOP's Driver API. */ +@RunWith(Suite.class) +@SuiteClasses({ BasicDriverTestCase.class }) public class BasicDriverTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite( - "Basic functionality test suite for FOP's Driver API"); - //$JUnit-BEGIN$ - suite.addTest(new TestSuite(BasicDriverTestCase.class)); - //$JUnit-END$ - return suite; - } } diff --git a/test/java/org/apache/fop/BasicPDFTranscoderTestCase.java b/test/java/org/apache/fop/BasicPDFTranscoderTestCase.java index 44668d004..de35db94e 100644 --- a/test/java/org/apache/fop/BasicPDFTranscoderTestCase.java +++ b/test/java/org/apache/fop/BasicPDFTranscoderTestCase.java @@ -26,18 +26,9 @@ import org.apache.fop.svg.PDFTranscoder; * Basic runtime test for the PDF transcoder. It is used to verify that * nothing obvious is broken after compiling. */ -public class BasicPDFTranscoderTestCase extends AbstractBasicTranscoderTestCase { +public class BasicPDFTranscoderTestCase extends AbstractBasicTranscoderTest { - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public BasicPDFTranscoderTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.AbstractBasicTranscoderTestCase#createTranscoder() - */ + @Override protected Transcoder createTranscoder() { return new PDFTranscoder(); } diff --git a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java index 69be94b60..f2f233a5a 100644 --- a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java +++ b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java @@ -26,18 +26,9 @@ import org.apache.fop.render.ps.PSTranscoder; * Basic runtime test for the PS transcoder. It is used to verify that * nothing obvious is broken after compiling. */ -public class BasicPSTranscoderTestCase extends AbstractBasicTranscoderTestCase { +public class BasicPSTranscoderTestCase extends AbstractBasicTranscoderTest { - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public BasicPSTranscoderTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.AbstractBasicTranscoderTestCase#createTranscoder() - */ + @Override protected Transcoder createTranscoder() { return new PSTranscoder(); } diff --git a/test/java/org/apache/fop/BasicTranscoderTestSuite.java b/test/java/org/apache/fop/BasicTranscoderTestSuite.java index ed70afd82..a372f737a 100644 --- a/test/java/org/apache/fop/BasicTranscoderTestSuite.java +++ b/test/java/org/apache/fop/BasicTranscoderTestSuite.java @@ -19,25 +19,17 @@ package org.apache.fop; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * Test suite for basic functionality of FOP's transcoders. */ +@RunWith(Suite.class) +@SuiteClasses({ + BasicPDFTranscoderTestCase.class, + BasicPSTranscoderTestCase.class +}) public class BasicTranscoderTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite( - "Basic functionality test suite for FOP's transcoders"); - //$JUnit-BEGIN$ - suite.addTest(new TestSuite(BasicPDFTranscoderTestCase.class)); - suite.addTest(new TestSuite(BasicPSTranscoderTestCase.class)); - //$JUnit-END$ - return suite; - } } diff --git a/test/java/org/apache/fop/DigestFilterTestCase.java b/test/java/org/apache/fop/DigestFilterTestCase.java index 47fa34839..5606c2b66 100644 --- a/test/java/org/apache/fop/DigestFilterTestCase.java +++ b/test/java/org/apache/fop/DigestFilterTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop; +import static org.junit.Assert.assertTrue; + import java.io.IOException; import java.io.StringReader; import java.security.NoSuchAlgorithmException; @@ -26,9 +28,9 @@ import java.security.NoSuchAlgorithmException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import junit.framework.TestCase; - import org.apache.fop.util.DigestFilter; +import org.junit.Before; +import org.junit.Test; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; @@ -37,12 +39,12 @@ import org.xml.sax.XMLReader; * Test case for digesting SAX filter. * */ -public class DigestFilterTestCase extends TestCase { +public class DigestFilterTestCase { private SAXParserFactory parserFactory; - /** @see junit.framework.TestCase#setUp() */ - protected void setUp() { + @Before + public void setUp() { parserFactory = SAXParserFactory.newInstance(); parserFactory.setNamespaceAware(true); } @@ -95,6 +97,7 @@ public class DigestFilterTestCase extends TestCase { return digestFilter.getDigestValue(); } + @Test public final void testLineFeed() throws NoSuchAlgorithmException, @@ -111,6 +114,7 @@ public class DigestFilterTestCase extends TestCase { compareDigest(lfDigest, crlfDigest)); } + @Test public final void testAttributeOrder() throws NoSuchAlgorithmException, @@ -134,6 +138,7 @@ public class DigestFilterTestCase extends TestCase { compareDigest(sortDigest, reverseDigest)); } + @Test public final void testNamespacePrefix() throws NoSuchAlgorithmException, diff --git a/test/java/org/apache/fop/GenericFOPTestCase.java b/test/java/org/apache/fop/GenericFOPTestCase.java deleted file mode 100644 index 5b51a34e1..000000000 --- a/test/java/org/apache/fop/GenericFOPTestCase.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop; - -import java.io.ByteArrayOutputStream; -import java.io.StringReader; -import java.security.DigestOutputStream; -import java.security.MessageDigest; -import java.util.Date; - -import javax.xml.parsers.SAXParserFactory; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.xml.sax.InputSource; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.util.DigestFilter; - -/** - * Framework for simple regression testing. - * The testcase reads a control XML file which specifies a FO source, - * a MD5 for the source to help diferentiating failures caused by causal - * source modification from failures caused by regression, a renderer (only - * PDF currently supported) and a MD5 for the result. - * - */ -public final class GenericFOPTestCase extends TestCase { - - // configure fopFactory as desired - private FopFactory fopFactory = FopFactory.newInstance(); - - protected SAXParserFactory parserFactory; - - public static Test suite() { - TestSuite suite = new TestSuite(GenericFOPTestCase.class); - suite.setName("Fop regression tests"); - return suite; - } - - /** - * Constructor for FopTest. - * @param name the name of the test suite - */ - public GenericFOPTestCase(String name) { - super(name); - } - - /** @see junit.framework.TestCase#setUp() */ - protected void setUp() throws Exception { - parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - } - - public void testSimple() throws Exception { - final String digestIn = "17bf13298796065f7775db8707133aeb"; - final String digestOut = "e2761f51152f6663911e567901596707"; - final String fo - = "<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>" - + " <fo:layout-master-set>" - + " <fo:simple-page-master master-name='simple'" - + " page-height='25cm' page-width='20cm'>" - + " <fo:region-body/>" - + " </fo:simple-page-master>" - + " </fo:layout-master-set>" - + " <fo:page-sequence master-reference='simple'>" - + " <fo:flow flow-name='xsl-region-body'>" - + " <fo:block>This is a blind text.</fo:block>" - + " </fo:flow>" - + " </fo:page-sequence>" - + "</fo:root>"; - renderPDF(fo, digestIn, digestOut); - } - - private String digestToString(byte[] value) { - StringBuffer buffer = new StringBuffer(2 * value.length); - for (int i = 0; i < value.length; i++) { - int val = value[i]; - int hi = (val >> 4) & 0xF; - int lo = val & 0xF; - if (hi < 10) { - buffer.append((char) (hi + 0x30)); - } else { - buffer.append((char) (hi + 0x61 - 10)); - } - if (lo < 10) { - buffer.append((char) (lo + 0x30)); - } else { - buffer.append((char) (lo + 0x61 - 10)); - } - } - return buffer.toString(); - } - - private void renderPDF(String fo, String digestIn, String digestOut) - throws Exception { - FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); - foUserAgent.setCreationDate(new Date(10000)); - MessageDigest outDigest = MessageDigest.getInstance("MD5"); - DigestOutputStream out - = new DigestOutputStream(new ByteArrayOutputStream(), outDigest); - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); - InputSource source = new InputSource(new StringReader(fo)); - DigestFilter filter = new DigestFilter("MD5"); - filter.setParent(parserFactory.newSAXParser().getXMLReader()); - filter.setContentHandler(fop.getDefaultHandler()); - filter.parse(source); - String digestInActual = digestToString(filter.getDigestValue()); - if (!digestIn.equals(digestInActual)) { - fail("input MD5: was " + digestInActual + ", expected " + digestIn); - } - String digestOutActual = digestToString(outDigest.digest()); - if (!digestOut.equals(digestOutActual)) { - fail( - "output MD5: was " - + digestOutActual - + ", expected " - + digestOut); - } - } - -} diff --git a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java index 5a5523642..18176117c 100644 --- a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java +++ b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop; +import static org.junit.Assert.assertEquals; + import java.util.List; import org.apache.fop.layoutmgr.BlockKnuthSequence; @@ -28,17 +30,16 @@ import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; import org.apache.fop.layoutmgr.KnuthSequence; - -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; /** * Tests the Knuth algorithm implementation. */ -public class KnuthAlgorithmTestCase extends TestCase { +public class KnuthAlgorithmTestCase { - /** @see junit.framework.TestCase#setUp() */ - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() { DebugHelper.registerStandardElementListObservers(); } @@ -67,6 +68,7 @@ public class KnuthAlgorithmTestCase extends TestCase { * possibility. * @throws Exception if an error occurs */ + @Test public void test1() throws Exception { MyBreakingAlgorithm algo = new MyBreakingAlgorithm(0, 0, true, true, 0); algo.setConstantLineWidth(30000); diff --git a/test/java/org/apache/fop/StandardTestSuite.java b/test/java/org/apache/fop/StandardTestSuite.java index caf75b4b4..8649fdfa8 100644 --- a/test/java/org/apache/fop/StandardTestSuite.java +++ b/test/java/org/apache/fop/StandardTestSuite.java @@ -19,49 +19,67 @@ package org.apache.fop; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; -import org.apache.fop.fonts.DejaVuLGCSerifTest; +import org.apache.fop.afp.fonts.CharactersetEncoderTestCase; +import org.apache.fop.afp.parser.MODCAParserTestCase; +import org.apache.fop.area.ViewportTestSuite; +import org.apache.fop.fonts.DejaVuLGCSerifTestCase; +import org.apache.fop.fonts.FontEventProcessingTestCase; +import org.apache.fop.fonts.truetype.GlyfTableTestCase; +import org.apache.fop.fonts.type1.AFMParserTestCase; +import org.apache.fop.fonts.type1.AdobeStandardEncodingTestCase; import org.apache.fop.image.loader.batik.ImageLoaderTestCase; import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; import org.apache.fop.intermediate.IFMimickingTestCase; -import org.apache.fop.render.extensions.prepress.PageBoundariesTest; -import org.apache.fop.render.extensions.prepress.PageScaleTest; +import org.apache.fop.layoutmgr.PageSequenceLayoutManagerTestCase; +import org.apache.fop.pdf.PDFLibraryTestSuite; +import org.apache.fop.render.extensions.prepress.PageBoundariesTestCase; +import org.apache.fop.render.extensions.prepress.PageScaleTestCase; import org.apache.fop.render.pdf.PDFAConformanceTestCase; import org.apache.fop.render.pdf.PDFCMapTestCase; import org.apache.fop.render.pdf.PDFEncodingTestCase; import org.apache.fop.render.pdf.PDFsRGBSettingsTestCase; +import org.apache.fop.render.pdf.RenderPDFTestSuite; +import org.apache.fop.render.ps.PSTestSuite; import org.apache.fop.render.rtf.RichTextFormatTestSuite; -import org.apache.fop.traits.MinOptMaxTest; +import org.apache.fop.traits.MinOptMaxTestCase; /** * Test suite for basic functionality of FOP. */ +@RunWith(Suite.class) +@SuiteClasses({ + BasicDriverTestSuite.class, + UtilityCodeTestSuite.class, + PDFAConformanceTestCase.class, + PDFEncodingTestCase.class, + PDFCMapTestCase.class, + PDFsRGBSettingsTestCase.class, + DejaVuLGCSerifTestCase.class, + RichTextFormatTestSuite.class, + ImageLoaderTestCase.class, + ImagePreloaderTestCase.class, + IFMimickingTestCase.class, + PageSequenceLayoutManagerTestCase.class, + PageBoundariesTestCase.class, + PageScaleTestCase.class, + org.apache.fop.afp.AFPTestSuite.class, + GlyfTableTestCase.class, + ViewportTestSuite.class, + RenderPDFTestSuite.class, + MODCAParserTestCase.class, + CharactersetEncoderTestCase.class, + org.apache.fop.render.afp.AFPTestSuite.class, + PDFLibraryTestSuite.class, + PSTestSuite.class, + MinOptMaxTestCase.class, + AdobeStandardEncodingTestCase.class, + AFMParserTestCase.class, + FontEventProcessingTestCase.class, + org.apache.fop.render.intermediate.IFStructureTreeBuilderTestCase.class +}) public class StandardTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite("Basic functionality test suite for FOP"); - //$JUnit-BEGIN$ - suite.addTest(BasicDriverTestSuite.suite()); - suite.addTest(UtilityCodeTestSuite.suite()); - suite.addTest(new TestSuite(PDFAConformanceTestCase.class)); - suite.addTest(new TestSuite(PDFEncodingTestCase.class)); - suite.addTest(new TestSuite(PDFCMapTestCase.class)); - suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class)); - suite.addTest(new TestSuite(DejaVuLGCSerifTest.class)); - suite.addTest(RichTextFormatTestSuite.suite()); - suite.addTest(new TestSuite(ImageLoaderTestCase.class)); - suite.addTest(new TestSuite(ImagePreloaderTestCase.class)); - suite.addTest(new TestSuite(IFMimickingTestCase.class)); - suite.addTest(new TestSuite(PageBoundariesTest.class)); - suite.addTest(new TestSuite(PageScaleTest.class)); - suite.addTest(new TestSuite(MinOptMaxTest.class)); - //$JUnit-END$ - return suite; - } } diff --git a/test/java/org/apache/fop/URIResolutionTestCase.java b/test/java/org/apache/fop/URIResolutionTestCase.java index 0a197722b..490486158 100644 --- a/test/java/org/apache/fop/URIResolutionTestCase.java +++ b/test/java/org/apache/fop/URIResolutionTestCase.java @@ -19,6 +19,9 @@ package org.apache.fop; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.FileNotFoundException; import java.io.OutputStream; @@ -36,6 +39,8 @@ import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import org.junit.BeforeClass; +import org.junit.Test; import org.w3c.dom.Document; import org.apache.commons.io.IOUtils; @@ -53,7 +58,7 @@ import org.apache.fop.render.xml.XMLRenderer; /** * Tests URI resolution facilities. */ -public class URIResolutionTestCase extends AbstractFOPTestCase { +public class URIResolutionTestCase extends AbstractFOPTest { // configure fopFactory as desired private FopFactory fopFactory = FopFactory.newInstance(); @@ -61,11 +66,10 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { private SAXTransformerFactory tfactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); - private File backupDir = new File(getBaseDir(), "build/test-results"); + private final static File backupDir = new File(getBaseDir(), "build/test-results"); - /** @see junit.framework.TestCase#TestCase(String) */ - public URIResolutionTestCase(String name) { - super(name); + @BeforeClass + public static void makeDirs() { backupDir.mkdirs(); } @@ -73,6 +77,7 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { * Test custom URI resolution with a hand-written URIResolver. * @throws Exception if anything fails */ + @Test public void testFO1a() throws Exception { innerTestFO1(false); } @@ -81,6 +86,7 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { * Test custom URI resolution with a hand-written URIResolver. * @throws Exception if anything fails */ + @Test public void testFO1b() throws Exception { innerTestFO1(true); } @@ -112,7 +118,8 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { * Test custom URI resolution with a hand-written URIResolver. * @throws Exception if anything fails */ - public void DISABLEDtestFO2() throws Exception { + @Test + public void testFO2() throws Exception { //TODO This will only work when we can do URI resolution inside Batik! File foFile = new File(getBaseDir(), "test/xml/uri-resolution2.fo"); @@ -155,8 +162,7 @@ public class URIResolutionTestCase extends AbstractFOPTestCase { TransformerHandler athandler = tfactory.newTransformerHandler(); athandler.setResult(domres); - XMLRenderer atrenderer = new XMLRenderer(); - atrenderer.setUserAgent(ua); + XMLRenderer atrenderer = new XMLRenderer(ua); atrenderer.setContentHandler(athandler); ua.setRendererOverride(atrenderer); diff --git a/test/java/org/apache/fop/UtilityCodeTestSuite.java b/test/java/org/apache/fop/UtilityCodeTestSuite.java index 3a01f7bf8..762b86b14 100644 --- a/test/java/org/apache/fop/UtilityCodeTestSuite.java +++ b/test/java/org/apache/fop/UtilityCodeTestSuite.java @@ -19,41 +19,43 @@ package org.apache.fop; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; import org.apache.fop.events.BasicEventTestCase; +import org.apache.fop.pdf.FileIDGeneratorTestCase; +import org.apache.fop.pdf.PDFDocumentGraphics2DTestCase; +import org.apache.fop.pdf.PDFEncryptionJCETestCase; +import org.apache.fop.pdf.PDFFactoryTestCase; +import org.apache.fop.pdf.PDFNumberTestCase; import org.apache.fop.pdf.PDFObjectTestCase; import org.apache.fop.traits.BorderPropsTestCase; +import org.apache.fop.util.BitmapImageUtilTestCase; import org.apache.fop.util.ColorUtilTestCase; import org.apache.fop.util.ElementListUtilsTestCase; import org.apache.fop.util.HexEncoderTestCase; -import org.apache.fop.util.PDFNumberTestCase; import org.apache.fop.util.XMLResourceBundleTestCase; /** * Test suite for FOP's utility classes. */ +@RunWith(Suite.class) +@SuiteClasses({ + ColorUtilTestCase.class, + BorderPropsTestCase.class, + ElementListUtilsTestCase.class, + BasicEventTestCase.class, + XMLResourceBundleTestCase.class, + URIResolutionTestCase.class, + FileIDGeneratorTestCase.class, + PDFFactoryTestCase.class, + PDFEncryptionJCETestCase.class, + BitmapImageUtilTestCase.class, + PDFDocumentGraphics2DTestCase.class, + PDFNumberTestCase.class, + PDFObjectTestCase.class, + HexEncoderTestCase.class +}) public class UtilityCodeTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite( - "Test suite for FOP's utility classes"); - //$JUnit-BEGIN$ - suite.addTest(new TestSuite(PDFNumberTestCase.class)); - suite.addTest(new TestSuite(PDFObjectTestCase.class)); - suite.addTest(new TestSuite(ColorUtilTestCase.class)); - suite.addTest(new TestSuite(BorderPropsTestCase.class)); - suite.addTest(new TestSuite(ElementListUtilsTestCase.class)); - suite.addTest(new TestSuite(BasicEventTestCase.class)); - suite.addTest(new TestSuite(XMLResourceBundleTestCase.class)); - suite.addTest(new TestSuite(URIResolutionTestCase.class)); - suite.addTest(new TestSuite(HexEncoderTestCase.class)); - //$JUnit-END$ - return suite; - } } diff --git a/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java b/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java new file mode 100644 index 000000000..5b4e264f2 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.accessibility.fo; + +import java.io.File; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +/** + * Utility class to stream an instance of {@link DOMResult} into a file. May be + * useful for debugging. + */ +final class DOMResultUtil { + + private DOMResultUtil() { + } + + /** + * Streams the given result into a file of the given name. + * + * @param result the result of a transformation + * @param filename name of the file into which to stream the result + * @throws TransformerException if a problem occurs when streaming + */ + public static void streamToFile(DOMResult result, String filename) throws TransformerException { + DOMSource source = new DOMSource(result.getNode()); + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(); + transformer.transform(source, new StreamResult(new File(filename))); + } + +} diff --git a/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java new file mode 100644 index 000000000..9c53bdde3 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java @@ -0,0 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.accessibility.fo; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.custommonkey.xmlunit.Diff; +import org.junit.Test; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.accessibility.StructureTree2SAXEventAdapter; +import org.apache.fop.accessibility.StructureTreeEventHandler; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FODocumentParser; +import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.fo.FOEventHandler; +import org.apache.fop.fo.LoadingException; +import org.apache.fop.fotreetest.DummyFOEventHandler; + +public class FO2StructureTreeConverterTestCase { + + private interface FOLoader { + + InputStream getFoInputStream(); + } + + private static final String STRUCTURE_TREE_SEQUENCE_NAME = "structure-tree-sequence"; + + private FOLoader foLoader; + + @Test + public void testCompleteDocument() throws Exception { + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return getResource("/org/apache/fop/fo/complete_document.fo"); + } + }; + testConverter(); + } + + @Test + public void testTableFooters() throws Exception { + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return getResource("table-footers.fo"); + } + }; + testConverter(); + } + + @Test + public void testCompleteContentWrappedInTableFooter() throws Exception { + Source xslt = new StreamSource(getResource("wrapCompleteDocumentInTableFooter.xsl")); + Transformer transformer = createTransformer(xslt); + InputStream originalFO = getResource("/org/apache/fop/fo/complete_document.fo"); + ByteArrayOutputStream transformedFoOutput = new ByteArrayOutputStream(); + transformer.transform(new StreamSource(originalFO), new StreamResult(transformedFoOutput)); + final byte[] transformedFoOutputBytes = transformedFoOutput.toByteArray(); + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return new ByteArrayInputStream(transformedFoOutputBytes); + } + }; + testConverter(); + } + + private Transformer createTransformer(Source xslt) throws TransformerFactoryConfigurationError, + TransformerConfigurationException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + return transformerFactory.newTransformer(xslt); + } + + private static InputStream getResource(String name) { + return FO2StructureTreeConverterTestCase.class.getResourceAsStream(name); + } + + private void testConverter() throws Exception { + DOMResult expectedStructureTree = loadExpectedStructureTree(); + DOMResult actualStructureTree = buildActualStructureTree(); + final Diff diff = createDiff(expectedStructureTree, actualStructureTree); + assertTrue(diff.toString(), diff.identical()); + } + + private DOMResult loadExpectedStructureTree() { + DOMResult expectedStructureTree = new DOMResult(); + InputStream xslt = getResource("fo2StructureTree.xsl"); + runXSLT(xslt, foLoader.getFoInputStream(), expectedStructureTree); + return expectedStructureTree; + } + + private static void runXSLT(InputStream xslt, InputStream doc, Result result) { + Source fo = new StreamSource(doc); + try { + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(new StreamSource(xslt)); + transformer.transform(fo, result); + } catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } catch (TransformerException e) { + throw new RuntimeException(e); + } finally { + closeStream(xslt); + closeStream(doc); + } + } + + private static void closeStream(InputStream stream) { + try { + stream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private DOMResult buildActualStructureTree() throws Exception { + DOMResult actualStructureTree = new DOMResult(); + createStructureTreeFromDocument(foLoader.getFoInputStream(), actualStructureTree); + return actualStructureTree; + } + + private static void createStructureTreeFromDocument(InputStream foInputStream, + Result result) throws Exception { + TransformerHandler tHandler = createTransformerHandler(result); + startStructureTreeSequence(tHandler); + StructureTreeEventHandler structureTreeEventHandler + = StructureTree2SAXEventAdapter.newInstance(tHandler); + FODocumentParser documentParser = createDocumentParser(structureTreeEventHandler); + FOUserAgent userAgent = createFOUserAgent(documentParser); + parseDocument(foInputStream, documentParser, userAgent); + endStructureTreeSequence(tHandler); + } + + private static TransformerHandler createTransformerHandler(Result domResult) + throws TransformerConfigurationException, TransformerFactoryConfigurationError { + SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + TransformerHandler transformerHandler = factory.newTransformerHandler(); + transformerHandler.setResult(domResult); + return transformerHandler; + } + + private static void startStructureTreeSequence(TransformerHandler tHandler) throws SAXException { + tHandler.startDocument(); + tHandler.startElement("", STRUCTURE_TREE_SEQUENCE_NAME, STRUCTURE_TREE_SEQUENCE_NAME, + new AttributesImpl()); + } + + private static FODocumentParser createDocumentParser( + final StructureTreeEventHandler structureTreeEventHandler) { + return FODocumentParser.newInstance(new FOEventHandlerFactory() { + public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) { + return new FO2StructureTreeConverter(structureTreeEventHandler, + new DummyFOEventHandler(foUserAgent)); + } + }); + } + + private static FOUserAgent createFOUserAgent(FODocumentParser documentParser) { + FOUserAgent userAgent = documentParser.createFOUserAgent(); + userAgent.setAccessibility(true); + return userAgent; + } + + private static void parseDocument(InputStream foInputStream, FODocumentParser documentParser, + FOUserAgent userAgent) throws FOPException, LoadingException { + try { + documentParser.parse(foInputStream, userAgent); + } finally { + closeStream(foInputStream); + } + } + + private static void endStructureTreeSequence(TransformerHandler tHandler) throws SAXException { + tHandler.endElement("", STRUCTURE_TREE_SEQUENCE_NAME, STRUCTURE_TREE_SEQUENCE_NAME); + tHandler.endDocument(); + } + + private static Diff createDiff(DOMResult expected, DOMResult actual) { + Diff diff = new Diff(getDocument(expected), getDocument(actual)); + return diff; + } + + private static Document getDocument(DOMResult result) { + return (Document) result.getNode(); + } +} diff --git a/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl new file mode 100644 index 000000000..ce326f3b1 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" + xmlns:foi="http://xmlgraphics.apache.org/fop/internal"> + + <xsl:output method="xml" indent="no"/> + + <xsl:template name="copy"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> + + + <!-- Ignore fo:root --> + <xsl:template match="fo:root"> + <structure-tree-sequence> + <xsl:apply-templates/> + </structure-tree-sequence> + </xsl:template> + + <!-- fo:page-sequence maps to structure-tree --> + <xsl:template match="fo:page-sequence"> + <structure-tree xmlns="http://xmlgraphics.apache.org/fop/intermediate"> + <xsl:apply-templates/> + </structure-tree> + </xsl:template> + + + <!-- Declarations and Pagination and Layout Formatting Objects --> + <xsl:template match="fo:static-content|fo:flow"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Block-level Formatting Objects --> + <xsl:template match="fo:block|fo:block-container"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Inline-level Formatting Objects --> + <xsl:template match="fo:character|fo:inline|fo:inline-container"> + <xsl:call-template name="copy"/> + </xsl:template> + + <xsl:template match="fo:external-graphic|fo:instream-foreign-object"> + <xsl:call-template name="copy"/> + </xsl:template> + + <xsl:template match="fo:page-number|fo:page-number-citation|fo:page-number-citation-last"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Formatting Objects for Tables --> + <xsl:template match="fo:table-and-caption|fo:table-caption"> + <xsl:call-template name="copy"/> + </xsl:template> + + <xsl:template match="fo:table"> + <xsl:copy> + <xsl:apply-templates select="@*"/> + <xsl:apply-templates select="*[name() != 'fo:table-footer']"/> + <xsl:apply-templates select="fo:table-footer"/> + </xsl:copy> + </xsl:template> + + <xsl:template match="fo:table-header|fo:table-footer|fo:table-body|fo:table-row|fo:table-cell"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Formatting Objects for Lists --> + <xsl:template match="fo:list-block|fo:list-item|fo:list-item-label|fo:list-item-body"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Dynamic Effects: Link and Multi Formatting Objects --> + <xsl:template match="fo:basic-link"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Out-of-Line Formatting Objects --> + <xsl:template match="fo:float|fo:footnote|fo:footnote-body"> + <xsl:call-template name="copy"/> + </xsl:template> + + <!-- Other Formatting Objects --> + <xsl:template match="fo:wrapper|fo:marker"> + <xsl:call-template name="copy"/> + </xsl:template> + + + <!-- Discard descendants of fo:leader --> + <xsl:template match="fo:leader"/> + + + <!-- Keep fox:alt-text and role attributes, discard everything else --> + <xsl:template match="@fox:alt-text|@role"> + <xsl:copy-of select="."/> + </xsl:template> + + <xsl:template match="@*"/> + + + <!-- Discard text nodes... --> + <xsl:template match="text()"/> + + <!-- ...except those that will result into marked content --> + <xsl:template match="fo:title/text() + |fo:block/text() + |fo:bidi-override/text() + |fo:inline/text() + |fo:basic-link/text() + |fo:wrapper/text() + |fo:marker/text()"> + <marked-content xmlns="http://xmlgraphics.apache.org/fop/intermediate"/> + </xsl:template> + +</xsl:stylesheet> diff --git a/test/java/org/apache/fop/accessibility/fo/table-footers.fo b/test/java/org/apache/fop/accessibility/fo/table-footers.fo new file mode 100644 index 000000000..6dcb9b68d --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/table-footers.fo @@ -0,0 +1,195 @@ +<?xml version="1.0" standalone="no"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="440pt" page-width="420pt" margin="10pt"> + <fo:region-body display-align="center"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body" line-height="10pt" font-size="8pt"> + <fo:table width="100% - 6pt" table-layout="fixed" + border-collapse="separate" border="2pt solid black" border-separation="2pt" padding="1pt" + start-indent="3pt" end-indent="3pt" space-after="2pt"> + <fo:table-header start-indent="0" end-indent="0"> + <fo:table-cell background-color="#E0E0E0" padding="2pt"> + <fo:block>Start Outer Header</fo:block> + <fo:table width="100% - 6pt" table-layout="fixed" + border="2pt solid red" padding="1pt" + start-indent="3pt" end-indent="3pt" space-after="2pt"> + <fo:table-header start-indent="0" end-indent="0"> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Header 1.2</fo:block> + </fo:table-cell> + </fo:table-header> + <fo:table-footer start-indent="0" end-indent="0"> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-footer> + <fo:table-body start-indent="0" end-indent="0"> + <fo:table-row> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Body 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Body 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Body 2.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="#FFB0B0" padding="2pt"> + <fo:block>Inner Body 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>End Outer Header</fo:block> + </fo:table-cell> + </fo:table-header> + <fo:table-footer start-indent="0" end-indent="0"> + <fo:table-cell background-color="#E0E0E0" padding="2pt"> + <fo:block>Start Outer Footer</fo:block> + <fo:table width="100% - 6pt" table-layout="fixed" + border="2pt solid green" padding="1pt" + start-indent="3pt" end-indent="3pt" space-after="2pt"> + <fo:table-header start-indent="0" end-indent="0"> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Header 1.2</fo:block> + </fo:table-cell> + </fo:table-header> + <fo:table-footer start-indent="0" end-indent="0"> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Start Inner Footer 1.1</fo:block> + <fo:table width="100% - 6pt" table-layout="fixed" + border="2pt solid yellow" padding="1pt" + start-indent="3pt" end-indent="3pt" space-after="2pt"> + <fo:table-header start-indent="0" end-indent="0"> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Header 1.2</fo:block> + </fo:table-cell> + </fo:table-header> + <fo:table-footer start-indent="0" end-indent="0"> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-footer> + <fo:table-body start-indent="0" end-indent="0"> + <fo:table-row> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Body 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Body 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Body 2.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="yellow" padding="2pt"> + <fo:block>Inner Inner Body 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>End Inner Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-footer> + <fo:table-body start-indent="0" end-indent="0"> + <fo:table-row> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Body 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Body 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Body 2.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightgreen" padding="2pt"> + <fo:block>Inner Body 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>End Outer Footer</fo:block> + </fo:table-cell> + </fo:table-footer> + <fo:table-body start-indent="0" end-indent="0"> + <fo:table-row> + <fo:table-cell background-color="#E0E0E0" padding="2pt"> + <fo:block>Outer Body Cell 1</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell background-color="#E0E0E0" padding="2pt"> + <fo:block>Start Outer Body Cell 2</fo:block> + <fo:table width="100% - 6pt" table-layout="fixed" + border="2pt solid blue" padding="1pt" + start-indent="3pt" end-indent="3pt" space-after="2pt"> + <fo:table-header start-indent="0" end-indent="0"> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-header> + <fo:table-footer start-indent="0" end-indent="0"> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Header 1.2</fo:block> + </fo:table-cell> + </fo:table-footer> + <fo:table-body start-indent="0" end-indent="0"> + <fo:table-row> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Body 1.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Body 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Body 2.1</fo:block> + </fo:table-cell> + <fo:table-cell background-color="lightblue" padding="2pt"> + <fo:block>Inner Body 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>End Outer Body Cell 2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl b/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl new file mode 100644 index 000000000..9608b2fb9 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format"> + + <xsl:template match="@*|node()" name="copy"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> + + + <xsl:template match="/"> + <fo:root> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="500pt" page-width="300pt" margin="20pt"> + <fo:region-body margin-top="20pt"/> + </fo:simple-page-master> + </fo:layout-master-set> + <xsl:apply-templates select="//fo:page-sequence"/> + </fo:root> + </xsl:template> + + <xsl:template match="fo:page-sequence"> + <fo:page-sequence master-reference="page"> + <xsl:apply-templates select="fo:flow"/> + </fo:page-sequence> + </xsl:template> + + <xsl:template match="fo:flow"> + <xsl:copy> + <xsl:apply-templates select="@*[not(starts-with(name(), 'space-before'))]"/> + <fo:table width="100%" table-layout="fixed"> + <fo:table-footer> + <fo:table-cell background-color="#F0F0F0"> + <xsl:apply-templates select="@*[starts-with(name(), 'space-before')]"/> + <xsl:apply-templates select="*"/> + </fo:table-cell> + </fo:table-footer> + <fo:table-body> + <fo:table-cell> + <fo:block>The content below is in the table footer.</fo:block> + </fo:table-cell> + </fo:table-body> + </fo:table> + </xsl:copy> + </xsl:template> + +</xsl:stylesheet> diff --git a/test/java/org/apache/fop/afp/AFPEventProcessingTestCase.java b/test/java/org/apache/fop/afp/AFPEventProcessingTestCase.java new file mode 100644 index 000000000..cd0faa39b --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPEventProcessingTestCase.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.transform.TransformerException; + +import org.junit.Test; +import org.xml.sax.SAXException; + +import org.apache.xmlgraphics.util.MimeConstants; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.events.EventProcessingTestCase; + +/** + * A test class for testing AFP events. + */ +public class AFPEventProcessingTestCase { + + private EventProcessingTestCase eventsTests = new EventProcessingTestCase(); + private static final String CONFIG_BASE_DIR = EventProcessingTestCase.CONFIG_BASE_DIR; + + private void testInvalidConfigEvent(String xconf, String eventId) + throws FOPException, TransformerException, IOException, SAXException { + InputStream inStream = getClass().getResourceAsStream("simple.fo"); + eventsTests.doTest(inStream, CONFIG_BASE_DIR + xconf, + AFPEventProducer.class.getName() + eventId, MimeConstants.MIME_AFP); + } + + @Test + public void testMissingFontConfigurationElement() throws FOPException, TransformerException, + IOException, SAXException { + testInvalidConfigEvent("afp-font-missing.xconf", ".fontConfigMissing"); + } + + @Test + public void testInvalidCharactersetName() throws FOPException, TransformerException, + IOException, SAXException { + testInvalidConfigEvent("afp-invalid-characterset.xconf", ".characterSetNameInvalid"); + } + + @Test + public void testinvalidConfig() throws FOPException, TransformerException, IOException, + SAXException { + testInvalidConfigEvent("afp-invalid-config.xconf", ".invalidConfiguration"); + } + + @Test + public void testRasterFontElementMissing() throws FOPException, TransformerException, + IOException, SAXException { + testInvalidConfigEvent("afp-raster-font-missing.xconf", ".fontConfigMissing"); + } + + @Test + public void testTripletElementMissing() throws FOPException, TransformerException, + IOException, SAXException { + testInvalidConfigEvent("afp-triplet-missing.xconf", ".fontConfigMissing"); + } +} diff --git a/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java new file mode 100644 index 000000000..fc5f1825c --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test case for {@link AFPObjectAreaInfo}. + */ +public class AFPObjectAreaInfoTestCase { + + private AFPObjectAreaInfo sut; + + /** + * Instantiate the system under test + */ + @Before + public void setUp() { + sut = new AFPObjectAreaInfo(1, 2, 3, 4, 5, 6); + } + + /** + * Test the getter functions with arbitrary data. + */ + @Test + public void testGetters() { + assertEquals(1, sut.getX()); + assertEquals(2, sut.getY()); + assertEquals(3, sut.getWidth()); + assertEquals(4, sut.getHeight()); + assertEquals(5, sut.getWidthRes()); + assertEquals(5, sut.getHeightRes()); + assertEquals(6, sut.getRotation()); + } + + /** + * Test the resolution setters with arbitrary data. + */ + @Test + public void testSetters() { + assertEquals(5, sut.getWidthRes()); + assertEquals(5, sut.getHeightRes()); + + sut.setResolution(20); + assertEquals(20, sut.getWidthRes()); + assertEquals(20, sut.getHeightRes()); + + sut.setHeightRes(10); + assertEquals(20, sut.getWidthRes()); + assertEquals(10, sut.getHeightRes()); + + sut.setWidthRes(9); + assertEquals(9, sut.getWidthRes()); + assertEquals(10, sut.getHeightRes()); + } +} diff --git a/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java new file mode 100644 index 000000000..47c93064c --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test case for {@link AFPPaintingState}. + */ +public class AFPPaintingStateTestCase { + private AFPPaintingState sut; + + /** + * Set up the system under test + */ + @Before + public void setUp() { + sut = new AFPPaintingState(); + } + + /** + * Test {get,set}BitmapEncodingQuality() + */ + @Test + public void testGetSetBitmapEncodingQuality() { + sut.setBitmapEncodingQuality(0.5f); + assertEquals(0.5f, sut.getBitmapEncodingQuality(), 0.01f); + + sut.setBitmapEncodingQuality(0.9f); + assertEquals(0.9f, sut.getBitmapEncodingQuality(), 0.01f); + } + + /** + * Test {,set}CanEmbedJpeg + */ + public void testGetSetCanEmbedJpeg() { + assertEquals(false, sut.canEmbedJpeg()); + sut.setCanEmbedJpeg(true); + assertEquals(true, sut.canEmbedJpeg()); + } +} diff --git a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java new file mode 100644 index 000000000..c9ea9a5f4 --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +import org.apache.xmlgraphics.util.MimeConstants; + +/** + * Test case for {@link AFPResourceManager}. + */ +public class AFPResourceManagerTestCase { + + private AFPResourceManager sut; + + @Before + public void setUp() throws IOException { + sut = new AFPResourceManager(); + AFPPaintingState paintingState = new AFPPaintingState(); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + DataStream stream = sut.createDataStream(paintingState, outStream); + stream.startPage(0, 0, 0, 10, 10); + } + + /** + * Ensures that if tryIncludeObject() is called with a new object, it returns false suggesting + * that we have to create said object. However, if it is called with an object that has already + * been created, it returns true suggesting that we don't have to create that object again. + * Page-segment is false. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testTryIncludeObjectWithPageSegFalse() throws IOException { + AFPDataObjectInfo dataInfo = createAFPDataObjectInfo(); + // An empty object needs to be created every time! + assertFalse(sut.tryIncludeObject(dataInfo)); + sut.createObject(dataInfo); + assertTrue(sut.tryIncludeObject(dataInfo)); + } + + /** + * {@code testTryIncludeObjectWithPageSegFalse()} but with page-segment true. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testTryIncludeObjectWithPageSegTrue() throws IOException { + AFPDataObjectInfo dataInfo = createAFPDataObjectInfo(); + dataInfo.setCreatePageSegment(true); + // An empty object needs to be created every time! + assertFalse(sut.tryIncludeObject(dataInfo)); + sut.createObject(dataInfo); + assertTrue(sut.tryIncludeObject(dataInfo)); + } + + private AFPDataObjectInfo createAFPDataObjectInfo() { + AFPDataObjectInfo dataInfo = new AFPDataObjectInfo(); + dataInfo.setMimeType(MimeConstants.MIME_TIFF); + dataInfo.setData(new byte[1]); + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(0, 0, 10, 10, 1, 0); + dataInfo.setObjectAreaInfo(objectAreaInfo); + return dataInfo; + } +} diff --git a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java new file mode 100644 index 000000000..6ab7f475d --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Arrays; + +import org.apache.commons.io.IOUtils; +import org.apache.fop.afp.util.AFPResourceUtil; +import org.junit.Test; + +/** + * Tests the {@link AFPResourceUtil} class. + */ +public class AFPResourceUtilTestCase { + + private static final String RESOURCE_FILENAME = "expected_resource.afp"; + + private static final String NAMED_RESOURCE_FILENAME = "expected_named_resource.afp"; + + private static final String PSEG = "XFEATHER"; + + /** + * Tests copyResourceFile() + * @throws Exception - + */ + @Test + public void testCopyResourceFile() throws Exception { + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + InputStream in = null; + + try { + in = getClass().getResourceAsStream(RESOURCE_FILENAME); + AFPResourceUtil.copyResourceFile(in, baos); + } finally { + in.close(); + } + + byte[] expectedBytes = null; + + try { + in = getClass().getResourceAsStream(RESOURCE_FILENAME); + expectedBytes = IOUtils.toByteArray(in); + } finally { + in.close(); + } + + assertTrue(Arrays.equals(expectedBytes, baos.toByteArray())); + + } + + /** + * Tests copyNamedResource() + * @throws Exception - + */ + @Test + public void testCopyNamedResource() throws Exception { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + InputStream in = null; + + try { + in = getClass().getResourceAsStream(RESOURCE_FILENAME); + AFPResourceUtil.copyNamedResource(PSEG, in, baos); + } finally { + in.close(); + } + + byte[] expectedBytes = null; + + try { + in = getClass().getResourceAsStream(NAMED_RESOURCE_FILENAME); + expectedBytes = IOUtils.toByteArray(in); + } finally { + in.close(); + } + + assertTrue(Arrays.equals(expectedBytes, baos.toByteArray())); + } +} diff --git a/test/java/org/apache/fop/afp/AFPTestSuite.java b/test/java/org/apache/fop/afp/AFPTestSuite.java new file mode 100644 index 000000000..32d61cb35 --- /dev/null +++ b/test/java/org/apache/fop/afp/AFPTestSuite.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.afp.modca.IncludeObjectTestCase; + +/** + * Test suite for FOP's AFP classes. + */ +@RunWith(Suite.class) +@SuiteClasses({ + IncludeObjectTestCase.class, + AFPResourceUtilTestCase.class, + AFPObjectAreaInfoTestCase.class, + AFPPaintingStateTestCase.class +}) +public class AFPTestSuite { +} diff --git a/test/java/org/apache/fop/afp/expected_named_resource.afp b/test/java/org/apache/fop/afp/expected_named_resource.afp Binary files differnew file mode 100644 index 000000000..9fe45c388 --- /dev/null +++ b/test/java/org/apache/fop/afp/expected_named_resource.afp diff --git a/test/java/org/apache/fop/afp/expected_resource.afp b/test/java/org/apache/fop/afp/expected_resource.afp Binary files differnew file mode 100644 index 000000000..a98ac0e5e --- /dev/null +++ b/test/java/org/apache/fop/afp/expected_resource.afp diff --git a/test/java/org/apache/fop/afp/fonts/CharactersetEncoderTestCase.java b/test/java/org/apache/fop/afp/fonts/CharactersetEncoderTestCase.java new file mode 100644 index 000000000..dd776e41c --- /dev/null +++ b/test/java/org/apache/fop/afp/fonts/CharactersetEncoderTestCase.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.fonts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.CharacterCodingException; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test {@link CharactersetEncoder} + */ +public class CharactersetEncoderTestCase { + private CharactersetEncoder singlebyteEncoder; + private CharactersetEncoder doublebyteEncoder; + + @Before + public void setUp() { + singlebyteEncoder = CharactersetEncoder.newInstance("cp500", false); + doublebyteEncoder = CharactersetEncoder.newInstance("cp937", true); + } + + // This is just an arbitrary CJK string + private final String testCJKText = "\u8ACB\u65BC\u627F\u505A\u65E5\u4E03\u65E5\u5167\u672A\u9054" + + "\u4E03\u65E5\u4E4B\u5B9A\u5B58\u8005\u4EE5\u5BE6\u969B\u5230\u671F\u65E5\u5167\u78BA" + + "\u8A8D\u672C\u4EA4\u6613\u5167\u5BB9\u3002\u5982\u672A\u65BC\u4E0A\u8FF0\u671F\u9593" + + "\u5167\u63D0\u51FA\u7570\u8B70\uFF0C\u8996\u540C\u610F\u627F\u8A8D\u672C\u4EA4\u6613" + + "\u3002"; + + private final byte[] test6CJKChars = { + (byte) 0x61, (byte) 0x99, + (byte) 0x50, (byte) 0xf4, + (byte) 0x50, (byte) 0xd4, + (byte) 0x56, (byte) 0x99, + (byte) 0x4c, (byte) 0xc9, + (byte) 0x4c, (byte) 0x44 }; + + private final String testEngText = "Hello World!"; + private final byte[] testEngChars = { + (byte) 0xc8, // H + (byte) 0x85, // e + (byte) 0x93, // l + (byte) 0x93, // l + (byte) 0x96, // o + (byte) 0x40, // " " + (byte) 0xe6, // W + (byte) 0x96, // o + (byte) 0x99, // r + (byte) 0x93, // l + (byte) 0x84, // d + (byte) 0x4f // ! + }; + + /** + * Tests canEncode() - tests that canEncode() responds properly to various input characters. + */ + @Test + public void testCanEncode() { + // Both SBCS and DBCS should support Latin characters + for (char c = '!'; c < '~'; c++) { + assertTrue(singlebyteEncoder.canEncode(c)); + assertTrue(doublebyteEncoder.canEncode(c)); + } + // ONLY the double byte characters can handle CJK text + for (char c : testCJKText.toCharArray()) { + assertFalse(singlebyteEncoder.canEncode(c)); + assertTrue(doublebyteEncoder.canEncode(c)); + } + // Ensure that double byte encoder doesn't just return true all the time... + assertFalse(doublebyteEncoder.canEncode('\u00BB')); + } + + @Test + public void testEncode() throws CharacterCodingException, IOException { + CharactersetEncoder.EncodedChars encChars;// = doublebyteEncoder.encode(testCJKText); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + // JAVA 1.5 has a bug in the JVM in which these err for some reason... JAVA 1.6 no issues + /*encChars.writeTo(bOut, 0, encChars.getLength()); + byte[] bytes = bOut.toByteArray(); + for (int i = 0; i < 12; i++) { + assertEquals(test6CJKChars[i], bytes[i]); + } + bOut.reset();*/ + + encChars = singlebyteEncoder.encode(testEngText); + encChars.writeTo(bOut, 0, encChars.getLength()); + byte[] engBytes = bOut.toByteArray(); + for (int i = 0; i < testEngChars.length; i++) { + assertEquals(testEngChars[i], engBytes[i]); + } + assertEquals(testEngChars.length, engBytes.length); + } +} diff --git a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java new file mode 100644 index 000000000..b77ef6e12 --- /dev/null +++ b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.fop.afp.goca; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.apache.fop.afp.fonts.CharacterSet; +import org.apache.fop.afp.fonts.CharacterSetBuilder; +import org.apache.fop.fonts.Typeface; +import org.junit.Before; +import org.junit.Test; + +public class GraphicsCharacterStringTestCase { + private GraphicsCharacterString gcsCp500; + private GraphicsCharacterString gcsCp1146; + // consider the EBCDIC code page variants Cp500 and Cp1146 + // the <A3> (pound sign) corresponds to byte 5B (position 91) in the CCSID 285 and CCSID 1146 + // the $ corresponds to byte 5B (position 91) in the CCSID 500 + private final String poundsText = "\u00A3\u00A3\u00A3\u00A3"; + private final String dollarsText = "$$$$"; + private final byte[] bytesToCheck = {(byte) 0x5b, (byte) 0x5b, (byte) 0x5b, (byte) 0x5b}; + + @Before + public void setUp() throws Exception { + CharacterSetBuilder csb = CharacterSetBuilder.getSingleByteInstance(); + CharacterSet cs1146 = csb.build("C0H200B0", "T1V10500", "Cp1146", + Class.forName("org.apache.fop.fonts.base14.Helvetica").asSubclass(Typeface.class) + .newInstance(), null); + gcsCp1146 = new GraphicsCharacterString(poundsText, 0, 0, cs1146); + CharacterSet cs500 = csb.build("C0H200B0", "T1V10500", "Cp500", + Class.forName("org.apache.fop.fonts.base14.Helvetica").asSubclass(Typeface.class) + .newInstance(), null); + gcsCp500 = new GraphicsCharacterString(dollarsText, 0, 0, cs500); + } + + @Test + public void testWriteToStream() throws IOException { + // check pounds + ByteArrayOutputStream baos1146 = new ByteArrayOutputStream(); + gcsCp1146.writeToStream(baos1146); + byte[] bytes1146 = baos1146.toByteArray(); + for (int i = 0; i < bytesToCheck.length; i++) { + assertEquals(bytesToCheck[i], bytes1146[6 + i]); + } + assertEquals(bytesToCheck.length + 6, bytes1146.length); + // check dollars + ByteArrayOutputStream baos500 = new ByteArrayOutputStream(); + gcsCp500.writeToStream(baos500); + byte[] bytes500 = baos500.toByteArray(); + for (int i = 0; i < bytesToCheck.length; i++) { + assertEquals(bytesToCheck[i], bytes500[6 + i]); + } + assertEquals(bytesToCheck.length + 6, bytes500.length); + } +} diff --git a/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java new file mode 100644 index 000000000..451616ad9 --- /dev/null +++ b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.modca; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.fop.afp.Streamable; +import org.junit.Test; + +/** + * Tests the {@link AbstractAFPObject} class. + */ +public abstract class AbstractAFPObjectTest<S extends AbstractAFPObject> { + + private S sut; + + protected final S getSut() { + return sut; + } + + protected final void setSut(S sut) { + if ( this.sut == null) { + this.sut = sut; + } + } + + + private byte[] header = new byte[] { + 0x5A, // Structured field identifier + 0x00, // Length byte 1 + 0x10, // Length byte 2 + 0x00, // Structured field id byte 1 + 0x00, // Structured field id byte 2 + 0x00, // Structured field id byte 3 + 0x00, // Flags + 0x00, // Reserved + 0x00 // Reserved + }; + + @Test + public void testCopySFStatic() { + byte[] actual = new byte[9]; + Arrays.fill(actual, (byte)-1); + + S.copySF(actual, (byte)0, (byte)0, (byte)0); + + assertTrue(Arrays.equals(actual, header)); + + byte[] expected2 = new byte[9]; + System.arraycopy(header, 0, expected2, 0, header.length); + + final byte clazz = (byte) 0x01; + final byte type = (byte) 0x02; + final byte catagory = (byte) 0x03; + expected2[3] = clazz; + expected2[4] = type; + expected2[5] = catagory; + + AbstractAFPObject.copySF(actual, clazz, type, catagory); + + assertTrue(Arrays.equals(actual, expected2)); + } + + @Test + public void testCopySF() { + byte[] expected = new byte[9]; + S.copySF(expected, (byte) 0xD3, (byte)0, (byte)0); + + byte[] actual = new byte[9]; + Arrays.fill(actual, (byte)-1); + + getSut().copySF(actual, (byte)0, (byte)0); + + assertTrue(Arrays.equals(actual, expected)); + + byte[] expected2 = new byte[9]; + System.arraycopy(expected, 0, expected2, 0, expected.length); + + final byte type = (byte)1; + final byte catagory = (byte)2; + expected2[4] = type; + expected2[5] = catagory; + + getSut().copySF(actual, type, catagory); + + assertTrue(Arrays.equals(actual, expected2)); + } + + /** + * + */ + @Test + public void testwriteObjects() { + final byte[][] expected = {{(byte)0, (byte)1}, {(byte)2, (byte)3}, {(byte)4, (byte)5}}; + + List<Streamable> objects = new ArrayList<Streamable>() { + { + add(StreamableObject.instance(expected[0])); + add(StreamableObject.instance(expected[1])); + add(StreamableObject.instance(expected[2])); + } }; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + getSut().writeObjects(objects, baos); + } catch (IOException e) { + fail(); + } + + byte[] actual = baos.toByteArray(); + + int index = 0; + for (int i = 0; i < expected.length; i++) { + for (int j = 0; j < expected[i].length; j++) { + assertTrue("" + index, actual[index] == expected[i][j]); + index++; + } + } + } + + /** + * + */ + @Test + public void testTruncate() { + String expected = "abc"; + assertTrue(AbstractAFPObject.truncate(expected, 4) == expected); + assertTrue(AbstractAFPObject.truncate(expected, 3) == expected); + assertEquals(AbstractAFPObject.truncate(expected + "d", 3), expected); + assertEquals(AbstractAFPObject.truncate(expected, 0), ""); + try { + assertTrue(AbstractAFPObject.truncate(null, 4) == null); + fail(); + } catch (NullPointerException e) { + // PASS + } + } + + /** + * + */ + @Test + public void testWriteChunksToStream() throws IOException { + final byte[] data = new byte[256]; + int counter = 0; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) counter++; + } + + byte[] header = new byte[9]; + // Test when chunk size % data.length == 0 + testWithGivenChunkSize(data, header, 16); + + // test when chunk size % data.length != 0 + testWithGivenChunkSize(data, header, 10); + + // test with an odd number... + testWithGivenChunkSize(data, header, 13); + } + + private void testWithGivenChunkSize(byte[] data, byte[] header, int chunkSize) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + S.writeChunksToStream(data, header, 0, chunkSize, baos); + byte[] testData = baos.toByteArray(); + + int numberOfFullDataChunks = data.length / chunkSize; + int lastChunkSize = data.length % chunkSize; + int lengthOfTestData = numberOfFullDataChunks * (chunkSize + header.length); + lengthOfTestData += lastChunkSize == 0 ? 0 : header.length + lastChunkSize; + + putLengthInHeader(header, chunkSize); + + assertEquals(lengthOfTestData, testData.length); + int testIndex = 0; + int expectedIndex = 0; + for (int i = 0; i < numberOfFullDataChunks; i++) { + checkHeaderAndData(header, data, testData, expectedIndex, testIndex, chunkSize); + expectedIndex += chunkSize + header.length; + testIndex += chunkSize; + } + + putLengthInHeader(header, lastChunkSize); + // check last chunk + if (lastChunkSize != 0) { + checkHeaderAndData(header, data, testData, expectedIndex, testIndex, lastChunkSize); + } + } + + private void putLengthInHeader(byte[] header, int chunkSize) { + header[0] = 0; + header[1] = (byte) (chunkSize + header.length); + } + + private void checkHeaderAndData(byte[] header, byte[] data, byte[] testData, int expectedIndex, + int testIndex, int chunkSize) { + for (int i = 0; i < header.length; i++) { + assertEquals(testData[expectedIndex++], header[i]); + } + for (int i = 0; i < chunkSize; i++) { + assertEquals(testData[expectedIndex++], data[i + testIndex]); + } + } + + /** + * + */ + private static class StreamableObject implements Streamable { + private byte[] bytes; + + StreamableObject(byte[] bytes) { + this.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, this.bytes, 0, bytes.length); + } + + private static Streamable instance(byte[] bytes) { + return new StreamableObject(bytes); + } + + public void writeToStream(OutputStream os) throws IOException { + os.write(bytes); + } + } +} diff --git a/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java new file mode 100644 index 000000000..5c863b6e4 --- /dev/null +++ b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.modca; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +/** + * Tests the {@linkplain AbstractAFPObject} class. + */ +public abstract class AbstractNamedAFPObjectTest<S extends AbstractNamedAFPObject> + extends AbstractAFPObjectTest<S> { + @Test + public void testCopySF() { + + final S sut = getSut(); + + byte[] expected = new byte[17]; + S.copySF(expected, (byte) 0xD3, (byte)0, (byte)0); + + byte[] nameData = sut.getNameBytes(); + System.arraycopy(nameData, 0, expected, 9, nameData.length); + + byte[] actual = new byte[17]; + Arrays.fill(actual, (byte)-1); + + getSut().copySF(actual, (byte)0, (byte)0); + + assertTrue(Arrays.equals(actual, expected)); + + byte[] expected2 = new byte[17]; + System.arraycopy(expected, 0, expected2, 0, expected.length); + System.arraycopy(nameData, 0, expected, 9, nameData.length); + + final byte type = (byte)1; + final byte catagory = (byte)2; + expected2[4] = type; + expected2[5] = catagory; + + getSut().copySF(actual, type, catagory); + + assertTrue(Arrays.equals(actual, expected2)); + } +} diff --git a/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java new file mode 100644 index 000000000..faef0a4f6 --- /dev/null +++ b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.modca; + +import java.io.IOException; + +public abstract class AbstractStructuredObjectTest<S extends AbstractStructuredObject> extends AbstractAFPObjectTest<S> { + + /** + * Test writeStart() - test that the contract is maintained with + * {@link AbstractStructuredObject}. + * + * @throws IOException + */ + public void testwriteStart() throws IOException { + } + + /** + * Test writeEnd() - test that the contract is maintained with {@link AbstractStructuredObject}. + * + * @throws IOException + */ + public void testWriteEnd() throws IOException { + } + + /** + * Test writeContent() - test that the contract is maintained with + * {@link AbstractStructuredObject}. + * + * @throws IOException + */ + public void testWriteContent() throws IOException { + } + + /** + * Test writeToStream() - test that the contract is maintained with + * {@link AbstractStructuredObject}. + * + * @throws IOException + */ + public void testWriteToStream() throws IOException { + testwriteStart(); + testWriteEnd(); + testWriteContent(); + } +} diff --git a/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java new file mode 100644 index 000000000..10c154550 --- /dev/null +++ b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.modca; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import org.apache.fop.afp.modca.triplets.AbstractTriplet; +import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet; +import org.apache.fop.afp.modca.triplets.CommentTriplet; +import org.apache.fop.afp.modca.triplets.ObjectAreaSizeTriplet; +import org.apache.fop.afp.modca.triplets.Triplet; + +/** + * Test {@link AbstractTripletStructuredObject} + */ +public class AbstractTripletStructuredObjectTest<S extends AbstractTripletStructuredObject> + extends AbstractStructuredObjectTest<AbstractTripletStructuredObject> { + + private static final List<AbstractTriplet> TRIPLETS; + + static { + List<AbstractTriplet> triplets = new ArrayList<AbstractTriplet>(); + + triplets.add(new CommentTriplet((byte) 0x01, "test comment")); + + triplets.add(new AttributeQualifierTriplet(1, 1)); + + triplets.add(new ObjectAreaSizeTriplet(10, 20)); + + TRIPLETS = Collections.unmodifiableList(triplets); + } + + private AbstractTripletStructuredObject emptyStructuredObject + = new AbstractTripletStructuredObject() { }; + + @Before + public void setUp() throws Exception { + AbstractTripletStructuredObject sut = getSut(); + + for (AbstractTriplet triplet : TRIPLETS) { + sut.addTriplet(triplet); + } + } + + + /** + * Test getTripletLength() - ensure a sum of all enclosing object lengths is returned. + */ + public void testGetTripletLength() { + + int dataLength = 0; + for (Triplet t : TRIPLETS) { + dataLength += t.getDataLength(); + } + assertEquals(dataLength, getSut().getTripletDataLength()); + assertEquals(0, emptyStructuredObject.getTripletDataLength()); + } + + /** + * Test hasTriplets() + */ + public void testHasTriplets() { + assertTrue(getSut().hasTriplets()); + assertFalse(emptyStructuredObject.hasTriplets()); + } + + /** + * Test writeTriplets() - Ensure the triplets are written properly. + * + * @throws IOException - + */ + public void testWriteObjects() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + for (AbstractTriplet triplet : TRIPLETS) { + triplet.writeToStream(baos); + } + byte[] expected = baos.toByteArray(); + baos.reset(); + getSut().writeTriplets(baos); + assertTrue(Arrays.equals(expected, baos.toByteArray())); + + baos.reset(); + // Ensure it doesn't die if no data has been added + emptyStructuredObject.writeTriplets(baos); + byte[] emptyArray = baos.toByteArray(); + assertTrue(Arrays.equals(emptyArray, new byte[0])); + } + + /** + * Test hasTriplet() - ensure both positive and negative values are returned. + */ + public void testHasTriplet() { + for (AbstractTriplet triplet : TRIPLETS) { + assertTrue(getSut().hasTriplet(triplet.getId())); + assertFalse(emptyStructuredObject.hasTriplet(triplet.getId())); + } + CommentTriplet notInSystem = new CommentTriplet((byte) 0x30, "This should return false"); + assertFalse(getSut().hasTriplet(notInSystem.getId())); + } + + /** + * Test addTriplet() - mostly tested above, but check boundary cases + */ + public void testAddTriplet() { + // ensure null doesn't kill it... not sure what else to test + getSut().addTriplet(null); + } + + /** + * Test addTriplets() - ensure all triplets are added. + */ + @Test + public void testAddTriplets() { + // Tested on empty object + List<AbstractTriplet> expectedList = TRIPLETS; + emptyStructuredObject.addTriplets(expectedList); + // checks equals() on each member of both lists + assertEquals(expectedList, emptyStructuredObject.getTriplets()); + + // Add a list to an already populated list + getSut().addTriplets(expectedList); + + List<AbstractTriplet> newExpected = new ArrayList<AbstractTriplet>(expectedList); + newExpected.addAll(expectedList); + assertEquals(newExpected, getSut().getTriplets()); + + // Ensure null doesn't throw exception + emptyStructuredObject.addTriplets(null); + } + +} diff --git a/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java new file mode 100644 index 000000000..0449f2599 --- /dev/null +++ b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id:$ */ + +package org.apache.fop.afp.modca; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.apache.fop.afp.util.BinaryUtils; +import org.junit.Before; +import org.junit.Test; + +/** + * Test {@link IncludeObject} + */ +public class IncludeObjectTestCase extends AbstractNamedAFPObjectTest<IncludeObject> { + + @Before + public void setUp() throws Exception { + setSut(new IncludeObject("8__chars")); + } + + /** + * Test writeToStream() + * @throws IOException - + */ + @Test + public void testWriteToStream() throws IOException { + final IncludeObject sut = getSut(); + + byte[] expected = defaultIncludeObjectBytes(sut.getTripletDataLength(), sut.getNameBytes()); + + testWriteToStreamHelper(sut, expected); + } + + /** + * Test writeToStream() - the orientation of the referenced object is a right- + * handed with a 180 x-axis + * @throws IOException - + */ + @Test + public void testWriteToStreamForOrientation() throws IOException { + final IncludeObject sut = getSut(); + + byte[] expected = defaultIncludeObjectBytes(sut.getTripletDataLength(), sut.getNameBytes()); + + expected[25] = (byte)0x5A; + expected[26] = (byte)0x00; + expected[27] = (byte)0x87; + expected[28] = (byte)0x00; + + sut.setObjectAreaOrientation(180); + + testWriteToStreamHelper(sut, expected); + } + + private void testWriteToStreamHelper(IncludeObject sut, byte[] expected) throws IOException { + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + sut.writeToStream(baos); + + byte[] actual = baos.toByteArray(); + + assertTrue(Arrays.equals(actual, expected)); + } + + private byte[] defaultIncludeObjectBytes(int tripletDataLength, byte[] nameData) { + + byte[] expected = new byte[36]; + + byte[] header = new byte[] { + 0x5A, // Structured field identifier + 0x00, // Length byte 1 + 0x10, // Length byte 2 + (byte)0xD3, // Structured field id byte 1 + (byte)0xAF, // Structured field id byte 2 - type 'input' + (byte)0xC3, // Structured field id byte 3 - category 'data resource' + 0x00, // Flags + 0x00, // Reserved + 0x00, // Reserved + }; + + System.arraycopy(header, 0, expected, 0, header.length); + + byte[] lengthBytes = BinaryUtils.convert(35 + tripletDataLength, 2); //Ignore first byte + expected[1] = lengthBytes[0]; + expected[2] = lengthBytes[1]; + + System.arraycopy(nameData, 0, expected, 9, nameData.length); + + expected[18] = (byte)0x92; // object type 'other' + + expected[27] = (byte)0x2D; // orientation of the reference object + writeOsetTo(expected, 29, -1); // the X-axis origin defined in the object + writeOsetTo(expected, 32, -1); // the Y-axis origin defined in the object + + expected[35] = 0x01; // Page or overlay coordinate system + + return expected; + } + + private static void writeOsetTo(byte[] out, int offset, int oset) { + if (oset > -1) { + byte[] y = BinaryUtils.convert(oset, 3); + out[offset] = y[0]; + out[offset + 1] = y[1]; + out[offset + 2] = y[2]; + } else { + out[offset] = (byte)0xFF; + out[offset + 1] = (byte)0xFF; + out[offset + 2] = (byte)0xFF; + } + } +} diff --git a/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java new file mode 100644 index 000000000..c80ef086c --- /dev/null +++ b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.afp.parser; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.InputStream; +import java.util.Arrays; + +import org.junit.Test; + +/** + * MODCAParser and MODCAParser.UnparsedStructuredField Unit tests + */ +public class MODCAParserTestCase { + + /** The carriage control character (0x5A) used to indicate the start of a structured field. */ + public static final byte CARRIAGE_CONTROL_CHAR = (byte)0x5A; + /**ASCII carriage return control character*/ + public static final byte CARRIAGE_RETURN = (byte)0x0A; + /**ASCII line feed control character */ + public static final byte LINE_FEED = (byte)0x0D; + /** 8 byte introducer describe the SF */ + private static final int INTRODUCER_LENGTH = 8; + + /** + * Test that the MODCA parser recognises carriage control (0x5A) as the Structured Field + * delimeter + * + * @throws Exception * + */ + @Test + public void testReadNextStructuredField1() throws Exception { + + // carriage control (0x5A) delimits structured fields, + // and control is handed to readStructuredField(DataInputStream) + byte[][] goodInputStream = new byte[][]{ + new byte[]{CARRIAGE_CONTROL_CHAR} + }; + + for (byte[] b : goodInputStream) { + try { + new MODCAParser(new ByteArrayInputStream(b)) + .readNextStructuredField(); + fail("BAD SF should throw EOF: " + byteArrayToString(b)); + } catch (EOFException eof) { + //passed + } + } + + // EOFException thrown when reading the input stream are caught and + // a null value is returned + byte[][] badInputStream = new byte[][]{ + new byte[]{}, + new byte[]{CARRIAGE_RETURN}, + new byte[]{LINE_FEED} + }; + + for (byte[] b : badInputStream) { + UnparsedStructuredField usf = new MODCAParser(new ByteArrayInputStream(b)) + .readNextStructuredField(); + assertNull(usf); + } + } + + + /** + * Test that the MODCA parser correctly constructs an UnparsedStructuredField + * from a well formed structured field + * + * @throws Exception * + */ + @Test + public void testReadNextStructuredField2() throws Exception { + + // no extension data + testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID + (byte)0, //flags excluding the bits for + //extension present, segmented data and padding present + false, false, + new byte[]{0, 0}, + new byte[]{1}, null); + + // with extension data + testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID + (byte)0, //flags excluding the bits for + //extension present, segmented data and padding present + false, false, + new byte[]{0, 0}, + new byte[]{1}, new byte[]{10}); + + // with ignored reserved bits + testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID + (byte)0, //flags excluding the bits for + //extension present, segmented data and padding present + false, false, + new byte[]{1, 2}, + new byte[]{1}, null); + + // with padding present and segmented data + testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID + (byte)(1 << 3), //flags excluding the bits for + //extension present, segmented data and padding present + true, true, + new byte[]{0, 0}, + new byte[]{1}, null); + + // with flags non zero + testSF((byte)0xd3, (byte)0xa8, (byte)0x89, //SFTypeID + (byte)(1 << 3), //flags excluding the bits for + //extension present, segmented data and padding present + false, false, + new byte[]{0, 0}, + new byte[]{1}, null); + } + + + private void testSF(byte classCode, byte typeCode, byte categoryCode, + byte flags, boolean segmentedData, boolean paddingPresent, byte[] reserved, + byte[] data, byte[] extData) throws Exception { + + byte extDataLength = 0; + boolean extensionPresent = (extData != null); + + if (extensionPresent) { + flags = (byte)(flags | 0x01); + extDataLength = (byte)(extData.length + 1); //length includes length byte + } + + if (segmentedData) { + flags = (byte)(flags | 0x04); + } + + if (paddingPresent) { + flags = (byte)(flags | 0x10); + } + + short length = (short)(INTRODUCER_LENGTH + data.length + extDataLength); + byte[] lengthBytes = new byte[]{(byte)(length >> 8), (byte)(length & 0xFF)}; + + byte[] sfBytes = new byte[length]; + + //introducer bytes + sfBytes[0] = lengthBytes[0]; + sfBytes[1] = lengthBytes[1]; + sfBytes[2] = classCode; + sfBytes[3] = typeCode; + sfBytes[4] = categoryCode; + sfBytes[5] = flags; + sfBytes[6] = reserved[0]; + sfBytes[7] = reserved[1]; + + if (extDataLength > 0) { + sfBytes[8] = (byte)(extData.length + 1); + System.arraycopy(extData, 0, sfBytes, 9, extData.length); + } + + System.arraycopy(data, 0, sfBytes, length - data.length, data.length); + + + byte[] delimiteredSF = new byte[length + 1]; + + delimiteredSF[0] = (byte)0x5A; + + System.arraycopy(sfBytes, 0, delimiteredSF, 1, length); + + InputStream bis = new ByteArrayInputStream(delimiteredSF); + + UnparsedStructuredField actual = new MODCAParser(bis) + .readNextStructuredField(); + + //check introducer + assertEquals(length, actual.getSfLength()); + assertEquals(classCode, actual.getSfClassCode()); + assertEquals(typeCode, actual.getSfTypeCode()); + assertEquals(categoryCode, actual.getSfCategoryCode()); + assertEquals(extensionPresent, actual.isSfiExtensionPresent()); + assertEquals(segmentedData, actual.isSfiSegmentedData()); + assertEquals(paddingPresent, actual.isSfiPaddingPresent()); + + byte[] introducerData = new byte[]{(byte)(length >> 8), (byte)(length & 0xFF), + classCode, typeCode, categoryCode, flags, reserved[0], reserved[1]}; + + assertTrue(Arrays.equals(introducerData, actual.getIntroducerData())); + + //check data + assertTrue(Arrays.equals(data, actual.getData())); + + //check extension data + if (extData != null) { + assertTrue(Arrays.equals(extData, actual.getExtData())); + } + assertEquals( + (extData == null) ? 0 : extData.length + 1, // 1 byte for length byte + actual.getExtLength()); + + assertTrue(Arrays.equals(data, actual.getData())); + + int expectedSfTypeID = ((classCode & 0xFF) << 16) + | ((typeCode & 0xFF) << 8) + | (categoryCode & 0xFF); + + assertEquals(expectedSfTypeID, actual.getSfTypeID()); + + assertTrue(Arrays.equals(sfBytes, actual.getCompleteFieldAsBytes())); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + actual.writeTo(baos); + assertTrue(Arrays.equals(sfBytes, baos.toByteArray())); + + } + + + private static String byteArrayToString(byte[] byteArray) { + StringBuilder sb = new StringBuilder(); + for (byte b : byteArray) { + sb.append(Integer.toHexString(b & 0xFF)).append(" "); + } + return sb.toString(); + } + +} diff --git a/test/java/org/apache/fop/afp/simple.fo b/test/java/org/apache/fop/afp/simple.fo new file mode 100644 index 000000000..760ff4b63 --- /dev/null +++ b/test/java/org/apache/fop/afp/simple.fo @@ -0,0 +1,14 @@ +<?xml version="1.0" standalone="no"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="420pt" page-width="320pt" margin="10pt"> + <fo:region-body background-color="#F0F0F0"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block>This is a simple document.</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/java/org/apache/fop/area/BlockViewportTestCase.java b/test/java/org/apache/fop/area/BlockViewportTestCase.java new file mode 100644 index 000000000..f825fdda5 --- /dev/null +++ b/test/java/org/apache/fop/area/BlockViewportTestCase.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area; + +import org.junit.Test; + +/** + * Tests the {@linkplain BlockViewport} class. + */ +public class BlockViewportTestCase extends ViewportTest { + + @Test + public void testNonClip() throws Exception { + BlockViewport bv = new BlockViewport(); + bv.setIPD(100); + bv.setBPD(50); + checkNonClip(bv); + } + + @Test + public void testClip() throws Exception { + BlockViewport bv = new BlockViewport(); + int ipd = 100; + int bpd = 50; + bv.setIPD(ipd); + bv.setBPD(bpd); + bv.setClip(true); + checkClip(bv, ipd, bpd); + } +} diff --git a/test/java/org/apache/fop/area/RegionViewportTestCase.java b/test/java/org/apache/fop/area/RegionViewportTestCase.java new file mode 100644 index 000000000..638126efb --- /dev/null +++ b/test/java/org/apache/fop/area/RegionViewportTestCase.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area; + +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; + +import org.junit.Test; + +/** + * Tests the {@linkplain RegionViewport} class. + */ +public class RegionViewportTestCase extends ViewportTest { + + private RegionViewport createRegionViewport(int x, int y, int ipd, int bpd) { + Rectangle2D v = new Rectangle(x, y, ipd, bpd); + RegionViewport viewport = new RegionViewport(v); + viewport.setIPD(ipd); + viewport.setBPD(bpd); + return viewport; + } + + @Test + public void testNonClip() throws Exception { + RegionViewport viewport = createRegionViewport(10, 10, 100, 20); + checkNonClip(viewport); + } + + @Test + public void testClip() throws Exception { + int ipd = 150; + int bpd = 20; + RegionViewport viewport = createRegionViewport(10, 10, ipd, bpd); + viewport.setClip(true); + checkClip(viewport, ipd, bpd); + } +} diff --git a/test/java/org/apache/fop/area/ViewportTest.java b/test/java/org/apache/fop/area/ViewportTest.java new file mode 100644 index 000000000..cb2282071 --- /dev/null +++ b/test/java/org/apache/fop/area/ViewportTest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.awt.Rectangle; + +/** + * Tests implementations of the {@linkplain Viewport} interface. + */ +public abstract class ViewportTest { + + protected void checkNonClip(Viewport v) throws Exception { + assertFalse(v.hasClip()); + assertNull(v.getClipRectangle()); + } + + protected void checkClip(Viewport v, int expectedWidth, int expectedHeight) throws Exception { + assertTrue(v.hasClip()); + assertEquals(new Rectangle(0, 0, expectedWidth, expectedHeight), v.getClipRectangle()); + } +} diff --git a/test/java/org/apache/fop/area/ViewportTestSuite.java b/test/java/org/apache/fop/area/ViewportTestSuite.java new file mode 100644 index 000000000..065e07bf9 --- /dev/null +++ b/test/java/org/apache/fop/area/ViewportTestSuite.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area; + +import org.apache.fop.area.inline.InlineViewportTestCase; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * A suite of all the tests relating to the {@linkplain Viewport} interface. + */ +@RunWith(Suite.class) +@SuiteClasses({ + RegionViewportTestCase.class, + BlockViewportTestCase.class, + InlineViewportTestCase.class +}) +public final class ViewportTestSuite { +} diff --git a/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java new file mode 100644 index 000000000..edcf99d14 --- /dev/null +++ b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.area.inline; + +import org.apache.fop.area.ViewportTest; +import org.junit.Test; + +/** + * Tests the {@linkplain InlineViewport} class. + */ +public class InlineViewportTestCase extends ViewportTest { + + @Test + public void testNonClip() throws Exception { + InlineViewport v = new InlineViewport(null); + v.setIPD(50); + v.setBPD(25); + checkNonClip(v); + } + + @Test + public void testClip() throws Exception { + InlineViewport v = new InlineViewport(null); + int ipd = 50; + int bpd = 25; + v.setIPD(ipd); + v.setBPD(bpd); + v.setClip(true); + checkClip(v, ipd, bpd); + } + +} diff --git a/test/java/org/apache/fop/check/Check.java b/test/java/org/apache/fop/check/Check.java new file mode 100644 index 000000000..ffc7e3cbc --- /dev/null +++ b/test/java/org/apache/fop/check/Check.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.check; + +/** + * A marker interface to identify checks in XML test cases. + */ +public interface Check { + +} diff --git a/test/java/org/apache/fop/check/ChecksFactory.java b/test/java/org/apache/fop/check/ChecksFactory.java new file mode 100644 index 000000000..a493c09f2 --- /dev/null +++ b/test/java/org/apache/fop/check/ChecksFactory.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.check; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A factory class for creating checks that belong to a same family. + * @param <C> a family of checks + */ +public abstract class ChecksFactory<C extends Check> { + + /** + * A factory to create a particular kind of check. + */ + protected static interface CheckFactory<C> { + + /** + * Creates a {@link Check} instance from the given XML element. + * + * @param element an element representing a check + * @return the corresponding check + */ + C createCheck(Element element); + } + + private final Map<String, CheckFactory<C>> checkFactories + = new HashMap<String, CheckFactory<C>>(); + + /** Default constructor. */ + protected ChecksFactory() { } + + /** + * Registers a factory for a new kind of check. + * + * @param elementName the name of the element under which the check is identified in + * the XML test case + * @param factory the corresponding factory + */ + protected void registerCheckFactory(String elementName, CheckFactory<C> factory) { + checkFactories.put(elementName, factory); + } + + /** + * Creates a new {@link Check} instance corresponding to the given element. + * + * @param element an element in the XML test case that identifies a particular check + * @return the corresponding check + * @throws IllegalArgumentException if not check corresponding to the given element + * has been found + */ + public final C createCheck(Element element) { + String name = element.getTagName(); + CheckFactory<C> factory = checkFactories.get(name); + if (factory == null) { + throw new IllegalArgumentException("No check class found for " + name); + } else { + return factory.createCheck(element); + } + } + + public final List<C> createCheckList(Element container) { + List<C> checks = new ArrayList<C>(); + NodeList nodes = container.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node instanceof Element) { + checks.add(createCheck((Element) node)); + } + } + return checks; + } +} diff --git a/test/java/org/apache/fop/check/package-info.java b/test/java/org/apache/fop/check/package-info.java new file mode 100644 index 000000000..5785f7a4b --- /dev/null +++ b/test/java/org/apache/fop/check/package-info.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +/** + * A framework for creating checks from elements stored in an XML test case. The test case + * typically contains the XML document under test, along with a series of checks expressed + * as XML elements. + */ +package org.apache.fop.check; diff --git a/test/java/org/apache/fop/complexscripts/ComplexScriptsTestSuite.java b/test/java/org/apache/fop/complexscripts/ComplexScriptsTestSuite.java new file mode 100644 index 000000000..1dc0610b9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/ComplexScriptsTestSuite.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.complexscripts.bidi.BidiTestSuite; +import org.apache.fop.complexscripts.fonts.FontsTestSuite; +import org.apache.fop.complexscripts.scripts.ScriptsTestSuite; +import org.apache.fop.complexscripts.util.UtilTestSuite; + +/** + * Test suite for complex scripts functionality. + */ +@RunWith(Suite.class) +@SuiteClasses({ + BidiTestSuite.class, + FontsTestSuite.class, + ScriptsTestSuite.class, + UtilTestSuite.class +}) +public class ComplexScriptsTestSuite { +} diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java new file mode 100644 index 000000000..6593ef1ba --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.bidi; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.complexscripts.bidi.UnicodeBidiAlgorithm; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * <p>Test case for Unicode Bidi Algorithm.</p> + * @author Glenn Adams + */ +public class BidiAlgorithmTestCase { + + /** + * logging instance + */ + private static final Log log = LogFactory.getLog(BidiAlgorithmTestCase.class); // CSOK: ConstantNameCheck + + /** + * Concatenated array of <test-set,test-sequence> tuples + * specifying which sequences are to be excluded from testing, + * where -1 for either component is a wildcard. + */ + private static final int[] EXCLUSIONS = { + // no exclusions + }; + + /** + * Concatenated array of <test-set,test-sequence> tuples + * specifying which sequences are to be included in testing, where + * -1 for either component is a wildcard. + */ + private static final int[] INCLUSIONS = { + -1, -1 // all sequences + }; + + /** + * Concatenated array of <start,end> tuples expressing ranges of + * test sets to be tested, where -1 in the end position signifies + * all remaining test sets. + */ + private static final int[] TEST_SET_RANGES = { + 0, -1 // all test sets + }; + + // instrumentation + private int includedSequences; + private int excludedSequences; + private int passedSequences; + + @Test + public void testBidiAlgorithm() throws Exception { + String ldPfx = BidiTestData.LD_PFX; + int ldCount = BidiTestData.LD_CNT; + for ( int i = 0; i < ldCount; i++ ) { + int[] da = BidiTestData.readTestData ( ldPfx, i ); + if ( da != null ) { + testBidiAlgorithm ( i, da ); + } else { + fail ( "unable to read bidi test data for resource at index " + i ); + } + } + // ensure we passed all test sequences + assertEquals ( "did not pass all test sequences", BidiTestData.NUM_TEST_SEQUENCES, passedSequences ); + if ( log.isDebugEnabled() ) { + log.debug ( "Included Sequences : " + includedSequences ); + log.debug ( "Excluded Sequences : " + excludedSequences ); + log.debug( "Passed Sequences : " + passedSequences ); + } + } + + private void testBidiAlgorithm ( int testSet, int[] da ) throws Exception { + if ( da.length < 1 ) { + fail ( "test data is empty" ); + } else if ( da.length < ( ( da[0] * 2 ) + 1 ) ) { + fail ( "test data is truncated" ); + } else { + int k = 0; + // extract level count + int n = da[k++]; + // extract level array + int[] la = new int [ n ]; + for ( int i = 0; i < n; i++ ) { + la[i] = da[k++]; + } + // extract reorder array + int[] ra = new int [ n ]; + for ( int i = 0; i < n; i++ ) { + ra[i] = da[k++]; + } + // extract and test each test sequence + int testSequence = 0; + int[] ta = new int [ n ]; + while ( ( k + ( 1 + n ) ) <= da.length ) { + int bs = da[k++]; + for ( int i = 0; i < n; i++ ) { + ta[i] = da[k++]; + } + if ( includeSequence ( testSet, testSequence ) ) { + includedSequences++; + if ( ! excludeSequence ( testSet, testSequence ) ) { + if ( testBidiAlgorithm ( testSet, testSequence, la, ra, ta, bs ) ) { + passedSequences++; + } + } else { + excludedSequences++; + } + } + testSequence++; + } + // ensure we exhausted test data + assertEquals ( "extraneous test data", da.length, k ); + } + } + + private boolean includeTestSet ( int testSet ) { + for ( int i = 0, n = TEST_SET_RANGES.length / 2; i < n; i++ ) { + int s = TEST_SET_RANGES [ ( i * 2 ) + 0 ]; + int e = TEST_SET_RANGES [ ( i * 2 ) + 1 ]; + if ( testSet >= s ) { + if ( ( e < 0 ) || ( testSet <= e ) ) { + return true; + } + } + } + return false; + } + + private boolean includeSequence ( int testSet, int testSequence ) { + if ( ! includeTestSet ( testSet ) ) { + return false; + } else { + for ( int i = 0, n = INCLUSIONS.length / 2; i < n; i++ ) { + int setno = INCLUSIONS [ ( i * 2 ) + 0 ]; + int seqno = INCLUSIONS [ ( i * 2 ) + 1 ]; + if ( setno < 0 ) { + if ( seqno < 0 ) { + return true; + } else if ( seqno == testSequence ) { + return true; + } + } else if ( setno == testSet ) { + if ( seqno < 0 ) { + return true; + } else if ( seqno == testSequence ) { + return true; + } + } + } + return false; + } + } + + private boolean excludeSequence ( int testSet, int testSequence ) { + for ( int i = 0, n = EXCLUSIONS.length / 2; i < n; i++ ) { + int setno = EXCLUSIONS [ ( i * 2 ) + 0 ]; + int seqno = EXCLUSIONS [ ( i * 2 ) + 1 ]; + if ( setno < 0 ) { + if ( seqno < 0 ) { + return true; + } else if ( seqno == testSequence ) { + return true; + } + } else if ( setno == testSet ) { + if ( seqno < 0 ) { + return true; + } else if ( seqno == testSequence ) { + return true; + } + } + } + return false; + } + + private boolean testBidiAlgorithm ( int testSet, int testSequence, int[] la, int[] ra, int[] ta, int bs ) throws Exception { + boolean passed = true; + int n = la.length; + if ( ra.length != n ) { + fail ( "bad reorder array length, expected " + n + ", got " + ra.length ); + } else if ( ta.length != n ) { + fail ( "bad test array length, expected " + n + ", got " + ta.length ); + } else { + // auto-LTR + if ( ( bs & 1 ) != 0 ) { + // auto-LTR is performed at higher level + } + // LTR + if ( ( bs & 2 ) != 0 ) { + int[] levels = UnicodeBidiAlgorithm.resolveLevels ( null, ta, 0, new int [ n ], true ); + if ( ! verifyResults ( la, levels, ta, 0, testSet, testSequence ) ) { + passed = false; + } + } + // RTL + if ( ( bs & 4 ) != 0 ) { + int[] levels = UnicodeBidiAlgorithm.resolveLevels ( null, ta, 1, new int [ n ], true ); + if ( ! verifyResults ( la, levels, ta, 1, testSet, testSequence ) ) { + passed = false; + } + } + } + return passed; + } + + private boolean verifyResults ( int[] laExp, int[] laOut, int[] ta, int dl, int testSet, int testSequence ) { + if ( laOut.length != laExp.length ) { + fail ( "output levels array length mismatch, expected " + laExp.length + ", got " + laOut.length ); + return false; + } else { + int numMatch = 0; + for ( int i = 0, n = laExp.length; i < n; i++ ) { + if ( laExp[i] >= 0 ) { + int lo = laOut[i]; + int le = laExp[i]; + if ( lo != le ) { + assertEquals ( getMismatchMessage ( testSet, testSequence, i, dl ), le, lo ); + } else { + numMatch++; + } + } else { + numMatch++; + } + } + return numMatch == laExp.length; + } + } + + private String getMismatchMessage ( int testSet, int testSequence, int seqIndex, int defaultLevel ) { + StringBuffer sb = new StringBuffer(); + sb.append ( "level mismatch for default level " ); + sb.append ( defaultLevel ); + sb.append ( " at sequence index " ); + sb.append ( seqIndex ); + sb.append ( " in test sequence " ); + sb.append ( testSequence ); + sb.append ( " of test set " ); + sb.append ( testSet ); + return sb.toString(); + } + +} diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java new file mode 100644 index 000000000..0ea9017bc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.bidi; + +import org.apache.fop.complexscripts.bidi.BidiClass; +import org.apache.fop.util.CharUtilities; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class BidiClassTestCase { + + @Test + public void testBidiClasses() throws Exception { + String tdPfx = BidiTestData.TD_PFX; + int tdCount = BidiTestData.TD_CNT; + for ( int i = 0; i < tdCount; i++ ) { + int[] da = BidiTestData.readTestData ( tdPfx, i ); + if ( da != null ) { + testBidiClass ( da ); + } else { + fail ( "unable to read bidi test data for resource at index " + i ); + } + } + } + + private void testBidiClass ( int[] da ) throws Exception { + int bc = da[0]; + for ( int i = 1, n = da.length; i < n; i += 2 ) { + int s = da[i+0]; + int e = da[i+1]; + for ( int c = s; c < e; c++ ) { + int cbc = BidiClass.getBidiClass ( c ); + assertEquals ( "bad bidi class for CH(" + CharUtilities.format ( c ) + ")", bc, cbc ); + } + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD0.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD0.ser Binary files differnew file mode 100644 index 000000000..6eccb4b6f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD0.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser Binary files differnew file mode 100644 index 000000000..8a7a802d2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser Binary files differnew file mode 100644 index 000000000..74a52f212 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser Binary files differnew file mode 100644 index 000000000..4058da121 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser Binary files differnew file mode 100644 index 000000000..321ed2682 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser Binary files differnew file mode 100644 index 000000000..f5e3973dd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser Binary files differnew file mode 100644 index 000000000..0235952c9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser Binary files differnew file mode 100644 index 000000000..00d9ff6b4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser Binary files differnew file mode 100644 index 000000000..b924c8d19 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser Binary files differnew file mode 100644 index 000000000..2cdabbf17 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser Binary files differnew file mode 100644 index 000000000..24e41ceab --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser Binary files differnew file mode 100644 index 000000000..8c9d014f2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser Binary files differnew file mode 100644 index 000000000..fc2fc255e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser Binary files differnew file mode 100644 index 000000000..2a40fe758 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser Binary files differnew file mode 100644 index 000000000..89ef3a341 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser Binary files differnew file mode 100644 index 000000000..0691f5f96 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser Binary files differnew file mode 100644 index 000000000..c3bd6103e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser Binary files differnew file mode 100644 index 000000000..54d27e213 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser Binary files differnew file mode 100644 index 000000000..0ba52993a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser Binary files differnew file mode 100644 index 000000000..0b95e6283 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser Binary files differnew file mode 100644 index 000000000..ca1111447 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser Binary files differnew file mode 100644 index 000000000..fbce0f949 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser Binary files differnew file mode 100644 index 000000000..c7bee5162 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser Binary files differnew file mode 100644 index 000000000..83ad166ef --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser Binary files differnew file mode 100644 index 000000000..81ff5dcbd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser Binary files differnew file mode 100644 index 000000000..2a84369ef --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser Binary files differnew file mode 100644 index 000000000..3c3f08edf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser Binary files differnew file mode 100644 index 000000000..81a342bc0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser Binary files differnew file mode 100644 index 000000000..f2fdba316 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser Binary files differnew file mode 100644 index 000000000..5bebb054f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser Binary files differnew file mode 100644 index 000000000..1292a8a01 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser Binary files differnew file mode 100644 index 000000000..f7c910fb0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser Binary files differnew file mode 100644 index 000000000..bb2d2353a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser Binary files differnew file mode 100644 index 000000000..4ef886527 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser Binary files differnew file mode 100644 index 000000000..7538307f8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser Binary files differnew file mode 100644 index 000000000..5a81f8f76 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser Binary files differnew file mode 100644 index 000000000..dfa56bb42 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser Binary files differnew file mode 100644 index 000000000..04c0e6b02 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser Binary files differnew file mode 100644 index 000000000..5389ec53c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser Binary files differnew file mode 100644 index 000000000..6ec49f1c7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser Binary files differnew file mode 100644 index 000000000..381b6b741 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser Binary files differnew file mode 100644 index 000000000..e991a278f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser Binary files differnew file mode 100644 index 000000000..84eb27fa3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser Binary files differnew file mode 100644 index 000000000..3e3ceb4f0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser Binary files differnew file mode 100644 index 000000000..52f01ebbf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser Binary files differnew file mode 100644 index 000000000..54a66ac43 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser Binary files differnew file mode 100644 index 000000000..5bad9fe23 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser Binary files differnew file mode 100644 index 000000000..7e58aea97 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser Binary files differnew file mode 100644 index 000000000..60811580c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser Binary files differnew file mode 100644 index 000000000..bfa39bf75 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser Binary files differnew file mode 100644 index 000000000..5df598aa7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser Binary files differnew file mode 100644 index 000000000..f46f6a289 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser Binary files differnew file mode 100644 index 000000000..825930ea8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser Binary files differnew file mode 100644 index 000000000..3d2efe600 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser Binary files differnew file mode 100644 index 000000000..5e3667df8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser Binary files differnew file mode 100644 index 000000000..4a04343a5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser Binary files differnew file mode 100644 index 000000000..85260e0f8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser Binary files differnew file mode 100644 index 000000000..c1cb2878d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser Binary files differnew file mode 100644 index 000000000..ab5dd0c00 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser Binary files differnew file mode 100644 index 000000000..df304a84b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser Binary files differnew file mode 100644 index 000000000..887699163 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser Binary files differnew file mode 100644 index 000000000..fa70ead76 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser Binary files differnew file mode 100644 index 000000000..73402d898 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser Binary files differnew file mode 100644 index 000000000..c611d952e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser Binary files differnew file mode 100644 index 000000000..a5a70cf81 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser Binary files differnew file mode 100644 index 000000000..736576c15 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser Binary files differnew file mode 100644 index 000000000..4667a5a4a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser Binary files differnew file mode 100644 index 000000000..9a07236c3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser Binary files differnew file mode 100644 index 000000000..6a8e667fb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser Binary files differnew file mode 100644 index 000000000..abfeac3ec --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser Binary files differnew file mode 100644 index 000000000..1b225c825 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser Binary files differnew file mode 100644 index 000000000..36aab1fd1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser Binary files differnew file mode 100644 index 000000000..77a744263 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser Binary files differnew file mode 100644 index 000000000..6f340e971 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser Binary files differnew file mode 100644 index 000000000..92ab48e50 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser Binary files differnew file mode 100644 index 000000000..412885433 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser Binary files differnew file mode 100644 index 000000000..3b4b83607 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser Binary files differnew file mode 100644 index 000000000..3e04f60f7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser Binary files differnew file mode 100644 index 000000000..5e58d00f8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser Binary files differnew file mode 100644 index 000000000..290d0e5b4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser Binary files differnew file mode 100644 index 000000000..fb1f6b7ae --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser Binary files differnew file mode 100644 index 000000000..7ba80984d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser Binary files differnew file mode 100644 index 000000000..594645bdc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser Binary files differnew file mode 100644 index 000000000..5d995d076 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser Binary files differnew file mode 100644 index 000000000..e57c46d8e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser Binary files differnew file mode 100644 index 000000000..ad4317529 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser Binary files differnew file mode 100644 index 000000000..52cdcd567 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser Binary files differnew file mode 100644 index 000000000..e786ab17e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser Binary files differnew file mode 100644 index 000000000..2f9e41f08 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser Binary files differnew file mode 100644 index 000000000..94f739223 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser Binary files differnew file mode 100644 index 000000000..53073211e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser Binary files differnew file mode 100644 index 000000000..172498f80 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser Binary files differnew file mode 100644 index 000000000..c5a9b434d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser Binary files differnew file mode 100644 index 000000000..1c98e34a4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser Binary files differnew file mode 100644 index 000000000..4e8c8e30c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser Binary files differnew file mode 100644 index 000000000..824fad23d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser Binary files differnew file mode 100644 index 000000000..969e34a37 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser Binary files differnew file mode 100644 index 000000000..0867d2e55 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser Binary files differnew file mode 100644 index 000000000..dd052d7a1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser Binary files differnew file mode 100644 index 000000000..d52c97d1d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser Binary files differnew file mode 100644 index 000000000..2bdb9dab4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser Binary files differnew file mode 100644 index 000000000..21128bf86 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser Binary files differnew file mode 100644 index 000000000..d153d3442 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser Binary files differnew file mode 100644 index 000000000..5019d6fea --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser Binary files differnew file mode 100644 index 000000000..e726e2651 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser Binary files differnew file mode 100644 index 000000000..c37e1cdd0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser Binary files differnew file mode 100644 index 000000000..1ba7b2877 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser Binary files differnew file mode 100644 index 000000000..62215ed07 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser Binary files differnew file mode 100644 index 000000000..709279994 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser Binary files differnew file mode 100644 index 000000000..788ac372f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser Binary files differnew file mode 100644 index 000000000..9d4a14249 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser Binary files differnew file mode 100644 index 000000000..6cbb79535 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser Binary files differnew file mode 100644 index 000000000..05cf07859 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser Binary files differnew file mode 100644 index 000000000..9c10e367c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser Binary files differnew file mode 100644 index 000000000..583084f0b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser Binary files differnew file mode 100644 index 000000000..d8ed032c6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser Binary files differnew file mode 100644 index 000000000..21e97fff0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser Binary files differnew file mode 100644 index 000000000..5e3e01293 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser Binary files differnew file mode 100644 index 000000000..eba9874c5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser Binary files differnew file mode 100644 index 000000000..182c5fc35 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser Binary files differnew file mode 100644 index 000000000..47ed04ba6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser Binary files differnew file mode 100644 index 000000000..b56f3ee7c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser Binary files differnew file mode 100644 index 000000000..302b20c39 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser Binary files differnew file mode 100644 index 000000000..c97cbbe12 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser Binary files differnew file mode 100644 index 000000000..e7eb886be --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser Binary files differnew file mode 100644 index 000000000..4da33f6c0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser Binary files differnew file mode 100644 index 000000000..46f29b71a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser Binary files differnew file mode 100644 index 000000000..b84d2efaa --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser Binary files differnew file mode 100644 index 000000000..2d0995a6f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser Binary files differnew file mode 100644 index 000000000..66a505aae --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser Binary files differnew file mode 100644 index 000000000..cbd99924e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser Binary files differnew file mode 100644 index 000000000..46b5315a0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser Binary files differnew file mode 100644 index 000000000..4afc67dbc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser Binary files differnew file mode 100644 index 000000000..992177ded --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser Binary files differnew file mode 100644 index 000000000..e75b1d344 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser Binary files differnew file mode 100644 index 000000000..ca7478b6c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser Binary files differnew file mode 100644 index 000000000..3f754847c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser Binary files differnew file mode 100644 index 000000000..02efa8786 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser Binary files differnew file mode 100644 index 000000000..1897b09f8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser Binary files differnew file mode 100644 index 000000000..cd24d1101 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser Binary files differnew file mode 100644 index 000000000..aba011dba --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser Binary files differnew file mode 100644 index 000000000..dad463960 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser Binary files differnew file mode 100644 index 000000000..6430967e4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser Binary files differnew file mode 100644 index 000000000..4f2bde014 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser Binary files differnew file mode 100644 index 000000000..7be09ec92 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser Binary files differnew file mode 100644 index 000000000..6ffa285db --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser Binary files differnew file mode 100644 index 000000000..d6c532596 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser Binary files differnew file mode 100644 index 000000000..3519adb5e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser Binary files differnew file mode 100644 index 000000000..7540663aa --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser Binary files differnew file mode 100644 index 000000000..788e4c7e1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser Binary files differnew file mode 100644 index 000000000..c36265614 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser Binary files differnew file mode 100644 index 000000000..772b72aef --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser Binary files differnew file mode 100644 index 000000000..e5fa50b85 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser Binary files differnew file mode 100644 index 000000000..13fdb364c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser Binary files differnew file mode 100644 index 000000000..c600524d6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser Binary files differnew file mode 100644 index 000000000..6043e0155 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser Binary files differnew file mode 100644 index 000000000..14250a315 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser Binary files differnew file mode 100644 index 000000000..209e8179e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser Binary files differnew file mode 100644 index 000000000..bdbc02f69 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser Binary files differnew file mode 100644 index 000000000..d3f40a8de --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser Binary files differnew file mode 100644 index 000000000..03b94bc76 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser Binary files differnew file mode 100644 index 000000000..cb0321933 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser Binary files differnew file mode 100644 index 000000000..3cdc87c9c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser Binary files differnew file mode 100644 index 000000000..7c50f1284 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser Binary files differnew file mode 100644 index 000000000..b04164e4c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser Binary files differnew file mode 100644 index 000000000..bdce40f9c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser Binary files differnew file mode 100644 index 000000000..e50ed7988 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser Binary files differnew file mode 100644 index 000000000..14ac62043 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser Binary files differnew file mode 100644 index 000000000..c1b31fcce --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser Binary files differnew file mode 100644 index 000000000..d96343972 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser Binary files differnew file mode 100644 index 000000000..7b3168b23 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser Binary files differnew file mode 100644 index 000000000..7f9b9056d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser Binary files differnew file mode 100644 index 000000000..d5849ec9d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser Binary files differnew file mode 100644 index 000000000..00a2b4a0e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser Binary files differnew file mode 100644 index 000000000..5cc330f12 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser Binary files differnew file mode 100644 index 000000000..23e032ac9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser Binary files differnew file mode 100644 index 000000000..7ba16c21a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser Binary files differnew file mode 100644 index 000000000..334737ecd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser Binary files differnew file mode 100644 index 000000000..26defabff --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser Binary files differnew file mode 100644 index 000000000..09dc4ca08 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser Binary files differnew file mode 100644 index 000000000..03cb82426 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser Binary files differnew file mode 100644 index 000000000..6d00960cf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser Binary files differnew file mode 100644 index 000000000..920e4c5b1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser Binary files differnew file mode 100644 index 000000000..dbbee5d7f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser Binary files differnew file mode 100644 index 000000000..716661a75 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser Binary files differnew file mode 100644 index 000000000..b418d9b9f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser Binary files differnew file mode 100644 index 000000000..bc16ddcff --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser Binary files differnew file mode 100644 index 000000000..a105347f0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser Binary files differnew file mode 100644 index 000000000..f75552dc3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser Binary files differnew file mode 100644 index 000000000..a3f6eab8f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser Binary files differnew file mode 100644 index 000000000..604170dcc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser Binary files differnew file mode 100644 index 000000000..755d6cd60 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser Binary files differnew file mode 100644 index 000000000..9b29a7d1e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser Binary files differnew file mode 100644 index 000000000..5685e40b8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser Binary files differnew file mode 100644 index 000000000..49a7c0739 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser Binary files differnew file mode 100644 index 000000000..1697a421b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser Binary files differnew file mode 100644 index 000000000..ea0d9adf1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser Binary files differnew file mode 100644 index 000000000..067dca228 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser Binary files differnew file mode 100644 index 000000000..9f9078678 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser Binary files differnew file mode 100644 index 000000000..9cd498c3c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser Binary files differnew file mode 100644 index 000000000..c5c4c6ab0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser Binary files differnew file mode 100644 index 000000000..890ce30bb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser Binary files differnew file mode 100644 index 000000000..fac475452 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser Binary files differnew file mode 100644 index 000000000..4711e4586 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser Binary files differnew file mode 100644 index 000000000..1fcea5dbf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser Binary files differnew file mode 100644 index 000000000..bf2a0bcc5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser Binary files differnew file mode 100644 index 000000000..29a3c23d4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser Binary files differnew file mode 100644 index 000000000..fea28c7d2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser Binary files differnew file mode 100644 index 000000000..48663053e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser Binary files differnew file mode 100644 index 000000000..43f440cf7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser Binary files differnew file mode 100644 index 000000000..385ac7184 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser Binary files differnew file mode 100644 index 000000000..8a032f261 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser Binary files differnew file mode 100644 index 000000000..fdc27290b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser Binary files differnew file mode 100644 index 000000000..264c28e08 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser Binary files differnew file mode 100644 index 000000000..daf236abf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser Binary files differnew file mode 100644 index 000000000..8f972bf5a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser Binary files differnew file mode 100644 index 000000000..647424ee0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser Binary files differnew file mode 100644 index 000000000..9e8b99773 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser Binary files differnew file mode 100644 index 000000000..486bcf475 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser Binary files differnew file mode 100644 index 000000000..856d72fd1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser Binary files differnew file mode 100644 index 000000000..ce0b5bf4c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser Binary files differnew file mode 100644 index 000000000..cad0d5049 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser Binary files differnew file mode 100644 index 000000000..b14aa4597 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser Binary files differnew file mode 100644 index 000000000..6657a3593 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser Binary files differnew file mode 100644 index 000000000..b30faf809 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser Binary files differnew file mode 100644 index 000000000..4baca2704 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser Binary files differnew file mode 100644 index 000000000..630a13467 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser Binary files differnew file mode 100644 index 000000000..0f8e3d7d8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser Binary files differnew file mode 100644 index 000000000..42a05ced7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser Binary files differnew file mode 100644 index 000000000..13ba94a7e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser Binary files differnew file mode 100644 index 000000000..e5a3a925e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser Binary files differnew file mode 100644 index 000000000..1ada57413 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser Binary files differnew file mode 100644 index 000000000..a14a0bebf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser Binary files differnew file mode 100644 index 000000000..c66ae933f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser Binary files differnew file mode 100644 index 000000000..fd1e62ca8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser Binary files differnew file mode 100644 index 000000000..4914c3b65 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser Binary files differnew file mode 100644 index 000000000..e8aad8cad --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser Binary files differnew file mode 100644 index 000000000..0d8f4cf1e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser Binary files differnew file mode 100644 index 000000000..54d856156 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser Binary files differnew file mode 100644 index 000000000..5bd0e8286 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser Binary files differnew file mode 100644 index 000000000..37a4d8c68 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser Binary files differnew file mode 100644 index 000000000..a16a7b8f9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser Binary files differnew file mode 100644 index 000000000..6e5747ed9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser Binary files differnew file mode 100644 index 000000000..3ee6650ed --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser Binary files differnew file mode 100644 index 000000000..8c6f200a2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser Binary files differnew file mode 100644 index 000000000..4774611b5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser Binary files differnew file mode 100644 index 000000000..09332a05e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser Binary files differnew file mode 100644 index 000000000..88327e077 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser Binary files differnew file mode 100644 index 000000000..600eb2ac3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser Binary files differnew file mode 100644 index 000000000..eed01d875 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser Binary files differnew file mode 100644 index 000000000..cc2db9896 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser Binary files differnew file mode 100644 index 000000000..d0ae70999 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser Binary files differnew file mode 100644 index 000000000..eb2a30d19 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser Binary files differnew file mode 100644 index 000000000..5825c9571 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser Binary files differnew file mode 100644 index 000000000..c1b927a19 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser Binary files differnew file mode 100644 index 000000000..5d7eb7f7e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser Binary files differnew file mode 100644 index 000000000..a78094615 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser Binary files differnew file mode 100644 index 000000000..efb28b562 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser Binary files differnew file mode 100644 index 000000000..686c66e20 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser Binary files differnew file mode 100644 index 000000000..b210f7896 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser Binary files differnew file mode 100644 index 000000000..da93f81fc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser Binary files differnew file mode 100644 index 000000000..8a0f567f1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser Binary files differnew file mode 100644 index 000000000..622bdd1e1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser Binary files differnew file mode 100644 index 000000000..4baa13941 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser Binary files differnew file mode 100644 index 000000000..1d40b0818 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser Binary files differnew file mode 100644 index 000000000..ef0b76e42 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser Binary files differnew file mode 100644 index 000000000..bd0a0456f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser Binary files differnew file mode 100644 index 000000000..73ee20cbe --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser Binary files differnew file mode 100644 index 000000000..9e33d39e9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser Binary files differnew file mode 100644 index 000000000..6afa6bf7c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser Binary files differnew file mode 100644 index 000000000..84782b980 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser Binary files differnew file mode 100644 index 000000000..fdde6d7a5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser Binary files differnew file mode 100644 index 000000000..2654a884a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser Binary files differnew file mode 100644 index 000000000..b24a2a444 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser Binary files differnew file mode 100644 index 000000000..613d80bee --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser Binary files differnew file mode 100644 index 000000000..df1df5fbf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser Binary files differnew file mode 100644 index 000000000..3f68bd344 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser Binary files differnew file mode 100644 index 000000000..361734a3c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser Binary files differnew file mode 100644 index 000000000..009e2419c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser Binary files differnew file mode 100644 index 000000000..7c142c3e3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser Binary files differnew file mode 100644 index 000000000..6e14a51a4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser Binary files differnew file mode 100644 index 000000000..ed8f2450d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser Binary files differnew file mode 100644 index 000000000..80489aa41 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser Binary files differnew file mode 100644 index 000000000..ede61bef1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser Binary files differnew file mode 100644 index 000000000..e837ec5a6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser Binary files differnew file mode 100644 index 000000000..0dbeb4a18 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser Binary files differnew file mode 100644 index 000000000..fdbc6a8f2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser Binary files differnew file mode 100644 index 000000000..47665da0c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser Binary files differnew file mode 100644 index 000000000..aae718782 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser Binary files differnew file mode 100644 index 000000000..5bc6e4083 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser Binary files differnew file mode 100644 index 000000000..07d3b8d15 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser Binary files differnew file mode 100644 index 000000000..81af1c964 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser Binary files differnew file mode 100644 index 000000000..4abfa7c14 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser Binary files differnew file mode 100644 index 000000000..aec3af860 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser Binary files differnew file mode 100644 index 000000000..ac1eecb96 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser Binary files differnew file mode 100644 index 000000000..1f1367be6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser Binary files differnew file mode 100644 index 000000000..3cf337cda --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser Binary files differnew file mode 100644 index 000000000..19f7fd9e9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser Binary files differnew file mode 100644 index 000000000..8c92df043 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser Binary files differnew file mode 100644 index 000000000..dad7f014b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser Binary files differnew file mode 100644 index 000000000..b0022c672 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser Binary files differnew file mode 100644 index 000000000..bfbb586fb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser Binary files differnew file mode 100644 index 000000000..b435feea0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser Binary files differnew file mode 100644 index 000000000..dafe64d04 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser Binary files differnew file mode 100644 index 000000000..973fcdc92 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser Binary files differnew file mode 100644 index 000000000..a49d73cfe --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser Binary files differnew file mode 100644 index 000000000..892a50d1b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser Binary files differnew file mode 100644 index 000000000..0fa29c84b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser Binary files differnew file mode 100644 index 000000000..a29b52179 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser Binary files differnew file mode 100644 index 000000000..e7c2a5a36 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser Binary files differnew file mode 100644 index 000000000..0ec361014 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser Binary files differnew file mode 100644 index 000000000..bca795879 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser Binary files differnew file mode 100644 index 000000000..49ca3d106 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser Binary files differnew file mode 100644 index 000000000..0a340e65e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser Binary files differnew file mode 100644 index 000000000..2e73aff87 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser Binary files differnew file mode 100644 index 000000000..d3a437077 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser Binary files differnew file mode 100644 index 000000000..963e0a877 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser Binary files differnew file mode 100644 index 000000000..092300f46 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser Binary files differnew file mode 100644 index 000000000..0c4c00312 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser Binary files differnew file mode 100644 index 000000000..9abf70ed9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser Binary files differnew file mode 100644 index 000000000..7e518db09 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser Binary files differnew file mode 100644 index 000000000..797d08f9c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser Binary files differnew file mode 100644 index 000000000..672e36e4a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser Binary files differnew file mode 100644 index 000000000..de9d5aadb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser Binary files differnew file mode 100644 index 000000000..44c076196 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser Binary files differnew file mode 100644 index 000000000..2706725f7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser Binary files differnew file mode 100644 index 000000000..1cc61a4ed --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser Binary files differnew file mode 100644 index 000000000..33305fe62 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser Binary files differnew file mode 100644 index 000000000..278fb38d7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser Binary files differnew file mode 100644 index 000000000..3d2ff817c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser Binary files differnew file mode 100644 index 000000000..45833bacc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser Binary files differnew file mode 100644 index 000000000..54e88ffc0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser Binary files differnew file mode 100644 index 000000000..751b118a7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser Binary files differnew file mode 100644 index 000000000..4acd804ca --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser Binary files differnew file mode 100644 index 000000000..c65761df1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser Binary files differnew file mode 100644 index 000000000..d6759145b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser Binary files differnew file mode 100644 index 000000000..4c9b21368 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser Binary files differnew file mode 100644 index 000000000..e3e6c6ec2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser Binary files differnew file mode 100644 index 000000000..92e5a6187 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser Binary files differnew file mode 100644 index 000000000..873595ead --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser Binary files differnew file mode 100644 index 000000000..1709012da --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser Binary files differnew file mode 100644 index 000000000..5ad6315e3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser Binary files differnew file mode 100644 index 000000000..aa04c95e2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser Binary files differnew file mode 100644 index 000000000..12edd65ab --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser Binary files differnew file mode 100644 index 000000000..40290ec4c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser Binary files differnew file mode 100644 index 000000000..b59671610 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser Binary files differnew file mode 100644 index 000000000..5d664e82c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser Binary files differnew file mode 100644 index 000000000..9c5866504 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser Binary files differnew file mode 100644 index 000000000..01fe69955 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser Binary files differnew file mode 100644 index 000000000..b71d6c546 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser Binary files differnew file mode 100644 index 000000000..5ad3f0613 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser Binary files differnew file mode 100644 index 000000000..b89491a41 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser Binary files differnew file mode 100644 index 000000000..289f9b48d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser Binary files differnew file mode 100644 index 000000000..24d1e1cbe --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser Binary files differnew file mode 100644 index 000000000..927349572 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser Binary files differnew file mode 100644 index 000000000..8208a5005 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser Binary files differnew file mode 100644 index 000000000..346fb131d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser Binary files differnew file mode 100644 index 000000000..28c0e15e1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser Binary files differnew file mode 100644 index 000000000..53d6b158d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser Binary files differnew file mode 100644 index 000000000..c324000e4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser Binary files differnew file mode 100644 index 000000000..d99423cbb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser Binary files differnew file mode 100644 index 000000000..d78b800db --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser Binary files differnew file mode 100644 index 000000000..eabb33cc3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser Binary files differnew file mode 100644 index 000000000..571728da3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser Binary files differnew file mode 100644 index 000000000..25d9cb0aa --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser Binary files differnew file mode 100644 index 000000000..d493f3859 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser Binary files differnew file mode 100644 index 000000000..06b90d501 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser Binary files differnew file mode 100644 index 000000000..5b97f90ca --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser Binary files differnew file mode 100644 index 000000000..22b1b8d9b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser Binary files differnew file mode 100644 index 000000000..db3749949 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser Binary files differnew file mode 100644 index 000000000..272364c6f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser Binary files differnew file mode 100644 index 000000000..078a31f84 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser Binary files differnew file mode 100644 index 000000000..b4aaf015b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser Binary files differnew file mode 100644 index 000000000..52c01f7e9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser Binary files differnew file mode 100644 index 000000000..626e52df0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser Binary files differnew file mode 100644 index 000000000..2de03dae5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser Binary files differnew file mode 100644 index 000000000..041c1a4cf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser Binary files differnew file mode 100644 index 000000000..c8da3b083 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser Binary files differnew file mode 100644 index 000000000..74f71d784 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser Binary files differnew file mode 100644 index 000000000..d1321181b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser Binary files differnew file mode 100644 index 000000000..bcf11b73c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser Binary files differnew file mode 100644 index 000000000..a9ba2dea1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser Binary files differnew file mode 100644 index 000000000..fe728d89c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser Binary files differnew file mode 100644 index 000000000..23d7eb22b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser Binary files differnew file mode 100644 index 000000000..58f06cbce --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser Binary files differnew file mode 100644 index 000000000..bd56f8524 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser Binary files differnew file mode 100644 index 000000000..54d14da06 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser Binary files differnew file mode 100644 index 000000000..ee6f83422 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser Binary files differnew file mode 100644 index 000000000..f94d24f69 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser Binary files differnew file mode 100644 index 000000000..feef36694 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser Binary files differnew file mode 100644 index 000000000..93720aeac --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser Binary files differnew file mode 100644 index 000000000..d1a58aaa5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser Binary files differnew file mode 100644 index 000000000..11f0d14b3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser Binary files differnew file mode 100644 index 000000000..2aef6789e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser Binary files differnew file mode 100644 index 000000000..e60e00a75 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser Binary files differnew file mode 100644 index 000000000..e7ed6f17e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser Binary files differnew file mode 100644 index 000000000..49062bd27 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser Binary files differnew file mode 100644 index 000000000..5b4049240 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser Binary files differnew file mode 100644 index 000000000..c051bb336 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser Binary files differnew file mode 100644 index 000000000..bb781c485 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser Binary files differnew file mode 100644 index 000000000..289e7e587 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser Binary files differnew file mode 100644 index 000000000..c4b5db34b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser Binary files differnew file mode 100644 index 000000000..bacc29cf6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser Binary files differnew file mode 100644 index 000000000..d791c7d59 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser Binary files differnew file mode 100644 index 000000000..eac181fa5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser Binary files differnew file mode 100644 index 000000000..4d4c36621 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser Binary files differnew file mode 100644 index 000000000..ab10d3c9d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser Binary files differnew file mode 100644 index 000000000..ada0cfb53 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser Binary files differnew file mode 100644 index 000000000..b2f924cb4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser Binary files differnew file mode 100644 index 000000000..4965ccab3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser Binary files differnew file mode 100644 index 000000000..f04ae6182 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser Binary files differnew file mode 100644 index 000000000..27fc5e31f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser Binary files differnew file mode 100644 index 000000000..dd2f2f73d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser Binary files differnew file mode 100644 index 000000000..868c0718f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser Binary files differnew file mode 100644 index 000000000..95ba064e9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser Binary files differnew file mode 100644 index 000000000..ec1bcb735 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser Binary files differnew file mode 100644 index 000000000..d4bfab753 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser Binary files differnew file mode 100644 index 000000000..bf4de5393 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser Binary files differnew file mode 100644 index 000000000..b01e493df --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser Binary files differnew file mode 100644 index 000000000..247977216 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser Binary files differnew file mode 100644 index 000000000..0a4655675 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser Binary files differnew file mode 100644 index 000000000..7847c8b34 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser Binary files differnew file mode 100644 index 000000000..6ac093714 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser Binary files differnew file mode 100644 index 000000000..1fb8a568a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser Binary files differnew file mode 100644 index 000000000..4f5ce8e37 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser Binary files differnew file mode 100644 index 000000000..b9cf2310e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser Binary files differnew file mode 100644 index 000000000..d8cc78a39 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser Binary files differnew file mode 100644 index 000000000..44438e065 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser Binary files differnew file mode 100644 index 000000000..a6227255a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser Binary files differnew file mode 100644 index 000000000..415f6c049 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser Binary files differnew file mode 100644 index 000000000..8ea2f93ad --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser Binary files differnew file mode 100644 index 000000000..ca7f77129 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser Binary files differnew file mode 100644 index 000000000..5aaf07824 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser Binary files differnew file mode 100644 index 000000000..655516191 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser Binary files differnew file mode 100644 index 000000000..3cc2d4a75 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser Binary files differnew file mode 100644 index 000000000..94f1d83fd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser Binary files differnew file mode 100644 index 000000000..14b49f0a4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser Binary files differnew file mode 100644 index 000000000..adb3d3737 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser Binary files differnew file mode 100644 index 000000000..b2c4902eb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser Binary files differnew file mode 100644 index 000000000..8b28deac8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser Binary files differnew file mode 100644 index 000000000..5d238271b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser Binary files differnew file mode 100644 index 000000000..ab8f4d6d1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser Binary files differnew file mode 100644 index 000000000..901e4173d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser Binary files differnew file mode 100644 index 000000000..d6fd495bb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser Binary files differnew file mode 100644 index 000000000..52400b507 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser Binary files differnew file mode 100644 index 000000000..4d03b7211 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser Binary files differnew file mode 100644 index 000000000..975618522 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser Binary files differnew file mode 100644 index 000000000..33e7b0c7d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser Binary files differnew file mode 100644 index 000000000..8e101db57 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser Binary files differnew file mode 100644 index 000000000..f8246c2d2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser Binary files differnew file mode 100644 index 000000000..c8707cd48 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser Binary files differnew file mode 100644 index 000000000..41e6c694a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser Binary files differnew file mode 100644 index 000000000..595e24ff2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser Binary files differnew file mode 100644 index 000000000..731b47fd2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser Binary files differnew file mode 100644 index 000000000..8bf1d99fa --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser Binary files differnew file mode 100644 index 000000000..bc63d7e97 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser Binary files differnew file mode 100644 index 000000000..d7415c13a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser Binary files differnew file mode 100644 index 000000000..e8d28148e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser Binary files differnew file mode 100644 index 000000000..b94811af6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser Binary files differnew file mode 100644 index 000000000..91a3bd4ea --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser Binary files differnew file mode 100644 index 000000000..2e31b49d8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser Binary files differnew file mode 100644 index 000000000..2cef55911 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser Binary files differnew file mode 100644 index 000000000..84c1bdeb8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser Binary files differnew file mode 100644 index 000000000..431fe2dd8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser Binary files differnew file mode 100644 index 000000000..37c17f168 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser Binary files differnew file mode 100644 index 000000000..087847d57 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser Binary files differnew file mode 100644 index 000000000..8bd76318d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser Binary files differnew file mode 100644 index 000000000..318fc84a7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser Binary files differnew file mode 100644 index 000000000..5e853ec29 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser Binary files differnew file mode 100644 index 000000000..e72f8d30e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser Binary files differnew file mode 100644 index 000000000..cbd161b83 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser Binary files differnew file mode 100644 index 000000000..a2c4ccff7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser Binary files differnew file mode 100644 index 000000000..cbd7fa3b8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser Binary files differnew file mode 100644 index 000000000..b876b1b27 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser Binary files differnew file mode 100644 index 000000000..64e50de82 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser Binary files differnew file mode 100644 index 000000000..e5f094eeb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser Binary files differnew file mode 100644 index 000000000..537459e7f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser Binary files differnew file mode 100644 index 000000000..577b66158 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser Binary files differnew file mode 100644 index 000000000..4679568f4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser Binary files differnew file mode 100644 index 000000000..389261a05 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser Binary files differnew file mode 100644 index 000000000..635151fa9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser Binary files differnew file mode 100644 index 000000000..69e85f02b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser Binary files differnew file mode 100644 index 000000000..c28ba450a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser Binary files differnew file mode 100644 index 000000000..fe26705e5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser Binary files differnew file mode 100644 index 000000000..19595d9e3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser Binary files differnew file mode 100644 index 000000000..95e9836b4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser Binary files differnew file mode 100644 index 000000000..d179f7c8c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser Binary files differnew file mode 100644 index 000000000..1b91641ad --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser Binary files differnew file mode 100644 index 000000000..fc83f4562 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser Binary files differnew file mode 100644 index 000000000..ea2af6364 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser Binary files differnew file mode 100644 index 000000000..0f76396bb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser Binary files differnew file mode 100644 index 000000000..143d5894a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser Binary files differnew file mode 100644 index 000000000..671cf26d1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser Binary files differnew file mode 100644 index 000000000..1a7fda27b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser Binary files differnew file mode 100644 index 000000000..5aee466d8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser Binary files differnew file mode 100644 index 000000000..37f124113 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser Binary files differnew file mode 100644 index 000000000..8bc00e144 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser Binary files differnew file mode 100644 index 000000000..9d9b9c119 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser Binary files differnew file mode 100644 index 000000000..88411a216 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser Binary files differnew file mode 100644 index 000000000..f8324788b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser Binary files differnew file mode 100644 index 000000000..2d3118a56 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser Binary files differnew file mode 100644 index 000000000..51a8b7095 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser Binary files differnew file mode 100644 index 000000000..e939d4754 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser Binary files differnew file mode 100644 index 000000000..61e5e3f3c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser Binary files differnew file mode 100644 index 000000000..496e6912a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser Binary files differnew file mode 100644 index 000000000..0fc2f1a23 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser Binary files differnew file mode 100644 index 000000000..dc5183342 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser Binary files differnew file mode 100644 index 000000000..de477db15 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser Binary files differnew file mode 100644 index 000000000..6a4e51c29 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser Binary files differnew file mode 100644 index 000000000..fccb593ae --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser Binary files differnew file mode 100644 index 000000000..828b3a72e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser Binary files differnew file mode 100644 index 000000000..3b14d4a8f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser Binary files differnew file mode 100644 index 000000000..373392279 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser Binary files differnew file mode 100644 index 000000000..a91b8512a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser Binary files differnew file mode 100644 index 000000000..639a7be49 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser Binary files differnew file mode 100644 index 000000000..68dd4089b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser Binary files differnew file mode 100644 index 000000000..2908e3f63 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser Binary files differnew file mode 100644 index 000000000..391e3e14a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser Binary files differnew file mode 100644 index 000000000..5bd9c1e71 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser Binary files differnew file mode 100644 index 000000000..d4ecb3a88 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser Binary files differnew file mode 100644 index 000000000..d68ca24ac --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser Binary files differnew file mode 100644 index 000000000..73cd97bf6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser Binary files differnew file mode 100644 index 000000000..a6d766289 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser Binary files differnew file mode 100644 index 000000000..d0af60722 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser Binary files differnew file mode 100644 index 000000000..231290df6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser Binary files differnew file mode 100644 index 000000000..21e85e747 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser Binary files differnew file mode 100644 index 000000000..e99365766 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser Binary files differnew file mode 100644 index 000000000..4f844be2e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser Binary files differnew file mode 100644 index 000000000..ccb6d70f1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser Binary files differnew file mode 100644 index 000000000..aa3909601 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser Binary files differnew file mode 100644 index 000000000..5d1bb4981 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser Binary files differnew file mode 100644 index 000000000..64823ec47 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser Binary files differnew file mode 100644 index 000000000..09d6843e8 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser Binary files differnew file mode 100644 index 000000000..59f2572ad --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser Binary files differnew file mode 100644 index 000000000..cb600cfca --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser Binary files differnew file mode 100644 index 000000000..b1faa848b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser Binary files differnew file mode 100644 index 000000000..1e057fdf4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser Binary files differnew file mode 100644 index 000000000..cdd3cbec1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser Binary files differnew file mode 100644 index 000000000..84eed41fe --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser Binary files differnew file mode 100644 index 000000000..7b91077fc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser Binary files differnew file mode 100644 index 000000000..259194e4e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser Binary files differnew file mode 100644 index 000000000..0616c3c12 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser Binary files differnew file mode 100644 index 000000000..22430bd97 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser Binary files differnew file mode 100644 index 000000000..b583a1a1b --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser Binary files differnew file mode 100644 index 000000000..841747bdf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser Binary files differnew file mode 100644 index 000000000..23521f3cd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser Binary files differnew file mode 100644 index 000000000..168552d3c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser Binary files differnew file mode 100644 index 000000000..c0da95a76 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser Binary files differnew file mode 100644 index 000000000..276e0ffed --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser Binary files differnew file mode 100644 index 000000000..363f4f695 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser Binary files differnew file mode 100644 index 000000000..a0f6639ba --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser Binary files differnew file mode 100644 index 000000000..cdc9eb94a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser Binary files differnew file mode 100644 index 000000000..c6223a7ce --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser Binary files differnew file mode 100644 index 000000000..74f023e83 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser Binary files differnew file mode 100644 index 000000000..9755e4a3c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser Binary files differnew file mode 100644 index 000000000..986a332f3 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser Binary files differnew file mode 100644 index 000000000..edc35abdc --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser Binary files differnew file mode 100644 index 000000000..6ed639c5e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser Binary files differnew file mode 100644 index 000000000..d2c52eba1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser Binary files differnew file mode 100644 index 000000000..f34830970 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser Binary files differnew file mode 100644 index 000000000..7cea4a6c6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser Binary files differnew file mode 100644 index 000000000..e2c08df91 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser Binary files differnew file mode 100644 index 000000000..7a37cd019 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser Binary files differnew file mode 100644 index 000000000..85f679da2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser Binary files differnew file mode 100644 index 000000000..8f1d6966d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser Binary files differnew file mode 100644 index 000000000..f82e37287 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser Binary files differnew file mode 100644 index 000000000..f22902dd5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser Binary files differnew file mode 100644 index 000000000..bb7f98e41 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser Binary files differnew file mode 100644 index 000000000..d25cb04c7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser Binary files differnew file mode 100644 index 000000000..8ddaeb744 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser Binary files differnew file mode 100644 index 000000000..b11de6c32 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser Binary files differnew file mode 100644 index 000000000..2b1ea8898 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser Binary files differnew file mode 100644 index 000000000..1d2ea017c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser Binary files differnew file mode 100644 index 000000000..ae74ca063 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser Binary files differnew file mode 100644 index 000000000..fed68df6e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser Binary files differnew file mode 100644 index 000000000..94b09c1e1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser Binary files differnew file mode 100644 index 000000000..0af062be1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser Binary files differnew file mode 100644 index 000000000..bd93b288c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser Binary files differnew file mode 100644 index 000000000..ea7a544bf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser Binary files differnew file mode 100644 index 000000000..c3510ec9e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser Binary files differnew file mode 100644 index 000000000..c02164344 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser Binary files differnew file mode 100644 index 000000000..16cf973f2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser Binary files differnew file mode 100644 index 000000000..f827db274 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser Binary files differnew file mode 100644 index 000000000..c079752d6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser Binary files differnew file mode 100644 index 000000000..18d091c4a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser Binary files differnew file mode 100644 index 000000000..2628ac645 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser Binary files differnew file mode 100644 index 000000000..e0a656874 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser Binary files differnew file mode 100644 index 000000000..cd908264a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser Binary files differnew file mode 100644 index 000000000..da9a56794 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser Binary files differnew file mode 100644 index 000000000..1eec94eeb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser Binary files differnew file mode 100644 index 000000000..1458485b6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser Binary files differnew file mode 100644 index 000000000..0bb894af9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser Binary files differnew file mode 100644 index 000000000..596af011c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser Binary files differnew file mode 100644 index 000000000..adac3305c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser Binary files differnew file mode 100644 index 000000000..1440bb78a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser Binary files differnew file mode 100644 index 000000000..2a1091e9c --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser Binary files differnew file mode 100644 index 000000000..a519dc078 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser Binary files differnew file mode 100644 index 000000000..533579a8f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser Binary files differnew file mode 100644 index 000000000..cd8bea1c7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser Binary files differnew file mode 100644 index 000000000..16635b605 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser Binary files differnew file mode 100644 index 000000000..05616a937 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser Binary files differnew file mode 100644 index 000000000..44ce6375e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser Binary files differnew file mode 100644 index 000000000..cfd698d7d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser Binary files differnew file mode 100644 index 000000000..415f1bf8e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser Binary files differnew file mode 100644 index 000000000..2fc94de93 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser Binary files differnew file mode 100644 index 000000000..a7e226ec1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser Binary files differnew file mode 100644 index 000000000..573c8ce87 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser Binary files differnew file mode 100644 index 000000000..e8df233a5 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser Binary files differnew file mode 100644 index 000000000..abcad78d0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser Binary files differnew file mode 100644 index 000000000..e702881e7 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser Binary files differnew file mode 100644 index 000000000..1b76a8499 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser Binary files differnew file mode 100644 index 000000000..13edb5406 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser Binary files differnew file mode 100644 index 000000000..da2ee39ec --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser Binary files differnew file mode 100644 index 000000000..7f9f0a3fd --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser Binary files differnew file mode 100644 index 000000000..6cbe89840 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser Binary files differnew file mode 100644 index 000000000..423f92310 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser Binary files differnew file mode 100644 index 000000000..331ba261f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser Binary files differnew file mode 100644 index 000000000..0c4e54135 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser Binary files differnew file mode 100644 index 000000000..20afc295a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser Binary files differnew file mode 100644 index 000000000..e801916f4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser Binary files differnew file mode 100644 index 000000000..7fc398de9 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser Binary files differnew file mode 100644 index 000000000..5c7a0de21 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser Binary files differnew file mode 100644 index 000000000..f7b1fbed1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser Binary files differnew file mode 100644 index 000000000..dc3634dec --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser Binary files differnew file mode 100644 index 000000000..a3108b43e --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser Binary files differnew file mode 100644 index 000000000..f561c2d2f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser Binary files differnew file mode 100644 index 000000000..1dc99e434 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser Binary files differnew file mode 100644 index 000000000..e1b97d053 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser Binary files differnew file mode 100644 index 000000000..5600cbfa2 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser Binary files differnew file mode 100644 index 000000000..fe4068c42 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser Binary files differnew file mode 100644 index 000000000..59ad5e462 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser Binary files differnew file mode 100644 index 000000000..b11600cd0 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser Binary files differnew file mode 100644 index 000000000..5abc2b1b6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser Binary files differnew file mode 100644 index 000000000..37814223f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser Binary files differnew file mode 100644 index 000000000..58bb75a7f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser Binary files differnew file mode 100644 index 000000000..f905fc364 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser Binary files differnew file mode 100644 index 000000000..0c1e74beb --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser Binary files differnew file mode 100644 index 000000000..1032043be --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser Binary files differnew file mode 100644 index 000000000..d0e34603a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser Binary files differnew file mode 100644 index 000000000..4d47ada2d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser Binary files differnew file mode 100644 index 000000000..eb522634d --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java new file mode 100644 index 000000000..273240a27 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id: License.java 1039179 2010-11-25 21:04:09Z vhennebert $ */ + +package org.apache.fop.complexscripts.bidi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; + +// CSOFF: WhitespaceAfterCheck + +/* + * !!! THIS IS A GENERATED FILE !!! + * If updates to the source are needed, then: + * - apply the necessary modifications to + * 'src/codegen/unicode/java/org/apache/fop/text/bidi/GenerateBidiTestData.java' + * - run 'ant codegen-unicode', which will generate a new BidiTestData.java + * in 'test/java/org/apache/fop/complexscripts/bidi' + * - commit BOTH changed files + */ + +/** Bidirectional test data. */ +public final class BidiTestData { + + private BidiTestData() { + } + + public static final String TD_PFX = "TD"; + public static final int TD_CNT = 19; + + public static final String LD_PFX = "LD"; + public static final int LD_CNT = 622; + + public static final int NUM_TEST_SEQUENCES = 216357; + + public static int[] readTestData ( String prefix, int index ) { + int[] data = null; + InputStream is = null; + Class btc = BidiTestData.class; + String name = btc.getSimpleName() + "$" + prefix + index + ".ser"; + try { + if ( ( is = btc.getResourceAsStream ( name ) ) != null ) { + ObjectInputStream ois = new ObjectInputStream ( is ); + data = (int[]) ois.readObject(); + ois.close(); + } + } catch ( IOException e ) { + data = null; + } catch ( ClassNotFoundException e ) { + data = null; + } finally { + if ( is != null ) { + try { is.close(); } catch ( Exception e ) {} + } + } + return data; + } +} diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestSuite.java b/test/java/org/apache/fop/complexscripts/bidi/BidiTestSuite.java new file mode 100644 index 000000000..7a6a095c6 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestSuite.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.bidi; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Test suite for bidirectional functionality. + */ +@RunWith(Suite.class) +@SuiteClasses({ + BidiClassTestCase.class, + BidiAlgorithmTestCase.class +}) +public class BidiTestSuite { +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java b/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java new file mode 100644 index 000000000..a7e4b0615 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.complexscripts.fonts.ttx.TTXFileTestCase; + +/** + * Test suite for fonts functionality related to complex scripts. + */ +@RunWith(Suite.class) +@SuiteClasses({ + TTXFileTestCase.class, + GDEFTestCase.class, + GSUBTestCase.class, + GPOSTestCase.class +}) +public class FontsTestSuite { +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java new file mode 100644 index 000000000..3b7263795 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java @@ -0,0 +1,3177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts; + +import java.io.File; + +import org.apache.fop.complexscripts.fonts.GlyphSubtable; +import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable; +import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphContextTester; +import org.apache.fop.complexscripts.util.GlyphSequence; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class GDEFTestCase { + + private static String ttxFilesRoot = "test/resources/complexscripts"; + + private static String[][] ttxFonts = { + { "f0", "arab/ttx/arab-001.ttx" }, // simplified arabic + { "f1", "arab/ttx/arab-002.ttx" }, // traditional arabic + { "f2", "arab/ttx/arab-003.ttx" }, // lateef + { "f3", "arab/ttx/arab-004.ttx" }, // scheherazade + }; + + private static Object[][] ltGlyphClass = { + { GlyphDefinitionTable.GDEF_LOOKUP_TYPE_GLYPH_CLASS }, + // arab-001.ttx + { "f0", "lu0", + new String[][] { + { "a", "1" }, + { "aacute", "1" }, + { "acircumflex", "1" }, + { "acute", "1" }, + { "adieresis", "1" }, + { "ae", "1" }, + { "agrave", "1" }, + { "ain", "1" }, + { "ainfinal", "1" }, + { "aininitial", "1" }, + { "ainisolated", "1" }, + { "ainmedial", "1" }, + { "aleffinal", "1" }, + { "alefisolated", "1" }, + { "alefmaksura", "1" }, + { "alefmaksurafinal", "1" }, + { "alefmaksuraisolated", "1" }, + { "alefwasla", "1" }, + { "alefwaslafinal", "1" }, + { "alefwaslaisolated", "1" }, + { "alefwithfathatanfinal", "1" }, + { "alefwithfathatanisolated", "1" }, + { "alefwithhamzaabove", "1" }, + { "alefwithhamzaabovefinal", "1" }, + { "alefwithhamzaaboveisolated", "1" }, + { "alefwithhamzabelow", "1" }, + { "alefwithhamzabelowfinal", "1" }, + { "alefwithhamzabelowisolated", "1" }, + { "alefwithmaddaabove", "1" }, + { "alefwithmaddaabovefinal", "1" }, + { "alefwithmaddaaboveisolated", "1" }, + { "allahisolated", "2" }, + { "ampersand", "1" }, + { "arabicae", "1" }, + { "arabicalef", "1" }, + { "arabiccomma", "1" }, + { "arabicfivepointedstar", "1" }, + { "arabicindicdigiteight", "1" }, + { "arabicindicdigitfive", "1" }, + { "arabicindicdigitfour", "1" }, + { "arabicindicdigitnine", "1" }, + { "arabicindicdigitone", "1" }, + { "arabicindicdigitseven", "1" }, + { "arabicindicdigitsix", "1" }, + { "arabicindicdigitthree", "1" }, + { "arabicindicdigittwo", "1" }, + { "arabicindicdigitzero", "1" }, + { "arabickaf", "1" }, + { "arabicpercentsign", "1" }, + { "arabicquestionmark", "1" }, + { "arabicsemicolon", "1" }, + { "aring", "1" }, + { "asciicircum", "1" }, + { "asciitilde", "1" }, + { "asterisk", "1" }, + { "at", "1" }, + { "atilde", "1" }, + { "b", "1" }, + { "backslash", "1" }, + { "bar", "1" }, + { "beh", "1" }, + { "behisolated", "1" }, + { "behmedial", "1" }, + { "braceleft", "1" }, + { "braceright", "1" }, + { "bracketleft", "1" }, + { "bracketright", "1" }, + { "brokenbar", "1" }, + { "bullet", "1" }, + { "c", "1" }, + { "caron", "1" }, + { "ccedilla", "1" }, + { "cedilla", "1" }, + { "cent", "1" }, + { "circumflex", "1" }, + { "colon", "1" }, + { "comma", "1" }, + { "copyright", "1" }, + { "currency", "1" }, + { "d", "1" }, + { "dad", "1" }, + { "dadisolated", "1" }, + { "dadmedial", "1" }, + { "dagger", "1" }, + { "daggerdbl", "1" }, + { "dal", "1" }, + { "dalisolated", "1" }, + { "damma", "3" }, + { "dammahontatweel", "3" }, + { "dammaisolated", "3" }, + { "dammalow", "1" }, + { "dammaonhamza", "3" }, + { "dammatan", "3" }, + { "dammatanisolated", "3" }, + { "dammatanlow", "1" }, + { "dammatanonhamza", "3" }, + { "degree", "1" }, + { "delete", "1" }, + { "dieresis", "1" }, + { "divide", "1" }, + { "dollar", "1" }, + { "dotlessi", "1" }, + { "e", "1" }, + { "eacute", "1" }, + { "ecircumflex", "1" }, + { "edieresis", "1" }, + { "egrave", "1" }, + { "eight", "1" }, + { "ellipsis", "1" }, + { "endash", "1" }, + { "equal", "1" }, + { "eth", "1" }, + { "exclam", "1" }, + { "exclamdown", "1" }, + { "extendedarabicindicdigiteight", "1" }, + { "extendedarabicindicdigitfive", "1" }, + { "extendedarabicindicdigitfour", "1" }, + { "extendedarabicindicdigitnine", "1" }, + { "extendedarabicindicdigitone", "1" }, + { "extendedarabicindicdigitseven", "1" }, + { "extendedarabicindicdigitsix", "1" }, + { "extendedarabicindicdigitthree", "1" }, + { "extendedarabicindicdigittwo", "1" }, + { "extendedarabicindicdigitzero", "1" }, + { "f", "1" }, + { "farsiyeh", "1" }, + { "farsiyehfinal", "1" }, + { "farsiyehisolated", "1" }, + { "fatha", "3" }, + { "fathahontatweel", "3" }, + { "fathaisolated", "3" }, + { "fathalow", "1" }, + { "fathaonhamza", "3" }, + { "fathatan", "3" }, + { "fathatanisolated", "3" }, + { "fathatanlow", "1" }, + { "fathatanonhamza", "3" }, + { "fathatanontatweel", "1" }, + { "feh", "1" }, + { "fehinitial", "1" }, + { "fehisolated", "1" }, + { "fehmedial", "1" }, + { "five", "1" }, + { "florin", "1" }, + { "four", "1" }, + { "g", "1" }, + { "gaf", "1" }, + { "gaffinal", "1" }, + { "gafinitial", "1" }, + { "gafisolated", "1" }, + { "gafmedial", "1" }, + { "germandbls", "1" }, + { "ghain", "1" }, + { "ghainfinal", "1" }, + { "ghaininitial", "1" }, + { "ghainisolated", "1" }, + { "ghainmedial", "1" }, + { "glyph1", "1" }, + { "glyph2", "1" }, + { "glyph99", "1" }, + { "grave", "1" }, + { "greater", "1" }, + { "guillemotleft", "1" }, + { "guillemotright", "1" }, + { "guilsinglleft", "1" }, + { "guilsinglright", "1" }, + { "h", "1" }, + { "hah", "1" }, + { "hahfinal", "1" }, + { "hahisolated", "1" }, + { "hahmedial", "1" }, + { "hamza", "1" }, + { "hamzaisolated", "3" }, + { "heh", "1" }, + { "hehfinal", "1" }, + { "hehinitial", "1" }, + { "hehisolated", "1" }, + { "hehmedial", "1" }, + { "highhamza", "1" }, + { "hyphenminus", "1" }, + { "i", "1" }, + { "iacute", "1" }, + { "icircumflex", "1" }, + { "idieresis", "1" }, + { "igrave", "1" }, + { "j", "1" }, + { "jeem", "1" }, + { "jeemfinal", "1" }, + { "jeemisolated", "1" }, + { "jeemmedial", "1" }, + { "jeh", "1" }, + { "jehisolated", "1" }, + { "k", "1" }, + { "kafisolated", "1" }, + { "kafmedial", "1" }, + { "kasra", "3" }, + { "kasrahontatweel", "3" }, + { "kasraisolated", "3" }, + { "kasralow", "1" }, + { "kasratan", "3" }, + { "kasratanisolated", "3" }, + { "kasratanlow", "1" }, + { "keheh", "1" }, + { "kehehfinal", "1" }, + { "kehehinitial", "1" }, + { "kehehisolated", "1" }, + { "kehehmedial", "1" }, + { "khah", "1" }, + { "khahfinal", "1" }, + { "khahisolated", "1" }, + { "khahmedial", "1" }, + { "l", "1" }, + { "lam", "1" }, + { "lamisolated", "1" }, + { "lammedial", "1" }, + { "lamwithaleffinal", "2" }, + { "lamwithalefhamzaabovefinal", "2" }, + { "lamwithalefhamzaaboveisolatedd", "2" }, + { "lamwithalefhamzabelowfinal", "2" }, + { "lamwithalefhamzabelowisolated", "2" }, + { "lamwithalefisolated", "2" }, + { "lamwithalefmaddaabovefinal", "2" }, + { "lamwithalefmaddaaboveisolatedd", "2" }, + { "lamwithmeemwithjeeminitial", "1" }, + { "lefttoright", "1" }, + { "less", "1" }, + { "logicalnot", "1" }, + { "m", "1" }, + { "macron", "1" }, + { "meem", "1" }, + { "meemisolated", "1" }, + { "meemmedial", "1" }, + { "micro", "1" }, + { "multiply", "1" }, + { "n", "1" }, + { "nbspace", "1" }, + { "nine", "1" }, + { "noon", "1" }, + { "noonisolated", "1" }, + { "noonmedial", "1" }, + { "ntilde", "1" }, + { "numbersign", "1" }, + { "o", "1" }, + { "oacute", "1" }, + { "ocircumflex", "1" }, + { "odieresis", "1" }, + { "oe", "1" }, + { "ograve", "1" }, + { "one", "1" }, + { "onehalf", "1" }, + { "onequarter", "1" }, + { "onesuperior", "1" }, + { "ordfeminine", "1" }, + { "ordmasculine", "1" }, + { "ornateleftparenthesis", "1" }, + { "ornaterightparenthesis", "1" }, + { "oslash", "1" }, + { "otilde", "1" }, + { "p", "1" }, + { "paragraph", "1" }, + { "parenleft", "1" }, + { "parenright", "1" }, + { "peh", "1" }, + { "pehisolated", "1" }, + { "pehmedial", "1" }, + { "percent", "1" }, + { "period", "1" }, + { "periodcentered", "1" }, + { "perthousand", "1" }, + { "plus", "1" }, + { "plusminus", "1" }, + { "q", "1" }, + { "qaf", "1" }, + { "qafinitial", "1" }, + { "qafisolated", "1" }, + { "qafmedial", "1" }, + { "question", "1" }, + { "questiondown", "1" }, + { "quotedash", "1" }, + { "quotedbl", "1" }, + { "quotedblbase", "1" }, + { "quotedblleft", "1" }, + { "quotedblright", "1" }, + { "quoteleft", "1" }, + { "quoteright", "1" }, + { "quotesinglbase", "1" }, + { "quotesingle", "1" }, + { "r", "1" }, + { "rayaleflam", "2" }, + { "registered", "1" }, + { "reh", "1" }, + { "rehisolated", "1" }, + { "righttoleft", "1" }, + { "s", "1" }, + { "sad", "1" }, + { "sadisolated", "1" }, + { "sadmedial", "1" }, + { "scaron", "1" }, + { "section", "1" }, + { "seen", "1" }, + { "seenisolated", "1" }, + { "seenmedial", "1" }, + { "semicolon", "1" }, + { "seven", "1" }, + { "sfthyphen", "1" }, + { "shadda", "3" }, + { "shaddahontatweel", "3" }, + { "shaddaisolated", "3" }, + { "shaddalow", "1" }, + { "shaddawithdammaisolated", "3" }, + { "shaddawithdammalow", "3" }, + { "shaddawithdammamedial", "1" }, + { "shaddawithdammatanisolated", "1" }, + { "shaddawithdammatanlow", "3" }, + { "shaddawithfathaisolated", "3" }, + { "shaddawithfathalow", "3" }, + { "shaddawithfathamedial", "1" }, + { "shaddawithfathatanisolated", "1" }, + { "shaddawithfathatanlow", "3" }, + { "shaddawithkasraisolated", "3" }, + { "shaddawithkasralow", "3" }, + { "shaddawithkasramedial", "1" }, + { "shaddawithkasratanisolated", "1" }, + { "shaddawithkasratanlow", "3" }, + { "sheen", "1" }, + { "sheenisolated", "1" }, + { "sheenmedial", "1" }, + { "six", "1" }, + { "slash", "1" }, + { "smallhighmadda", "3" }, + { "space", "1" }, + { "sterling", "1" }, + { "sukun", "3" }, + { "sukunisolated", "3" }, + { "sukunlow", "1" }, + { "sukunonhamza", "3" }, + { "sukunontatweel", "3" }, + { "superscriptalef", "3" }, + { "t", "1" }, + { "tah", "1" }, + { "tahisolated", "1" }, + { "tatweel", "1" }, + { "tcheh", "1" }, + { "tchehfinal", "1" }, + { "tchehisolated", "1" }, + { "tchehmedial", "1" }, + { "teh", "1" }, + { "tehisolated", "1" }, + { "tehmarbuta", "1" }, + { "tehmarbutafinal", "1" }, + { "tehmarbutaisolated", "1" }, + { "tehmedial", "1" }, + { "thal", "1" }, + { "thalisolated", "1" }, + { "theh", "1" }, + { "thehisolated", "1" }, + { "thehmedial", "1" }, + { "thorn", "1" }, + { "three", "1" }, + { "threequarters", "1" }, + { "threesuperior", "1" }, + { "tilde", "1" }, + { "trademark", "1" }, + { "two", "1" }, + { "twosuperior", "1" }, + { "u", "1" }, + { "uacute", "1" }, + { "ucircumflex", "1" }, + { "udieresis", "1" }, + { "ugrave", "1" }, + { "underscore", "1" }, + { "uni000D", "1" }, + { "uni0649.init", "1" }, + { "uni0654", "3" }, + { "uni0655", "3" }, + { "uni0655064D", "3" }, + { "uni06550650", "3" }, + { "uni06A5.init", "1" }, + { "uni25CC", "1" }, + { "v", "1" }, + { "veh", "1" }, + { "vehisolated", "1" }, + { "vehmedial", "1" }, + { "w", "1" }, + { "waw", "1" }, + { "wawisolated", "1" }, + { "wawwithhamzaabove", "1" }, + { "wawwithhamzaaboveisolated", "1" }, + { "x", "1" }, + { "y", "1" }, + { "yacute", "1" }, + { "ydieresis", "1" }, + { "yeh", "1" }, + { "yehfinal", "1" }, + { "yehisolated", "1" }, + { "yehmedial", "1" }, + { "yehwithhamzaabove", "1" }, + { "yehwithhamzaabovefinal", "1" }, + { "yehwithhamzaaboveisolated", "1" }, + { "yehwithhamzaabovemedial", "1" }, + { "yen", "1" }, + { "z", "1" }, + { "zah", "1" }, + { "zahisolated", "1" }, + { "zain", "1" }, + { "zainisolated", "1" }, + { "zcaron", "1" }, + { "zero", "1" }, + { "zerojoin", "1" }, + { "zeronojoin", "1" }, + { "zerowidthnobreakspace", "1" }, + }, + }, + // arab-002.ttx + { "f1", "lu0", + new String[][] { + { "a", "1" }, + { "aacute", "1" }, + { "acircumflex", "1" }, + { "acute", "1" }, + { "adieresis", "1" }, + { "ae", "1" }, + { "agrave", "1" }, + { "ain", "1" }, + { "ainfinal", "1" }, + { "aininitial", "1" }, + { "ainisolated", "1" }, + { "ainmedial", "1" }, + { "aleffinal", "1" }, + { "alefisolated", "1" }, + { "alefmaksura", "1" }, + { "alefmaksurafinal", "1" }, + { "alefmaksuraisolated", "1" }, + { "alefwasla", "1" }, + { "alefwaslafinal", "1" }, + { "alefwaslaisolated", "1" }, + { "alefwithfathatanfinal", "1" }, + { "alefwithfathatanisolated", "1" }, + { "alefwithhamzaabove", "1" }, + { "alefwithhamzaabovefinal", "1" }, + { "alefwithhamzaaboveisolated", "1" }, + { "alefwithhamzabelow", "1" }, + { "alefwithhamzabelowfinal", "1" }, + { "alefwithhamzabelowisolated", "1" }, + { "alefwithmaddaabove", "1" }, + { "alefwithmaddaabovefinal", "1" }, + { "alefwithmaddaaboveisolated", "1" }, + { "allahisolated", "2" }, + { "ampersand", "1" }, + { "arabicae", "1" }, + { "arabicalef", "1" }, + { "arabiccomma", "1" }, + { "arabicfivepointedstar", "3" }, + { "arabicindicdigiteight", "1" }, + { "arabicindicdigitfive", "1" }, + { "arabicindicdigitfour", "1" }, + { "arabicindicdigitnine", "1" }, + { "arabicindicdigitone", "1" }, + { "arabicindicdigitseven", "1" }, + { "arabicindicdigitsix", "1" }, + { "arabicindicdigitthree", "1" }, + { "arabicindicdigittwo", "1" }, + { "arabicindicdigitzero", "1" }, + { "arabickaf", "1" }, + { "arabickaffinal", "1" }, + { "arabicpercentsign", "1" }, + { "arabicquestionmark", "1" }, + { "arabicsemicolon", "1" }, + { "aring", "1" }, + { "asciicircum", "1" }, + { "asciitilde", "1" }, + { "asterisk", "1" }, + { "at", "1" }, + { "atilde", "1" }, + { "b", "1" }, + { "backslash", "1" }, + { "bar", "1" }, + { "beh", "1" }, + { "behfinal", "1" }, + { "behinitial", "1" }, + { "behisolated", "1" }, + { "behmedial", "1" }, + { "behwithalefmaksurafinal", "2" }, + { "behwithalefmaksuraisolated", "2" }, + { "behwithhahinitial", "2" }, + { "behwithhehinitial", "2" }, + { "behwithjeeminitial", "2" }, + { "behwithkhahinitial", "2" }, + { "behwithmeeminitial", "2" }, + { "behwithmeemisolated", "2" }, + { "behwithnoonfinal", "2" }, + { "behwithrehfinal", "2" }, + { "behwithyehfinal", "2" }, + { "behwithyehisolated", "2" }, + { "braceleft", "1" }, + { "braceright", "1" }, + { "bracketleft", "1" }, + { "bracketright", "1" }, + { "brokenbar", "1" }, + { "bullet", "1" }, + { "c", "1" }, + { "caron", "1" }, + { "ccedilla", "1" }, + { "cedilla", "1" }, + { "cent", "1" }, + { "circumflex", "1" }, + { "colon", "1" }, + { "comma", "1" }, + { "copyright", "1" }, + { "currency", "1" }, + { "d", "1" }, + { "dad", "1" }, + { "dadfinal", "1" }, + { "dadinitial", "1" }, + { "dadisolated", "1" }, + { "dadmedial", "1" }, + { "dagger", "1" }, + { "daggerdbl", "1" }, + { "dal", "1" }, + { "dalfinal", "1" }, + { "dalisolated", "1" }, + { "damma", "3" }, + { "dammahontatweel", "1" }, + { "dammaisolated", "1" }, + { "dammalow", "1" }, + { "dammaonhamza", "3" }, + { "dammatan", "3" }, + { "dammatanisolated", "1" }, + { "dammatanlow", "1" }, + { "dammatanonhamza", "3" }, + { "degree", "1" }, + { "delete", "1" }, + { "dieresis", "1" }, + { "divide", "1" }, + { "dollar", "1" }, + { "dotlessi", "1" }, + { "e", "1" }, + { "eacute", "1" }, + { "ecircumflex", "1" }, + { "edieresis", "1" }, + { "egrave", "1" }, + { "eight", "1" }, + { "ellipsis", "1" }, + { "endash", "1" }, + { "equal", "1" }, + { "eth", "1" }, + { "exclam", "1" }, + { "exclamdown", "1" }, + { "extendedarabicindicdigiteight", "1" }, + { "extendedarabicindicdigitfive", "1" }, + { "extendedarabicindicdigitfour", "1" }, + { "extendedarabicindicdigitnine", "1" }, + { "extendedarabicindicdigitone", "1" }, + { "extendedarabicindicdigitseven", "1" }, + { "extendedarabicindicdigitsix", "1" }, + { "extendedarabicindicdigitthree", "1" }, + { "extendedarabicindicdigittwo", "1" }, + { "extendedarabicindicdigitzero", "1" }, + { "f", "1" }, + { "farsiyeh", "1" }, + { "farsiyehfinal", "1" }, + { "farsiyehisolated", "1" }, + { "fatha", "3" }, + { "fathahontatweel", "1" }, + { "fathaisolated", "1" }, + { "fathalow", "1" }, + { "fathaonhamza", "3" }, + { "fathatan", "3" }, + { "fathatanisolated", "1" }, + { "fathatanlow", "1" }, + { "fathatanonhamza", "3" }, + { "fathatanontatweel", "1" }, + { "feh", "1" }, + { "fehfinal", "1" }, + { "fehinitial", "1" }, + { "fehisolated", "1" }, + { "fehmedial", "1" }, + { "fehwithalefmaksuraisolated", "2" }, + { "fehwithyehisolated", "2" }, + { "five", "1" }, + { "florin", "1" }, + { "four", "1" }, + { "g", "1" }, + { "gaf", "1" }, + { "gaffinal", "1" }, + { "gafinitial", "1" }, + { "gafisolated", "1" }, + { "gafmedial", "1" }, + { "germandbls", "1" }, + { "ghain", "1" }, + { "ghainfinal", "1" }, + { "ghaininitial", "1" }, + { "ghainisolated", "1" }, + { "ghainmedial", "1" }, + { "grave", "1" }, + { "greater", "1" }, + { "guillemotleft", "1" }, + { "guillemotright", "1" }, + { "guilsinglleft", "1" }, + { "guilsinglright", "1" }, + { "h", "1" }, + { "hah", "1" }, + { "hahfinal", "1" }, + { "hahinitial", "1" }, + { "hahisolated", "1" }, + { "hahmedial", "1" }, + { "hahwithmeeminitial", "2" }, + { "hamza", "1" }, + { "hamzaisolated", "1" }, + { "heh", "1" }, + { "hehfinal", "1" }, + { "hehinitial", "1" }, + { "hehisolated", "1" }, + { "hehmedial", "1" }, + { "hehwithmeeminitial", "2" }, + { "highhamza", "1" }, + { "hyphenminus", "1" }, + { "i", "1" }, + { "iacute", "1" }, + { "icircumflex", "1" }, + { "idieresis", "1" }, + { "igrave", "1" }, + { "j", "1" }, + { "jeem", "1" }, + { "jeemfinal", "1" }, + { "jeeminitial", "1" }, + { "jeemisolated", "1" }, + { "jeemmedial", "1" }, + { "jeemwithmeeminitial", "2" }, + { "jeh", "1" }, + { "jehfinal", "1" }, + { "jehisolated", "1" }, + { "k", "1" }, + { "kafinitial", "1" }, + { "kafisolated", "1" }, + { "kafmedial", "1" }, + { "kasra", "3" }, + { "kasrahontatweel", "1" }, + { "kasraisolated", "1" }, + { "kasralow", "1" }, + { "kasratan", "3" }, + { "kasratanisolated", "1" }, + { "kasratanlow", "1" }, + { "keheh", "1" }, + { "kehehfinal", "1" }, + { "kehehinitial", "1" }, + { "kehehisolated", "1" }, + { "kehehmedial", "1" }, + { "khah", "1" }, + { "khahfinal", "1" }, + { "khahinitial", "1" }, + { "khahisolated", "1" }, + { "khahmedial", "1" }, + { "khahwithmeeminitial", "2" }, + { "l", "1" }, + { "lam", "1" }, + { "lamfinal", "1" }, + { "laminitial", "1" }, + { "lamisolated", "1" }, + { "lammedial", "1" }, + { "lamwithaleffinal", "2" }, + { "lamwithalefhamzaabovefinal", "2" }, + { "lamwithalefhamzaaboveisolatedd", "2" }, + { "lamwithalefhamzabelowfinal", "2" }, + { "lamwithalefhamzabelowisolated", "2" }, + { "lamwithalefisolated", "2" }, + { "lamwithalefmaddaabovefinal", "2" }, + { "lamwithalefmaddaaboveisolatedd", "2" }, + { "lamwithalefmaksuraisolated", "2" }, + { "lamwithhahinitial", "2" }, + { "lamwithhahisolated", "2" }, + { "lamwithhehinitial", "2" }, + { "lamwithjeeminitial", "2" }, + { "lamwithjeemisolated", "2" }, + { "lamwithkhahinitial", "2" }, + { "lamwithkhahisolated", "2" }, + { "lamwithmeeminitial", "2" }, + { "lamwithmeemisolated", "2" }, + { "lamwithmeemwithhahinitial", "2" }, + { "lamwithmeemwithjeeminitial", "2" }, + { "lamwithyehisolated", "2" }, + { "lefttoright", "1" }, + { "less", "1" }, + { "logicalnot", "1" }, + { "m", "1" }, + { "macron", "1" }, + { "meem", "1" }, + { "meemfinal", "1" }, + { "meeminitial", "1" }, + { "meemisolated", "1" }, + { "meemmedial", "1" }, + { "meemwithhahinitial", "2" }, + { "meemwithjeeminitial", "2" }, + { "meemwithkhahinitial", "2" }, + { "meemwithmeeminitial", "2" }, + { "micro", "1" }, + { "multiply", "1" }, + { "n", "1" }, + { "nine", "1" }, + { "nonbreakingspace", "1" }, + { "nonmarkingreturn", "1" }, + { "noon", "1" }, + { "noonfinal", "1" }, + { "nooninitial", "1" }, + { "noonisolated", "1" }, + { "noonmedial", "1" }, + { "noonwithalefmaksurafinal", "2" }, + { "noonwithalefmaksuraisolated", "2" }, + { "noonwithhahinitial", "2" }, + { "noonwithhehinitial", "2" }, + { "noonwithjeeminitial", "2" }, + { "noonwithkhahinitial", "2" }, + { "noonwithmeeminitial", "2" }, + { "noonwithmeemisolated", "2" }, + { "noonwithyehfinal", "2" }, + { "noonwithyehisolated", "2" }, + { "noonwithzainfinal", "2" }, + { "ntilde", "1" }, + { "numbersign", "1" }, + { "o", "1" }, + { "oacute", "1" }, + { "ocircumflex", "1" }, + { "odieresis", "1" }, + { "oe", "1" }, + { "ograve", "1" }, + { "one", "1" }, + { "onehalf", "1" }, + { "onequarter", "1" }, + { "onesuperior", "1" }, + { "ordfeminine", "1" }, + { "ordmasculine", "1" }, + { "ornateleftparenthesis", "1" }, + { "ornaterightparenthesis", "1" }, + { "oslash", "1" }, + { "otilde", "1" }, + { "p", "1" }, + { "paragraph", "1" }, + { "parenleft", "1" }, + { "parenright", "1" }, + { "peh", "1" }, + { "pehfinal", "1" }, + { "pehinitial", "1" }, + { "pehisolated", "1" }, + { "pehmedial", "1" }, + { "pehwithhehinitial", "2" }, + { "percent", "1" }, + { "period", "1" }, + { "periodcentered", "1" }, + { "perthousand", "1" }, + { "plus", "1" }, + { "plusminus", "1" }, + { "q", "1" }, + { "qaf", "1" }, + { "qaffinal", "1" }, + { "qafinitial", "1" }, + { "qafisolated", "1" }, + { "qafmedial", "1" }, + { "question", "1" }, + { "questiondown", "1" }, + { "quotedash", "1" }, + { "quotedbl", "1" }, + { "quotedblbase", "1" }, + { "quotedblleft", "1" }, + { "quotedblright", "1" }, + { "quoteleft", "1" }, + { "quoteright", "1" }, + { "quotesinglbase", "1" }, + { "quotesingle", "1" }, + { "r", "1" }, + { "rayaleflam", "2" }, + { "registered", "1" }, + { "reh", "1" }, + { "rehfinal", "1" }, + { "rehisolated", "1" }, + { "righttoleft", "1" }, + { "s", "1" }, + { "sad", "1" }, + { "sadfinal", "1" }, + { "sadinitial", "1" }, + { "sadisolated", "1" }, + { "sadmedial", "1" }, + { "scaron", "1" }, + { "section", "1" }, + { "seen", "1" }, + { "seenfinal", "1" }, + { "seeninitial", "1" }, + { "seenisolated", "1" }, + { "seenmedial", "1" }, + { "seenwithmeeminitial", "2" }, + { "semicolon", "1" }, + { "seven", "1" }, + { "sfthyphen", "1" }, + { "shadda", "3" }, + { "shaddahontatweel", "1" }, + { "shaddaisolated", "1" }, + { "shaddalow", "1" }, + { "shaddawithdammaisolated", "1" }, + { "shaddawithdammaisolatedlow", "3" }, + { "shaddawithdammamedial", "1" }, + { "shaddawithdammatanisolated", "1" }, + { "shaddawithdammatanisolatedlow", "3" }, + { "shaddawithfathaisolated", "1" }, + { "shaddawithfathaisolatedlow", "3" }, + { "shaddawithfathamedial", "1" }, + { "shaddawithfathatanisolated", "3" }, + { "shaddawithfathatanisolatedlow", "3" }, + { "shaddawithkasraisolated", "1" }, + { "shaddawithkasraisolatedlow", "3" }, + { "shaddawithkasramedial", "1" }, + { "shaddawithkasratanisolated", "1" }, + { "shaddawithkasratanisolatedlow", "3" }, + { "sheen", "1" }, + { "sheenfinal", "1" }, + { "sheeninitial", "1" }, + { "sheenisolated", "1" }, + { "sheenmedial", "1" }, + { "sheenwithmeeminitial", "2" }, + { "six", "1" }, + { "slash", "1" }, + { "smallhighmadda", "3" }, + { "space", "1" }, + { "sterling", "1" }, + { "sukun", "3" }, + { "sukunisolated", "1" }, + { "sukunlow", "1" }, + { "sukunonhamza", "3" }, + { "sukunontatweel", "1" }, + { "superscriptalef", "3" }, + { "t", "1" }, + { "tah", "1" }, + { "tahfinal", "1" }, + { "tahinitial", "1" }, + { "tahisolated", "1" }, + { "tahmedial", "1" }, + { "tatweel", "1" }, + { "tcheh", "1" }, + { "tchehfinal", "1" }, + { "tchehinitial", "1" }, + { "tchehisolated", "1" }, + { "tchehmedial", "1" }, + { "teh", "1" }, + { "tehfinal", "1" }, + { "tehinitial", "1" }, + { "tehisolated", "1" }, + { "tehmarbuta", "1" }, + { "tehmarbutafinal", "1" }, + { "tehmarbutaisolated", "1" }, + { "tehmedial", "1" }, + { "tehwithalefmaksurafinal", "2" }, + { "tehwithhahinitial", "2" }, + { "tehwithhehinitial", "2" }, + { "tehwithjeeminitial", "2" }, + { "tehwithkhahinitial", "2" }, + { "tehwithmeeminitial", "2" }, + { "tehwithmeemisolated", "2" }, + { "tehwithnoonfinal", "2" }, + { "tehwithyehfinal", "2" }, + { "tehwithyehisolated", "2" }, + { "thal", "1" }, + { "thalfinal", "1" }, + { "thalisolated", "1" }, + { "theh", "1" }, + { "thehfinal", "1" }, + { "thehinitial", "1" }, + { "thehisolated", "1" }, + { "thehmedial", "1" }, + { "thehwithmeeminitial", "2" }, + { "thehwithmeemisolated", "2" }, + { "thorn", "1" }, + { "three", "1" }, + { "threequarters", "1" }, + { "threesuperior", "1" }, + { "tilde", "1" }, + { "trademark", "1" }, + { "two", "1" }, + { "twosuperior", "1" }, + { "u", "1" }, + { "uacute", "1" }, + { "ucircumflex", "1" }, + { "udieresis", "1" }, + { "ugrave", "1" }, + { "underscore", "1" }, + { "uni000D", "1" }, + { "uni0649.init", "1" }, + { "uni0649.medi", "1" }, + { "uni0654", "3" }, + { "uni0655", "3" }, + { "uni0655064D", "3" }, + { "uni06550650", "3" }, + { "uni25CC", "1" }, + { "uniE817", "2" }, + { "v", "1" }, + { "veh", "1" }, + { "vehfinal", "1" }, + { "vehinitial", "1" }, + { "vehisolated", "1" }, + { "vehmedial", "1" }, + { "w", "1" }, + { "waw", "1" }, + { "wawfinal", "1" }, + { "wawisolated", "1" }, + { "wawwithhamzaabove", "1" }, + { "wawwithhamzaabovefinal", "1" }, + { "wawwithhamzaaboveisolated", "1" }, + { "x", "1" }, + { "y", "1" }, + { "yacute", "1" }, + { "ydieresis", "1" }, + { "yeh", "1" }, + { "yehfinal", "1" }, + { "yehinitial", "1" }, + { "yehisolated", "1" }, + { "yehmedial", "1" }, + { "yehwithalefmaksurafinal", "2" }, + { "yehwithalefmaksuraisolated", "2" }, + { "yehwithhahinitial", "2" }, + { "yehwithhamzaabove", "1" }, + { "yehwithhamzaabovefinal", "1" }, + { "yehwithhamzaaboveinitial", "1" }, + { "yehwithhamzaaboveisolated", "1" }, + { "yehwithhamzaabovemedial", "1" }, + { "yehwithjeeminitial", "2" }, + { "yehwithkhahinitial", "2" }, + { "yehwithmeeminitial", "2" }, + { "yehwithmeemisolated", "2" }, + { "yehwithnoonfinal", "2" }, + { "yehwithrehfinal", "2" }, + { "yen", "1" }, + { "z", "1" }, + { "zah", "1" }, + { "zahfinal", "1" }, + { "zahinitial", "1" }, + { "zahisolated", "1" }, + { "zahmedial", "1" }, + { "zain", "1" }, + { "zainfinal", "1" }, + { "zainisolated", "1" }, + { "zcaron", "1" }, + { "zero", "1" }, + { "zerojoin", "1" }, + { "zeronojoin", "1" }, + { "zerowidthnobreakspace", "1" }, + }, + }, + // arab-003.ttx + { "f2", "lu0", + new String[][] { + { "_bar", "1" }, + { "_damma", "1" }, + { "_dot1", "1" }, + { "_dot1_hat", "1" }, + { "_dot1_smallV", "1" }, + { "_dot1_tah", "1" }, + { "_dot2h", "1" }, + { "_dot2h_tah", "1" }, + { "_dot2v", "1" }, + { "_dot3d", "1" }, + { "_dot3h", "1" }, + { "_dot3u", "1" }, + { "_dot3u_tah", "1" }, + { "_dot4", "1" }, + { "_gafBar", "1" }, + { "_gafBar_dot2h", "1" }, + { "_gafBar_dot3u", "1" }, + { "_hamza", "1" }, + { "_hamzaDamma", "1" }, + { "_hat", "1" }, + { "_highHamza", "1" }, + { "_hook", "1" }, + { "_invSmallV", "1" }, + { "_lines", "1" }, + { "_madda", "1" }, + { "_ring", "1" }, + { "_smallV", "1" }, + { "_tah", "1" }, + { "_vline", "1" }, + { "_wasla", "1" }, + { "_wavyHamza", "1" }, + { "_wavyHamza.b", "1" }, + { "a", "1" }, + { "absAutoKashida", "1" }, + { "absJeemRetro1", "1" }, + { "absJeemRetro1Fin", "1" }, + { "absJeemRetro1Ini", "1" }, + { "absJeemRetro1Med", "1" }, + { "absJeemRetro2", "1" }, + { "absJeemRetro2Fin", "1" }, + { "absJeemRetro2Ini", "1" }, + { "absJeemRetro2Med", "1" }, + { "absJeemRetro3", "1" }, + { "absJeemRetro3Fin", "1" }, + { "absJeemRetro3Ini", "1" }, + { "absJeemRetro3Med", "1" }, + { "absJehRetro1", "1" }, + { "absJehRetro1Fin", "1" }, + { "absJehRetro2", "1" }, + { "absJehRetro2Fin", "1" }, + { "absLamRetro", "1" }, + { "absLamRetroAlef", "2" }, + { "absLamRetroAlefFin", "2" }, + { "absLamRetroFin", "1" }, + { "absLamRetroIni", "1" }, + { "absLamRetroIni.preAlef", "1" }, + { "absLamRetroMed", "1" }, + { "absLamRetroMed.preAlef", "1" }, + { "absShaddaAlef", "3" }, + { "absSheenRetro1", "1" }, + { "absSheenRetro1Fin", "1" }, + { "absSheenRetro1Ini", "1" }, + { "absSheenRetro1Med", "1" }, + { "absSheenRetro2", "1" }, + { "absSheenRetro2Fin", "1" }, + { "absSheenRetro2Ini", "1" }, + { "absSheenRetro2Med", "1" }, + { "absTchehRetro1", "1" }, + { "absTchehRetro1Fin", "1" }, + { "absTchehRetro1Ini", "1" }, + { "absTchehRetro1Med", "1" }, + { "absTchehRetro2", "1" }, + { "absTchehRetro2Fin", "1" }, + { "absTchehRetro2Ini", "1" }, + { "absTchehRetro2Med", "1" }, + { "absWawDotBelow", "1" }, + { "absWawDotBelowFin", "1" }, + { "ampersand", "1" }, + { "asciicircum", "1" }, + { "asciitilde", "1" }, + { "asterisk", "1" }, + { "asterisk.arab", "1" }, + { "at", "1" }, + { "b", "1" }, + { "backslash", "1" }, + { "bar", "1" }, + { "braceleft", "1" }, + { "braceright", "1" }, + { "bracketleft", "1" }, + { "bracketright", "1" }, + { "c", "1" }, + { "colon", "1" }, + { "colon.arab", "1" }, + { "comma", "1" }, + { "d", "1" }, + { "dollar", "1" }, + { "e", "1" }, + { "eight", "1" }, + { "eightMedium", "3" }, + { "eightSmall", "3" }, + { "equal", "1" }, + { "exclam", "1" }, + { "exclam.arab", "1" }, + { "f", "1" }, + { "five", "1" }, + { "fiveMedium", "3" }, + { "fiveSmall", "3" }, + { "four", "1" }, + { "fourMedium", "3" }, + { "fourSmall", "3" }, + { "g", "1" }, + { "grave", "1" }, + { "greater", "1" }, + { "h", "1" }, + { "hyphen", "1" }, + { "i", "1" }, + { "j", "1" }, + { "k", "1" }, + { "l", "1" }, + { "less", "1" }, + { "m", "1" }, + { "n", "1" }, + { "nine", "1" }, + { "nineMedium", "3" }, + { "nineSmall", "3" }, + { "nonmarkingreturn", "1" }, + { "numbersign", "1" }, + { "o", "1" }, + { "one", "1" }, + { "oneMedium", "3" }, + { "oneSmall", "3" }, + { "p", "1" }, + { "parenleft", "1" }, + { "parenleft.arab", "1" }, + { "parenright", "1" }, + { "parenright.arab", "1" }, + { "percent", "1" }, + { "period", "1" }, + { "plus", "1" }, + { "q", "1" }, + { "question", "1" }, + { "quotedbl", "1" }, + { "quotedblleft.arab", "1" }, + { "quotedblright.arab", "1" }, + { "quoteleft.arab", "1" }, + { "quoteright.arab", "1" }, + { "quotesingle", "1" }, + { "r", "1" }, + { "s", "1" }, + { "semicolon", "1" }, + { "seven", "1" }, + { "sevenMedium", "3" }, + { "sevenSmall", "3" }, + { "six", "1" }, + { "sixMedium", "3" }, + { "sixSmall", "3" }, + { "slash", "1" }, + { "space", "1" }, + { "t", "1" }, + { "three", "1" }, + { "threeMedium", "3" }, + { "threeSmall", "3" }, + { "two", "1" }, + { "twoMedium", "3" }, + { "twoSmall", "3" }, + { "u", "1" }, + { "underscore", "1" }, + { "uni060C", "1" }, + { "uni060C.downward", "1" }, + { "uni0614", "3" }, + { "uni061B", "1" }, + { "uni061B.downward", "1" }, + { "uni061E", "1" }, + { "uni061F", "1" }, + { "uni0621", "1" }, + { "uni0622", "1" }, + { "uni0622.fina", "1" }, + { "uni0622.fina.postLamIni", "1" }, + { "uni0622.fina.postLamMed", "1" }, + { "uni0623", "1" }, + { "uni0623.fina", "1" }, + { "uni0623.fina.postLamIni", "1" }, + { "uni0623.fina.postLamMed", "1" }, + { "uni0624", "1" }, + { "uni0624.fina", "1" }, + { "uni0625", "1" }, + { "uni0625.fina", "1" }, + { "uni0625.fina.postLamIni", "1" }, + { "uni0625.fina.postLamMed", "1" }, + { "uni0626", "1" }, + { "uni0626.fina", "1" }, + { "uni0626.init", "1" }, + { "uni0626.medi", "1" }, + { "uni0627", "1" }, + { "uni0627.fina", "1" }, + { "uni0627.fina.postLamIni", "1" }, + { "uni0627.fina.postLamMed", "1" }, + { "uni0628", "1" }, + { "uni0628.fina", "1" }, + { "uni0628.init", "1" }, + { "uni0628.medi", "1" }, + { "uni0629", "1" }, + { "uni0629.fina", "1" }, + { "uni062A", "1" }, + { "uni062A.fina", "1" }, + { "uni062A.init", "1" }, + { "uni062A.medi", "1" }, + { "uni062B", "1" }, + { "uni062B.fina", "1" }, + { "uni062B.init", "1" }, + { "uni062B.medi", "1" }, + { "uni062C", "1" }, + { "uni062C.fina", "1" }, + { "uni062C.init", "1" }, + { "uni062C.medi", "1" }, + { "uni062D", "1" }, + { "uni062D.fina", "1" }, + { "uni062D.init", "1" }, + { "uni062D.medi", "1" }, + { "uni062E", "1" }, + { "uni062E.fina", "1" }, + { "uni062E.init", "1" }, + { "uni062E.medi", "1" }, + { "uni062F", "1" }, + { "uni062F.fina", "1" }, + { "uni0630", "1" }, + { "uni0630.fina", "1" }, + { "uni0631", "1" }, + { "uni0631.fina", "1" }, + { "uni0632", "1" }, + { "uni0632.fina", "1" }, + { "uni0633", "1" }, + { "uni0633.fina", "1" }, + { "uni0633.init", "1" }, + { "uni0633.medi", "1" }, + { "uni0634", "1" }, + { "uni0634.fina", "1" }, + { "uni0634.init", "1" }, + { "uni0634.medi", "1" }, + { "uni0635", "1" }, + { "uni0635.fina", "1" }, + { "uni0635.init", "1" }, + { "uni0635.medi", "1" }, + { "uni0636", "1" }, + { "uni0636.fina", "1" }, + { "uni0636.init", "1" }, + { "uni0636.medi", "1" }, + { "uni0637", "1" }, + { "uni0637.fina", "1" }, + { "uni0637.init", "1" }, + { "uni0637.medi", "1" }, + { "uni0638", "1" }, + { "uni0638.fina", "1" }, + { "uni0638.init", "1" }, + { "uni0638.medi", "1" }, + { "uni0639", "1" }, + { "uni0639.fina", "1" }, + { "uni0639.init", "1" }, + { "uni0639.medi", "1" }, + { "uni063A", "1" }, + { "uni063A.fina", "1" }, + { "uni063A.init", "1" }, + { "uni063A.medi", "1" }, + { "uni0640", "1" }, + { "uni0641", "1" }, + { "uni0641.fina", "1" }, + { "uni0641.init", "1" }, + { "uni0641.medi", "1" }, + { "uni0642", "1" }, + { "uni0642.fina", "1" }, + { "uni0642.init", "1" }, + { "uni0642.medi", "1" }, + { "uni0643", "1" }, + { "uni0643.fina", "1" }, + { "uni0643.init", "1" }, + { "uni0643.medi", "1" }, + { "uni0644", "1" }, + { "uni0644.fina", "1" }, + { "uni0644.init", "1" }, + { "uni0644.init.preAlef", "1" }, + { "uni0644.medi", "1" }, + { "uni0644.medi.preAlef", "1" }, + { "uni06440627", "2" }, + { "uni06440627.fina", "2" }, + { "uni0645", "1" }, + { "uni0645.fina", "1" }, + { "uni0645.fina.sindhi", "1" }, + { "uni0645.init", "1" }, + { "uni0645.medi", "1" }, + { "uni0645.sindhi", "1" }, + { "uni0646", "1" }, + { "uni0646.fina", "1" }, + { "uni0646.init", "1" }, + { "uni0646.medi", "1" }, + { "uni0647", "1" }, + { "uni0647.fina", "1" }, + { "uni0647.fina.hooked", "1" }, + { "uni0647.fina.knottedFlat", "1" }, + { "uni0647.fina.knottedHigh", "1" }, + { "uni0647.init", "1" }, + { "uni0647.init.hooked", "1" }, + { "uni0647.knotted", "1" }, + { "uni0647.medi", "1" }, + { "uni0647.medi.hooked", "1" }, + { "uni0647.medi.knottedHigh", "1" }, + { "uni0648", "1" }, + { "uni0648.fina", "1" }, + { "uni0649", "1" }, + { "uni0649.fina", "1" }, + { "uni0649.init", "1" }, + { "uni0649.medi", "1" }, + { "uni064A", "1" }, + { "uni064A.fina", "1" }, + { "uni064A.fina.noDots", "1" }, + { "uni064A.init", "1" }, + { "uni064A.init.noDots", "1" }, + { "uni064A.medi", "1" }, + { "uni064A.medi.noDots", "1" }, + { "uni064A.noDots", "1" }, + { "uni064B", "3" }, + { "uni064C", "3" }, + { "uni064C.sixNine", "3" }, + { "uni064D", "3" }, + { "uni064E", "3" }, + { "uni064F", "3" }, + { "uni0650", "3" }, + { "uni0651", "3" }, + { "uni0651064B", "3" }, + { "uni0651064C", "3" }, + { "uni0651064D", "3" }, + { "uni0651064E", "3" }, + { "uni0651064F", "3" }, + { "uni06510650", "3" }, + { "uni0652", "3" }, + { "uni0652.downOpen", "3" }, + { "uni0652.leftOpen", "3" }, + { "uni0653", "3" }, + { "uni0654", "3" }, + { "uni0654064E", "3" }, + { "uni0654064F", "3" }, + { "uni0655", "3" }, + { "uni0656", "3" }, + { "uni0657", "3" }, + { "uni0658", "3" }, + { "uni0659", "3" }, + { "uni065A", "3" }, + { "uni065B", "3" }, + { "uni065C", "3" }, + { "uni065D", "3" }, + { "uni065E", "3" }, + { "uni0660", "1" }, + { "uni0660.Medium", "3" }, + { "uni0660.Small", "3" }, + { "uni0661", "1" }, + { "uni0661.Medium", "3" }, + { "uni0661.Small", "3" }, + { "uni0662", "1" }, + { "uni0662.Medium", "3" }, + { "uni0662.Small", "3" }, + { "uni0663", "1" }, + { "uni0663.Medium", "3" }, + { "uni0663.Small", "3" }, + { "uni0664", "1" }, + { "uni0664.Medium", "3" }, + { "uni0664.Small", "3" }, + { "uni0665", "1" }, + { "uni0665.Medium", "3" }, + { "uni0665.Small", "3" }, + { "uni0666", "1" }, + { "uni0666.Medium", "3" }, + { "uni0666.Small", "3" }, + { "uni0667", "1" }, + { "uni0667.Medium", "3" }, + { "uni0667.Small", "3" }, + { "uni0668", "1" }, + { "uni0668.Medium", "3" }, + { "uni0668.Small", "3" }, + { "uni0669", "1" }, + { "uni0669.Medium", "3" }, + { "uni0669.Small", "3" }, + { "uni066A", "1" }, + { "uni066B", "1" }, + { "uni066C", "1" }, + { "uni066D", "1" }, + { "uni066E", "1" }, + { "uni066E.fina", "1" }, + { "uni066E.init", "1" }, + { "uni066E.medi", "1" }, + { "uni066F", "1" }, + { "uni066F.fina", "1" }, + { "uni066F.init", "1" }, + { "uni066F.medi", "1" }, + { "uni0670", "3" }, + { "uni0670.large", "3" }, + { "uni0671", "1" }, + { "uni0671.fina", "1" }, + { "uni0671.fina.postLamIni", "1" }, + { "uni0671.fina.postLamMed", "1" }, + { "uni0672", "1" }, + { "uni0672.fina", "1" }, + { "uni0672.fina.postLamIni", "1" }, + { "uni0672.fina.postLamMed", "1" }, + { "uni0673", "1" }, + { "uni0673.fina", "1" }, + { "uni0673.fina.postLamIni", "1" }, + { "uni0673.fina.postLamMed", "1" }, + { "uni0674", "3" }, + { "uni0675", "1" }, + { "uni0675.fina", "1" }, + { "uni0675.fina.postLamIni", "1" }, + { "uni0675.fina.postLamMed", "1" }, + { "uni0676", "1" }, + { "uni0676.fina", "1" }, + { "uni0677", "1" }, + { "uni0677.fina", "1" }, + { "uni0678", "1" }, + { "uni0678.fina", "1" }, + { "uni0678.init", "1" }, + { "uni0678.medi", "1" }, + { "uni0679", "1" }, + { "uni0679.fina", "1" }, + { "uni0679.init", "1" }, + { "uni0679.medi", "1" }, + { "uni067A", "1" }, + { "uni067A.fina", "1" }, + { "uni067A.init", "1" }, + { "uni067A.medi", "1" }, + { "uni067B", "1" }, + { "uni067B.fina", "1" }, + { "uni067B.init", "1" }, + { "uni067B.medi", "1" }, + { "uni067C", "1" }, + { "uni067C.fina", "1" }, + { "uni067C.init", "1" }, + { "uni067C.medi", "1" }, + { "uni067D", "1" }, + { "uni067D.fina", "1" }, + { "uni067D.init", "1" }, + { "uni067D.medi", "1" }, + { "uni067E", "1" }, + { "uni067E.fina", "1" }, + { "uni067E.init", "1" }, + { "uni067E.medi", "1" }, + { "uni067F", "1" }, + { "uni067F.fina", "1" }, + { "uni067F.init", "1" }, + { "uni067F.medi", "1" }, + { "uni0680", "1" }, + { "uni0680.fina", "1" }, + { "uni0680.init", "1" }, + { "uni0680.medi", "1" }, + { "uni0681", "1" }, + { "uni0681.fina", "1" }, + { "uni0681.init", "1" }, + { "uni0681.medi", "1" }, + { "uni0682", "1" }, + { "uni0682.fina", "1" }, + { "uni0682.init", "1" }, + { "uni0682.medi", "1" }, + { "uni0683", "1" }, + { "uni0683.fina", "1" }, + { "uni0683.init", "1" }, + { "uni0683.medi", "1" }, + { "uni0684", "1" }, + { "uni0684.fina", "1" }, + { "uni0684.init", "1" }, + { "uni0684.medi", "1" }, + { "uni0685", "1" }, + { "uni0685.fina", "1" }, + { "uni0685.init", "1" }, + { "uni0685.medi", "1" }, + { "uni0686", "1" }, + { "uni0686.fina", "1" }, + { "uni0686.init", "1" }, + { "uni0686.medi", "1" }, + { "uni0687", "1" }, + { "uni0687.fina", "1" }, + { "uni0687.init", "1" }, + { "uni0687.medi", "1" }, + { "uni0688", "1" }, + { "uni0688.fina", "1" }, + { "uni0689", "1" }, + { "uni0689.fina", "1" }, + { "uni068A", "1" }, + { "uni068A.fina", "1" }, + { "uni068B", "1" }, + { "uni068B.fina", "1" }, + { "uni068C", "1" }, + { "uni068C.fina", "1" }, + { "uni068D", "1" }, + { "uni068D.fina", "1" }, + { "uni068E", "1" }, + { "uni068E.fina", "1" }, + { "uni068F", "1" }, + { "uni068F.fina", "1" }, + { "uni0690", "1" }, + { "uni0690.fina", "1" }, + { "uni0691", "1" }, + { "uni0691.fina", "1" }, + { "uni0692", "1" }, + { "uni0692.fina", "1" }, + { "uni0693", "1" }, + { "uni0693.fina", "1" }, + { "uni0694", "1" }, + { "uni0694.fina", "1" }, + { "uni0695", "1" }, + { "uni0695.fina", "1" }, + { "uni0696", "1" }, + { "uni0696.fina", "1" }, + { "uni0697", "1" }, + { "uni0697.fina", "1" }, + { "uni0698", "1" }, + { "uni0698.dotHat", "1" }, + { "uni0698.fina", "1" }, + { "uni0698.fina.dotHat", "1" }, + { "uni0699", "1" }, + { "uni0699.fina", "1" }, + { "uni069A", "1" }, + { "uni069A.fina", "1" }, + { "uni069A.init", "1" }, + { "uni069A.medi", "1" }, + { "uni069B", "1" }, + { "uni069B.fina", "1" }, + { "uni069B.init", "1" }, + { "uni069B.medi", "1" }, + { "uni069C", "1" }, + { "uni069C.fina", "1" }, + { "uni069C.init", "1" }, + { "uni069C.medi", "1" }, + { "uni069D", "1" }, + { "uni069D.fina", "1" }, + { "uni069D.init", "1" }, + { "uni069D.medi", "1" }, + { "uni069E", "1" }, + { "uni069E.fina", "1" }, + { "uni069E.init", "1" }, + { "uni069E.medi", "1" }, + { "uni069F", "1" }, + { "uni069F.fina", "1" }, + { "uni069F.init", "1" }, + { "uni069F.medi", "1" }, + { "uni06A0", "1" }, + { "uni06A0.fina", "1" }, + { "uni06A0.init", "1" }, + { "uni06A0.medi", "1" }, + { "uni06A1", "1" }, + { "uni06A1.fina", "1" }, + { "uni06A1.init", "1" }, + { "uni06A1.medi", "1" }, + { "uni06A2", "1" }, + { "uni06A2.fina", "1" }, + { "uni06A2.init", "1" }, + { "uni06A2.medi", "1" }, + { "uni06A3", "1" }, + { "uni06A3.fina", "1" }, + { "uni06A3.init", "1" }, + { "uni06A3.medi", "1" }, + { "uni06A4", "1" }, + { "uni06A4.fina", "1" }, + { "uni06A4.init", "1" }, + { "uni06A4.medi", "1" }, + { "uni06A5", "1" }, + { "uni06A5.fina", "1" }, + { "uni06A5.init", "1" }, + { "uni06A5.medi", "1" }, + { "uni06A6", "1" }, + { "uni06A6.fina", "1" }, + { "uni06A6.init", "1" }, + { "uni06A6.medi", "1" }, + { "uni06A7", "1" }, + { "uni06A7.fina", "1" }, + { "uni06A7.init", "1" }, + { "uni06A7.medi", "1" }, + { "uni06A8", "1" }, + { "uni06A8.fina", "1" }, + { "uni06A8.init", "1" }, + { "uni06A8.medi", "1" }, + { "uni06A9", "1" }, + { "uni06A9.fina", "1" }, + { "uni06A9.init", "1" }, + { "uni06A9.medi", "1" }, + { "uni06AA", "1" }, + { "uni06AA.fina", "1" }, + { "uni06AA.init", "1" }, + { "uni06AA.medi", "1" }, + { "uni06AB", "1" }, + { "uni06AB.fina", "1" }, + { "uni06AB.init", "1" }, + { "uni06AB.medi", "1" }, + { "uni06AC", "1" }, + { "uni06AC.fina", "1" }, + { "uni06AC.init", "1" }, + { "uni06AC.medi", "1" }, + { "uni06AD", "1" }, + { "uni06AD.fina", "1" }, + { "uni06AD.init", "1" }, + { "uni06AD.medi", "1" }, + { "uni06AE", "1" }, + { "uni06AE.fina", "1" }, + { "uni06AE.init", "1" }, + { "uni06AE.medi", "1" }, + { "uni06AF", "1" }, + { "uni06AF.fina", "1" }, + { "uni06AF.init", "1" }, + { "uni06AF.medi", "1" }, + { "uni06B0", "1" }, + { "uni06B0.fina", "1" }, + { "uni06B0.init", "1" }, + { "uni06B0.medi", "1" }, + { "uni06B1", "1" }, + { "uni06B1.fina", "1" }, + { "uni06B1.init", "1" }, + { "uni06B1.medi", "1" }, + { "uni06B2", "1" }, + { "uni06B2.fina", "1" }, + { "uni06B2.init", "1" }, + { "uni06B2.medi", "1" }, + { "uni06B3", "1" }, + { "uni06B3.fina", "1" }, + { "uni06B3.init", "1" }, + { "uni06B3.medi", "1" }, + { "uni06B4", "1" }, + { "uni06B4.fina", "1" }, + { "uni06B4.init", "1" }, + { "uni06B4.medi", "1" }, + { "uni06B5", "1" }, + { "uni06B5.fina", "1" }, + { "uni06B5.init", "1" }, + { "uni06B5.init.preAlef", "1" }, + { "uni06B5.medi", "1" }, + { "uni06B5.medi.preAlef", "1" }, + { "uni06B50627", "2" }, + { "uni06B50627.fina", "2" }, + { "uni06B6", "1" }, + { "uni06B6.fina", "1" }, + { "uni06B6.init", "1" }, + { "uni06B6.init.preAlef", "1" }, + { "uni06B6.medi", "1" }, + { "uni06B6.medi.preAlef", "1" }, + { "uni06B60627", "2" }, + { "uni06B60627.fina", "2" }, + { "uni06B7", "1" }, + { "uni06B7.fina", "1" }, + { "uni06B7.init", "1" }, + { "uni06B7.init.preAlef", "1" }, + { "uni06B7.medi", "1" }, + { "uni06B7.medi.preAlef", "1" }, + { "uni06B70627", "2" }, + { "uni06B70627.fina", "2" }, + { "uni06B8", "1" }, + { "uni06B8.fina", "1" }, + { "uni06B8.init", "1" }, + { "uni06B8.init.preAlef", "1" }, + { "uni06B8.medi", "1" }, + { "uni06B8.medi.preAlef", "1" }, + { "uni06B80627", "2" }, + { "uni06B80627.fina", "2" }, + { "uni06B9", "1" }, + { "uni06B9.fina", "1" }, + { "uni06B9.init", "1" }, + { "uni06B9.medi", "1" }, + { "uni06BA", "1" }, + { "uni06BA.fina", "1" }, + { "uni06BA.init", "1" }, + { "uni06BA.medi", "1" }, + { "uni06BB", "1" }, + { "uni06BB.fina", "1" }, + { "uni06BB.init", "1" }, + { "uni06BB.medi", "1" }, + { "uni06BC", "1" }, + { "uni06BC.fina", "1" }, + { "uni06BC.init", "1" }, + { "uni06BC.medi", "1" }, + { "uni06BD", "1" }, + { "uni06BD.fina", "1" }, + { "uni06BD.init", "1" }, + { "uni06BD.medi", "1" }, + { "uni06BE", "1" }, + { "uni06BE.fina", "1" }, + { "uni06BE.init", "1" }, + { "uni06BE.medi", "1" }, + { "uni06BF", "1" }, + { "uni06BF.fina", "1" }, + { "uni06BF.init", "1" }, + { "uni06BF.medi", "1" }, + { "uni06C0", "1" }, + { "uni06C0.fina", "1" }, + { "uni06C0.init", "1" }, + { "uni06C0.medi", "1" }, + { "uni06C1", "1" }, + { "uni06C1.fina", "1" }, + { "uni06C1.init", "1" }, + { "uni06C1.medi", "1" }, + { "uni06C2", "1" }, + { "uni06C2.fina", "1" }, + { "uni06C2.init", "1" }, + { "uni06C2.medi", "1" }, + { "uni06C3", "1" }, + { "uni06C3.fina", "1" }, + { "uni06C4", "1" }, + { "uni06C4.fina", "1" }, + { "uni06C5", "1" }, + { "uni06C5.fina", "1" }, + { "uni06C6", "1" }, + { "uni06C6.fina", "1" }, + { "uni06C7", "1" }, + { "uni06C7.fina", "1" }, + { "uni06C8", "1" }, + { "uni06C8.fina", "1" }, + { "uni06C9", "1" }, + { "uni06C9.fina", "1" }, + { "uni06CA", "1" }, + { "uni06CA.fina", "1" }, + { "uni06CB", "1" }, + { "uni06CB.fina", "1" }, + { "uni06CC", "1" }, + { "uni06CC.fina", "1" }, + { "uni06CC.init", "1" }, + { "uni06CC.medi", "1" }, + { "uni06CD", "1" }, + { "uni06CD.fina", "1" }, + { "uni06CE", "1" }, + { "uni06CE.fina", "1" }, + { "uni06CE.init", "1" }, + { "uni06CE.medi", "1" }, + { "uni06CF", "1" }, + { "uni06CF.fina", "1" }, + { "uni06D0", "1" }, + { "uni06D0.fina", "1" }, + { "uni06D0.init", "1" }, + { "uni06D0.medi", "1" }, + { "uni06D1", "1" }, + { "uni06D1.fina", "1" }, + { "uni06D1.init", "1" }, + { "uni06D1.medi", "1" }, + { "uni06D2", "1" }, + { "uni06D2.fina", "1" }, + { "uni06D3", "1" }, + { "uni06D3.fina", "1" }, + { "uni06D4", "1" }, + { "uni06D5", "1" }, + { "uni06D6", "3" }, + { "uni06D7", "3" }, + { "uni06D8", "3" }, + { "uni06D9", "3" }, + { "uni06DA", "3" }, + { "uni06DB", "3" }, + { "uni06DC", "3" }, + { "uni06DD", "1" }, + { "uni06DD.2", "1" }, + { "uni06DD.3", "1" }, + { "uni06DD.aat1", "1" }, + { "uni06DD.aat2", "1" }, + { "uni06DD.aat3", "1" }, + { "uni06DD.sp1", "1" }, + { "uni06DD.sp2", "1" }, + { "uni06DD.sp3", "1" }, + { "uni06DE", "1" }, + { "uni06DF", "3" }, + { "uni06E0", "3" }, + { "uni06E1", "3" }, + { "uni06E2", "3" }, + { "uni06E3", "3" }, + { "uni06E4", "3" }, + { "uni06E5", "3" }, + { "uni06E6", "3" }, + { "uni06E7", "3" }, + { "uni06E8", "3" }, + { "uni06E9", "1" }, + { "uni06EA", "3" }, + { "uni06EB", "3" }, + { "uni06EC", "3" }, + { "uni06ED", "3" }, + { "uni06EE", "1" }, + { "uni06EE.fina", "1" }, + { "uni06EF", "1" }, + { "uni06EF.fina", "1" }, + { "uni06F0", "1" }, + { "uni06F0.Medium", "3" }, + { "uni06F0.Small", "3" }, + { "uni06F1", "1" }, + { "uni06F1.Medium", "3" }, + { "uni06F1.Small", "3" }, + { "uni06F2", "1" }, + { "uni06F2.Medium", "3" }, + { "uni06F2.Small", "3" }, + { "uni06F3", "1" }, + { "uni06F3.Medium", "3" }, + { "uni06F3.Small", "3" }, + { "uni06F4", "1" }, + { "uni06F4.Medium", "3" }, + { "uni06F4.Medium.urdu", "3" }, + { "uni06F4.Small", "3" }, + { "uni06F4.Small.urdu", "3" }, + { "uni06F4.urdu", "1" }, + { "uni06F5", "1" }, + { "uni06F5.Medium", "3" }, + { "uni06F5.Small", "3" }, + { "uni06F6", "1" }, + { "uni06F6.Medium", "3" }, + { "uni06F6.Medium.urdu", "3" }, + { "uni06F6.Small", "3" }, + { "uni06F6.Small.urdu", "3" }, + { "uni06F6.urdu", "1" }, + { "uni06F7", "1" }, + { "uni06F7.Medium", "3" }, + { "uni06F7.Medium.urdu", "3" }, + { "uni06F7.Small", "3" }, + { "uni06F7.Small.urdu", "3" }, + { "uni06F7.urdu", "1" }, + { "uni06F8", "1" }, + { "uni06F8.Medium", "3" }, + { "uni06F8.Small", "3" }, + { "uni06F9", "1" }, + { "uni06F9.Medium", "3" }, + { "uni06F9.Small", "3" }, + { "uni06FA", "1" }, + { "uni06FA.fina", "1" }, + { "uni06FA.init", "1" }, + { "uni06FA.medi", "1" }, + { "uni06FB", "1" }, + { "uni06FB.fina", "1" }, + { "uni06FB.init", "1" }, + { "uni06FB.medi", "1" }, + { "uni06FC", "1" }, + { "uni06FC.fina", "1" }, + { "uni06FC.init", "1" }, + { "uni06FC.medi", "1" }, + { "uni06FD", "1" }, + { "uni06FE", "1" }, + { "uni06FF", "1" }, + { "uni06FF.fina", "1" }, + { "uni06FF.init", "1" }, + { "uni06FF.medi", "1" }, + { "uni0750", "1" }, + { "uni0750.fina", "1" }, + { "uni0750.init", "1" }, + { "uni0750.medi", "1" }, + { "uni0751", "1" }, + { "uni0751.fina", "1" }, + { "uni0751.init", "1" }, + { "uni0751.medi", "1" }, + { "uni0752", "1" }, + { "uni0752.fina", "1" }, + { "uni0752.init", "1" }, + { "uni0752.medi", "1" }, + { "uni0753", "1" }, + { "uni0753.fina", "1" }, + { "uni0753.init", "1" }, + { "uni0753.medi", "1" }, + { "uni0754", "1" }, + { "uni0754.fina", "1" }, + { "uni0754.init", "1" }, + { "uni0754.medi", "1" }, + { "uni0755", "1" }, + { "uni0755.fina", "1" }, + { "uni0755.init", "1" }, + { "uni0755.medi", "1" }, + { "uni0756", "1" }, + { "uni0756.fina", "1" }, + { "uni0756.init", "1" }, + { "uni0756.medi", "1" }, + { "uni0757", "1" }, + { "uni0757.fina", "1" }, + { "uni0757.init", "1" }, + { "uni0757.medi", "1" }, + { "uni0758", "1" }, + { "uni0758.fina", "1" }, + { "uni0758.init", "1" }, + { "uni0758.medi", "1" }, + { "uni0759", "1" }, + { "uni0759.fina", "1" }, + { "uni075A", "1" }, + { "uni075A.fina", "1" }, + { "uni075B", "1" }, + { "uni075B.fina", "1" }, + { "uni075C", "1" }, + { "uni075C.fina", "1" }, + { "uni075C.init", "1" }, + { "uni075C.medi", "1" }, + { "uni075D", "1" }, + { "uni075D.fina", "1" }, + { "uni075D.init", "1" }, + { "uni075D.medi", "1" }, + { "uni075E", "1" }, + { "uni075E.fina", "1" }, + { "uni075E.init", "1" }, + { "uni075E.medi", "1" }, + { "uni075F", "1" }, + { "uni075F.fina", "1" }, + { "uni075F.init", "1" }, + { "uni075F.medi", "1" }, + { "uni0760", "1" }, + { "uni0760.fina", "1" }, + { "uni0760.init", "1" }, + { "uni0760.medi", "1" }, + { "uni0761", "1" }, + { "uni0761.fina", "1" }, + { "uni0761.init", "1" }, + { "uni0761.medi", "1" }, + { "uni0762", "1" }, + { "uni0762.fina", "1" }, + { "uni0762.init", "1" }, + { "uni0762.medi", "1" }, + { "uni0763", "1" }, + { "uni0763.fina", "1" }, + { "uni0763.init", "1" }, + { "uni0763.medi", "1" }, + { "uni0764", "1" }, + { "uni0764.fina", "1" }, + { "uni0764.init", "1" }, + { "uni0764.medi", "1" }, + { "uni0765", "1" }, + { "uni0765.fina", "1" }, + { "uni0765.init", "1" }, + { "uni0765.medi", "1" }, + { "uni0766", "1" }, + { "uni0766.fina", "1" }, + { "uni0766.init", "1" }, + { "uni0766.medi", "1" }, + { "uni0767", "1" }, + { "uni0767.fina", "1" }, + { "uni0767.init", "1" }, + { "uni0767.medi", "1" }, + { "uni0768", "1" }, + { "uni0768.fina", "1" }, + { "uni0768.init", "1" }, + { "uni0768.medi", "1" }, + { "uni0769", "1" }, + { "uni0769.fina", "1" }, + { "uni0769.init", "1" }, + { "uni0769.medi", "1" }, + { "uni076A", "1" }, + { "uni076A.fina", "1" }, + { "uni076A.init", "1" }, + { "uni076A.init.preAlef", "1" }, + { "uni076A.medi", "1" }, + { "uni076A.medi.preAlef", "1" }, + { "uni076A0627", "2" }, + { "uni076A0627.fina", "2" }, + { "uni076B", "1" }, + { "uni076B.fina", "1" }, + { "uni076C", "1" }, + { "uni076C.fina", "1" }, + { "uni076D", "1" }, + { "uni076D.fina", "1" }, + { "uni076D.init", "1" }, + { "uni076D.medi", "1" }, + { "uni2000", "1" }, + { "uni2001", "1" }, + { "uni2002", "1" }, + { "uni2003", "1" }, + { "uni2004", "1" }, + { "uni2005", "1" }, + { "uni2006", "1" }, + { "uni2007", "1" }, + { "uni2008", "1" }, + { "uni2009", "1" }, + { "uni200A", "1" }, + { "uni200B", "1" }, + { "uni200C", "1" }, + { "uni200D", "1" }, + { "uni200E", "1" }, + { "uni200F", "1" }, + { "uni202A", "1" }, + { "uni202B", "1" }, + { "uni202C", "1" }, + { "uni202D", "1" }, + { "uni202E", "1" }, + { "uni2060", "1" }, + { "uni206C", "1" }, + { "uni206D", "1" }, + { "uni25CC", "1" }, + { "uniFD3E", "1" }, + { "uniFD3F", "1" }, + { "uniFDF2", "1" }, + { "uniFDFC", "1" }, + { "uniFEFF", "1" }, + { "v", "1" }, + { "w", "1" }, + { "x", "1" }, + { "y", "1" }, + { "z", "1" }, + { "zero", "1" }, + { "zeroMedium", "3" }, + { "zeroSmall", "3" }, + }, + }, + // arab-004.ttx + { "f3", "lu0", + new String[][] { + { "_bar", "1" }, + { "_damma", "1" }, + { "_dot1", "1" }, + { "_dot1_hat", "1" }, + { "_dot1_smallV", "1" }, + { "_dot1_tah", "1" }, + { "_dot2h", "1" }, + { "_dot2h_tah", "1" }, + { "_dot2v", "1" }, + { "_dot3d", "1" }, + { "_dot3h", "1" }, + { "_dot3u", "1" }, + { "_dot3u_tah", "1" }, + { "_dot4", "1" }, + { "_gafBar", "1" }, + { "_gafBarShort", "1" }, + { "_gafBarShort_dot2h", "1" }, + { "_gafBarShort_dot3u", "1" }, + { "_gafBar_dot2h", "1" }, + { "_gafBar_dot3u", "1" }, + { "_hamza", "1" }, + { "_hamzaDamma", "1" }, + { "_hat", "1" }, + { "_highHamza", "1" }, + { "_invSmallV", "1" }, + { "_lines", "1" }, + { "_madda", "1" }, + { "_ring", "1" }, + { "_smallV", "1" }, + { "_tah", "1" }, + { "_vline", "1" }, + { "_wasla", "1" }, + { "_wavyHamza", "1" }, + { "_wavyHamza.b", "1" }, + { "a", "1" }, + { "absAutoKashida", "1" }, + { "absJeemRetro1", "1" }, + { "absJeemRetro1Fin", "1" }, + { "absJeemRetro1Ini", "1" }, + { "absJeemRetro1Med", "1" }, + { "absJeemRetro2", "1" }, + { "absJeemRetro2Fin", "1" }, + { "absJeemRetro2Ini", "1" }, + { "absJeemRetro2Med", "1" }, + { "absJeemRetro3", "1" }, + { "absJeemRetro3Fin", "1" }, + { "absJeemRetro3Ini", "1" }, + { "absJeemRetro3Med", "1" }, + { "absJehRetro1", "1" }, + { "absJehRetro1Fin", "1" }, + { "absJehRetro2", "1" }, + { "absJehRetro2Fin", "1" }, + { "absLamRetro", "1" }, + { "absLamRetroAlef", "2" }, + { "absLamRetroAlefFin", "2" }, + { "absLamRetroFin", "1" }, + { "absLamRetroIni", "1" }, + { "absLamRetroIni.preAlef", "1" }, + { "absLamRetroMed", "1" }, + { "absLamRetroMed.preAlef", "1" }, + { "absShaddaAlef", "3" }, + { "absSheenRetro1", "1" }, + { "absSheenRetro1Fin", "1" }, + { "absSheenRetro1Ini", "1" }, + { "absSheenRetro1Med", "1" }, + { "absSheenRetro2", "1" }, + { "absSheenRetro2Fin", "1" }, + { "absSheenRetro2Ini", "1" }, + { "absSheenRetro2Med", "1" }, + { "absTchehRetro1", "1" }, + { "absTchehRetro1Fin", "1" }, + { "absTchehRetro1Ini", "1" }, + { "absTchehRetro1Med", "1" }, + { "absTchehRetro2", "1" }, + { "absTchehRetro2Fin", "1" }, + { "absTchehRetro2Ini", "1" }, + { "absTchehRetro2Med", "1" }, + { "absWawDotBelow", "1" }, + { "absWawDotBelowFin", "1" }, + { "ampersand", "1" }, + { "asciicircum", "1" }, + { "asciitilde", "1" }, + { "asterisk", "1" }, + { "at", "1" }, + { "b", "1" }, + { "backslash", "1" }, + { "bar", "1" }, + { "braceleft", "1" }, + { "braceright", "1" }, + { "bracketleft", "1" }, + { "bracketright", "1" }, + { "c", "1" }, + { "colon", "1" }, + { "comma", "1" }, + { "d", "1" }, + { "dollar", "1" }, + { "e", "1" }, + { "eight", "1" }, + { "eightMedium", "3" }, + { "eightSmall", "3" }, + { "equal", "1" }, + { "exclam", "1" }, + { "f", "1" }, + { "five", "1" }, + { "fiveMedium", "3" }, + { "fiveSmall", "3" }, + { "four", "1" }, + { "fourMedium", "3" }, + { "fourSmall", "3" }, + { "g", "1" }, + { "grave", "1" }, + { "greater", "1" }, + { "h", "1" }, + { "hyphen", "1" }, + { "i", "1" }, + { "j", "1" }, + { "k", "1" }, + { "l", "1" }, + { "less", "1" }, + { "m", "1" }, + { "n", "1" }, + { "nine", "1" }, + { "nineMedium", "3" }, + { "nineSmall", "3" }, + { "nonmarkingreturn", "1" }, + { "numbersign", "1" }, + { "o", "1" }, + { "one", "1" }, + { "oneMedium", "3" }, + { "oneSmall", "3" }, + { "p", "1" }, + { "parenleft", "1" }, + { "parenright", "1" }, + { "percent", "1" }, + { "period", "1" }, + { "plus", "1" }, + { "q", "1" }, + { "question", "1" }, + { "quotedbl", "1" }, + { "quotesingle", "1" }, + { "r", "1" }, + { "s", "1" }, + { "semicolon", "1" }, + { "seven", "1" }, + { "sevenMedium", "3" }, + { "sevenSmall", "3" }, + { "six", "1" }, + { "sixMedium", "3" }, + { "sixSmall", "3" }, + { "slash", "1" }, + { "space", "1" }, + { "t", "1" }, + { "three", "1" }, + { "threeMedium", "3" }, + { "threeSmall", "3" }, + { "two", "1" }, + { "twoMedium", "3" }, + { "twoSmall", "3" }, + { "u", "1" }, + { "underscore", "1" }, + { "uni0600", "1" }, + { "uni0600.2", "1" }, + { "uni0600.3", "1" }, + { "uni0600.aat1", "1" }, + { "uni0600.aat2", "1" }, + { "uni0600.aat3", "1" }, + { "uni0600.sp1", "1" }, + { "uni0600.sp2", "1" }, + { "uni0600.sp3", "1" }, + { "uni0601", "1" }, + { "uni0601.2", "1" }, + { "uni0601.3", "1" }, + { "uni0601.4", "1" }, + { "uni0601.aat1", "1" }, + { "uni0601.aat2", "1" }, + { "uni0601.aat3", "1" }, + { "uni0601.aat4", "1" }, + { "uni0601.sp1", "1" }, + { "uni0601.sp2", "1" }, + { "uni0601.sp3", "1" }, + { "uni0601.sp4", "1" }, + { "uni0602", "1" }, + { "uni0602.2", "1" }, + { "uni0602.aat1", "1" }, + { "uni0602.aat2", "1" }, + { "uni0602.sp1", "1" }, + { "uni0602.sp2", "1" }, + { "uni0603", "1" }, + { "uni0603.2", "1" }, + { "uni0603.3", "1" }, + { "uni0603.aat1", "1" }, + { "uni0603.aat2", "1" }, + { "uni0603.aat3", "1" }, + { "uni0603.sp1", "1" }, + { "uni0603.sp2", "1" }, + { "uni0603.sp3", "1" }, + { "uni060B", "1" }, + { "uni060C", "1" }, + { "uni060C.downward", "1" }, + { "uni060D", "1" }, + { "uni060E", "1" }, + { "uni060F", "1" }, + { "uni0610", "3" }, + { "uni0611", "3" }, + { "uni0612", "3" }, + { "uni0613", "3" }, + { "uni0614", "3" }, + { "uni0615", "3" }, + { "uni061B", "1" }, + { "uni061B.downward", "1" }, + { "uni061E", "1" }, + { "uni061F", "1" }, + { "uni0621", "1" }, + { "uni0622", "1" }, + { "uni0622.fina", "1" }, + { "uni0622.fina.postLamIni", "1" }, + { "uni0622.fina.postLamMed", "1" }, + { "uni0623", "1" }, + { "uni0623.fina", "1" }, + { "uni0623.fina.postLamIni", "1" }, + { "uni0623.fina.postLamMed", "1" }, + { "uni0624", "1" }, + { "uni0624.fina", "1" }, + { "uni0625", "1" }, + { "uni0625.fina", "1" }, + { "uni0625.fina.postLamIni", "1" }, + { "uni0625.fina.postLamMed", "1" }, + { "uni0626", "1" }, + { "uni0626.fina", "1" }, + { "uni0626.init", "1" }, + { "uni0626.medi", "1" }, + { "uni0627", "1" }, + { "uni0627.fina", "1" }, + { "uni0627.fina.postLamIni", "1" }, + { "uni0627.fina.postLamMed", "1" }, + { "uni0628", "1" }, + { "uni0628.fina", "1" }, + { "uni0628.init", "1" }, + { "uni0628.medi", "1" }, + { "uni0629", "1" }, + { "uni0629.fina", "1" }, + { "uni062A", "1" }, + { "uni062A.fina", "1" }, + { "uni062A.init", "1" }, + { "uni062A.medi", "1" }, + { "uni062B", "1" }, + { "uni062B.fina", "1" }, + { "uni062B.init", "1" }, + { "uni062B.medi", "1" }, + { "uni062C", "1" }, + { "uni062C.fina", "1" }, + { "uni062C.init", "1" }, + { "uni062C.medi", "1" }, + { "uni062D", "1" }, + { "uni062D.fina", "1" }, + { "uni062D.init", "1" }, + { "uni062D.medi", "1" }, + { "uni062E", "1" }, + { "uni062E.fina", "1" }, + { "uni062E.init", "1" }, + { "uni062E.medi", "1" }, + { "uni062F", "1" }, + { "uni062F.fina", "1" }, + { "uni0630", "1" }, + { "uni0630.fina", "1" }, + { "uni0631", "1" }, + { "uni0631.fina", "1" }, + { "uni0632", "1" }, + { "uni0632.fina", "1" }, + { "uni0633", "1" }, + { "uni0633.fina", "1" }, + { "uni0633.init", "1" }, + { "uni0633.medi", "1" }, + { "uni0634", "1" }, + { "uni0634.fina", "1" }, + { "uni0634.init", "1" }, + { "uni0634.medi", "1" }, + { "uni0635", "1" }, + { "uni0635.fina", "1" }, + { "uni0635.init", "1" }, + { "uni0635.medi", "1" }, + { "uni0636", "1" }, + { "uni0636.fina", "1" }, + { "uni0636.init", "1" }, + { "uni0636.medi", "1" }, + { "uni0637", "1" }, + { "uni0637.fina", "1" }, + { "uni0637.init", "1" }, + { "uni0637.medi", "1" }, + { "uni0638", "1" }, + { "uni0638.fina", "1" }, + { "uni0638.init", "1" }, + { "uni0638.medi", "1" }, + { "uni0639", "1" }, + { "uni0639.fina", "1" }, + { "uni0639.init", "1" }, + { "uni0639.medi", "1" }, + { "uni063A", "1" }, + { "uni063A.fina", "1" }, + { "uni063A.init", "1" }, + { "uni063A.medi", "1" }, + { "uni0640", "1" }, + { "uni0641", "1" }, + { "uni0641.fina", "1" }, + { "uni0641.init", "1" }, + { "uni0641.medi", "1" }, + { "uni0642", "1" }, + { "uni0642.fina", "1" }, + { "uni0642.init", "1" }, + { "uni0642.medi", "1" }, + { "uni0643", "1" }, + { "uni0643.fina", "1" }, + { "uni0643.init", "1" }, + { "uni0643.medi", "1" }, + { "uni0644", "1" }, + { "uni0644.fina", "1" }, + { "uni0644.init", "1" }, + { "uni0644.init.preAlef", "1" }, + { "uni0644.medi", "1" }, + { "uni0644.medi.preAlef", "1" }, + { "uni06440627", "2" }, + { "uni06440627.fina", "2" }, + { "uni0645", "1" }, + { "uni0645.fina", "1" }, + { "uni0645.fina.sindhi", "1" }, + { "uni0645.init", "1" }, + { "uni0645.medi", "1" }, + { "uni0645.sindhi", "1" }, + { "uni0646", "1" }, + { "uni0646.fina", "1" }, + { "uni0646.init", "1" }, + { "uni0646.medi", "1" }, + { "uni0647", "1" }, + { "uni0647.fina", "1" }, + { "uni0647.fina.hooked", "1" }, + { "uni0647.fina.knottedFlat", "1" }, + { "uni0647.fina.knottedHigh", "1" }, + { "uni0647.init", "1" }, + { "uni0647.init.hooked", "1" }, + { "uni0647.knotted", "1" }, + { "uni0647.medi", "1" }, + { "uni0647.medi.hooked", "1" }, + { "uni0647.medi.knottedHigh", "1" }, + { "uni0648", "1" }, + { "uni0648.fina", "1" }, + { "uni0649", "1" }, + { "uni0649.fina", "1" }, + { "uni0649.init", "1" }, + { "uni0649.medi", "1" }, + { "uni064A", "1" }, + { "uni064A.fina", "1" }, + { "uni064A.fina.noDots", "1" }, + { "uni064A.init", "1" }, + { "uni064A.init.noDots", "1" }, + { "uni064A.medi", "1" }, + { "uni064A.medi.noDots", "1" }, + { "uni064A.noDots", "1" }, + { "uni064B", "3" }, + { "uni064C", "3" }, + { "uni064C.sixNine", "3" }, + { "uni064D", "3" }, + { "uni064E", "3" }, + { "uni064F", "3" }, + { "uni0650", "3" }, + { "uni0651", "3" }, + { "uni0651064B", "3" }, + { "uni0651064C", "3" }, + { "uni0651064D", "3" }, + { "uni0651064E", "3" }, + { "uni0651064F", "3" }, + { "uni06510650", "3" }, + { "uni0652", "3" }, + { "uni0652.downOpen", "3" }, + { "uni0652.leftOpen", "3" }, + { "uni0653", "3" }, + { "uni0654", "3" }, + { "uni0654064E", "3" }, + { "uni0654064F", "3" }, + { "uni0655", "3" }, + { "uni0656", "3" }, + { "uni0657", "3" }, + { "uni0658", "3" }, + { "uni0659", "3" }, + { "uni065A", "3" }, + { "uni065B", "3" }, + { "uni065C", "3" }, + { "uni065D", "3" }, + { "uni065E", "3" }, + { "uni0660", "1" }, + { "uni0660.Medium", "3" }, + { "uni0660.Small", "3" }, + { "uni0661", "1" }, + { "uni0661.Medium", "3" }, + { "uni0661.Small", "3" }, + { "uni0662", "1" }, + { "uni0662.Medium", "3" }, + { "uni0662.Small", "3" }, + { "uni0663", "1" }, + { "uni0663.Medium", "3" }, + { "uni0663.Small", "3" }, + { "uni0664", "1" }, + { "uni0664.Medium", "3" }, + { "uni0664.Small", "3" }, + { "uni0665", "1" }, + { "uni0665.Medium", "3" }, + { "uni0665.Small", "3" }, + { "uni0666", "1" }, + { "uni0666.Medium", "3" }, + { "uni0666.Small", "3" }, + { "uni0667", "1" }, + { "uni0667.Medium", "3" }, + { "uni0667.Small", "3" }, + { "uni0668", "1" }, + { "uni0668.Medium", "3" }, + { "uni0668.Small", "3" }, + { "uni0669", "1" }, + { "uni0669.Medium", "3" }, + { "uni0669.Small", "3" }, + { "uni066A", "1" }, + { "uni066B", "1" }, + { "uni066C", "1" }, + { "uni066D", "1" }, + { "uni066E", "1" }, + { "uni066E.fina", "1" }, + { "uni066E.init", "1" }, + { "uni066E.medi", "1" }, + { "uni066F", "1" }, + { "uni066F.fina", "1" }, + { "uni066F.init", "1" }, + { "uni066F.medi", "1" }, + { "uni0670", "3" }, + { "uni0670.large", "3" }, + { "uni0671", "1" }, + { "uni0671.fina", "1" }, + { "uni0671.fina.postLamIni", "1" }, + { "uni0671.fina.postLamMed", "1" }, + { "uni0672", "1" }, + { "uni0672.fina", "1" }, + { "uni0672.fina.postLamIni", "1" }, + { "uni0672.fina.postLamMed", "1" }, + { "uni0673", "1" }, + { "uni0673.fina", "1" }, + { "uni0673.fina.postLamIni", "1" }, + { "uni0673.fina.postLamMed", "1" }, + { "uni0674", "3" }, + { "uni0675", "1" }, + { "uni0675.fina", "1" }, + { "uni0675.fina.postLamIni", "1" }, + { "uni0675.fina.postLamMed", "1" }, + { "uni0676", "1" }, + { "uni0676.fina", "1" }, + { "uni0677", "1" }, + { "uni0677.fina", "1" }, + { "uni0678", "1" }, + { "uni0678.fina", "1" }, + { "uni0678.init", "1" }, + { "uni0678.medi", "1" }, + { "uni0679", "1" }, + { "uni0679.fina", "1" }, + { "uni0679.init", "1" }, + { "uni0679.medi", "1" }, + { "uni067A", "1" }, + { "uni067A.fina", "1" }, + { "uni067A.init", "1" }, + { "uni067A.medi", "1" }, + { "uni067B", "1" }, + { "uni067B.fina", "1" }, + { "uni067B.init", "1" }, + { "uni067B.medi", "1" }, + { "uni067C", "1" }, + { "uni067C.fina", "1" }, + { "uni067C.init", "1" }, + { "uni067C.medi", "1" }, + { "uni067D", "1" }, + { "uni067D.fina", "1" }, + { "uni067D.init", "1" }, + { "uni067D.medi", "1" }, + { "uni067E", "1" }, + { "uni067E.fina", "1" }, + { "uni067E.init", "1" }, + { "uni067E.medi", "1" }, + { "uni067F", "1" }, + { "uni067F.fina", "1" }, + { "uni067F.init", "1" }, + { "uni067F.medi", "1" }, + { "uni0680", "1" }, + { "uni0680.fina", "1" }, + { "uni0680.init", "1" }, + { "uni0680.medi", "1" }, + { "uni0681", "1" }, + { "uni0681.fina", "1" }, + { "uni0681.init", "1" }, + { "uni0681.medi", "1" }, + { "uni0682", "1" }, + { "uni0682.fina", "1" }, + { "uni0682.init", "1" }, + { "uni0682.medi", "1" }, + { "uni0683", "1" }, + { "uni0683.fina", "1" }, + { "uni0683.init", "1" }, + { "uni0683.medi", "1" }, + { "uni0684", "1" }, + { "uni0684.fina", "1" }, + { "uni0684.init", "1" }, + { "uni0684.medi", "1" }, + { "uni0685", "1" }, + { "uni0685.fina", "1" }, + { "uni0685.init", "1" }, + { "uni0685.medi", "1" }, + { "uni0686", "1" }, + { "uni0686.fina", "1" }, + { "uni0686.init", "1" }, + { "uni0686.medi", "1" }, + { "uni0687", "1" }, + { "uni0687.fina", "1" }, + { "uni0687.init", "1" }, + { "uni0687.medi", "1" }, + { "uni0688", "1" }, + { "uni0688.fina", "1" }, + { "uni0689", "1" }, + { "uni0689.fina", "1" }, + { "uni068A", "1" }, + { "uni068A.fina", "1" }, + { "uni068B", "1" }, + { "uni068B.fina", "1" }, + { "uni068C", "1" }, + { "uni068C.fina", "1" }, + { "uni068D", "1" }, + { "uni068D.fina", "1" }, + { "uni068E", "1" }, + { "uni068E.fina", "1" }, + { "uni068F", "1" }, + { "uni068F.fina", "1" }, + { "uni0690", "1" }, + { "uni0690.fina", "1" }, + { "uni0691", "1" }, + { "uni0691.fina", "1" }, + { "uni0692", "1" }, + { "uni0692.fina", "1" }, + { "uni0693", "1" }, + { "uni0693.fina", "1" }, + { "uni0694", "1" }, + { "uni0694.fina", "1" }, + { "uni0695", "1" }, + { "uni0695.fina", "1" }, + { "uni0696", "1" }, + { "uni0696.fina", "1" }, + { "uni0697", "1" }, + { "uni0697.fina", "1" }, + { "uni0698", "1" }, + { "uni0698.dotHat", "1" }, + { "uni0698.fina", "1" }, + { "uni0698.fina.dotHat", "1" }, + { "uni0699", "1" }, + { "uni0699.fina", "1" }, + { "uni069A", "1" }, + { "uni069A.fina", "1" }, + { "uni069A.init", "1" }, + { "uni069A.medi", "1" }, + { "uni069B", "1" }, + { "uni069B.fina", "1" }, + { "uni069B.init", "1" }, + { "uni069B.medi", "1" }, + { "uni069C", "1" }, + { "uni069C.fina", "1" }, + { "uni069C.init", "1" }, + { "uni069C.medi", "1" }, + { "uni069D", "1" }, + { "uni069D.fina", "1" }, + { "uni069D.init", "1" }, + { "uni069D.medi", "1" }, + { "uni069E", "1" }, + { "uni069E.fina", "1" }, + { "uni069E.init", "1" }, + { "uni069E.medi", "1" }, + { "uni069F", "1" }, + { "uni069F.fina", "1" }, + { "uni069F.init", "1" }, + { "uni069F.medi", "1" }, + { "uni06A0", "1" }, + { "uni06A0.fina", "1" }, + { "uni06A0.init", "1" }, + { "uni06A0.medi", "1" }, + { "uni06A1", "1" }, + { "uni06A1.fina", "1" }, + { "uni06A1.init", "1" }, + { "uni06A1.medi", "1" }, + { "uni06A2", "1" }, + { "uni06A2.fina", "1" }, + { "uni06A2.init", "1" }, + { "uni06A2.medi", "1" }, + { "uni06A3", "1" }, + { "uni06A3.fina", "1" }, + { "uni06A3.init", "1" }, + { "uni06A3.medi", "1" }, + { "uni06A4", "1" }, + { "uni06A4.fina", "1" }, + { "uni06A4.init", "1" }, + { "uni06A4.medi", "1" }, + { "uni06A5", "1" }, + { "uni06A5.fina", "1" }, + { "uni06A5.init", "1" }, + { "uni06A5.medi", "1" }, + { "uni06A6", "1" }, + { "uni06A6.fina", "1" }, + { "uni06A6.init", "1" }, + { "uni06A6.medi", "1" }, + { "uni06A7", "1" }, + { "uni06A7.fina", "1" }, + { "uni06A7.init", "1" }, + { "uni06A7.medi", "1" }, + { "uni06A8", "1" }, + { "uni06A8.fina", "1" }, + { "uni06A8.init", "1" }, + { "uni06A8.medi", "1" }, + { "uni06A9", "1" }, + { "uni06A9.fina", "1" }, + { "uni06A9.init", "1" }, + { "uni06A9.medi", "1" }, + { "uni06AA", "1" }, + { "uni06AA.fina", "1" }, + { "uni06AA.init", "1" }, + { "uni06AA.medi", "1" }, + { "uni06AB", "1" }, + { "uni06AB.fina", "1" }, + { "uni06AB.init", "1" }, + { "uni06AB.medi", "1" }, + { "uni06AC", "1" }, + { "uni06AC.fina", "1" }, + { "uni06AC.init", "1" }, + { "uni06AC.medi", "1" }, + { "uni06AD", "1" }, + { "uni06AD.fina", "1" }, + { "uni06AD.init", "1" }, + { "uni06AD.medi", "1" }, + { "uni06AE", "1" }, + { "uni06AE.fina", "1" }, + { "uni06AE.init", "1" }, + { "uni06AE.medi", "1" }, + { "uni06AF", "1" }, + { "uni06AF.fina", "1" }, + { "uni06AF.init", "1" }, + { "uni06AF.medi", "1" }, + { "uni06B0", "1" }, + { "uni06B0.fina", "1" }, + { "uni06B0.init", "1" }, + { "uni06B0.medi", "1" }, + { "uni06B1", "1" }, + { "uni06B1.fina", "1" }, + { "uni06B1.init", "1" }, + { "uni06B1.medi", "1" }, + { "uni06B2", "1" }, + { "uni06B2.fina", "1" }, + { "uni06B2.init", "1" }, + { "uni06B2.medi", "1" }, + { "uni06B3", "1" }, + { "uni06B3.fina", "1" }, + { "uni06B3.init", "1" }, + { "uni06B3.medi", "1" }, + { "uni06B4", "1" }, + { "uni06B4.fina", "1" }, + { "uni06B4.init", "1" }, + { "uni06B4.medi", "1" }, + { "uni06B5", "1" }, + { "uni06B5.fina", "1" }, + { "uni06B5.init", "1" }, + { "uni06B5.init.preAlef", "1" }, + { "uni06B5.medi", "1" }, + { "uni06B5.medi.preAlef", "1" }, + { "uni06B50627", "2" }, + { "uni06B50627.fina", "2" }, + { "uni06B6", "1" }, + { "uni06B6.fina", "1" }, + { "uni06B6.init", "1" }, + { "uni06B6.init.preAlef", "1" }, + { "uni06B6.medi", "1" }, + { "uni06B6.medi.preAlef", "1" }, + { "uni06B60627", "2" }, + { "uni06B60627.fina", "2" }, + { "uni06B7", "1" }, + { "uni06B7.fina", "1" }, + { "uni06B7.init", "1" }, + { "uni06B7.init.preAlef", "1" }, + { "uni06B7.medi", "1" }, + { "uni06B7.medi.preAlef", "1" }, + { "uni06B70627", "2" }, + { "uni06B70627.fina", "2" }, + { "uni06B8", "1" }, + { "uni06B8.fina", "1" }, + { "uni06B8.init", "1" }, + { "uni06B8.init.preAlef", "1" }, + { "uni06B8.medi", "1" }, + { "uni06B8.medi.preAlef", "1" }, + { "uni06B80627", "2" }, + { "uni06B80627.fina", "2" }, + { "uni06B9", "1" }, + { "uni06B9.fina", "1" }, + { "uni06B9.init", "1" }, + { "uni06B9.medi", "1" }, + { "uni06BA", "1" }, + { "uni06BA.fina", "1" }, + { "uni06BA.init", "1" }, + { "uni06BA.medi", "1" }, + { "uni06BB", "1" }, + { "uni06BB.fina", "1" }, + { "uni06BB.init", "1" }, + { "uni06BB.medi", "1" }, + { "uni06BC", "1" }, + { "uni06BC.fina", "1" }, + { "uni06BC.init", "1" }, + { "uni06BC.medi", "1" }, + { "uni06BD", "1" }, + { "uni06BD.fina", "1" }, + { "uni06BD.init", "1" }, + { "uni06BD.medi", "1" }, + { "uni06BE", "1" }, + { "uni06BE.fina", "1" }, + { "uni06BE.init", "1" }, + { "uni06BE.medi", "1" }, + { "uni06BF", "1" }, + { "uni06BF.fina", "1" }, + { "uni06BF.init", "1" }, + { "uni06BF.medi", "1" }, + { "uni06C0", "1" }, + { "uni06C0.fina", "1" }, + { "uni06C0.init", "1" }, + { "uni06C0.medi", "1" }, + { "uni06C1", "1" }, + { "uni06C1.fina", "1" }, + { "uni06C1.init", "1" }, + { "uni06C1.medi", "1" }, + { "uni06C2", "1" }, + { "uni06C2.fina", "1" }, + { "uni06C2.init", "1" }, + { "uni06C2.medi", "1" }, + { "uni06C3", "1" }, + { "uni06C3.fina", "1" }, + { "uni06C4", "1" }, + { "uni06C4.fina", "1" }, + { "uni06C5", "1" }, + { "uni06C5.fina", "1" }, + { "uni06C6", "1" }, + { "uni06C6.fina", "1" }, + { "uni06C7", "1" }, + { "uni06C7.fina", "1" }, + { "uni06C8", "1" }, + { "uni06C8.fina", "1" }, + { "uni06C9", "1" }, + { "uni06C9.fina", "1" }, + { "uni06CA", "1" }, + { "uni06CA.fina", "1" }, + { "uni06CB", "1" }, + { "uni06CB.fina", "1" }, + { "uni06CC", "1" }, + { "uni06CC.fina", "1" }, + { "uni06CC.init", "1" }, + { "uni06CC.medi", "1" }, + { "uni06CD", "1" }, + { "uni06CD.fina", "1" }, + { "uni06CE", "1" }, + { "uni06CE.fina", "1" }, + { "uni06CE.init", "1" }, + { "uni06CE.medi", "1" }, + { "uni06CF", "1" }, + { "uni06CF.fina", "1" }, + { "uni06D0", "1" }, + { "uni06D0.fina", "1" }, + { "uni06D0.init", "1" }, + { "uni06D0.medi", "1" }, + { "uni06D1", "1" }, + { "uni06D1.fina", "1" }, + { "uni06D1.init", "1" }, + { "uni06D1.medi", "1" }, + { "uni06D2", "1" }, + { "uni06D2.fina", "1" }, + { "uni06D3", "1" }, + { "uni06D3.fina", "1" }, + { "uni06D4", "1" }, + { "uni06D5", "1" }, + { "uni06D6", "3" }, + { "uni06D7", "3" }, + { "uni06D8", "3" }, + { "uni06D9", "3" }, + { "uni06DA", "3" }, + { "uni06DB", "3" }, + { "uni06DC", "3" }, + { "uni06DD", "1" }, + { "uni06DD.2", "1" }, + { "uni06DD.3", "1" }, + { "uni06DD.aat1", "1" }, + { "uni06DD.aat2", "1" }, + { "uni06DD.aat3", "1" }, + { "uni06DD.alt", "1" }, + { "uni06DD.alt.2", "1" }, + { "uni06DD.alt.3", "1" }, + { "uni06DD.alt.aat1", "1" }, + { "uni06DD.alt.aat2", "1" }, + { "uni06DD.alt.aat3", "1" }, + { "uni06DD.altB", "1" }, + { "uni06DD.altB.2", "1" }, + { "uni06DD.altB.3", "1" }, + { "uni06DD.altB.aat1", "1" }, + { "uni06DD.altB.aat2", "1" }, + { "uni06DD.altB.aat3", "1" }, + { "uni06DD.sp1", "1" }, + { "uni06DD.sp2", "1" }, + { "uni06DD.sp3", "1" }, + { "uni06DE", "1" }, + { "uni06DF", "3" }, + { "uni06E0", "3" }, + { "uni06E1", "3" }, + { "uni06E2", "3" }, + { "uni06E3", "3" }, + { "uni06E4", "3" }, + { "uni06E5", "3" }, + { "uni06E6", "3" }, + { "uni06E7", "3" }, + { "uni06E8", "3" }, + { "uni06E9", "1" }, + { "uni06EA", "3" }, + { "uni06EB", "3" }, + { "uni06EC", "3" }, + { "uni06ED", "3" }, + { "uni06EE", "1" }, + { "uni06EE.fina", "1" }, + { "uni06EF", "1" }, + { "uni06EF.fina", "1" }, + { "uni06F0", "1" }, + { "uni06F0.Medium", "3" }, + { "uni06F0.Small", "3" }, + { "uni06F1", "1" }, + { "uni06F1.Medium", "3" }, + { "uni06F1.Small", "3" }, + { "uni06F2", "1" }, + { "uni06F2.Medium", "3" }, + { "uni06F2.Small", "3" }, + { "uni06F3", "1" }, + { "uni06F3.Medium", "3" }, + { "uni06F3.Small", "3" }, + { "uni06F4", "1" }, + { "uni06F4.Medium", "3" }, + { "uni06F4.Medium.urdu", "3" }, + { "uni06F4.Small", "3" }, + { "uni06F4.Small.urdu", "3" }, + { "uni06F4.urdu", "1" }, + { "uni06F5", "1" }, + { "uni06F5.Medium", "3" }, + { "uni06F5.Small", "3" }, + { "uni06F6", "1" }, + { "uni06F6.Medium", "3" }, + { "uni06F6.Medium.urdu", "3" }, + { "uni06F6.Small", "3" }, + { "uni06F6.Small.urdu", "3" }, + { "uni06F6.urdu", "1" }, + { "uni06F7", "1" }, + { "uni06F7.Medium", "3" }, + { "uni06F7.Medium.urdu", "3" }, + { "uni06F7.Small", "3" }, + { "uni06F7.Small.urdu", "3" }, + { "uni06F7.urdu", "1" }, + { "uni06F8", "1" }, + { "uni06F8.Medium", "3" }, + { "uni06F8.Small", "3" }, + { "uni06F9", "1" }, + { "uni06F9.Medium", "3" }, + { "uni06F9.Small", "3" }, + { "uni06FA", "1" }, + { "uni06FA.fina", "1" }, + { "uni06FA.init", "1" }, + { "uni06FA.medi", "1" }, + { "uni06FB", "1" }, + { "uni06FB.fina", "1" }, + { "uni06FB.init", "1" }, + { "uni06FB.medi", "1" }, + { "uni06FC", "1" }, + { "uni06FC.fina", "1" }, + { "uni06FC.init", "1" }, + { "uni06FC.medi", "1" }, + { "uni06FD", "1" }, + { "uni06FE", "1" }, + { "uni06FF", "1" }, + { "uni06FF.fina", "1" }, + { "uni06FF.init", "1" }, + { "uni06FF.medi", "1" }, + { "uni0750", "1" }, + { "uni0750.fina", "1" }, + { "uni0750.init", "1" }, + { "uni0750.medi", "1" }, + { "uni0751", "1" }, + { "uni0751.fina", "1" }, + { "uni0751.init", "1" }, + { "uni0751.medi", "1" }, + { "uni0752", "1" }, + { "uni0752.fina", "1" }, + { "uni0752.init", "1" }, + { "uni0752.medi", "1" }, + { "uni0753", "1" }, + { "uni0753.fina", "1" }, + { "uni0753.init", "1" }, + { "uni0753.medi", "1" }, + { "uni0754", "1" }, + { "uni0754.fina", "1" }, + { "uni0754.init", "1" }, + { "uni0754.medi", "1" }, + { "uni0755", "1" }, + { "uni0755.fina", "1" }, + { "uni0755.init", "1" }, + { "uni0755.medi", "1" }, + { "uni0756", "1" }, + { "uni0756.fina", "1" }, + { "uni0756.init", "1" }, + { "uni0756.medi", "1" }, + { "uni0757", "1" }, + { "uni0757.fina", "1" }, + { "uni0757.init", "1" }, + { "uni0757.medi", "1" }, + { "uni0758", "1" }, + { "uni0758.fina", "1" }, + { "uni0758.init", "1" }, + { "uni0758.medi", "1" }, + { "uni0759", "1" }, + { "uni0759.fina", "1" }, + { "uni075A", "1" }, + { "uni075A.fina", "1" }, + { "uni075B", "1" }, + { "uni075B.fina", "1" }, + { "uni075C", "1" }, + { "uni075C.fina", "1" }, + { "uni075C.init", "1" }, + { "uni075C.medi", "1" }, + { "uni075D", "1" }, + { "uni075D.fina", "1" }, + { "uni075D.init", "1" }, + { "uni075D.medi", "1" }, + { "uni075E", "1" }, + { "uni075E.fina", "1" }, + { "uni075E.init", "1" }, + { "uni075E.medi", "1" }, + { "uni075F", "1" }, + { "uni075F.fina", "1" }, + { "uni075F.init", "1" }, + { "uni075F.medi", "1" }, + { "uni0760", "1" }, + { "uni0760.fina", "1" }, + { "uni0760.init", "1" }, + { "uni0760.medi", "1" }, + { "uni0761", "1" }, + { "uni0761.fina", "1" }, + { "uni0761.init", "1" }, + { "uni0761.medi", "1" }, + { "uni0762", "1" }, + { "uni0762.fina", "1" }, + { "uni0762.init", "1" }, + { "uni0762.medi", "1" }, + { "uni0763", "1" }, + { "uni0763.fina", "1" }, + { "uni0763.init", "1" }, + { "uni0763.medi", "1" }, + { "uni0764", "1" }, + { "uni0764.fina", "1" }, + { "uni0764.init", "1" }, + { "uni0764.medi", "1" }, + { "uni0765", "1" }, + { "uni0765.fina", "1" }, + { "uni0765.init", "1" }, + { "uni0765.medi", "1" }, + { "uni0766", "1" }, + { "uni0766.fina", "1" }, + { "uni0766.init", "1" }, + { "uni0766.medi", "1" }, + { "uni0767", "1" }, + { "uni0767.fina", "1" }, + { "uni0767.init", "1" }, + { "uni0767.medi", "1" }, + { "uni0768", "1" }, + { "uni0768.fina", "1" }, + { "uni0768.init", "1" }, + { "uni0768.medi", "1" }, + { "uni0769", "1" }, + { "uni0769.fina", "1" }, + { "uni0769.init", "1" }, + { "uni0769.medi", "1" }, + { "uni076A", "1" }, + { "uni076A.fina", "1" }, + { "uni076A.init", "1" }, + { "uni076A.init.preAlef", "1" }, + { "uni076A.medi", "1" }, + { "uni076A.medi.preAlef", "1" }, + { "uni076A0627", "2" }, + { "uni076A0627.fina", "2" }, + { "uni076B", "1" }, + { "uni076B.fina", "1" }, + { "uni076C", "1" }, + { "uni076C.fina", "1" }, + { "uni076D", "1" }, + { "uni076D.fina", "1" }, + { "uni076D.init", "1" }, + { "uni076D.medi", "1" }, + { "uni2000", "1" }, + { "uni2001", "1" }, + { "uni2002", "1" }, + { "uni2003", "1" }, + { "uni2004", "1" }, + { "uni2005", "1" }, + { "uni2006", "1" }, + { "uni2007", "1" }, + { "uni2008", "1" }, + { "uni2009", "1" }, + { "uni200A", "1" }, + { "uni200B", "1" }, + { "uni200C", "1" }, + { "uni200D", "1" }, + { "uni200E", "1" }, + { "uni200F", "1" }, + { "uni202A", "1" }, + { "uni202B", "1" }, + { "uni202C", "1" }, + { "uni202D", "1" }, + { "uni202E", "1" }, + { "uni2060", "1" }, + { "uni206C", "1" }, + { "uni206D", "1" }, + { "uni25CC", "1" }, + { "uniFD3E", "1" }, + { "uniFD3F", "1" }, + { "uniFDF2", "1" }, + { "uniFDFC", "1" }, + { "uniFEFF", "1" }, + { "v", "1" }, + { "w", "1" }, + { "x", "1" }, + { "y", "1" }, + { "z", "1" }, + { "zero", "1" }, + { "zeroMedium", "3" }, + { "zeroSmall", "3" }, + }, + }, + }; + + private static Object[][] ltAttachmentPoint = { + { GlyphDefinitionTable.GDEF_LOOKUP_TYPE_ATTACHMENT_POINT }, + // arab-001.ttx - not present + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltLigatureCaret = { + { GlyphDefinitionTable.GDEF_LOOKUP_TYPE_LIGATURE_CARET }, + // arab-001.ttx - not present + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltMarkAttachment = { + { GlyphDefinitionTable.GDEF_LOOKUP_TYPE_MARK_ATTACHMENT }, + // arab-001.ttx - not present + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + @Test + public void testGDEFGlyphClass() throws Exception { + performLookups ( ltGlyphClass ); + } + + @Test + public void testGDEFAttachmentPoint() throws Exception { + performLookups ( ltAttachmentPoint ); + } + + @Test + public void testGDEFLigatureCaret() throws Exception { + performLookups ( ltLigatureCaret ); + } + + @Test + public void testGDEFMarkAttachment() throws Exception { + performLookups ( ltMarkAttachment ); + } + + /** + * Perform lookups on all test data in test specification TS. + * @param ts test specification + */ + private void performLookups ( Object[][] ts ) { + assert ts.length > 0; + Object[] tp = ts[0]; + for ( int i = 1; i < ts.length; i++ ) { + performLookups ( tp, ts[i] ); + } + } + + /** + * Perform lookups on all test data TD using test parameters TP. + * @param tp test parameters + * @param td test data + */ + private void performLookups ( Object[] tp, Object[] td ) { + assert tp.length > 0; + if ( td.length > 1 ) { + String fid = (String) td[0]; + String lid = (String) td[1]; + TTXFile tf = findTTX ( fid ); + assertTrue ( tf != null ); + GlyphDefinitionTable gdef = tf.getGDEF(); + assertTrue ( gdef != null ); + String[][] tia = (String[][]) td[2]; + switch ( (int) ( (Integer) tp[0] ) ) { + case GlyphDefinitionTable.GDEF_LOOKUP_TYPE_GLYPH_CLASS: + performGlyphClassLookups ( tf, lid, tia ); + break; + case GlyphDefinitionTable.GDEF_LOOKUP_TYPE_ATTACHMENT_POINT: + performAttachmentPointLookups ( tf, lid, tia ); + break; + case GlyphDefinitionTable.GDEF_LOOKUP_TYPE_LIGATURE_CARET: + performLigatureCaretLookups ( tf, lid, tia ); + break; + case GlyphDefinitionTable.GDEF_LOOKUP_TYPE_MARK_ATTACHMENT: + performMarkAttachmentLookups ( tf, lid, tia ); + break; + default: + assertTrue ( "bad lookup type", false ); + break; + } + } + } + + private void performGlyphClassLookups ( TTXFile tf, String lid, String[][] tia ) { + GlyphDefinitionTable gdef = tf.getGDEF(); + assert gdef != null; + for ( String[] ti : tia ) { + assert ti != null; + assert ti.length > 1; + String gn = ti[0]; + assert gn != null; + String cn = ti[1]; + assert cn != null; + int g = tf.getGlyph ( gn ); + assertTrue ( g >= 0 ); + int oc = Integer.parseInt ( cn ); + int tc = gdef.getGlyphClass ( g ); + assertEquals ( "bad glyph class for glyph \'" + gn + "\', gid(" + g + ")", oc, tc ); + } + } + + private void performAttachmentPointLookups ( TTXFile tf, String lid, String[][] tia ) { + // not yet supported by GDEF or test TTX files + } + + private void performLigatureCaretLookups ( TTXFile tf, String lid, String[][] tia ) { + // not yet supported by GDEF or test TTX files + } + + private void performMarkAttachmentLookups ( TTXFile tf, String lid, String[][] tia ) { + // not yet supported by GDEF or test TTX files + } + + private String findTTXPath ( String fid ) { + for ( String[] fs : ttxFonts ) { + if ( ( fs != null ) && ( fs.length > 1 ) ) { + if ( fs[0].equals ( fid ) ) { + return ttxFilesRoot + File.separator + fs[1]; + } + } + } + return null; + } + + private TTXFile findTTX ( String fid ) { + String pn = findTTXPath ( fid ); + assertTrue ( pn != null ); + try { + TTXFile tf = TTXFile.getFromCache ( pn ); + return tf; + } catch ( Exception e ) { + fail ( e.getMessage() ); + return null; + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java new file mode 100644 index 000000000..a2b2f7fba --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java @@ -0,0 +1,473 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import org.apache.fop.complexscripts.fonts.GlyphSubtable; +import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphContextTester; +import org.apache.fop.complexscripts.util.GlyphSequence; +import org.apache.fop.complexscripts.util.ScriptContextTester; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class GPOSTestCase implements ScriptContextTester, GlyphContextTester { + + private static String ttxFilesRoot = "test/resources/complexscripts"; + + private static String[][] ttxFonts = { + { "f0", "arab/ttx/arab-001.ttx" }, // simplified arabic + { "f1", "arab/ttx/arab-002.ttx" }, // traditional arabic + { "f2", "arab/ttx/arab-003.ttx" }, // lateef + { "f3", "arab/ttx/arab-004.ttx" }, // scheherazade + }; + + private static Object[][] ltSingle = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_SINGLE }, + // arab-001.ttx + { "f0", "lu1", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "fathatan" }, + new int[][] { + { 0, 0, -412, 0 } + } + }, + { + new String[] { "fatha" }, + new int[][] { + { 0, 0, -410, 0 } + } + }, + }, + }, + { "f0", "lu9", "arab", "*", "*", + new Object[][] { + { + new String[] { "fathatan" }, + new int[][] { + { 50, 0, 0, 0 } + } + }, + { + new String[] { "fatha" }, + new int[][] { + { 50, 0, 0, 0 } + } + }, + }, + }, + { "f0", "lu10", "arab", "*", "*", + new Object[][] { + { + new String[] { "kasratan" }, + new int[][] { + { 0, -200, 0, 0 } + } + }, + { + new String[] { "kasra" }, + new int[][] { + { 0, -200, 0, 0 } + } + }, + }, + }, + { "f0", "lu11", "arab", "*", "*", + new Object[][] { + { + new String[] { "kasratan" }, + new int[][] { + { 0, -300, 0, 0 } + } + }, + { + new String[] { "kasra" }, + new int[][] { + { 0, -300, 0, 0 } + } + }, + { + new String[] { "uni0655" }, + new int[][] { + { 0, -250, 0, 0 } + } + }, + }, + }, + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltPair = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_PAIR }, + // arab-001.ttx + { "f0", "lu0", "arab", "dflt", "kern", + new Object[][] { + { + new String[] { "wawwithhamzaabove", "hamza" }, + new int[][] { + { -300, 0, -300, 0 }, { 0, 0, 0, 0 } + } + }, + { + new String[] { "reh", "alefwithmaddaabove" }, + new int[][] { + { -500, 0, -500, 0 }, { 0, 0, 0, 0 } + } + }, + { + new String[] { "zain", "zain" }, + new int[][] { + { -190, 0, -190, 0 }, { 0, 0, 0, 0 } + } + }, + { + new String[] { "waw", "uni0649.init" }, + new int[][] { + { -145, 0, -145, 0 }, { 0, 0, 0, 0 } + } + }, + { + new String[] { "jeh", "uni06A5.init" }, + new int[][] { + { -345, 0, -345, 0 }, { 0, 0, 0, 0 } + } + }, + }, + }, + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltCursive = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_CURSIVE }, + // arab-001.ttx - none used + // arab-002.ttx - none used + // arab-003.ttx - maybe add tests + { "f2", "lu0", "arab", "dflt", "curs", + new Object[][] { + { + new String[] { "uni0644.init.preAlef", "uni0622.fina.postLamIni" }, + new int[][] { + // { 576, 0, 0, 0 }, { 0, 0, 0, 0 } - with zero widths + { 295, 0, 0, 0 }, { 0, 0, 0, 0 } + } + }, + { + new String[] { "uni0644.medi.preAlef", "uni0622.fina.postLamMed" }, + new int[][] { + // { 550, 0, 0, 0 }, { 0, 0, 0, 0 } - with zero widths + { 282, 0, 0, 0 }, { 0, 0, 0, 0 } + } + }, + }, + }, + // arab-004.ttx - none used + }; + + private static Object[][] ltMarkToBase = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_BASE }, + // arab-001.ttx - maybe add tests + // arab-002.ttx + { "f1", "lu4", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "beh", "fatha" }, + new int[][] { + // { 0, 0, 0, 0 }, { 266, -672, 0, 0 } - with zero widths + { 0, 0, 0, 0 }, { 266, -672, -199, 0 } + } + }, + { + new String[] { "alefwithhamzabelow", "kasra" }, + new int[][] { + // { 0, 0, 0, 0 }, { -48, 344, 0, 0 } - with zero widths + { 0, 0, 0, 0 }, { -48, 344, -199, 0 } + } + }, + }, + }, + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltMarkToLigature = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_LIGATURE }, + // arab-001.ttx + { "f0", "lu4", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "rayaleflam", "fatha", "fatha", "fatha", "fatha" }, + new int[][] { + { 0, 0, 0, 0 }, { 1260, -1150, 0, 0 }, { 910, -1020, 0, 0 }, { 590, -630, 0, 0 }, { 110, -720, 0, 0 } + } + }, + { + new String[] { "rayaleflam", "kasra", "kasra", "kasra", "kasra" }, + new int[][] { + { 0, 0, 0, 0 }, { 1110 , 225, 0, 0 }, { 760, 275, 0, 0 }, { 520, 475, 0, 0 }, { 110, 425, 0, 0 } + } + }, + }, + }, + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx - maybe add tests + }; + + private static Object[][] ltMarkToMark = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_MARK }, + // arab-001.ttx - maybe add tests + // arab-002.ttx - maybe add tests + // arab-003.ttx - maybe add tests + // arab-004.ttx + { "f3", "lu3", "arab", "dflt", "mkmk", + new Object[][] { + { + new String[] { "uni064F", "uni064E" }, + new int[][] { + { 0, 0, 0, 0 }, { -15, 495, 0, 0 } + } + }, + { + new String[] { "uni0651", "uni0670" }, + new int[][] { + { 0, 0, 0, 0 }, { -30, 705, 0, 0 } + } + }, + }, + }, + }; + + private static Object[][] ltContextual = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_CONTEXTUAL }, + // arab-001.ttx - none used + // arab-002.ttx - none used + // arab-003.ttx - none used + // arab-004.ttx - none used + }; + + private static Object[][] ltChainedContextual = { + { GlyphPositioningTable.GPOS_LOOKUP_TYPE_CHAINED_CONTEXTUAL }, + // arab-001.ttx + { "f0", "lu3", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "behmedial", "fatha", "lam" }, + new int[][] { + { 0, 0, 0, 0 }, { 50, 0, 0, 0 }, { 0, 0, 0, 0 } + } + }, + }, + }, + // arab-002.ttx + { "f1", "lu6", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "zain", "fatha", "kafinitial" }, + new int[][] { + { 0, 0, 0, 0 }, { 0, 250, 0, 0 }, { 0, 0, 0, 0 } + } + }, + }, + }, + // arab-003.ttx - none used + // arab-004.ttx + { "f3", "lu5", "arab", "dflt", "mark", + new Object[][] { + { + new String[] { "uni064D", "uni0622.fina.postLamIni", "uni0650" }, + new int[][] { + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 55, 424, 0, 0 } + } + }, + }, + }, + }; + + @Test + public void testGPOSSingle() throws Exception { + performPositioning ( ltSingle ); + } + + @Test + public void testGPOSPair() throws Exception { + performPositioning ( ltPair ); + } + + @Test + public void testGPOSCursive() throws Exception { + performPositioning ( ltCursive ); + } + + @Test + public void testGPOSMarkToBase() throws Exception { + performPositioning ( ltMarkToBase ); + } + + @Test + public void testGPOSMarkToLigature() throws Exception { + performPositioning ( ltMarkToLigature ); + } + + @Test + public void testGPOSMarkToMark() throws Exception { + performPositioning ( ltMarkToMark ); + } + + @Test + public void testGPOSContextual() throws Exception { + performPositioning ( ltContextual ); + } + + @Test + public void testGPOSChainedContextual() throws Exception { + performPositioning ( ltChainedContextual ); + } + + /** + * Perform positioning on all test data in test specification TS. + * @param ts test specification + */ + private void performPositioning ( Object[][] ts ) { + assert ts.length > 0; + Object[] tp = ts[0]; + for ( int i = 1; i < ts.length; i++ ) { + performPositioning ( tp, ts[i] ); + } + } + + /** + * Perform positioning on all test data TD using test parameters TP. + * @param tp test parameters + * @param td test data + */ + private void performPositioning ( Object[] tp, Object[] td ) { + assert tp.length > 0; + if ( td.length > 5 ) { + String fid = (String) td[0]; + String lid = (String) td[1]; + String script = (String) td[2]; + String language = (String) td[3]; + String feature = (String) td[4]; + TTXFile tf = findTTX ( fid ); + assertTrue ( tf != null ); + GlyphPositioningTable gpos = tf.getGPOS(); + assertTrue ( gpos != null ); + GlyphPositioningSubtable[] sta = findGPOSSubtables ( gpos, script, language, feature, lid ); + assertTrue ( sta != null ); + assertTrue ( sta.length > 0 ); + ScriptContextTester sct = findScriptContextTester ( script, language, feature ); + Object[][] tia = (Object[][]) td[5]; // test instance array + for ( Object[] ti : tia ) { // test instance + if ( ti != null ) { + if ( ti.length > 0 ) { // must have at least input glyphs + String[] igia = (String[]) ti[0]; // input glyph id array + int[][] ogpa = (int[][]) ti[1]; // output glyph positioning array + GlyphSequence igs = tf.getGlyphSequence ( igia ); + int[] widths = tf.getWidths(); + int[][] tgpa = new int [ igia.length ] [ 4 ]; + boolean adjusted = GlyphPositioningSubtable.position ( igs, script, language, feature, 1000, sta, widths, tgpa, sct ); + assertTrue ( adjusted ); + assertSamePositions ( ogpa, tgpa ); + } + } + } + } + } + + private String findTTXPath ( String fid ) { + for ( String[] fs : ttxFonts ) { + if ( ( fs != null ) && ( fs.length > 1 ) ) { + if ( fs[0].equals ( fid ) ) { + return ttxFilesRoot + File.separator + fs[1]; + } + } + } + return null; + } + + private TTXFile findTTX ( String fid ) { + String pn = findTTXPath ( fid ); + assertTrue ( pn != null ); + try { + TTXFile tf = TTXFile.getFromCache ( pn ); + return tf; + } catch ( Exception e ) { + fail ( e.getMessage() ); + return null; + } + } + + private GlyphPositioningSubtable[] findGPOSSubtables ( GlyphPositioningTable gpos, String script, String language, String feature, String lid ) { + LookupTable lt = gpos.getLookupTable ( lid ); + if ( lt != null ) { + return (GlyphPositioningSubtable[]) lt.getSubtables(); + } else { + return null; + } + } + + private ScriptContextTester findScriptContextTester ( String script, String language, String feature ) { + return this; + } + + public GlyphContextTester getTester ( String feature ) { + return this; + } + + public boolean test ( String script, String language, String feature, GlyphSequence gs, int index, int flags ) { + return true; + } + + private void assertSamePositions ( int[][] pa1, int[][] pa2 ) { + assertNotNull ( pa1 ); + assertNotNull ( pa2 ); + assertEquals ( "unequal adjustment count", pa1.length, pa2.length ); + for ( int i = 0; i < pa1.length; i++ ) { + int[] a1 = pa1 [ i ]; + int[] a2 = pa2 [ i ]; + assertNotNull ( a1 ); + assertNotNull ( a2 ); + assertEquals ( "bad adjustment array length", 4, a1.length ); + assertEquals ( "bad adjustment array length", 4, a2.length ); + for ( int k = 0; k < a1.length; k++ ) { + int p1 = a1[k]; + int p2 = a2[k]; + assertEquals ( "bad adjustment", p1, p2 ); + } + } + } +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java new file mode 100644 index 000000000..8510f5e1f --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java @@ -0,0 +1,2266 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts; + +import java.io.File; +import java.nio.IntBuffer; +import java.util.List; +import java.util.Map; + +import org.apache.fop.complexscripts.fonts.GlyphSubtable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec; +import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphContextTester; +import org.apache.fop.complexscripts.util.GlyphSequence; +import org.apache.fop.complexscripts.util.ScriptContextTester; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class GSUBTestCase implements ScriptContextTester, GlyphContextTester { + + private static String ttxFilesRoot = "test/resources/complexscripts"; + + private static String[][] ttxFonts = { + { "f0", "arab/ttx/arab-001.ttx" }, // simplified arabic + { "f1", "arab/ttx/arab-002.ttx" }, // traditional arabic + { "f2", "arab/ttx/arab-003.ttx" }, // lateef + { "f3", "arab/ttx/arab-004.ttx" }, // scheherazade + }; + + private static Object[][] ltSingle = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_SINGLE }, + // arab-001.ttx + { "f0", "lu2", "arab", "dflt", "isol", + new String[][][] { + { { "ainisolated" }, { "ain" } }, + { { "alefmaksuraisolated" }, { "alefmaksura" } }, + { { "behisolated" }, { "beh" } }, + { { "dadisolated" }, { "dad" } }, + { { "dalisolated" }, { "dal" } }, + { { "farsiyehisolated" }, { "farsiyeh" } }, + { { "fehisolated" }, { "feh" } }, + { { "gafisolated" }, { "gaf" } }, + { { "ghainisolated" }, { "ghain" } }, + { { "hahisolated" }, { "hah" } }, + { { "jeemisolated" }, { "jeem" } }, + { { "jehisolated" }, { "jeh" } }, + { { "kafisolated" }, { "arabickaf" } }, + { { "kehehisolated" }, { "keheh" } }, + { { "khahisolated" }, { "khah" } }, + { { "meemisolated" }, { "meem" } }, + { { "noonisolated" }, { "noon" } }, + { { "pehisolated" }, { "peh" } }, + { { "qafisolated" }, { "qaf" } }, + { { "rehisolated" }, { "reh" } }, + { { "sadisolated" }, { "sad" } }, + { { "seenisolated" }, { "seen" } }, + { { "sheenisolated" }, { "sheen" } }, + { { "tahisolated" }, { "tah" } }, + { { "tchehisolated" }, { "tcheh" } }, + { { "tehisolated" }, { "teh" } }, + { { "tehmarbutaisolated" }, { "tehmarbuta" } }, + { { "thalisolated" }, { "thal" } }, + { { "thehisolated" }, { "theh" } }, + { { "vehisolated" }, { "veh" } }, + { { "wawisolated" }, { "waw" } }, + { { "yehisolated" }, { "yeh" } }, + { { "yehwithhamzaaboveisolated" }, { "yehwithhamzaabove" } }, + { { "zahisolated" }, { "zah" } }, + { { "zainisolated" }, { "zain" } }, + }, + }, + { "f0", "lu4", "arab", "dflt", "fina", + new String[][][] { + { { "ain" }, { "ainfinal" } }, + { { "alefmaksura" }, { "alefmaksurafinal" } }, + { { "alefwasla" }, { "alefwaslafinal" } }, + { { "alefwithhamzaabove" }, { "alefwithhamzaabovefinal" } }, + { { "alefwithhamzabelow" }, { "alefwithhamzabelowfinal" } }, + { { "alefwithmaddaabove" }, { "alefwithmaddaabovefinal" } }, + { { "arabicae" }, { "hehfinal" } }, + { { "arabicalef" }, { "aleffinal" } }, + { { "arabickaf" }, { "arabickaf" } }, + { { "beh" }, { "beh" } }, + { { "dad" }, { "dad" } }, + { { "dal" }, { "dal" } }, + { { "farsiyeh" }, { "farsiyehfinal" } }, + { { "feh" }, { "feh" } }, + { { "gaf" }, { "gaffinal" } }, + { { "ghain" }, { "ghainfinal" } }, + { { "hah" }, { "hahfinal" } }, + { { "heh" }, { "hehfinal" } }, + { { "jeem" }, { "jeemfinal" } }, + { { "jeh" }, { "jeh" } }, + { { "keheh" }, { "kehehfinal" } }, + { { "khah" }, { "khahfinal" } }, + { { "lam" }, { "lam" } }, + { { "meem" }, { "meem" } }, + { { "noon" }, { "noon" } }, + { { "peh" }, { "peh" } }, + { { "qaf" }, { "qaf" } }, + { { "reh" }, { "reh" } }, + { { "sad" }, { "sad" } }, + { { "seen" }, { "seen" } }, + { { "sheen" }, { "sheen" } }, + { { "tah" }, { "tah" } }, + { { "tcheh" }, { "tchehfinal" } }, + { { "teh" }, { "teh" } }, + { { "tehmarbuta" }, { "tehmarbutafinal" } }, + { { "thal" }, { "thal" } }, + { { "theh" }, { "theh" } }, + { { "veh" }, { "veh" } }, + { { "waw" }, { "waw" } }, + { { "wawwithhamzaabove" }, { "wawwithhamzaabove" } }, + { { "yeh" }, { "yehfinal" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaabovefinal" } }, + { { "zah" }, { "zah" } }, + { { "zain" }, { "zain" } }, + } + }, + { "f0", "lu5", "arab", "dflt", "init", + new String[][][] { + { { "ain" }, { "aininitial" } }, + { { "alefmaksura" }, { "uni0649.init" } }, + { { "arabickaf" }, { "kafmedial" } }, + { { "beh" }, { "behmedial" } }, + { { "dad" }, { "dadmedial" } }, + { { "farsiyeh" }, { "yehmedial" } }, + { { "feh" }, { "fehinitial" } }, + { { "gaf" }, { "gafinitial" } }, + { { "ghain" }, { "ghaininitial" } }, + { { "hah" }, { "hahmedial" } }, + { { "heh" }, { "hehinitial" } }, + { { "jeem" }, { "jeemmedial" } }, + { { "keheh" }, { "kehehinitial" } }, + { { "khah" }, { "khahmedial" } }, + { { "lam" }, { "lamisolated" } }, + { { "meem" }, { "meemmedial" } }, + { { "noon" }, { "noonmedial" } }, + { { "peh" }, { "pehmedial" } }, + { { "qaf" }, { "qafinitial" } }, + { { "sad" }, { "sadmedial" } }, + { { "seen" }, { "seenmedial" } }, + { { "sheen" }, { "sheenmedial" } }, + { { "tah" }, { "tah" } }, + { { "tcheh" }, { "tchehmedial" } }, + { { "teh" }, { "tehmedial" } }, + { { "theh" }, { "thehmedial" } }, + { { "veh" }, { "uni06A5.init" } }, + { { "yeh" }, { "yehmedial" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaabovemedial" } }, + { { "zah" }, { "zah" } }, + } + }, + { "f0", "lu6", "arab", "dflt", "medi", + new String[][][] { + { { "ain" }, { "ainmedial" } }, + { { "alefmaksura" }, { "uni0649.init" } }, + { { "arabickaf" }, { "kafmedial" } }, + { { "beh" }, { "behmedial" } }, + { { "dad" }, { "dadmedial" } }, + { { "farsiyeh" }, { "yehmedial" } }, + { { "feh" }, { "fehmedial" } }, + { { "gaf" }, { "gafmedial" } }, + { { "ghain" }, { "ghainmedial" } }, + { { "hah" }, { "hahmedial" } }, + { { "heh" }, { "hehmedial" } }, + { { "jeem" }, { "jeemmedial" } }, + { { "keheh" }, { "kehehmedial" } }, + { { "khah" }, { "khahmedial" } }, + { { "lam" }, { "lammedial" } }, + { { "meem" }, { "meemmedial" } }, + { { "noon" }, { "noonmedial" } }, + { { "peh" }, { "pehmedial" } }, + { { "qaf" }, { "qafmedial" } }, + { { "sad" }, { "sadmedial" } }, + { { "seen" }, { "seenmedial" } }, + { { "sheen" }, { "sheenmedial" } }, + { { "tah" }, { "tah" } }, + { { "tcheh" }, { "tchehmedial" } }, + { { "teh" }, { "tehmedial" } }, + { { "theh" }, { "thehmedial" } }, + { { "veh" }, { "vehmedial" } }, + { { "yeh" }, { "yehmedial" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaabovemedial" } }, + { { "zah" }, { "zah" } }, + } + }, + // arab-002.ttx + { "f1", "lu1", "arab", "*", "isol", + new String[][][] { + { { "ainisolated" }, { "ain" } }, + { { "alefmaksuraisolated" }, { "alefmaksura" } }, + { { "behisolated" }, { "beh" } }, + { { "dadisolated" }, { "dad" } }, + { { "dalisolated" }, { "dal" } }, + { { "farsiyehisolated" }, { "farsiyeh" } }, + { { "fehisolated" }, { "feh" } }, + { { "gafisolated" }, { "gaf" } }, + { { "ghainisolated" }, { "ghain" } }, + { { "hahisolated" }, { "hah" } }, + { { "jeemisolated" }, { "jeem" } }, + { { "jehisolated" }, { "jeh" } }, + { { "kafisolated" }, { "arabickaf" } }, + { { "kehehisolated" }, { "keheh" } }, + { { "khahisolated" }, { "khah" } }, + { { "meemisolated" }, { "meem" } }, + { { "noonisolated" }, { "noon" } }, + { { "pehisolated" }, { "peh" } }, + { { "qafisolated" }, { "qaf" } }, + { { "rehisolated" }, { "reh" } }, + { { "sadisolated" }, { "sad" } }, + { { "seenisolated" }, { "seen" } }, + { { "sheenisolated" }, { "sheen" } }, + { { "tahisolated" }, { "tah" } }, + { { "tchehisolated" }, { "tcheh" } }, + { { "tehisolated" }, { "teh" } }, + { { "tehmarbutaisolated" }, { "tehmarbuta" } }, + { { "thalisolated" }, { "thal" } }, + { { "thehisolated" }, { "theh" } }, + { { "vehisolated" }, { "veh" } }, + { { "wawisolated" }, { "waw" } }, + { { "yehisolated" }, { "yeh" } }, + { { "yehwithhamzaaboveisolated" }, { "yehwithhamzaabove" } }, + { { "zahisolated" }, { "zah" } }, + { { "zainisolated" }, { "zain" } }, + } + }, + { "f1", "lu3", "arab", "*", "fina", + new String[][][] { + { { "ain" }, { "ainfinal" } }, + { { "alefmaksura" }, { "alefmaksurafinal" } }, + { { "alefwasla" }, { "alefwaslafinal" } }, + { { "alefwithhamzaabove" }, { "alefwithhamzaabovefinal" } }, + { { "alefwithhamzabelow" }, { "alefwithhamzabelowfinal" } }, + { { "alefwithmaddaabove" }, { "alefwithmaddaabovefinal" } }, + { { "arabicae" }, { "hehfinal" } }, + { { "arabicalef" }, { "aleffinal" } }, + { { "arabickaf" }, { "arabickaffinal" } }, + { { "beh" }, { "behfinal" } }, + { { "dad" }, { "dadfinal" } }, + { { "dal" }, { "dalfinal" } }, + { { "farsiyeh" }, { "farsiyehfinal" } }, + { { "feh" }, { "fehfinal" } }, + { { "gaf" }, { "gaffinal" } }, + { { "ghain" }, { "ghainfinal" } }, + { { "hah" }, { "hahfinal" } }, + { { "heh" }, { "hehfinal" } }, + { { "jeem" }, { "jeemfinal" } }, + { { "jeh" }, { "jehfinal" } }, + { { "keheh" }, { "kehehfinal" } }, + { { "khah" }, { "khahfinal" } }, + { { "lam" }, { "lamfinal" } }, + { { "meem" }, { "meemfinal" } }, + { { "noon" }, { "noonfinal" } }, + { { "peh" }, { "pehfinal" } }, + { { "qaf" }, { "qaffinal" } }, + { { "reh" }, { "rehfinal" } }, + { { "sad" }, { "sadfinal" } }, + { { "seen" }, { "seenfinal" } }, + { { "sheen" }, { "sheenfinal" } }, + { { "tah" }, { "tahfinal" } }, + { { "tcheh" }, { "tchehfinal" } }, + { { "teh" }, { "tehfinal" } }, + { { "tehmarbuta" }, { "tehmarbutafinal" } }, + { { "thal" }, { "thalfinal" } }, + { { "theh" }, { "thehfinal" } }, + { { "veh" }, { "vehfinal" } }, + { { "waw" }, { "wawfinal" } }, + { { "wawwithhamzaabove" }, { "wawwithhamzaabovefinal" } }, + { { "yeh" }, { "yehfinal" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaabovefinal" } }, + { { "zah" }, { "zahfinal" } }, + { { "zain" }, { "zainfinal" } }, + } + }, + { "f1", "lu4", "arab", "*", "init", + new String[][][] { + { { "ain" }, { "aininitial" } }, + { { "alefmaksura" }, { "uni0649.init" } }, + { { "arabickaf" }, { "kafinitial" } }, + { { "beh" }, { "behinitial" } }, + { { "dad" }, { "dadinitial" } }, + { { "farsiyeh" }, { "yehinitial" } }, + { { "feh" }, { "fehinitial" } }, + { { "gaf" }, { "gafinitial" } }, + { { "ghain" }, { "ghaininitial" } }, + { { "hah" }, { "hahinitial" } }, + { { "heh" }, { "hehinitial" } }, + { { "jeem" }, { "jeeminitial" } }, + { { "keheh" }, { "kehehinitial" } }, + { { "khah" }, { "khahinitial" } }, + { { "lam" }, { "laminitial" } }, + { { "meem" }, { "meeminitial" } }, + { { "noon" }, { "nooninitial" } }, + { { "peh" }, { "pehinitial" } }, + { { "qaf" }, { "qafinitial" } }, + { { "sad" }, { "sadinitial" } }, + { { "seen" }, { "seeninitial" } }, + { { "sheen" }, { "sheeninitial" } }, + { { "tah" }, { "tahinitial" } }, + { { "tcheh" }, { "tchehinitial" } }, + { { "teh" }, { "tehinitial" } }, + { { "theh" }, { "thehinitial" } }, + { { "veh" }, { "vehinitial" } }, + { { "yeh" }, { "yehinitial" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaaboveinitial" } }, + { { "zah" }, { "zahinitial" } }, + } + }, + { "f1", "lu5", "arab", "*", "medi", + new String[][][] { + { { "ain" }, { "ainmedial" } }, + { { "alefmaksura" }, { "uni0649.medi" } }, + { { "arabickaf" }, { "kafmedial" } }, + { { "beh" }, { "behmedial" } }, + { { "dad" }, { "dadmedial" } }, + { { "farsiyeh" }, { "yehmedial" } }, + { { "feh" }, { "fehmedial" } }, + { { "gaf" }, { "gafmedial" } }, + { { "ghain" }, { "ghainmedial" } }, + { { "hah" }, { "hahmedial" } }, + { { "heh" }, { "hehmedial" } }, + { { "jeem" }, { "jeemmedial" } }, + { { "keheh" }, { "kehehmedial" } }, + { { "khah" }, { "khahmedial" } }, + { { "lam" }, { "lammedial" } }, + { { "meem" }, { "meemmedial" } }, + { { "noon" }, { "noonmedial" } }, + { { "peh" }, { "pehmedial" } }, + { { "qaf" }, { "qafmedial" } }, + { { "sad" }, { "sadmedial" } }, + { { "seen" }, { "seenmedial" } }, + { { "sheen" }, { "sheenmedial" } }, + { { "tah" }, { "tahmedial" } }, + { { "tcheh" }, { "tchehmedial" } }, + { { "teh" }, { "tehmedial" } }, + { { "theh" }, { "thehmedial" } }, + { { "veh" }, { "vehmedial" } }, + { { "yeh" }, { "yehmedial" } }, + { { "yehwithhamzaabove" }, { "yehwithhamzaabovemedial" } }, + { { "zah" }, { "zahmedial" } }, + } + }, + { "f1", "lu13", "arab", "*", "*", + new String[][][] { + { { "heh" }, { "hehisolated" } }, + } + }, + // arab-003.ttx + { "f2", "lu1", "arab", "dflt", "init", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Ini" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Ini" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Ini" } }, + { { "absLamRetro" }, { "absLamRetroIni" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Ini" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Ini" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Ini" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Ini" } }, + { { "uni0626" }, { "uni0626.init" } }, + { { "uni0628" }, { "uni0628.init" } }, + { { "uni062A" }, { "uni062A.init" } }, + { { "uni062B" }, { "uni062B.init" } }, + { { "uni062C" }, { "uni062C.init" } }, + { { "uni062D" }, { "uni062D.init" } }, + { { "uni062E" }, { "uni062E.init" } }, + { { "uni0633" }, { "uni0633.init" } }, + { { "uni0634" }, { "uni0634.init" } }, + { { "uni0635" }, { "uni0635.init" } }, + { { "uni0636" }, { "uni0636.init" } }, + { { "uni0637" }, { "uni0637.init" } }, + { { "uni0638" }, { "uni0638.init" } }, + { { "uni0639" }, { "uni0639.init" } }, + { { "uni063A" }, { "uni063A.init" } }, + { { "uni0641" }, { "uni0641.init" } }, + { { "uni0642" }, { "uni0642.init" } }, + { { "uni0643" }, { "uni0643.init" } }, + { { "uni0644" }, { "uni0644.init" } }, + { { "uni0645" }, { "uni0645.init" } }, + { { "uni0646" }, { "uni0646.init" } }, + { { "uni0647" }, { "uni0647.init" } }, + { { "uni0649" }, { "uni0649.init" } }, + { { "uni064A" }, { "uni064A.init" } }, + { { "uni064A.noDots" }, { "uni064A.init.noDots" } }, + { { "uni066E" }, { "uni066E.init" } }, + { { "uni066F" }, { "uni066F.init" } }, + { { "uni0678" }, { "uni0678.init" } }, + { { "uni0679" }, { "uni0679.init" } }, + { { "uni067A" }, { "uni067A.init" } }, + { { "uni067B" }, { "uni067B.init" } }, + { { "uni067C" }, { "uni067C.init" } }, + { { "uni067D" }, { "uni067D.init" } }, + { { "uni067E" }, { "uni067E.init" } }, + { { "uni067F" }, { "uni067F.init" } }, + { { "uni0680" }, { "uni0680.init" } }, + { { "uni0681" }, { "uni0681.init" } }, + { { "uni0682" }, { "uni0682.init" } }, + { { "uni0683" }, { "uni0683.init" } }, + { { "uni0684" }, { "uni0684.init" } }, + { { "uni0685" }, { "uni0685.init" } }, + { { "uni0686" }, { "uni0686.init" } }, + { { "uni0687" }, { "uni0687.init" } }, + { { "uni069A" }, { "uni069A.init" } }, + { { "uni069B" }, { "uni069B.init" } }, + { { "uni069C" }, { "uni069C.init" } }, + { { "uni069D" }, { "uni069D.init" } }, + { { "uni069E" }, { "uni069E.init" } }, + { { "uni069F" }, { "uni069F.init" } }, + { { "uni06A0" }, { "uni06A0.init" } }, + { { "uni06A1" }, { "uni06A1.init" } }, + { { "uni06A2" }, { "uni06A2.init" } }, + { { "uni06A3" }, { "uni06A3.init" } }, + { { "uni06A4" }, { "uni06A4.init" } }, + { { "uni06A5" }, { "uni06A5.init" } }, + { { "uni06A6" }, { "uni06A6.init" } }, + { { "uni06A7" }, { "uni06A7.init" } }, + { { "uni06A8" }, { "uni06A8.init" } }, + { { "uni06A9" }, { "uni06A9.init" } }, + { { "uni06AA" }, { "uni06AA.init" } }, + { { "uni06AB" }, { "uni06AB.init" } }, + { { "uni06AC" }, { "uni06AC.init" } }, + { { "uni06AD" }, { "uni06AD.init" } }, + { { "uni06AE" }, { "uni06AE.init" } }, + { { "uni06AF" }, { "uni06AF.init" } }, + { { "uni06B0" }, { "uni06B0.init" } }, + { { "uni06B1" }, { "uni06B1.init" } }, + { { "uni06B2" }, { "uni06B2.init" } }, + { { "uni06B3" }, { "uni06B3.init" } }, + { { "uni06B4" }, { "uni06B4.init" } }, + { { "uni06B5" }, { "uni06B5.init" } }, + { { "uni06B6" }, { "uni06B6.init" } }, + { { "uni06B7" }, { "uni06B7.init" } }, + { { "uni06B8" }, { "uni06B8.init" } }, + { { "uni06B9" }, { "uni06B9.init" } }, + { { "uni06BA" }, { "uni06BA.init" } }, + { { "uni06BB" }, { "uni06BB.init" } }, + { { "uni06BC" }, { "uni06BC.init" } }, + { { "uni06BD" }, { "uni06BD.init" } }, + { { "uni06BE" }, { "uni06BE.init" } }, + { { "uni06BF" }, { "uni06BF.init" } }, + { { "uni06C1" }, { "uni06C1.init" } }, + { { "uni06C2" }, { "uni06C2.init" } }, + { { "uni06CC" }, { "uni06CC.init" } }, + { { "uni06CE" }, { "uni06CE.init" } }, + { { "uni06D0" }, { "uni06D0.init" } }, + { { "uni06D1" }, { "uni06D1.init" } }, + { { "uni06FA" }, { "uni06FA.init" } }, + { { "uni06FB" }, { "uni06FB.init" } }, + { { "uni06FC" }, { "uni06FC.init" } }, + { { "uni06FF" }, { "uni06FF.init" } }, + { { "uni0750" }, { "uni0750.init" } }, + { { "uni0751" }, { "uni0751.init" } }, + { { "uni0752" }, { "uni0752.init" } }, + { { "uni0753" }, { "uni0753.init" } }, + { { "uni0754" }, { "uni0754.init" } }, + { { "uni0755" }, { "uni0755.init" } }, + { { "uni0756" }, { "uni0756.init" } }, + { { "uni0757" }, { "uni0757.init" } }, + { { "uni0758" }, { "uni0758.init" } }, + { { "uni075C" }, { "uni075C.init" } }, + { { "uni075D" }, { "uni075D.init" } }, + { { "uni075E" }, { "uni075E.init" } }, + { { "uni075F" }, { "uni075F.init" } }, + { { "uni0760" }, { "uni0760.init" } }, + { { "uni0761" }, { "uni0761.init" } }, + { { "uni0762" }, { "uni0762.init" } }, + { { "uni0763" }, { "uni0763.init" } }, + { { "uni0764" }, { "uni0764.init" } }, + { { "uni0765" }, { "uni0765.init" } }, + { { "uni0766" }, { "uni0766.init" } }, + { { "uni0767" }, { "uni0767.init" } }, + { { "uni0768" }, { "uni0768.init" } }, + { { "uni0769" }, { "uni0769.init" } }, + { { "uni076A" }, { "uni076A.init" } }, + { { "uni076D" }, { "uni076D.init" } }, + } + }, + { "f2", "lu2", "arab", "dflt", "fina", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Fin" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Fin" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Fin" } }, + { { "absJehRetro1" }, { "absJehRetro1Fin" } }, + { { "absJehRetro2" }, { "absJehRetro2Fin" } }, + { { "absLamRetro" }, { "absLamRetroFin" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Fin" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Fin" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Fin" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Fin" } }, + { { "absWawDotBelow" }, { "absWawDotBelowFin" } }, + { { "uni0622" }, { "uni0622.fina" } }, + { { "uni0623" }, { "uni0623.fina" } }, + { { "uni0624" }, { "uni0624.fina" } }, + { { "uni0625" }, { "uni0625.fina" } }, + { { "uni0626" }, { "uni0626.fina" } }, + { { "uni0627" }, { "uni0627.fina" } }, + { { "uni0628" }, { "uni0628.fina" } }, + { { "uni0629" }, { "uni0629.fina" } }, + { { "uni062A" }, { "uni062A.fina" } }, + { { "uni062B" }, { "uni062B.fina" } }, + { { "uni062C" }, { "uni062C.fina" } }, + { { "uni062D" }, { "uni062D.fina" } }, + { { "uni062E" }, { "uni062E.fina" } }, + { { "uni062F" }, { "uni062F.fina" } }, + { { "uni0630" }, { "uni0630.fina" } }, + { { "uni0631" }, { "uni0631.fina" } }, + { { "uni0632" }, { "uni0632.fina" } }, + { { "uni0633" }, { "uni0633.fina" } }, + { { "uni0634" }, { "uni0634.fina" } }, + { { "uni0635" }, { "uni0635.fina" } }, + { { "uni0636" }, { "uni0636.fina" } }, + { { "uni0637" }, { "uni0637.fina" } }, + { { "uni0638" }, { "uni0638.fina" } }, + { { "uni0639" }, { "uni0639.fina" } }, + { { "uni063A" }, { "uni063A.fina" } }, + { { "uni0641" }, { "uni0641.fina" } }, + { { "uni0642" }, { "uni0642.fina" } }, + { { "uni0643" }, { "uni0643.fina" } }, + { { "uni0644" }, { "uni0644.fina" } }, + { { "uni0645" }, { "uni0645.fina" } }, + { { "uni0646" }, { "uni0646.fina" } }, + { { "uni0647" }, { "uni0647.fina" } }, + { { "uni0648" }, { "uni0648.fina" } }, + { { "uni0649" }, { "uni0649.fina" } }, + { { "uni064A" }, { "uni064A.fina" } }, + { { "uni064A.noDots" }, { "uni064A.fina.noDots" } }, + { { "uni066E" }, { "uni066E.fina" } }, + { { "uni066F" }, { "uni066F.fina" } }, + { { "uni0671" }, { "uni0671.fina" } }, + { { "uni0672" }, { "uni0672.fina" } }, + { { "uni0673" }, { "uni0673.fina" } }, + { { "uni0675" }, { "uni0675.fina" } }, + { { "uni0676" }, { "uni0676.fina" } }, + { { "uni0677" }, { "uni0677.fina" } }, + { { "uni0678" }, { "uni0678.fina" } }, + { { "uni0679" }, { "uni0679.fina" } }, + { { "uni067A" }, { "uni067A.fina" } }, + { { "uni067B" }, { "uni067B.fina" } }, + { { "uni067C" }, { "uni067C.fina" } }, + { { "uni067D" }, { "uni067D.fina" } }, + { { "uni067E" }, { "uni067E.fina" } }, + { { "uni067F" }, { "uni067F.fina" } }, + { { "uni0680" }, { "uni0680.fina" } }, + { { "uni0681" }, { "uni0681.fina" } }, + { { "uni0682" }, { "uni0682.fina" } }, + { { "uni0683" }, { "uni0683.fina" } }, + { { "uni0684" }, { "uni0684.fina" } }, + { { "uni0685" }, { "uni0685.fina" } }, + { { "uni0686" }, { "uni0686.fina" } }, + { { "uni0687" }, { "uni0687.fina" } }, + { { "uni0688" }, { "uni0688.fina" } }, + { { "uni0689" }, { "uni0689.fina" } }, + { { "uni068A" }, { "uni068A.fina" } }, + { { "uni068B" }, { "uni068B.fina" } }, + { { "uni068C" }, { "uni068C.fina" } }, + { { "uni068D" }, { "uni068D.fina" } }, + { { "uni068E" }, { "uni068E.fina" } }, + { { "uni068F" }, { "uni068F.fina" } }, + { { "uni0690" }, { "uni0690.fina" } }, + { { "uni0691" }, { "uni0691.fina" } }, + { { "uni0692" }, { "uni0692.fina" } }, + { { "uni0693" }, { "uni0693.fina" } }, + { { "uni0694" }, { "uni0694.fina" } }, + { { "uni0695" }, { "uni0695.fina" } }, + { { "uni0696" }, { "uni0696.fina" } }, + { { "uni0697" }, { "uni0697.fina" } }, + { { "uni0698" }, { "uni0698.fina" } }, + { { "uni0698.dotHat" }, { "uni0698.fina.dotHat" } }, + { { "uni0699" }, { "uni0699.fina" } }, + { { "uni069A" }, { "uni069A.fina" } }, + { { "uni069B" }, { "uni069B.fina" } }, + { { "uni069C" }, { "uni069C.fina" } }, + { { "uni069D" }, { "uni069D.fina" } }, + { { "uni069E" }, { "uni069E.fina" } }, + { { "uni069F" }, { "uni069F.fina" } }, + { { "uni06A0" }, { "uni06A0.fina" } }, + { { "uni06A1" }, { "uni06A1.fina" } }, + { { "uni06A2" }, { "uni06A2.fina" } }, + { { "uni06A3" }, { "uni06A3.fina" } }, + { { "uni06A4" }, { "uni06A4.fina" } }, + { { "uni06A5" }, { "uni06A5.fina" } }, + { { "uni06A6" }, { "uni06A6.fina" } }, + { { "uni06A7" }, { "uni06A7.fina" } }, + { { "uni06A8" }, { "uni06A8.fina" } }, + { { "uni06A9" }, { "uni06A9.fina" } }, + { { "uni06AA" }, { "uni06AA.fina" } }, + { { "uni06AB" }, { "uni06AB.fina" } }, + { { "uni06AC" }, { "uni06AC.fina" } }, + { { "uni06AD" }, { "uni06AD.fina" } }, + { { "uni06AE" }, { "uni06AE.fina" } }, + { { "uni06AF" }, { "uni06AF.fina" } }, + { { "uni06B0" }, { "uni06B0.fina" } }, + { { "uni06B1" }, { "uni06B1.fina" } }, + { { "uni06B2" }, { "uni06B2.fina" } }, + { { "uni06B3" }, { "uni06B3.fina" } }, + { { "uni06B4" }, { "uni06B4.fina" } }, + { { "uni06B5" }, { "uni06B5.fina" } }, + { { "uni06B6" }, { "uni06B6.fina" } }, + { { "uni06B7" }, { "uni06B7.fina" } }, + { { "uni06B8" }, { "uni06B8.fina" } }, + { { "uni06B9" }, { "uni06B9.fina" } }, + { { "uni06BA" }, { "uni06BA.fina" } }, + { { "uni06BB" }, { "uni06BB.fina" } }, + { { "uni06BC" }, { "uni06BC.fina" } }, + { { "uni06BD" }, { "uni06BD.fina" } }, + { { "uni06BE" }, { "uni06BE.fina" } }, + { { "uni06BF" }, { "uni06BF.fina" } }, + { { "uni06C0" }, { "uni06C0.fina" } }, + { { "uni06C1" }, { "uni06C1.fina" } }, + { { "uni06C2" }, { "uni06C2.fina" } }, + { { "uni06C3" }, { "uni06C3.fina" } }, + { { "uni06C4" }, { "uni06C4.fina" } }, + { { "uni06C5" }, { "uni06C5.fina" } }, + { { "uni06C6" }, { "uni06C6.fina" } }, + { { "uni06C7" }, { "uni06C7.fina" } }, + { { "uni06C8" }, { "uni06C8.fina" } }, + { { "uni06C9" }, { "uni06C9.fina" } }, + { { "uni06CA" }, { "uni06CA.fina" } }, + { { "uni06CB" }, { "uni06CB.fina" } }, + { { "uni06CC" }, { "uni06CC.fina" } }, + { { "uni06CD" }, { "uni06CD.fina" } }, + { { "uni06CE" }, { "uni06CE.fina" } }, + { { "uni06CF" }, { "uni06CF.fina" } }, + { { "uni06D0" }, { "uni06D0.fina" } }, + { { "uni06D1" }, { "uni06D1.fina" } }, + { { "uni06D2" }, { "uni06D2.fina" } }, + { { "uni06D3" }, { "uni06D3.fina" } }, + { { "uni06D5" }, { "uni06D5.fina" } }, + { { "uni06EE" }, { "uni06EE.fina" } }, + { { "uni06EF" }, { "uni06EF.fina" } }, + { { "uni06FA" }, { "uni06FA.fina" } }, + { { "uni06FB" }, { "uni06FB.fina" } }, + { { "uni06FC" }, { "uni06FC.fina" } }, + { { "uni06FF" }, { "uni06FF.fina" } }, + { { "uni0750" }, { "uni0750.fina" } }, + { { "uni0751" }, { "uni0751.fina" } }, + { { "uni0752" }, { "uni0752.fina" } }, + { { "uni0753" }, { "uni0753.fina" } }, + { { "uni0754" }, { "uni0754.fina" } }, + { { "uni0755" }, { "uni0755.fina" } }, + { { "uni0756" }, { "uni0756.fina" } }, + { { "uni0757" }, { "uni0757.fina" } }, + { { "uni0758" }, { "uni0758.fina" } }, + { { "uni0759" }, { "uni0759.fina" } }, + { { "uni075A" }, { "uni075A.fina" } }, + { { "uni075B" }, { "uni075B.fina" } }, + { { "uni075C" }, { "uni075C.fina" } }, + { { "uni075D" }, { "uni075D.fina" } }, + { { "uni075E" }, { "uni075E.fina" } }, + { { "uni075F" }, { "uni075F.fina" } }, + { { "uni0760" }, { "uni0760.fina" } }, + { { "uni0761" }, { "uni0761.fina" } }, + { { "uni0762" }, { "uni0762.fina" } }, + { { "uni0763" }, { "uni0763.fina" } }, + { { "uni0764" }, { "uni0764.fina" } }, + { { "uni0765" }, { "uni0765.fina" } }, + { { "uni0766" }, { "uni0766.fina" } }, + { { "uni0767" }, { "uni0767.fina" } }, + { { "uni0768" }, { "uni0768.fina" } }, + { { "uni0769" }, { "uni0769.fina" } }, + { { "uni076A" }, { "uni076A.fina" } }, + { { "uni076B" }, { "uni076B.fina" } }, + { { "uni076C" }, { "uni076C.fina" } }, + { { "uni076D" }, { "uni076D.fina" } }, + } + }, + { "f2", "lu3", "arab", "dflt", "medi", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Med" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Med" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Med" } }, + { { "absLamRetro" }, { "absLamRetroMed" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Med" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Med" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Med" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Med" } }, + { { "uni0626" }, { "uni0626.medi" } }, + { { "uni0628" }, { "uni0628.medi" } }, + { { "uni062A" }, { "uni062A.medi" } }, + { { "uni062B" }, { "uni062B.medi" } }, + { { "uni062C" }, { "uni062C.medi" } }, + { { "uni062D" }, { "uni062D.medi" } }, + { { "uni062E" }, { "uni062E.medi" } }, + { { "uni0633" }, { "uni0633.medi" } }, + { { "uni0634" }, { "uni0634.medi" } }, + { { "uni0635" }, { "uni0635.medi" } }, + { { "uni0636" }, { "uni0636.medi" } }, + { { "uni0637" }, { "uni0637.medi" } }, + { { "uni0638" }, { "uni0638.medi" } }, + { { "uni0639" }, { "uni0639.medi" } }, + { { "uni063A" }, { "uni063A.medi" } }, + { { "uni0641" }, { "uni0641.medi" } }, + { { "uni0642" }, { "uni0642.medi" } }, + { { "uni0643" }, { "uni0643.medi" } }, + { { "uni0644" }, { "uni0644.medi" } }, + { { "uni0645" }, { "uni0645.medi" } }, + { { "uni0646" }, { "uni0646.medi" } }, + { { "uni0647" }, { "uni0647.medi" } }, + { { "uni0649" }, { "uni0649.medi" } }, + { { "uni064A" }, { "uni064A.medi" } }, + { { "uni064A.noDots" }, { "uni064A.medi.noDots" } }, + { { "uni066E" }, { "uni066E.medi" } }, + { { "uni066F" }, { "uni066F.medi" } }, + { { "uni0678" }, { "uni0678.medi" } }, + { { "uni0679" }, { "uni0679.medi" } }, + { { "uni067A" }, { "uni067A.medi" } }, + { { "uni067B" }, { "uni067B.medi" } }, + { { "uni067C" }, { "uni067C.medi" } }, + { { "uni067D" }, { "uni067D.medi" } }, + { { "uni067E" }, { "uni067E.medi" } }, + { { "uni067F" }, { "uni067F.medi" } }, + { { "uni0680" }, { "uni0680.medi" } }, + { { "uni0681" }, { "uni0681.medi" } }, + { { "uni0682" }, { "uni0682.medi" } }, + { { "uni0683" }, { "uni0683.medi" } }, + { { "uni0684" }, { "uni0684.medi" } }, + { { "uni0685" }, { "uni0685.medi" } }, + { { "uni0686" }, { "uni0686.medi" } }, + { { "uni0687" }, { "uni0687.medi" } }, + { { "uni069A" }, { "uni069A.medi" } }, + { { "uni069B" }, { "uni069B.medi" } }, + { { "uni069C" }, { "uni069C.medi" } }, + { { "uni069D" }, { "uni069D.medi" } }, + { { "uni069E" }, { "uni069E.medi" } }, + { { "uni069F" }, { "uni069F.medi" } }, + { { "uni06A0" }, { "uni06A0.medi" } }, + { { "uni06A1" }, { "uni06A1.medi" } }, + { { "uni06A2" }, { "uni06A2.medi" } }, + { { "uni06A3" }, { "uni06A3.medi" } }, + { { "uni06A4" }, { "uni06A4.medi" } }, + { { "uni06A5" }, { "uni06A5.medi" } }, + { { "uni06A6" }, { "uni06A6.medi" } }, + { { "uni06A7" }, { "uni06A7.medi" } }, + { { "uni06A8" }, { "uni06A8.medi" } }, + { { "uni06A9" }, { "uni06A9.medi" } }, + { { "uni06AA" }, { "uni06AA.medi" } }, + { { "uni06AB" }, { "uni06AB.medi" } }, + { { "uni06AC" }, { "uni06AC.medi" } }, + { { "uni06AD" }, { "uni06AD.medi" } }, + { { "uni06AE" }, { "uni06AE.medi" } }, + { { "uni06AF" }, { "uni06AF.medi" } }, + { { "uni06B0" }, { "uni06B0.medi" } }, + { { "uni06B1" }, { "uni06B1.medi" } }, + { { "uni06B2" }, { "uni06B2.medi" } }, + { { "uni06B3" }, { "uni06B3.medi" } }, + { { "uni06B4" }, { "uni06B4.medi" } }, + { { "uni06B5" }, { "uni06B5.medi" } }, + { { "uni06B6" }, { "uni06B6.medi" } }, + { { "uni06B7" }, { "uni06B7.medi" } }, + { { "uni06B8" }, { "uni06B8.medi" } }, + { { "uni06B9" }, { "uni06B9.medi" } }, + { { "uni06BA" }, { "uni06BA.medi" } }, + { { "uni06BB" }, { "uni06BB.medi" } }, + { { "uni06BC" }, { "uni06BC.medi" } }, + { { "uni06BD" }, { "uni06BD.medi" } }, + { { "uni06BE" }, { "uni06BE.medi" } }, + { { "uni06BF" }, { "uni06BF.medi" } }, + { { "uni06C1" }, { "uni06C1.medi" } }, + { { "uni06C2" }, { "uni06C2.medi" } }, + { { "uni06CC" }, { "uni06CC.medi" } }, + { { "uni06CE" }, { "uni06CE.medi" } }, + { { "uni06D0" }, { "uni06D0.medi" } }, + { { "uni06D1" }, { "uni06D1.medi" } }, + { { "uni06FA" }, { "uni06FA.medi" } }, + { { "uni06FB" }, { "uni06FB.medi" } }, + { { "uni06FC" }, { "uni06FC.medi" } }, + { { "uni06FF" }, { "uni06FF.medi" } }, + { { "uni0750" }, { "uni0750.medi" } }, + { { "uni0751" }, { "uni0751.medi" } }, + { { "uni0752" }, { "uni0752.medi" } }, + { { "uni0753" }, { "uni0753.medi" } }, + { { "uni0754" }, { "uni0754.medi" } }, + { { "uni0755" }, { "uni0755.medi" } }, + { { "uni0756" }, { "uni0756.medi" } }, + { { "uni0757" }, { "uni0757.medi" } }, + { { "uni0758" }, { "uni0758.medi" } }, + { { "uni075C" }, { "uni075C.medi" } }, + { { "uni075D" }, { "uni075D.medi" } }, + { { "uni075E" }, { "uni075E.medi" } }, + { { "uni075F" }, { "uni075F.medi" } }, + { { "uni0760" }, { "uni0760.medi" } }, + { { "uni0761" }, { "uni0761.medi" } }, + { { "uni0762" }, { "uni0762.medi" } }, + { { "uni0763" }, { "uni0763.medi" } }, + { { "uni0764" }, { "uni0764.medi" } }, + { { "uni0765" }, { "uni0765.medi" } }, + { { "uni0766" }, { "uni0766.medi" } }, + { { "uni0767" }, { "uni0767.medi" } }, + { { "uni0768" }, { "uni0768.medi" } }, + { { "uni0769" }, { "uni0769.medi" } }, + { { "uni076A" }, { "uni076A.medi" } }, + { { "uni076D" }, { "uni076D.medi" } }, + } + }, + { "f2", "lu9", "arab", "SND ", "calt", + new String[][][] { + { { "uni060C" }, { "uni060C.downward" } }, + { { "uni061B" }, { "uni061B.downward" } }, + { { "uni0645" }, { "uni0645.sindhi" } }, + { { "uni0645.fina" }, { "uni0645.fina.sindhi" } }, + { { "uni0647" }, { "uni0647.knotted" } }, + { { "uni0647.fina" }, { "uni0647.fina.knottedHigh" } }, + { { "uni0647.medi" }, { "uni0647.medi.knottedHigh" } }, + { { "uni064C" }, { "uni064C.sixNine" } }, + { { "uni06F6" }, { "uni06F6.urdu" } }, + { { "uni06F7" }, { "uni06F7.urdu" } }, + } + }, + { "f2", "lu10", "arab", "URD ", "calt", + new String[][][] { + { { "uni0647.fina" }, { "uni0647.fina.hooked" } }, + { { "uni0647.init" }, { "uni0647.init.hooked" } }, + { { "uni0647.medi" }, { "uni0647.medi.hooked" } }, + { { "uni06F4" }, { "uni06F4.urdu" } }, + { { "uni06F6" }, { "uni06F6.urdu" } }, + { { "uni06F7" }, { "uni06F7.urdu" } }, + } + }, + { "f2", "lu11", "arab", "KUR ", "calt", + new String[][][] { + { { "uni0647" }, { "uni0647.knotted" } }, + { { "uni0647.fina" }, { "uni0647.fina.knottedHigh" } }, + } + }, + { "f2", "lu12", "latn", "dflt", "ccmp", + new String[][][] { + { { "asterisk.arab" }, { "asterisk" } }, + { { "colon.arab" }, { "colon" } }, + { { "exclam.arab" }, { "exclam" } }, + { { "parenleft.arab" }, { "parenleft" } }, + { { "parenright.arab" }, { "parenright" } }, + { { "quotedblleft.arab" }, { "quotedblleft" } }, + { { "quotedblright.arab" }, { "quotedblright" } }, + { { "quoteleft.arab" }, { "quoteleft" } }, + { { "quoteright.arab" }, { "quoteright" } }, + } + }, + { "f2", "lu14", "arab", "*", "*", + new String[][][] { + { { "absLamRetroIni" }, { "absLamRetroIni.preAlef" } }, + { { "absLamRetroMed" }, { "absLamRetroMed.preAlef" } }, + { { "uni0644.init" }, { "uni0644.init.preAlef" } }, + { { "uni0644.medi" }, { "uni0644.medi.preAlef" } }, + { { "uni06B5.init" }, { "uni06B5.init.preAlef" } }, + { { "uni06B5.medi" }, { "uni06B5.medi.preAlef" } }, + { { "uni06B6.init" }, { "uni06B6.init.preAlef" } }, + { { "uni06B6.medi" }, { "uni06B6.medi.preAlef" } }, + { { "uni06B7.init" }, { "uni06B7.init.preAlef" } }, + { { "uni06B7.medi" }, { "uni06B7.medi.preAlef" } }, + { { "uni06B8.init" }, { "uni06B8.init.preAlef" } }, + { { "uni06B8.medi" }, { "uni06B8.medi.preAlef" } }, + { { "uni076A.init" }, { "uni076A.init.preAlef" } }, + { { "uni076A.medi" }, { "uni076A.medi.preAlef" } }, + } + }, + { "f2", "lu15", "arab", "*", "*", + new String[][][] { + { { "uni0622.fina" }, { "uni0622.fina.postLamIni" } }, + { { "uni0623.fina" }, { "uni0623.fina.postLamIni" } }, + { { "uni0625.fina" }, { "uni0625.fina.postLamIni" } }, + { { "uni0627.fina" }, { "uni0627.fina.postLamIni" } }, + { { "uni0671.fina" }, { "uni0671.fina.postLamIni" } }, + { { "uni0672.fina" }, { "uni0672.fina.postLamIni" } }, + { { "uni0673.fina" }, { "uni0673.fina.postLamIni" } }, + { { "uni0675.fina" }, { "uni0675.fina.postLamIni" } }, + } + }, + { "f2", "lu16", "arab", "*", "*", + new String[][][] { + { { "uni0622.fina" }, { "uni0622.fina.postLamMed" } }, + { { "uni0623.fina" }, { "uni0623.fina.postLamMed" } }, + { { "uni0625.fina" }, { "uni0625.fina.postLamMed" } }, + { { "uni0627.fina" }, { "uni0627.fina.postLamMed" } }, + { { "uni0671.fina" }, { "uni0671.fina.postLamMed" } }, + { { "uni0672.fina" }, { "uni0672.fina.postLamMed" } }, + { { "uni0673.fina" }, { "uni0673.fina.postLamMed" } }, + { { "uni0675.fina" }, { "uni0675.fina.postLamMed" } }, + } + }, + { "f2", "lu17", "arab", "*", "*", + new String[][][] { + { { "uni0670" }, { "uni0670.large" } }, + } + }, + { "f2", "lu18", "arab", "*", "*", + new String[][][] { + { { "uni06DD" }, { "uni06DD.3" } }, + } + }, + { "f2", "lu19", "arab", "*", "*", + new String[][][] { + { { "uni06DD" }, { "uni06DD.2" } }, + } + }, + { "f2", "lu20", "arab", "*", "*", + new String[][][] { + { { "eight" }, { "eightMedium" } }, + { { "five" }, { "fiveMedium" } }, + { { "four" }, { "fourMedium" } }, + { { "nine" }, { "nineMedium" } }, + { { "one" }, { "oneMedium" } }, + { { "seven" }, { "sevenMedium" } }, + { { "six" }, { "sixMedium" } }, + { { "three" }, { "threeMedium" } }, + { { "two" }, { "twoMedium" } }, + { { "uni0660" }, { "uni0660.Medium" } }, + { { "uni0661" }, { "uni0661.Medium" } }, + { { "uni0662" }, { "uni0662.Medium" } }, + { { "uni0663" }, { "uni0663.Medium" } }, + { { "uni0664" }, { "uni0664.Medium" } }, + { { "uni0665" }, { "uni0665.Medium" } }, + { { "uni0666" }, { "uni0666.Medium" } }, + { { "uni0667" }, { "uni0667.Medium" } }, + { { "uni0668" }, { "uni0668.Medium" } }, + { { "uni0669" }, { "uni0669.Medium" } }, + { { "uni06F0" }, { "uni06F0.Medium" } }, + { { "uni06F1" }, { "uni06F1.Medium" } }, + { { "uni06F2" }, { "uni06F2.Medium" } }, + { { "uni06F3" }, { "uni06F3.Medium" } }, + { { "uni06F4" }, { "uni06F4.Medium" } }, + { { "uni06F4.urdu" }, { "uni06F4.Medium.urdu" } }, + { { "uni06F5" }, { "uni06F5.Medium" } }, + { { "uni06F6" }, { "uni06F6.Medium" } }, + { { "uni06F6.urdu" }, { "uni06F6.Medium.urdu" } }, + { { "uni06F7" }, { "uni06F7.Medium" } }, + { { "uni06F7.urdu" }, { "uni06F7.Medium.urdu" } }, + { { "uni06F8" }, { "uni06F8.Medium" } }, + { { "uni06F9" }, { "uni06F9.Medium" } }, + { { "zero" }, { "zeroMedium" } }, + } + }, + { "f2", "lu21", "arab", "*", "*", + new String[][][] { + { { "eight" }, { "eightSmall" } }, + { { "five" }, { "fiveSmall" } }, + { { "four" }, { "fourSmall" } }, + { { "nine" }, { "nineSmall" } }, + { { "one" }, { "oneSmall" } }, + { { "seven" }, { "sevenSmall" } }, + { { "six" }, { "sixSmall" } }, + { { "three" }, { "threeSmall" } }, + { { "two" }, { "twoSmall" } }, + { { "uni0660" }, { "uni0660.Small" } }, + { { "uni0661" }, { "uni0661.Small" } }, + { { "uni0662" }, { "uni0662.Small" } }, + { { "uni0663" }, { "uni0663.Small" } }, + { { "uni0664" }, { "uni0664.Small" } }, + { { "uni0665" }, { "uni0665.Small" } }, + { { "uni0666" }, { "uni0666.Small" } }, + { { "uni0667" }, { "uni0667.Small" } }, + { { "uni0668" }, { "uni0668.Small" } }, + { { "uni0669" }, { "uni0669.Small" } }, + { { "uni06F0" }, { "uni06F0.Small" } }, + { { "uni06F1" }, { "uni06F1.Small" } }, + { { "uni06F2" }, { "uni06F2.Small" } }, + { { "uni06F3" }, { "uni06F3.Small" } }, + { { "uni06F4" }, { "uni06F4.Small" } }, + { { "uni06F4.urdu" }, { "uni06F4.Small.urdu" } }, + { { "uni06F5" }, { "uni06F5.Small" } }, + { { "uni06F6" }, { "uni06F6.Small" } }, + { { "uni06F6.urdu" }, { "uni06F6.Small.urdu" } }, + { { "uni06F7" }, { "uni06F7.Small" } }, + { { "uni06F7.urdu" }, { "uni06F7.Small.urdu" } }, + { { "uni06F8" }, { "uni06F8.Small" } }, + { { "uni06F9" }, { "uni06F9.Small" } }, + { { "zero" }, { "zeroSmall" } }, + } + }, + // arab-004.ttx + { "f3", "lu1", "arab", "dflt", "init", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Ini" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Ini" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Ini" } }, + { { "absLamRetro" }, { "absLamRetroIni" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Ini" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Ini" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Ini" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Ini" } }, + { { "uni0626" }, { "uni0626.init" } }, + { { "uni0628" }, { "uni0628.init" } }, + { { "uni062A" }, { "uni062A.init" } }, + { { "uni062B" }, { "uni062B.init" } }, + { { "uni062C" }, { "uni062C.init" } }, + { { "uni062D" }, { "uni062D.init" } }, + { { "uni062E" }, { "uni062E.init" } }, + { { "uni0633" }, { "uni0633.init" } }, + { { "uni0634" }, { "uni0634.init" } }, + { { "uni0635" }, { "uni0635.init" } }, + { { "uni0636" }, { "uni0636.init" } }, + { { "uni0637" }, { "uni0637.init" } }, + { { "uni0638" }, { "uni0638.init" } }, + { { "uni0639" }, { "uni0639.init" } }, + { { "uni063A" }, { "uni063A.init" } }, + { { "uni0641" }, { "uni0641.init" } }, + { { "uni0642" }, { "uni0642.init" } }, + { { "uni0643" }, { "uni0643.init" } }, + { { "uni0644" }, { "uni0644.init" } }, + { { "uni0645" }, { "uni0645.init" } }, + { { "uni0646" }, { "uni0646.init" } }, + { { "uni0647" }, { "uni0647.init" } }, + { { "uni0649" }, { "uni0649.init" } }, + { { "uni064A" }, { "uni064A.init" } }, + { { "uni064A.noDots" }, { "uni064A.init.noDots" } }, + { { "uni066E" }, { "uni066E.init" } }, + { { "uni066F" }, { "uni066F.init" } }, + { { "uni0678" }, { "uni0678.init" } }, + { { "uni0679" }, { "uni0679.init" } }, + { { "uni067A" }, { "uni067A.init" } }, + { { "uni067B" }, { "uni067B.init" } }, + { { "uni067C" }, { "uni067C.init" } }, + { { "uni067D" }, { "uni067D.init" } }, + { { "uni067E" }, { "uni067E.init" } }, + { { "uni067F" }, { "uni067F.init" } }, + { { "uni0680" }, { "uni0680.init" } }, + { { "uni0681" }, { "uni0681.init" } }, + { { "uni0682" }, { "uni0682.init" } }, + { { "uni0683" }, { "uni0683.init" } }, + { { "uni0684" }, { "uni0684.init" } }, + { { "uni0685" }, { "uni0685.init" } }, + { { "uni0686" }, { "uni0686.init" } }, + { { "uni0687" }, { "uni0687.init" } }, + { { "uni069A" }, { "uni069A.init" } }, + { { "uni069B" }, { "uni069B.init" } }, + { { "uni069C" }, { "uni069C.init" } }, + { { "uni069D" }, { "uni069D.init" } }, + { { "uni069E" }, { "uni069E.init" } }, + { { "uni069F" }, { "uni069F.init" } }, + { { "uni06A0" }, { "uni06A0.init" } }, + { { "uni06A1" }, { "uni06A1.init" } }, + { { "uni06A2" }, { "uni06A2.init" } }, + { { "uni06A3" }, { "uni06A3.init" } }, + { { "uni06A4" }, { "uni06A4.init" } }, + { { "uni06A5" }, { "uni06A5.init" } }, + { { "uni06A6" }, { "uni06A6.init" } }, + { { "uni06A7" }, { "uni06A7.init" } }, + { { "uni06A8" }, { "uni06A8.init" } }, + { { "uni06A9" }, { "uni06A9.init" } }, + { { "uni06AA" }, { "uni06AA.init" } }, + { { "uni06AB" }, { "uni06AB.init" } }, + { { "uni06AC" }, { "uni06AC.init" } }, + { { "uni06AD" }, { "uni06AD.init" } }, + { { "uni06AE" }, { "uni06AE.init" } }, + { { "uni06AF" }, { "uni06AF.init" } }, + { { "uni06B0" }, { "uni06B0.init" } }, + { { "uni06B1" }, { "uni06B1.init" } }, + { { "uni06B2" }, { "uni06B2.init" } }, + { { "uni06B3" }, { "uni06B3.init" } }, + { { "uni06B4" }, { "uni06B4.init" } }, + { { "uni06B5" }, { "uni06B5.init" } }, + { { "uni06B6" }, { "uni06B6.init" } }, + { { "uni06B7" }, { "uni06B7.init" } }, + { { "uni06B8" }, { "uni06B8.init" } }, + { { "uni06B9" }, { "uni06B9.init" } }, + { { "uni06BA" }, { "uni06BA.init" } }, + { { "uni06BB" }, { "uni06BB.init" } }, + { { "uni06BC" }, { "uni06BC.init" } }, + { { "uni06BD" }, { "uni06BD.init" } }, + { { "uni06BE" }, { "uni06BE.init" } }, + { { "uni06BF" }, { "uni06BF.init" } }, + { { "uni06C1" }, { "uni06C1.init" } }, + { { "uni06CC" }, { "uni06CC.init" } }, + { { "uni06CE" }, { "uni06CE.init" } }, + { { "uni06D0" }, { "uni06D0.init" } }, + { { "uni06D1" }, { "uni06D1.init" } }, + { { "uni06FA" }, { "uni06FA.init" } }, + { { "uni06FB" }, { "uni06FB.init" } }, + { { "uni06FC" }, { "uni06FC.init" } }, + { { "uni06FF" }, { "uni06FF.init" } }, + { { "uni0750" }, { "uni0750.init" } }, + { { "uni0751" }, { "uni0751.init" } }, + { { "uni0752" }, { "uni0752.init" } }, + { { "uni0753" }, { "uni0753.init" } }, + { { "uni0754" }, { "uni0754.init" } }, + { { "uni0755" }, { "uni0755.init" } }, + { { "uni0756" }, { "uni0756.init" } }, + { { "uni0757" }, { "uni0757.init" } }, + { { "uni0758" }, { "uni0758.init" } }, + { { "uni075C" }, { "uni075C.init" } }, + { { "uni075D" }, { "uni075D.init" } }, + { { "uni075E" }, { "uni075E.init" } }, + { { "uni075F" }, { "uni075F.init" } }, + { { "uni0760" }, { "uni0760.init" } }, + { { "uni0761" }, { "uni0761.init" } }, + { { "uni0762" }, { "uni0762.init" } }, + { { "uni0763" }, { "uni0763.init" } }, + { { "uni0764" }, { "uni0764.init" } }, + { { "uni0765" }, { "uni0765.init" } }, + { { "uni0766" }, { "uni0766.init" } }, + { { "uni0767" }, { "uni0767.init" } }, + { { "uni0768" }, { "uni0768.init" } }, + { { "uni0769" }, { "uni0769.init" } }, + { { "uni076A" }, { "uni076A.init" } }, + { { "uni076D" }, { "uni076D.init" } }, + } + }, + { "f3", "lu2", "arab", "dflt", "fina", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Fin" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Fin" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Fin" } }, + { { "absJehRetro1" }, { "absJehRetro1Fin" } }, + { { "absJehRetro2" }, { "absJehRetro2Fin" } }, + { { "absLamRetro" }, { "absLamRetroFin" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Fin" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Fin" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Fin" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Fin" } }, + { { "absWawDotBelow" }, { "absWawDotBelowFin" } }, + { { "uni0622" }, { "uni0622.fina" } }, + { { "uni0623" }, { "uni0623.fina" } }, + { { "uni0624" }, { "uni0624.fina" } }, + { { "uni0625" }, { "uni0625.fina" } }, + { { "uni0626" }, { "uni0626.fina" } }, + { { "uni0627" }, { "uni0627.fina" } }, + { { "uni0628" }, { "uni0628.fina" } }, + { { "uni0629" }, { "uni0629.fina" } }, + { { "uni062A" }, { "uni062A.fina" } }, + { { "uni062B" }, { "uni062B.fina" } }, + { { "uni062C" }, { "uni062C.fina" } }, + { { "uni062D" }, { "uni062D.fina" } }, + { { "uni062E" }, { "uni062E.fina" } }, + { { "uni062F" }, { "uni062F.fina" } }, + { { "uni0630" }, { "uni0630.fina" } }, + { { "uni0631" }, { "uni0631.fina" } }, + { { "uni0632" }, { "uni0632.fina" } }, + { { "uni0633" }, { "uni0633.fina" } }, + { { "uni0634" }, { "uni0634.fina" } }, + { { "uni0635" }, { "uni0635.fina" } }, + { { "uni0636" }, { "uni0636.fina" } }, + { { "uni0637" }, { "uni0637.fina" } }, + { { "uni0638" }, { "uni0638.fina" } }, + { { "uni0639" }, { "uni0639.fina" } }, + { { "uni063A" }, { "uni063A.fina" } }, + { { "uni0641" }, { "uni0641.fina" } }, + { { "uni0642" }, { "uni0642.fina" } }, + { { "uni0643" }, { "uni0643.fina" } }, + { { "uni0644" }, { "uni0644.fina" } }, + { { "uni0645" }, { "uni0645.fina" } }, + { { "uni0646" }, { "uni0646.fina" } }, + { { "uni0647" }, { "uni0647.fina" } }, + { { "uni0648" }, { "uni0648.fina" } }, + { { "uni0649" }, { "uni0649.fina" } }, + { { "uni064A" }, { "uni064A.fina" } }, + { { "uni064A.noDots" }, { "uni064A.fina.noDots" } }, + { { "uni066E" }, { "uni066E.fina" } }, + { { "uni066F" }, { "uni066F.fina" } }, + { { "uni0671" }, { "uni0671.fina" } }, + { { "uni0672" }, { "uni0672.fina" } }, + { { "uni0673" }, { "uni0673.fina" } }, + { { "uni0675" }, { "uni0675.fina" } }, + { { "uni0676" }, { "uni0676.fina" } }, + { { "uni0677" }, { "uni0677.fina" } }, + { { "uni0678" }, { "uni0678.fina" } }, + { { "uni0679" }, { "uni0679.fina" } }, + { { "uni067A" }, { "uni067A.fina" } }, + { { "uni067B" }, { "uni067B.fina" } }, + { { "uni067C" }, { "uni067C.fina" } }, + { { "uni067D" }, { "uni067D.fina" } }, + { { "uni067E" }, { "uni067E.fina" } }, + { { "uni067F" }, { "uni067F.fina" } }, + { { "uni0680" }, { "uni0680.fina" } }, + { { "uni0681" }, { "uni0681.fina" } }, + { { "uni0682" }, { "uni0682.fina" } }, + { { "uni0683" }, { "uni0683.fina" } }, + { { "uni0684" }, { "uni0684.fina" } }, + { { "uni0685" }, { "uni0685.fina" } }, + { { "uni0686" }, { "uni0686.fina" } }, + { { "uni0687" }, { "uni0687.fina" } }, + { { "uni0688" }, { "uni0688.fina" } }, + { { "uni0689" }, { "uni0689.fina" } }, + { { "uni068A" }, { "uni068A.fina" } }, + { { "uni068B" }, { "uni068B.fina" } }, + { { "uni068C" }, { "uni068C.fina" } }, + { { "uni068D" }, { "uni068D.fina" } }, + { { "uni068E" }, { "uni068E.fina" } }, + { { "uni068F" }, { "uni068F.fina" } }, + { { "uni0690" }, { "uni0690.fina" } }, + { { "uni0691" }, { "uni0691.fina" } }, + { { "uni0692" }, { "uni0692.fina" } }, + { { "uni0693" }, { "uni0693.fina" } }, + { { "uni0694" }, { "uni0694.fina" } }, + { { "uni0695" }, { "uni0695.fina" } }, + { { "uni0696" }, { "uni0696.fina" } }, + { { "uni0697" }, { "uni0697.fina" } }, + { { "uni0698" }, { "uni0698.fina" } }, + { { "uni0698.dotHat" }, { "uni0698.fina.dotHat" } }, + { { "uni0699" }, { "uni0699.fina" } }, + { { "uni069A" }, { "uni069A.fina" } }, + { { "uni069B" }, { "uni069B.fina" } }, + { { "uni069C" }, { "uni069C.fina" } }, + { { "uni069D" }, { "uni069D.fina" } }, + { { "uni069E" }, { "uni069E.fina" } }, + { { "uni069F" }, { "uni069F.fina" } }, + { { "uni06A0" }, { "uni06A0.fina" } }, + { { "uni06A1" }, { "uni06A1.fina" } }, + { { "uni06A2" }, { "uni06A2.fina" } }, + { { "uni06A3" }, { "uni06A3.fina" } }, + { { "uni06A4" }, { "uni06A4.fina" } }, + { { "uni06A5" }, { "uni06A5.fina" } }, + { { "uni06A6" }, { "uni06A6.fina" } }, + { { "uni06A7" }, { "uni06A7.fina" } }, + { { "uni06A8" }, { "uni06A8.fina" } }, + { { "uni06A9" }, { "uni06A9.fina" } }, + { { "uni06AA" }, { "uni06AA.fina" } }, + { { "uni06AB" }, { "uni06AB.fina" } }, + { { "uni06AC" }, { "uni06AC.fina" } }, + { { "uni06AD" }, { "uni06AD.fina" } }, + { { "uni06AE" }, { "uni06AE.fina" } }, + { { "uni06AF" }, { "uni06AF.fina" } }, + { { "uni06B0" }, { "uni06B0.fina" } }, + { { "uni06B1" }, { "uni06B1.fina" } }, + { { "uni06B2" }, { "uni06B2.fina" } }, + { { "uni06B3" }, { "uni06B3.fina" } }, + { { "uni06B4" }, { "uni06B4.fina" } }, + { { "uni06B5" }, { "uni06B5.fina" } }, + { { "uni06B6" }, { "uni06B6.fina" } }, + { { "uni06B7" }, { "uni06B7.fina" } }, + { { "uni06B8" }, { "uni06B8.fina" } }, + { { "uni06B9" }, { "uni06B9.fina" } }, + { { "uni06BA" }, { "uni06BA.fina" } }, + { { "uni06BB" }, { "uni06BB.fina" } }, + { { "uni06BC" }, { "uni06BC.fina" } }, + { { "uni06BD" }, { "uni06BD.fina" } }, + { { "uni06BE" }, { "uni06BE.fina" } }, + { { "uni06BF" }, { "uni06BF.fina" } }, + { { "uni06C0" }, { "uni06C0.fina" } }, + { { "uni06C1" }, { "uni06C1.fina" } }, + { { "uni06C2" }, { "uni06C2.fina" } }, + { { "uni06C3" }, { "uni06C3.fina" } }, + { { "uni06C4" }, { "uni06C4.fina" } }, + { { "uni06C5" }, { "uni06C5.fina" } }, + { { "uni06C6" }, { "uni06C6.fina" } }, + { { "uni06C7" }, { "uni06C7.fina" } }, + { { "uni06C8" }, { "uni06C8.fina" } }, + { { "uni06C9" }, { "uni06C9.fina" } }, + { { "uni06CA" }, { "uni06CA.fina" } }, + { { "uni06CB" }, { "uni06CB.fina" } }, + { { "uni06CC" }, { "uni06CC.fina" } }, + { { "uni06CD" }, { "uni06CD.fina" } }, + { { "uni06CE" }, { "uni06CE.fina" } }, + { { "uni06CF" }, { "uni06CF.fina" } }, + { { "uni06D0" }, { "uni06D0.fina" } }, + { { "uni06D1" }, { "uni06D1.fina" } }, + { { "uni06D2" }, { "uni06D2.fina" } }, + { { "uni06D3" }, { "uni06D3.fina" } }, + { { "uni06D5" }, { "uni06D5.fina" } }, + { { "uni06EE" }, { "uni06EE.fina" } }, + { { "uni06EF" }, { "uni06EF.fina" } }, + { { "uni06FA" }, { "uni06FA.fina" } }, + { { "uni06FB" }, { "uni06FB.fina" } }, + { { "uni06FC" }, { "uni06FC.fina" } }, + { { "uni06FF" }, { "uni06FF.fina" } }, + { { "uni0750" }, { "uni0750.fina" } }, + { { "uni0751" }, { "uni0751.fina" } }, + { { "uni0752" }, { "uni0752.fina" } }, + { { "uni0753" }, { "uni0753.fina" } }, + { { "uni0754" }, { "uni0754.fina" } }, + { { "uni0755" }, { "uni0755.fina" } }, + { { "uni0756" }, { "uni0756.fina" } }, + { { "uni0757" }, { "uni0757.fina" } }, + { { "uni0758" }, { "uni0758.fina" } }, + { { "uni0759" }, { "uni0759.fina" } }, + { { "uni075A" }, { "uni075A.fina" } }, + { { "uni075B" }, { "uni075B.fina" } }, + { { "uni075C" }, { "uni075C.fina" } }, + { { "uni075D" }, { "uni075D.fina" } }, + { { "uni075E" }, { "uni075E.fina" } }, + { { "uni075F" }, { "uni075F.fina" } }, + { { "uni0760" }, { "uni0760.fina" } }, + { { "uni0761" }, { "uni0761.fina" } }, + { { "uni0762" }, { "uni0762.fina" } }, + { { "uni0763" }, { "uni0763.fina" } }, + { { "uni0764" }, { "uni0764.fina" } }, + { { "uni0765" }, { "uni0765.fina" } }, + { { "uni0766" }, { "uni0766.fina" } }, + { { "uni0767" }, { "uni0767.fina" } }, + { { "uni0768" }, { "uni0768.fina" } }, + { { "uni0769" }, { "uni0769.fina" } }, + { { "uni076A" }, { "uni076A.fina" } }, + { { "uni076B" }, { "uni076B.fina" } }, + { { "uni076C" }, { "uni076C.fina" } }, + { { "uni076D" }, { "uni076D.fina" } }, + } + }, + { "f3", "lu3", "arab", "dflt", "medi", + new String[][][] { + { { "absJeemRetro1" }, { "absJeemRetro1Med" } }, + { { "absJeemRetro2" }, { "absJeemRetro2Med" } }, + { { "absJeemRetro3" }, { "absJeemRetro3Med" } }, + { { "absLamRetro" }, { "absLamRetroMed" } }, + { { "absSheenRetro1" }, { "absSheenRetro1Med" } }, + { { "absSheenRetro2" }, { "absSheenRetro2Med" } }, + { { "absTchehRetro1" }, { "absTchehRetro1Med" } }, + { { "absTchehRetro2" }, { "absTchehRetro2Med" } }, + { { "uni0626" }, { "uni0626.medi" } }, + { { "uni0628" }, { "uni0628.medi" } }, + { { "uni062A" }, { "uni062A.medi" } }, + { { "uni062B" }, { "uni062B.medi" } }, + { { "uni062C" }, { "uni062C.medi" } }, + { { "uni062D" }, { "uni062D.medi" } }, + { { "uni062E" }, { "uni062E.medi" } }, + { { "uni0633" }, { "uni0633.medi" } }, + { { "uni0634" }, { "uni0634.medi" } }, + { { "uni0635" }, { "uni0635.medi" } }, + { { "uni0636" }, { "uni0636.medi" } }, + { { "uni0637" }, { "uni0637.medi" } }, + { { "uni0638" }, { "uni0638.medi" } }, + { { "uni0639" }, { "uni0639.medi" } }, + { { "uni063A" }, { "uni063A.medi" } }, + { { "uni0641" }, { "uni0641.medi" } }, + { { "uni0642" }, { "uni0642.medi" } }, + { { "uni0643" }, { "uni0643.medi" } }, + { { "uni0644" }, { "uni0644.medi" } }, + { { "uni0645" }, { "uni0645.medi" } }, + { { "uni0646" }, { "uni0646.medi" } }, + { { "uni0647" }, { "uni0647.medi" } }, + { { "uni0649" }, { "uni0649.medi" } }, + { { "uni064A" }, { "uni064A.medi" } }, + { { "uni064A.noDots" }, { "uni064A.medi.noDots" } }, + { { "uni066E" }, { "uni066E.medi" } }, + { { "uni066F" }, { "uni066F.medi" } }, + { { "uni0678" }, { "uni0678.medi" } }, + { { "uni0679" }, { "uni0679.medi" } }, + { { "uni067A" }, { "uni067A.medi" } }, + { { "uni067B" }, { "uni067B.medi" } }, + { { "uni067C" }, { "uni067C.medi" } }, + { { "uni067D" }, { "uni067D.medi" } }, + { { "uni067E" }, { "uni067E.medi" } }, + { { "uni067F" }, { "uni067F.medi" } }, + { { "uni0680" }, { "uni0680.medi" } }, + { { "uni0681" }, { "uni0681.medi" } }, + { { "uni0682" }, { "uni0682.medi" } }, + { { "uni0683" }, { "uni0683.medi" } }, + { { "uni0684" }, { "uni0684.medi" } }, + { { "uni0685" }, { "uni0685.medi" } }, + { { "uni0686" }, { "uni0686.medi" } }, + { { "uni0687" }, { "uni0687.medi" } }, + { { "uni069A" }, { "uni069A.medi" } }, + { { "uni069B" }, { "uni069B.medi" } }, + { { "uni069C" }, { "uni069C.medi" } }, + { { "uni069D" }, { "uni069D.medi" } }, + { { "uni069E" }, { "uni069E.medi" } }, + { { "uni069F" }, { "uni069F.medi" } }, + { { "uni06A0" }, { "uni06A0.medi" } }, + { { "uni06A1" }, { "uni06A1.medi" } }, + { { "uni06A2" }, { "uni06A2.medi" } }, + { { "uni06A3" }, { "uni06A3.medi" } }, + { { "uni06A4" }, { "uni06A4.medi" } }, + { { "uni06A5" }, { "uni06A5.medi" } }, + { { "uni06A6" }, { "uni06A6.medi" } }, + { { "uni06A7" }, { "uni06A7.medi" } }, + { { "uni06A8" }, { "uni06A8.medi" } }, + { { "uni06A9" }, { "uni06A9.medi" } }, + { { "uni06AA" }, { "uni06AA.medi" } }, + { { "uni06AB" }, { "uni06AB.medi" } }, + { { "uni06AC" }, { "uni06AC.medi" } }, + { { "uni06AD" }, { "uni06AD.medi" } }, + { { "uni06AE" }, { "uni06AE.medi" } }, + { { "uni06AF" }, { "uni06AF.medi" } }, + { { "uni06B0" }, { "uni06B0.medi" } }, + { { "uni06B1" }, { "uni06B1.medi" } }, + { { "uni06B2" }, { "uni06B2.medi" } }, + { { "uni06B3" }, { "uni06B3.medi" } }, + { { "uni06B4" }, { "uni06B4.medi" } }, + { { "uni06B5" }, { "uni06B5.medi" } }, + { { "uni06B6" }, { "uni06B6.medi" } }, + { { "uni06B7" }, { "uni06B7.medi" } }, + { { "uni06B8" }, { "uni06B8.medi" } }, + { { "uni06B9" }, { "uni06B9.medi" } }, + { { "uni06BA" }, { "uni06BA.medi" } }, + { { "uni06BB" }, { "uni06BB.medi" } }, + { { "uni06BC" }, { "uni06BC.medi" } }, + { { "uni06BD" }, { "uni06BD.medi" } }, + { { "uni06BE" }, { "uni06BE.medi" } }, + { { "uni06BF" }, { "uni06BF.medi" } }, + { { "uni06C1" }, { "uni06C1.medi" } }, + { { "uni06CC" }, { "uni06CC.medi" } }, + { { "uni06CE" }, { "uni06CE.medi" } }, + { { "uni06D0" }, { "uni06D0.medi" } }, + { { "uni06D1" }, { "uni06D1.medi" } }, + { { "uni06FA" }, { "uni06FA.medi" } }, + { { "uni06FB" }, { "uni06FB.medi" } }, + { { "uni06FC" }, { "uni06FC.medi" } }, + { { "uni06FF" }, { "uni06FF.medi" } }, + { { "uni0750" }, { "uni0750.medi" } }, + { { "uni0751" }, { "uni0751.medi" } }, + { { "uni0752" }, { "uni0752.medi" } }, + { { "uni0753" }, { "uni0753.medi" } }, + { { "uni0754" }, { "uni0754.medi" } }, + { { "uni0755" }, { "uni0755.medi" } }, + { { "uni0756" }, { "uni0756.medi" } }, + { { "uni0757" }, { "uni0757.medi" } }, + { { "uni0758" }, { "uni0758.medi" } }, + { { "uni075C" }, { "uni075C.medi" } }, + { { "uni075D" }, { "uni075D.medi" } }, + { { "uni075E" }, { "uni075E.medi" } }, + { { "uni075F" }, { "uni075F.medi" } }, + { { "uni0760" }, { "uni0760.medi" } }, + { { "uni0761" }, { "uni0761.medi" } }, + { { "uni0762" }, { "uni0762.medi" } }, + { { "uni0763" }, { "uni0763.medi" } }, + { { "uni0764" }, { "uni0764.medi" } }, + { { "uni0765" }, { "uni0765.medi" } }, + { { "uni0766" }, { "uni0766.medi" } }, + { { "uni0767" }, { "uni0767.medi" } }, + { { "uni0768" }, { "uni0768.medi" } }, + { { "uni0769" }, { "uni0769.medi" } }, + { { "uni076A" }, { "uni076A.medi" } }, + { { "uni076D" }, { "uni076D.medi" } }, + } + }, + { "f3", "lu11", "arab", "SND ", "calt", + new String[][][] { + { { "uni0645" }, { "uni0645.sindhi" } }, + { { "uni0645.fina" }, { "uni0645.fina.sindhi" } }, + { { "uni0647" }, { "uni0647.knotted" } }, + { { "uni0647.fina" }, { "uni0647.fina.knottedHigh" } }, + { { "uni0647.medi" }, { "uni0647.medi.knottedHigh" } }, + { { "uni06F6" }, { "uni06F6.urdu" } }, + { { "uni06F7" }, { "uni06F7.urdu" } }, + } + }, + { "f3", "lu12", "arab", "KUR ", "calt", + new String[][][] { + { { "uni0647" }, { "uni0647.knotted" } }, + { { "uni0647.fina" }, { "uni0647.fina.knottedHigh" } }, + } + }, + { "f3", "lu13", "arab", "URD ", "calt", + new String[][][] { + { { "uni0647.fina" }, { "uni0647.fina.hooked" } }, + { { "uni0647.init" }, { "uni0647.init.hooked" } }, + { { "uni0647.medi" }, { "uni0647.medi.hooked" } }, + { { "uni06F4" }, { "uni06F4.urdu" } }, + { { "uni06F6" }, { "uni06F6.urdu" } }, + { { "uni06F7" }, { "uni06F7.urdu" } }, + } + }, + { "f3", "lu15", "arab", "*", "*", + new String[][][] { + { { "absLamRetroIni" }, { "absLamRetroIni.preAlef" } }, + { { "absLamRetroMed" }, { "absLamRetroMed.preAlef" } }, + { { "uni0644.init" }, { "uni0644.init.preAlef" } }, + { { "uni0644.medi" }, { "uni0644.medi.preAlef" } }, + { { "uni06B5.init" }, { "uni06B5.init.preAlef" } }, + { { "uni06B5.medi" }, { "uni06B5.medi.preAlef" } }, + { { "uni06B6.init" }, { "uni06B6.init.preAlef" } }, + { { "uni06B6.medi" }, { "uni06B6.medi.preAlef" } }, + { { "uni06B7.init" }, { "uni06B7.init.preAlef" } }, + { { "uni06B7.medi" }, { "uni06B7.medi.preAlef" } }, + { { "uni06B8.init" }, { "uni06B8.init.preAlef" } }, + { { "uni06B8.medi" }, { "uni06B8.medi.preAlef" } }, + { { "uni076A.init" }, { "uni076A.init.preAlef" } }, + { { "uni076A.medi" }, { "uni076A.medi.preAlef" } }, + } + }, + { "f3", "lu16", "arab", "*", "*", + new String[][][] { + { { "uni0622.fina" }, { "uni0622.fina.postLamIni" } }, + { { "uni0623.fina" }, { "uni0623.fina.postLamIni" } }, + { { "uni0625.fina" }, { "uni0625.fina.postLamIni" } }, + { { "uni0627.fina" }, { "uni0627.fina.postLamIni" } }, + { { "uni0671.fina" }, { "uni0671.fina.postLamIni" } }, + { { "uni0672.fina" }, { "uni0672.fina.postLamIni" } }, + { { "uni0673.fina" }, { "uni0673.fina.postLamIni" } }, + { { "uni0675.fina" }, { "uni0675.fina.postLamIni" } }, + } + }, + { "f3", "lu17", "arab", "*", "*", + new String[][][] { + { { "uni0622.fina" }, { "uni0622.fina.postLamMed" } }, + { { "uni0623.fina" }, { "uni0623.fina.postLamMed" } }, + { { "uni0625.fina" }, { "uni0625.fina.postLamMed" } }, + { { "uni0627.fina" }, { "uni0627.fina.postLamMed" } }, + { { "uni0671.fina" }, { "uni0671.fina.postLamMed" } }, + { { "uni0672.fina" }, { "uni0672.fina.postLamMed" } }, + { { "uni0673.fina" }, { "uni0673.fina.postLamMed" } }, + { { "uni0675.fina" }, { "uni0675.fina.postLamMed" } }, + } + }, + { "f3", "lu18", "arab", "*", "*", + new String[][][] { + { { "uni0601" }, { "uni0601.4" } }, + } + }, + { "f3", "lu19", "arab", "*", "*", + new String[][][] { + { { "uni0600" }, { "uni0600.3" } }, + { { "uni0601" }, { "uni0601.3" } }, + { { "uni0603" }, { "uni0603.3" } }, + { { "uni06DD" }, { "uni06DD.3" } }, + { { "uni06DD.alt" }, { "uni06DD.alt.3" } }, + { { "uni06DD.altB" }, { "uni06DD.altB.3" } }, + } + }, + { "f3", "lu20", "arab", "*", "*", + new String[][][] { + { { "uni0600" }, { "uni0600.2" } }, + { { "uni0601" }, { "uni0601.2" } }, + { { "uni0602" }, { "uni0602.2" } }, + { { "uni0603" }, { "uni0603.2" } }, + { { "uni06DD" }, { "uni06DD.2" } }, + { { "uni06DD.alt" }, { "uni06DD.alt.2" } }, + { { "uni06DD.altB" }, { "uni06DD.altB.2" } }, + } + }, + { "f3", "lu21", "arab", "*", "*", + new String[][][] { + { { "eight" }, { "eightMedium" } }, + { { "five" }, { "fiveMedium" } }, + { { "four" }, { "fourMedium" } }, + { { "nine" }, { "nineMedium" } }, + { { "one" }, { "oneMedium" } }, + { { "seven" }, { "sevenMedium" } }, + { { "six" }, { "sixMedium" } }, + { { "three" }, { "threeMedium" } }, + { { "two" }, { "twoMedium" } }, + { { "uni0660" }, { "uni0660.Medium" } }, + { { "uni0661" }, { "uni0661.Medium" } }, + { { "uni0662" }, { "uni0662.Medium" } }, + { { "uni0663" }, { "uni0663.Medium" } }, + { { "uni0664" }, { "uni0664.Medium" } }, + { { "uni0665" }, { "uni0665.Medium" } }, + { { "uni0666" }, { "uni0666.Medium" } }, + { { "uni0667" }, { "uni0667.Medium" } }, + { { "uni0668" }, { "uni0668.Medium" } }, + { { "uni0669" }, { "uni0669.Medium" } }, + { { "uni06F0" }, { "uni06F0.Medium" } }, + { { "uni06F1" }, { "uni06F1.Medium" } }, + { { "uni06F2" }, { "uni06F2.Medium" } }, + { { "uni06F3" }, { "uni06F3.Medium" } }, + { { "uni06F4" }, { "uni06F4.Medium" } }, + { { "uni06F4.urdu" }, { "uni06F4.Medium.urdu" } }, + { { "uni06F5" }, { "uni06F5.Medium" } }, + { { "uni06F6" }, { "uni06F6.Medium" } }, + { { "uni06F6.urdu" }, { "uni06F6.Medium.urdu" } }, + { { "uni06F7" }, { "uni06F7.Medium" } }, + { { "uni06F7.urdu" }, { "uni06F7.Medium.urdu" } }, + { { "uni06F8" }, { "uni06F8.Medium" } }, + { { "uni06F9" }, { "uni06F9.Medium" } }, + { { "zero" }, { "zeroMedium" } }, + } + }, + { "f3", "lu22", "arab", "*", "*", + new String[][][] { + { { "eight" }, { "eightSmall" } }, + { { "five" }, { "fiveSmall" } }, + { { "four" }, { "fourSmall" } }, + { { "nine" }, { "nineSmall" } }, + { { "one" }, { "oneSmall" } }, + { { "seven" }, { "sevenSmall" } }, + { { "six" }, { "sixSmall" } }, + { { "three" }, { "threeSmall" } }, + { { "two" }, { "twoSmall" } }, + { { "uni0660" }, { "uni0660.Small" } }, + { { "uni0661" }, { "uni0661.Small" } }, + { { "uni0662" }, { "uni0662.Small" } }, + { { "uni0663" }, { "uni0663.Small" } }, + { { "uni0664" }, { "uni0664.Small" } }, + { { "uni0665" }, { "uni0665.Small" } }, + { { "uni0666" }, { "uni0666.Small" } }, + { { "uni0667" }, { "uni0667.Small" } }, + { { "uni0668" }, { "uni0668.Small" } }, + { { "uni0669" }, { "uni0669.Small" } }, + { { "uni06F0" }, { "uni06F0.Small" } }, + { { "uni06F1" }, { "uni06F1.Small" } }, + { { "uni06F2" }, { "uni06F2.Small" } }, + { { "uni06F3" }, { "uni06F3.Small" } }, + { { "uni06F4" }, { "uni06F4.Small" } }, + { { "uni06F4.urdu" }, { "uni06F4.Small.urdu" } }, + { { "uni06F5" }, { "uni06F5.Small" } }, + { { "uni06F6" }, { "uni06F6.Small" } }, + { { "uni06F6.urdu" }, { "uni06F6.Small.urdu" } }, + { { "uni06F7" }, { "uni06F7.Small" } }, + { { "uni06F7.urdu" }, { "uni06F7.Small.urdu" } }, + { { "uni06F8" }, { "uni06F8.Small" } }, + { { "uni06F9" }, { "uni06F9.Small" } }, + { { "zero" }, { "zeroSmall" } }, + } + }, + { "f3", "lu23", "arab", "*", "*", + new String[][][] { + { { "uni0670" }, { "uni0670.large" } }, + } + }, + }; + + private static Object[][] ltMultiple = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_MULTIPLE }, + // arab-001.ttx + { "f0", "lu9", "arab", "*", "*", + new String[][][] { + { { "alefwithhamzabelow" }, { "arabicalef", "uni0655" } }, + } + }, + // arab-002.ttx + { "f1", "lu14", "arab", "*", "*", + new String[][][] { + { { "pehinitial" }, { "pehinitial", "tatweel" } }, + { { "yehwithhamzaaboveinitial" }, { "yehwithhamzaaboveinitial", "tatweel" } }, + { { "behinitial" }, { "behinitial", "tatweel" } }, + { { "tehinitial" }, { "tehinitial", "tatweel" } }, + { { "thehinitial" }, { "thehinitial", "tatweel" } }, + { { "fehinitial" }, { "fehinitial", "tatweel" } }, + { { "qafinitial" }, { "qafinitial", "tatweel" } }, + { { "nooninitial" }, { "nooninitial", "tatweel" } }, + { { "yehinitial" }, { "yehinitial", "tatweel" } }, + { { "uni0649.init" }, { "uni0649.init", "tatweel" } }, + } + }, + { "f1", "lu15", "arab", "*", "*", + new String[][][] { + { { "pehmedial" }, { "pehmedial", "tatweel" } }, + { { "yehwithhamzaabovemedial" }, { "yehwithhamzaabovemedial", "tatweel" } }, + { { "behmedial" }, { "behmedial", "tatweel" } }, + { { "tehmedial" }, { "tehmedial", "tatweel" } }, + { { "thehmedial" }, { "thehmedial", "tatweel" } }, + { { "noonmedial" }, { "noonmedial", "tatweel" } }, + { { "yehmedial" }, { "yehmedial", "tatweel" } }, + { { "uni0649.medi" }, { "uni0649.medi", "tatweel" } }, + } + }, + // arab-003.ttx + { "f2", "lu0", "arab", "dflt", "ccmp", + new String[][][] { + { { "uni0622" }, { "uni0627", "uni0653" } }, + { { "uni0623" }, { "uni0627", "uni0654" } }, + { { "uni0625" }, { "uni0627", "uni0655" } }, + { { "uni0626" }, { "uni064A", "uni0654" } }, + } + }, + // arab-004.ttx + { "f3", "lu0", "arab", "dflt", "ccmp", + new String[][][] { + { { "uni0622" }, { "uni0627", "uni0653" } }, + { { "uni0623" }, { "uni0627", "uni0654" } }, + { { "uni0625" }, { "uni0627", "uni0655" } }, + } + }, + }; + + private static Object[][] ltAlternate = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_ALTERNATE }, + // arab-001.ttx - none used + // arab-002.ttx - none used + // arab-003.ttx - none used + // arab-004.ttx - add tests + { "f3", "lu14", "arab", "dflt", "salt" }, + }; + + private static Object[][] ltLigature = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_LIGATURE }, + // arab-001.ttx + { "f0", "lu0", "arab", "dflt", "ccmp", + new String[][][] { + { { "damma", "shadda" }, { "shaddawithdammalow" } }, + { { "damma", "highhamza" }, { "dammaonhamza" } }, + { { "dammatan", "shadda" }, { "shaddawithdammatanlow" } }, + { { "dammatan", "highhamza" }, { "dammatanonhamza" } }, + { { "fatha", "shadda" }, { "shaddawithfathalow" } }, + { { "fatha", "highhamza" }, { "fathaonhamza" } }, + { { "fathatan", "shadda" }, { "shaddawithfathatanlow" } }, + { { "fathatan", "highhamza" }, { "fathatanonhamza" } }, + { { "highhamza", "fatha" }, { "fathaonhamza" } }, + { { "highhamza", "fathatan" }, { "fathatanonhamza" } }, + { { "highhamza", "sukun" }, { "sukunonhamza" } }, + { { "highhamza", "damma" }, { "dammaonhamza" } }, + { { "highhamza", "dammatan" }, { "dammatanonhamza" } }, + { { "kasra", "shadda" }, { "shaddawithkasralow" } }, + { { "kasra", "uni0655" }, { "uni06550650" } }, + { { "kasratan", "shadda" }, { "shaddawithkasratanlow" } }, + { { "kasratan", "uni0655" }, { "uni0655064D" } }, + { { "shadda", "dammatan" }, { "shaddawithdammatanlow" } }, + { { "shadda", "fatha" }, { "shaddawithfathalow" } }, + { { "shadda", "damma" }, { "shaddawithdammalow" } }, + { { "shadda", "fathatan" }, { "shaddawithfathatanlow" } }, + { { "shadda", "kasratan" }, { "shaddawithkasratanlow" } }, + { { "shadda", "kasra" }, { "shaddawithkasralow" } }, + { { "sukun", "highhamza" }, { "sukunonhamza" } }, + { { "uni0655", "kasratan" }, { "uni0655064D" } }, + { { "uni0655", "kasra" }, { "uni06550650" } }, + } + }, + { "f0", "lu7", "arab", "dflt", "rlig", + new String[][][] { + { { "lamisolated", "alefwithmaddaabovefinal" }, { "lamwithalefmaddaaboveisolatedd" } }, + { { "lamisolated", "alefwithhamzaabovefinal" }, { "lamwithalefhamzaaboveisolatedd" } }, + { { "lamisolated", "alefwithhamzabelowfinal" }, { "lamwithalefhamzabelowisolated" } }, + { { "lamisolated", "aleffinal" }, { "lamwithalefisolated" } }, + { { "lammedial", "alefwithmaddaabovefinal" }, { "lamwithalefmaddaabovefinal" } }, + { { "lammedial", "alefwithhamzaabovefinal" }, { "lamwithalefhamzaabovefinal" } }, + { { "lammedial", "alefwithhamzabelowfinal" }, { "lamwithalefhamzabelowfinal" } }, + { { "lammedial", "aleffinal" }, { "lamwithaleffinal" } }, + } + }, + { "f0", "lu8", "arab", "dflt", "liga", + new String[][][] { + { { "lamisolated", "lammedial", "hehfinal" }, { "allahisolated" } }, + { { "reh", "yehmedial", "aleffinal", "lam" }, { "rayaleflam" } }, + } + }, + // arab-002.ttx + { "f1", "lu0", "arab", "dflt", "ccmp", + new String[][][] { + { { "damma", "shadda" }, { "shaddawithdammaisolatedlow" } }, + { { "damma", "highhamza" }, { "dammaonhamza" } }, + { { "dammatan", "shadda" }, { "shaddawithdammatanisolatedlow" } }, + { { "dammatan", "highhamza" }, { "dammatanonhamza" } }, + { { "fatha", "shadda" }, { "shaddawithfathaisolatedlow" } }, + { { "fatha", "highhamza" }, { "fathaonhamza" } }, + { { "fathatan", "shadda" }, { "shaddawithfathatanisolatedlow" } }, + { { "fathatan", "highhamza" }, { "fathatanonhamza" } }, + { { "highhamza", "fatha" }, { "fathaonhamza" } }, + { { "highhamza", "fathatan" }, { "fathatanonhamza" } }, + { { "highhamza", "sukun" }, { "sukunonhamza" } }, + { { "highhamza", "damma" }, { "dammaonhamza" } }, + { { "highhamza", "dammatan" }, { "dammatanonhamza" } }, + { { "kasra", "shadda" }, { "shaddawithkasraisolatedlow" } }, + { { "kasra", "uni0655" }, { "uni06550650" } }, + { { "kasratan", "shadda" }, { "shaddawithkasratanisolatedlow" } }, + { { "kasratan", "uni0655" }, { "uni0655064D" } }, + { { "shadda", "dammatan" }, { "shaddawithdammatanisolatedlow" } }, + { { "shadda", "fatha" }, { "shaddawithfathaisolatedlow" } }, + { { "shadda", "damma" }, { "shaddawithdammaisolatedlow" } }, + { { "shadda", "fathatan" }, { "shaddawithfathatanisolatedlow" } }, + { { "shadda", "kasratan" }, { "shaddawithkasratanisolatedlow" } }, + { { "shadda", "kasra" }, { "shaddawithkasraisolatedlow" } }, + { { "sukun", "highhamza" }, { "sukunonhamza" } }, + { { "uni0655", "kasratan" }, { "uni0655064D" } }, + { { "uni0655", "kasra" }, { "uni06550650" } }, + } + }, + { "f1", "lu6", "arab", "dflt", "liga", + new String[][][] { + { { "behinitial", "hehmedial" }, { "behwithhehinitial" } }, + { { "behinitial", "meemfinal" }, { "behwithmeemisolated" } }, + { { "behinitial", "meemmedial" }, { "behwithmeeminitial" } }, + { { "behinitial", "alefmaksurafinal" }, { "behwithalefmaksuraisolated" } }, + { { "behinitial", "yehfinal" }, { "behwithyehisolated" } }, + { { "behinitial", "jeemmedial" }, { "behwithjeeminitial" } }, + { { "behinitial", "hahmedial" }, { "behwithhahinitial" } }, + { { "behinitial", "khahmedial" }, { "behwithkhahinitial" } }, + { { "behmedial", "alefmaksurafinal" }, { "behwithalefmaksurafinal" } }, + { { "behmedial", "yehfinal" }, { "behwithyehfinal" } }, + { { "behmedial", "rehfinal" }, { "behwithrehfinal" } }, + { { "behmedial", "noonfinal" }, { "behwithnoonfinal" } }, + { { "fehinitial", "alefmaksurafinal" }, { "fehwithalefmaksuraisolated" } }, + { { "fehinitial", "yehfinal" }, { "fehwithyehisolated" } }, + { { "hahinitial", "meemmedial" }, { "hahwithmeeminitial" } }, + { { "hehinitial", "meemmedial" }, { "hehwithmeeminitial" } }, + { { "jeeminitial", "meemmedial" }, { "jeemwithmeeminitial" } }, + { { "khahinitial", "meemmedial" }, { "khahwithmeeminitial" } }, + { { "laminitial", "jeemmedial" }, { "lamwithjeeminitial" } }, + { { "laminitial", "hahmedial" }, { "lamwithhahinitial" } }, + { { "laminitial", "khahmedial" }, { "lamwithkhahinitial" } }, + { { "laminitial", "hehmedial" }, { "lamwithhehinitial" } }, + { { "laminitial", "meemfinal" }, { "lamwithmeemisolated" } }, + { { "laminitial", "alefmaksurafinal" }, { "lamwithalefmaksuraisolated" } }, + { { "laminitial", "yehfinal" }, { "lamwithyehisolated" } }, + { { "meeminitial", "jeemmedial" }, { "meemwithjeeminitial" } }, + { { "meeminitial", "hahmedial" }, { "meemwithhahinitial" } }, + { { "meeminitial", "khahmedial" }, { "meemwithkhahinitial" } }, + { { "meeminitial", "meemmedial" }, { "meemwithmeeminitial" } }, + { { "nooninitial", "hehmedial" }, { "noonwithhehinitial" } }, + { { "nooninitial", "meemfinal" }, { "noonwithmeemisolated" } }, + { { "nooninitial", "meemmedial" }, { "noonwithmeeminitial" } }, + { { "nooninitial", "alefmaksurafinal" }, { "noonwithalefmaksuraisolated" } }, + { { "nooninitial", "yehfinal" }, { "noonwithyehisolated" } }, + { { "nooninitial", "jeemmedial" }, { "noonwithjeeminitial" } }, + { { "nooninitial", "hahmedial" }, { "noonwithhahinitial" } }, + { { "nooninitial", "khahmedial" }, { "noonwithkhahinitial" } }, + { { "noonmedial", "alefmaksurafinal" }, { "noonwithalefmaksurafinal" } }, + { { "noonmedial", "yehfinal" }, { "noonwithyehfinal" } }, + { { "pehinitial", "hehmedial" }, { "pehwithhehinitial" } }, + { { "seeninitial", "meemmedial" }, { "seenwithmeeminitial" } }, + { { "sheeninitial", "meemmedial" }, { "sheenwithmeeminitial" } }, + { { "tchehinitial", "meemmedial" }, { "uniE817" } }, + { { "tehinitial", "hehmedial" }, { "tehwithhehinitial" } }, + { { "tehinitial", "meemfinal" }, { "tehwithmeemisolated" } }, + { { "tehinitial", "meemmedial" }, { "tehwithmeeminitial" } }, + { { "tehinitial", "yehfinal" }, { "tehwithyehisolated" } }, + { { "tehinitial", "jeemmedial" }, { "tehwithjeeminitial" } }, + { { "tehinitial", "hahmedial" }, { "tehwithhahinitial" } }, + { { "tehinitial", "khahmedial" }, { "tehwithkhahinitial" } }, + { { "tehmedial", "alefmaksurafinal" }, { "tehwithalefmaksurafinal" } }, + { { "tehmedial", "yehfinal" }, { "tehwithyehfinal" } }, + { { "tehmedial", "rehfinal" }, { "noonwithzainfinal" } }, + { { "tehmedial", "noonfinal" }, { "tehwithnoonfinal" } }, + { { "thehinitial", "meemfinal" }, { "thehwithmeemisolated" } }, + { { "thehinitial", "meemmedial" }, { "thehwithmeeminitial" } }, + { { "yehinitial", "meemfinal" }, { "yehwithmeemisolated" } }, + { { "yehinitial", "meemmedial" }, { "yehwithmeeminitial" } }, + { { "yehinitial", "alefmaksurafinal" }, { "yehwithalefmaksuraisolated" } }, + { { "yehinitial", "jeemmedial" }, { "yehwithjeeminitial" } }, + { { "yehinitial", "hahmedial" }, { "yehwithhahinitial" } }, + { { "yehinitial", "khahmedial" }, { "yehwithkhahinitial" } }, + { { "yehmedial", "alefmaksurafinal" }, { "yehwithalefmaksurafinal" } }, + { { "yehmedial", "rehfinal" }, { "yehwithrehfinal" } }, + { { "yehmedial", "noonfinal" }, { "yehwithnoonfinal" } }, + } + }, + { "f1", "lu7", "arab", "dflt", "liga", + new String[][][] { + { { "laminitial", "meemmedial", "jeemmedial" }, { "lamwithmeemwithjeeminitial" } }, + { { "laminitial", "meemmedial", "hahmedial" }, { "lamwithmeemwithhahinitial" } }, + { { "laminitial", "meemmedial" }, { "lamwithmeeminitial" } }, + } + }, + { "f1", "lu8", "arab", "dflt", "liga", + new String[][][] { + { { "laminitial", "jeemfinal" }, { "lamwithjeemisolated" } }, + { { "laminitial", "hahfinal" }, { "lamwithhahisolated" } }, + { { "laminitial", "khahfinal" }, { "lamwithkhahisolated" } }, + } + }, + { "f1", "lu9", "arab", "dflt", "rlig", + new String[][][] { + { { "laminitial", "alefwithmaddaabovefinal" }, { "lamwithalefmaddaaboveisolatedd" } }, + { { "laminitial", "alefwithhamzaabovefinal" }, { "lamwithalefhamzaaboveisolatedd" } }, + { { "laminitial", "alefwithhamzabelowfinal" }, { "lamwithalefhamzabelowisolated" } }, + { { "laminitial", "aleffinal" }, { "lamwithalefisolated" } }, + { { "lammedial", "alefwithmaddaabovefinal" }, { "lamwithalefmaddaabovefinal" } }, + { { "lammedial", "alefwithhamzaabovefinal" }, { "lamwithalefhamzaabovefinal" } }, + { { "lammedial", "alefwithhamzabelowfinal" }, { "lamwithalefhamzabelowfinal" } }, + { { "lammedial", "aleffinal" }, { "lamwithaleffinal" } }, + } + }, + { "f1", "lu10", "arab", "dflt", "liga", + new String[][][] { + { { "laminitial", "lammedial", "hehfinal" }, { "allahisolated" } }, + { { "reh", "yehinitial", "aleffinal", "lam" }, { "rayaleflam" } }, + } + }, + // arab-003.ttx + { "f2", "lu5", "arab", "dflt", "rlig", + new String[][][] { + { { "uni064B", "uni0651" }, { "uni0651064B" } }, + { { "uni064C", "uni0651" }, { "uni0651064C" } }, + { { "uni064E", "uni0651" }, { "uni0651064E" } }, + { { "uni064F", "uni0651" }, { "uni0651064F" } }, + { { "uni0651", "uni064B" }, { "uni0651064B" } }, + { { "uni0651", "uni064C" }, { "uni0651064C" } }, + { { "uni0651", "uni064E" }, { "uni0651064E" } }, + { { "uni0651", "uni064F" }, { "uni0651064F" } }, + { { "uni0651", "uni0670" }, { "absShaddaAlef" } }, + { { "uni0670", "uni0651" }, { "absShaddaAlef" } }, + } + }, + { "f2", "lu6", "arab", "dflt", "rlig", + new String[][][] { + { { "uni064D", "uni0651" }, { "uni0651064D" } }, + { { "uni0650", "uni0651" }, { "uni06510650" } }, + { { "uni0651", "uni0650" }, { "uni06510650" } }, + { { "uni0651", "uni064D" }, { "uni0651064D" } }, + } + }, + { "f2", "lu7", "arab", "dflt", "rlig", + new String[][][] { + { { "uni0647", "uni0654" }, { "uni06C0" } }, + { { "uni0647.fina", "uni0654" }, { "uni06C0.fina" } }, + { { "uni0647.init", "uni0654" }, { "uni06C0.init" } }, + { { "uni0647.medi", "uni0654" }, { "uni06C0.medi" } }, + { { "uni0648", "uni0654" }, { "uni0624" } }, + { { "uni0648.fina", "uni0654" }, { "uni0624.fina" } }, + { { "uni064A", "uni0654" }, { "uni0626" } }, + { { "uni064A.fina", "uni0654" }, { "uni0626.fina" } }, + { { "uni064A.init", "uni0654" }, { "uni0626.init" } }, + { { "uni064A.medi", "uni0654" }, { "uni0626.medi" } }, + { { "uni06C1", "uni0654" }, { "uni06C2" } }, + { { "uni06C1.fina", "uni0654" }, { "uni06C2.fina" } }, + { { "uni06C1.init", "uni0654" }, { "uni06C2.init" } }, + { { "uni06C1.medi", "uni0654" }, { "uni06C2.medi" } }, + } + }, + // arab-004.ttx + { "f3", "lu5", "arab", "dflt", "rlig", + new String[][][] { + { { "uni064B", "uni0651" }, { "uni0651064B" } }, + { { "uni064C", "uni0651" }, { "uni0651064C" } }, + { { "uni064E", "uni0651" }, { "uni0651064E" } }, + { { "uni064F", "uni0651" }, { "uni0651064F" } }, + { { "uni0651", "uni064B" }, { "uni0651064B" } }, + { { "uni0651", "uni064C" }, { "uni0651064C" } }, + { { "uni0651", "uni064E" }, { "uni0651064E" } }, + { { "uni0651", "uni064F" }, { "uni0651064F" } }, + { { "uni0651", "uni0670" }, { "absShaddaAlef" } }, + { { "uni0670", "uni0651" }, { "absShaddaAlef" } }, + } + }, + { "f3", "lu6", "arab", "dflt", "rlig", + new String[][][] { + { { "uni064D", "uni0651" }, { "uni0651064D" } }, + { { "uni0650", "uni0651" }, { "uni06510650" } }, + { { "uni0651", "uni0650" }, { "uni06510650" } }, + { { "uni0651", "uni064D" }, { "uni0651064D" } }, + } + }, + { "f3", "lu7", "arab", "dflt", "rlig", + new String[][][] { + { { "uni0647", "uni0654" }, { "uni06C0" } }, + { { "uni0647.fina", "uni0654" }, { "uni06C0.fina" } }, + { { "uni0647.init", "uni0654" }, { "uni06C0.init" } }, + { { "uni0647.medi", "uni0654" }, { "uni06C0.medi" } }, + { { "uni0648", "uni0654" }, { "uni0624" } }, + { { "uni0648.fina", "uni0654" }, { "uni0624.fina" } }, + { { "uni064A", "uni0654" }, { "uni0626" } }, + { { "uni064A.fina", "uni0654" }, { "uni0626.fina" } }, + { { "uni064A.init", "uni0654" }, { "uni0626.init" } }, + { { "uni064A.medi", "uni0654" }, { "uni0626.medi" } }, + { { "uni06C1", "uni0654" }, { "uni06C2" } }, + { { "uni06C1.fina", "uni0654" }, { "uni06C2.fina" } }, + { { "uni06C1.init", "uni0654" }, { "uni06C2.init" } }, + { { "uni06C1.medi", "uni0654" }, { "uni06C2.medi" } }, + } + }, + { "f3", "lu8", "arab", "dflt", "rlig", + new String[][][] { + { { "uni064E", "uni0654" }, { "uni0654064E" } }, + { { "uni064F", "uni0654" }, { "uni0654064F" } }, + { { "uni0654", "uni064E" }, { "uni0654064E" } }, + { { "uni0654", "uni064F" }, { "uni0654064F" } }, + } + }, + }; + + private static Object[][] ltContextual = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_CONTEXTUAL }, + // arab-001.ttx - none used + // arab-002.ttx - none used + // arab-003.ttx - none used + // arab-004.ttx - none used + }; + + private static Object[][] ltChainedContextual = { + { GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_CHAINED_CONTEXTUAL }, + // arab-001.ttx + { "f0", "lu1", "arab", "dflt", "ccmp", + new String[][][] { + { { "wawwithhamzaabove", "alefwithhamzabelow" }, { "wawwithhamzaabove", "arabicalef", "uni0655" } }, + { { "reh", "alefwithhamzabelow" }, { "reh", "arabicalef", "uni0655" } }, + { { "zain", "alefwithhamzabelow" }, { "zain", "arabicalef", "uni0655" } }, + { { "waw", "alefwithhamzabelow" }, { "waw", "arabicalef", "uni0655" } }, + { { "jeh", "alefwithhamzabelow" }, { "jeh", "arabicalef", "uni0655" } }, + } + }, + { "f0", "lu3", "arab", "dflt", "isol", + new String[][][] { + { { "hamza", "heh" }, { "hamza", "hehisolated" } }, + { { "alefwithmaddaabove", "heh" }, { "alefwithmaddaabove", "hehisolated" } }, + { { "alefwithhamzaabove", "heh" }, { "alefwithhamzaabove", "hehisolated" } }, + { { "wawwithhamzaabove", "heh" }, { "wawwithhamzaabove", "hehisolated" } }, + { { "alefwithhamzabelow", "heh" }, { "alefwithhamzabelow", "hehisolated" } }, + { { "arabicalef", "heh" }, { "arabicalef", "hehisolated" } }, + { { "tehmarbuta", "heh" }, { "tehmarbuta", "hehisolated" } }, + { { "dal", "heh" }, { "dal", "hehisolated" } }, + { { "thal", "heh" }, { "thal", "hehisolated" } }, + { { "reh", "heh" }, { "reh", "hehisolated" } }, + { { "zain", "heh" }, { "zain", "hehisolated" } }, + { { "waw", "heh" }, { "waw", "hehisolated" } }, + { { "alefwasla", "heh" }, { "alefwasla", "hehisolated" } }, + { { "jeh", "heh" }, { "jeh", "hehisolated" } }, + { { "arabicae", "heh" }, { "arabicae", "hehisolated" } }, + { { "alefwaslafinal", "heh" }, { "alefwaslafinal", "hehisolated" } }, + { { "alefwithmaddaabovefinal", "heh" }, { "alefwithmaddaabovefinal", "hehisolated" } }, + { { "alefwithhamzaabovefinal", "heh" }, { "alefwithhamzaabovefinal", "hehisolated" } }, + { { "alefwithhamzabelowfinal", "heh" }, { "alefwithhamzabelowfinal", "hehisolated" } }, + { { "aleffinal", "heh" }, { "aleffinal", "hehisolated" } }, + { { "tehmarbutafinal", "heh" }, { "tehmarbutafinal", "hehisolated" } }, + { { "lamwithalefmaddaaboveisolatedd", "heh" }, { "lamwithalefmaddaaboveisolatedd", "hehisolated" } }, + { { "lamwithalefmaddaabovefinal", "heh" }, { "lamwithalefmaddaabovefinal", "hehisolated" } }, + { { "lamwithalefhamzaaboveisolatedd", "heh" }, { "lamwithalefhamzaaboveisolatedd", "hehisolated" } }, + { { "lamwithalefhamzaabovefinal", "heh" }, { "lamwithalefhamzaabovefinal", "hehisolated" } }, + { { "lamwithalefhamzabelowisolated", "heh" }, { "lamwithalefhamzabelowisolated", "hehisolated" } }, + { { "lamwithalefhamzabelowfinal", "heh" }, { "lamwithalefhamzabelowfinal", "hehisolated" } }, + { { "lamwithalefisolated", "heh" }, { "lamwithalefisolated", "hehisolated" } }, + { { "lamwithaleffinal", "heh" }, { "lamwithaleffinal", "hehisolated" } }, + } + }, + // arab-002.ttx + { "f1", "lu2", "arab", "dflt", "isol", + new String[][][] { + { { "hamza", "heh" }, { "hamza", "hehisolated" } }, + { { "alefwithmaddaabove", "heh" }, { "alefwithmaddaabove", "hehisolated" } }, + { { "alefwithhamzaabove", "heh" }, { "alefwithhamzaabove", "hehisolated" } }, + { { "wawwithhamzaabove", "heh" }, { "wawwithhamzaabove", "hehisolated" } }, + { { "alefwithhamzabelow", "heh" }, { "alefwithhamzabelow", "hehisolated" } }, + { { "arabicalef", "heh" }, { "arabicalef", "hehisolated" } }, + { { "tehmarbuta", "heh" }, { "tehmarbuta", "hehisolated" } }, + { { "dal", "heh" }, { "dal", "hehisolated" } }, + { { "thal", "heh" }, { "thal", "hehisolated" } }, + { { "reh", "heh" }, { "reh", "hehisolated" } }, + { { "zain", "heh" }, { "zain", "hehisolated" } }, + { { "waw", "heh" }, { "waw", "hehisolated" } }, + { { "alefwasla", "heh" }, { "alefwasla", "hehisolated" } }, + { { "jeh", "heh" }, { "jeh", "hehisolated" } }, + { { "arabicae", "heh" }, { "arabicae", "hehisolated" } }, + { { "alefwaslafinal", "heh" }, { "alefwaslafinal", "hehisolated" } }, + { { "alefwithmaddaabovefinal", "heh" }, { "alefwithmaddaabovefinal", "hehisolated" } }, + { { "alefwithhamzaabovefinal", "heh" }, { "alefwithhamzaabovefinal", "hehisolated" } }, + { { "alefwithhamzabelowfinal", "heh" }, { "alefwithhamzabelowfinal", "hehisolated" } }, + { { "aleffinal", "heh" }, { "aleffinal", "hehisolated" } }, + { { "tehmarbutafinal", "heh" }, { "tehmarbutafinal", "hehisolated" } }, + { { "lamwithalefmaddaaboveisolatedd", "heh" }, { "lamwithalefmaddaaboveisolatedd", "hehisolated" } }, + { { "lamwithalefmaddaabovefinal", "heh" }, { "lamwithalefmaddaabovefinal", "hehisolated" } }, + { { "lamwithalefhamzaaboveisolatedd", "heh" }, { "lamwithalefhamzaaboveisolatedd", "hehisolated" } }, + { { "lamwithalefhamzaabovefinal", "heh" }, { "lamwithalefhamzaabovefinal", "hehisolated" } }, + { { "lamwithalefhamzabelowisolated", "heh" }, { "lamwithalefhamzabelowisolated", "hehisolated" } }, + { { "lamwithalefhamzabelowfinal", "heh" }, { "lamwithalefhamzabelowfinal", "hehisolated" } }, + { { "lamwithalefisolated", "heh" }, { "lamwithalefisolated", "hehisolated" } }, + { { "lamwithaleffinal", "heh" }, { "lamwithaleffinal", "hehisolated" } }, + } + }, + { "f1", "lu11", "arab", "dflt", "calt", + new String[][][] { + { { "pehinitial", "fatha", "pehmedial", "fatha" }, { "pehinitial", "tatweel", "fatha", "pehmedial", "fatha" } }, + { { "yehwithhamzaaboveinitial", "damma", "vehmedial", "damma" }, { "yehwithhamzaaboveinitial", "tatweel", "damma", "vehmedial", "damma" } }, + { { "behinitial", "shadda", "jehfinal", "shadda" }, { "behinitial", "tatweel", "shadda", "jehfinal", "shadda" } }, + { { "tehinitial", "sukun", "behmedial", "sukun" }, { "tehinitial", "tatweel", "sukun", "behmedial", "sukun" } }, + { { "thehinitial", "smallhighmadda", "tehmedial", "smallhighmadda" }, { "thehinitial", "tatweel", "smallhighmadda", "tehmedial", "smallhighmadda" } }, + { { "fehinitial", "fathaonhamza", "ainmedial", "fathaonhamza" }, { "fehinitial", "tatweel", "fathaonhamza", "ainmedial", "fathaonhamza" } }, + { { "qafinitial", "dammaonhamza", "qafmedial", "dammaonhamza" }, { "qafinitial", "tatweel", "dammaonhamza", "qafmedial", "dammaonhamza" } }, + { { "nooninitial", "superscriptalef", "wawfinal", "superscriptalef" }, { "nooninitial", "tatweel", "superscriptalef", "wawfinal", "superscriptalef" } }, + { { "yehinitial", "dammatanonhamza", "rehfinal", "dammatanonhamza" }, { "yehinitial", "tatweel", "dammatanonhamza", "rehfinal", "dammatanonhamza" } }, + { { "uni0649.init", "uni0654", "wawwithhamzaabovefinal", "uni0654" }, { "uni0649.init", "tatweel", "uni0654", "wawwithhamzaabovefinal", "uni0654" } }, + } + }, + { "f1", "lu12", "arab", "dflt", "calt", + new String[][][] { + { { "pehmedial", "fatha", "pehmedial", "fatha" }, { "pehmedial", "tatweel", "fatha", "pehmedial", "fatha" } }, + { { "yehwithhamzaabovemedial", "damma", "vehmedial", "damma" }, { "yehwithhamzaabovemedial", "tatweel", "damma", "vehmedial", "damma" } }, + { { "behmedial", "shadda", "wawwithhamzaabovefinal", "shadda" }, { "behmedial", "tatweel", "shadda", "wawwithhamzaabovefinal", "shadda" } }, + { { "tehmedial", "sukun", "rehfinal", "sukun" }, { "tehmedial", "tatweel", "sukun", "rehfinal", "sukun" } }, + { { "thehmedial", "smallhighmadda", "zainfinal", "smallhighmadda" }, { "thehmedial", "tatweel", "smallhighmadda", "zainfinal", "smallhighmadda" } }, + { { "noonmedial", "superscriptalef", "ainmedial", "superscriptalef" }, { "noonmedial", "tatweel", "superscriptalef", "ainmedial", "superscriptalef" } }, + { { "yehmedial", "dammatanonhamza", "wawfinal", "dammatanonhamza" }, { "yehmedial", "tatweel", "dammatanonhamza", "wawfinal", "dammatanonhamza" } }, + { { "uni0649.medi", "uni0654", "yehmedial", "uni0654" }, { "uni0649.medi", "tatweel", "uni0654", "yehmedial", "uni0654" } }, + } + }, + // arab-003.ttx + { "f2", "lu4", "arab", "dflt", "rlig", + new String[][][] { + { { "uni0644.medi", "uni0622.fina" }, { "uni0644.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B5.medi", "uni0622.fina" }, { "uni06B5.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B6.medi", "uni0622.fina" }, { "uni06B6.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B7.medi", "uni0622.fina" }, { "uni06B7.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B8.medi", "uni0622.fina" }, { "uni06B8.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "absLamRetroMed", "uni0622.fina" }, { "absLamRetroMed.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni076A.medi", "uni0622.fina" }, { "uni076A.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni0644.init", "uni0622.fina" }, { "uni0644.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B5.init", "uni0622.fina" }, { "uni06B5.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B6.init", "uni0622.fina" }, { "uni06B6.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B7.init", "uni0622.fina" }, { "uni06B7.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B8.init", "uni0622.fina" }, { "uni06B8.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "absLamRetroIni", "uni0622.fina" }, { "absLamRetroIni.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni076A.init", "uni0622.fina" }, { "uni076A.init.preAlef", "uni0622.fina.postLamIni" } }, + } + }, + { "f2", "lu8", "arab", "dflt", "calt", + new String[][][] { + { { "uni064A", "uni0670" }, { "uni064A", "uni0670.large" } }, + } + }, + { "f2", "lu13", "arab", "dflt", "calt", + new String[][][] { + { { "uni06DD", "one" }, { "uni06DD", "oneMedium" } }, + { { "uni06DD", "one", "two" }, { "uni06DD.2", "oneMedium", "twoMedium" } }, + { { "uni06DD", "one", "two", "three" }, { "uni06DD.3", "oneSmall", "twoSmall", "threeSmall" } }, + } + }, + // arab-004.ttx + { "f3", "lu4", "arab", "dflt", "rlig", + new String[][][] { + { { "uni0644.medi", "uni0622.fina" }, { "uni0644.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B5.medi", "uni0622.fina" }, { "uni06B5.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B6.medi", "uni0622.fina" }, { "uni06B6.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B7.medi", "uni0622.fina" }, { "uni06B7.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni06B8.medi", "uni0622.fina" }, { "uni06B8.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "absLamRetroMed", "uni0622.fina" }, { "absLamRetroMed.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni076A.medi", "uni0622.fina" }, { "uni076A.medi.preAlef", "uni0622.fina.postLamMed" } }, + { { "uni0644.init", "uni0622.fina" }, { "uni0644.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B5.init", "uni0622.fina" }, { "uni06B5.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B6.init", "uni0622.fina" }, { "uni06B6.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B7.init", "uni0622.fina" }, { "uni06B7.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni06B8.init", "uni0622.fina" }, { "uni06B8.init.preAlef", "uni0622.fina.postLamIni" } }, + { { "absLamRetroIni", "uni0622.fina" }, { "absLamRetroIni.preAlef", "uni0622.fina.postLamIni" } }, + { { "uni076A.init", "uni0622.fina" }, { "uni076A.init.preAlef", "uni0622.fina.postLamIni" } }, + } + }, + { "f3", "lu9", "arab", "dflt", "calt", + new String[][][] { + { { "uni0601", "uni0661" }, { "uni0601", "uni0661.Medium" } }, + { { "uni0601", "uni0661", "uni0662" }, { "uni0601.2", "uni0661.Medium", "uni0662.Medium" } }, + { { "uni0601", "uni0661", "uni0662", "uni0663" }, { "uni0601.3", "uni0661.Medium", "uni0662.Medium", "uni0663.Medium", } }, + { { "uni0601", "uni0661", "uni0662", "uni0663", "uni0664" }, { "uni0601.4", "uni0661.Medium", "uni0662.Medium", "uni0663.Medium", "uni0664.Medium" } }, + } + }, + { "f3", "lu10", "arab", "dflt", "calt", + new String[][][] { + { { "uni064A", "uni0670" }, { "uni064A", "uni0670.large" } }, + } + }, + }; + + @Test + public void testGSUBSingle() throws Exception { + performSubstitutions ( ltSingle ); + } + + @Test + public void testGSUBMultiple() throws Exception { + performSubstitutions ( ltMultiple ); + } + + @Test + public void testGSUBAlternate() throws Exception { + performSubstitutions ( ltAlternate ); + } + + @Test + public void testGSUBLigature() throws Exception { + performSubstitutions ( ltLigature ); + } + + @Test + public void testGSUBContextual() throws Exception { + performSubstitutions ( ltContextual ); + } + + @Test + public void testGSUBChainedContextual() throws Exception { + performSubstitutions ( ltChainedContextual ); + } + + /** + * Perform substitutions on all test data in test specification TS. + * @param ts test specification + */ + private void performSubstitutions ( Object[][] ts ) { + assert ts.length > 0; + Object[] tp = ts[0]; + for ( int i = 1; i < ts.length; i++ ) { + performSubstitutions ( tp, ts[i] ); + } + } + + /** + * Perform substitutions on all test data TD using test parameters TP. + * @param tp test parameters + * @param td test data + */ + private void performSubstitutions ( Object[] tp, Object[] td ) { + assert tp.length > 0; + if ( td.length > 5 ) { + String fid = (String) td[0]; + String lid = (String) td[1]; + String script = (String) td[2]; + String language = (String) td[3]; + String feature = (String) td[4]; + TTXFile tf = findTTX ( fid ); + assertTrue ( tf != null ); + GlyphSubstitutionTable gsub = tf.getGSUB(); + assertTrue ( gsub != null ); + GlyphSubstitutionSubtable[] sta = findGSUBSubtables ( gsub, script, language, feature, lid ); + assertTrue ( sta != null ); + assertTrue ( sta.length > 0 ); + ScriptContextTester sct = findScriptContextTester ( script, language, feature ); + String[][][] tia = (String[][][]) td[5]; // test instance array + for ( String[][] ti : tia ) { // test instance + if ( ti != null ) { + if ( ti.length > 1 ) { // must have at least input and output glyph id arrays + String[] igia = ti[0]; // input glyph id array + String[] ogia = ti[1]; // output glyph id array + GlyphSequence igs = tf.getGlyphSequence ( igia ); + GlyphSequence ogs = tf.getGlyphSequence ( ogia ); + GlyphSequence tgs = GlyphSubstitutionSubtable.substitute ( igs, script, language, feature, sta, sct ); + assertSameGlyphs ( ogs, tgs ); + } + } + } + } + } + + private String findTTXPath ( String fid ) { + for ( String[] fs : ttxFonts ) { + if ( ( fs != null ) && ( fs.length > 1 ) ) { + if ( fs[0].equals ( fid ) ) { + return ttxFilesRoot + File.separator + fs[1]; + } + } + } + return null; + } + + private TTXFile findTTX ( String fid ) { + String pn = findTTXPath ( fid ); + assertTrue ( pn != null ); + try { + TTXFile tf = TTXFile.getFromCache ( pn ); + return tf; + } catch ( Exception e ) { + fail ( e.getMessage() ); + return null; + } + } + + private GlyphSubstitutionSubtable[] findGSUBSubtables ( GlyphSubstitutionTable gsub, String script, String language, String feature, String lid ) { + LookupTable lt = gsub.getLookupTable ( lid ); + if ( lt != null ) { + return (GlyphSubstitutionSubtable[]) lt.getSubtables(); + } else { + return null; + } + } + + private ScriptContextTester findScriptContextTester ( String script, String language, String feature ) { + return this; + } + + public GlyphContextTester getTester ( String feature ) { + return this; + } + + public boolean test ( String script, String language, String feature, GlyphSequence gs, int index, int flags ) { + return true; + } + + private void assertSameGlyphs ( GlyphSequence gs1, GlyphSequence gs2 ) { + assertNotNull ( gs1 ); + assertNotNull ( gs2 ); + IntBuffer gb1 = gs1.getGlyphs(); + IntBuffer gb2 = gs2.getGlyphs(); + assertEquals ( "unequal glyph count", gb1.limit(), gb2.limit() ); + for ( int i = 0; i < gb1.limit(); i++ ) { + int g1 = gb1.get(i); + int g2 = gb2.get(i); + assertEquals ( "unequal glyph code", g1, g2 ); + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java new file mode 100644 index 000000000..cc695ad42 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java @@ -0,0 +1,3450 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts.ttx; + +import java.io.File; +import java.io.IOException; + +import java.nio.IntBuffer; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.TreeMap; +import java.util.Vector; + +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.complexscripts.fonts.GlyphClassTable; +import org.apache.fop.complexscripts.fonts.GlyphCoverageTable; +import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable; +import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable; +import org.apache.fop.complexscripts.fonts.GlyphMappingTable; +import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Anchor; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.MarkAnchor; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.PairValues; +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Value; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.Ligature; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.LigatureSet; +import org.apache.fop.complexscripts.fonts.GlyphSubtable; +import org.apache.fop.complexscripts.fonts.GlyphTable; +import org.apache.fop.complexscripts.fonts.GlyphTable.RuleLookup; +import org.apache.fop.complexscripts.util.GlyphSequence; +import org.apache.fop.complexscripts.util.UTF32; +import org.apache.fop.util.CharUtilities; + +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + + +// CSOFF: InnerAssignmentCheck +// CSOFF: LineLengthCheck +// CSOFF: NoWhitespaceAfterCheck + +/** + * This class supports a subset of the <code>TTX</code> file as produced by the Adobe FLEX + * SDK (AFDKO). In particular, it is used to parse a <code>TTX</code> file in order to + * extract character to glyph code mapping data, glyph definition data, glyph substitution + * data, and glyph positioning data. + * + * <code>TTX</code> files are used in FOP for testing and debugging purposes only. Such + * files are used to represent font data employed by complex script processing, and + * normally extracted directly from an opentype (or truetype) file. However, due to + * copyright restrictions, it is not possible to include most opentype (or truetype) font + * files directly in the FOP distribution. In such cases, <code>TTX</code> files are used + * to distribute a subset of the complex script advanced table information contained in + * certain font files to facilitate testing. + * + * @author Glenn Adams + */ +public class TTXFile { + + /** logging instance */ + private static final Log log = LogFactory.getLog(TTXFile.class); // CSOK: ConstantNameCheck + /** default script tag */ + private static final String DEFAULT_SCRIPT_TAG = "dflt"; + /** default language tag */ + private static final String DEFAULT_LANGUAGE_TAG = "dflt"; + + /** ttxfile cache */ + private static Map<String,TTXFile> cache = new HashMap<String,TTXFile>(); + + // transient parsing state + private Locator locator; // current document locator + private Stack<String[]> elements; // stack of ttx elements being parsed + private Map<String,Integer> glyphIds; // map of glyph names to glyph identifiers + private List<int[]> cmapEntries; // list of <charCode,glyphCode> pairs + private Vector<int[]> hmtxEntries; // vector of <width,lsb> pairs + private Map<String,Integer> glyphClasses; // map of glyph names to glyph classes + private Map<String,Map<String,List<String>>> scripts; // map of script tag to Map<language-tag,List<features-id>>> + private Map<String,List<String>> languages; // map of language tag to List<feature-id> + private Map<String,Object[]> features; // map of feature id to Object[2] : { feature-tag, List<lookup-id> } + private List<String> languageFeatures; // list of language system feature ids, where first is (possibly null) required feature id + private List<String> featureLookups; // list of lookup ids for feature being constructed + private List<Integer> coverageEntries; // list of entries for coverage table being constructed + private Map<String,GlyphCoverageTable> coverages; // map of coverage table keys to coverage tables + private List subtableEntries; // list of lookup subtable entries + private List<GlyphSubtable> subtables; // list of constructed subtables + private List<Integer> alternates; // list of alternates in alternate set being constructed + private List<Ligature> ligatures; // list of ligatures in ligature set being constructed + private List<Integer> substitutes; // list of substitutes in (multiple substitution) sequence being constructed + private List<PairValues> pairs; // list of pair value records being constructed + private List<PairValues[]> pairSets; // list of pair value sets (as arrays) being constructed + private List<Anchor> anchors; // list of anchors of base|mark|component record being constructed + private List<Anchor[]> components; // list of ligature component anchors being constructed + private List<MarkAnchor> markAnchors; // list of mark anchors being constructed + private List<Anchor[]> baseOrMarkAnchors; // list of base|mark2 anchors being constructed + private List<Anchor[][]> ligatureAnchors; // list of ligature anchors being constructed + private List<Anchor[]> attachmentAnchors; // list of entry|exit attachment anchors being constructed + private List<RuleLookup> ruleLookups; // list of rule lookups being constructed + private int glyphIdMax; // maximum glyph id + private int cmPlatform; // plaform id of cmap being constructed + private int cmEncoding; // plaform id of cmap being constructed + private int cmLanguage; // plaform id of cmap being constructed + private int flIndex; // index of feature being constructed + private int flSequence; // feature sequence within feature list + private int ltIndex; // index of lookup table being constructed + private int ltSequence; // lookup sequence within table + private int ltFlags; // flags of current lookup being constructed + private int stSequence; // subtable sequence number within lookup + private int stFormat; // format of current subtable being constructed + private int ctFormat; // format of coverage table being constructed + private int ctIndex; // index of coverage table being constructed + private int rlSequence; // rule lookup sequence index + private int rlLookup; // rule lookup lookup index + private int psIndex; // pair set index + private int vf1; // value format 1 (used with pair pos and single pos) + private int vf2; // value format 2 (used with pair pos) + private int g2; // glyph id 2 (used with pair pos) + private int xCoord; // x coordinate of anchor being constructed + private int yCoord; // y coordinate of anchor being constructed + private int markClass; // mark class of mark anchor being constructed + private String defaultScriptTag; // tag of default script + private String scriptTag; // tag of script being constructed + private String defaultLanguageTag; // tag of default language system + private String languageTag; // tag of language system being constructed + private String featureTag; // tag of feature being constructed + private Value v1; // positioining value 1 + private Value v2; // positioining value 2 + + // resultant state + private int upem; // units per em + private Map<Integer,Integer> cmap; // constructed character map + private Map<Integer,Integer> gmap; // constructed glyph map + private int[][] hmtx; // constructed horizontal metrics - array of design { width, lsb } pairs, indexed by glyph code + private int[] widths; // pdf normalized widths (millipoints) + private GlyphDefinitionTable gdef; // constructed glyph definition table + private GlyphSubstitutionTable gsub; // constructed glyph substitution table + private GlyphPositioningTable gpos; // constructed glyph positioning table + + public TTXFile() { + elements = new Stack<String[]>(); + glyphIds = new HashMap<String,Integer>(); + cmapEntries = new ArrayList<int[]>(); + hmtxEntries = new Vector<int[]>(); + glyphClasses = new HashMap<String,Integer>(); + scripts = new HashMap<String,Map<String,List<String>>>(); + languages = new HashMap<String,List<String>>(); + features = new HashMap<String,Object[]>(); + languageFeatures = new ArrayList<String>(); + featureLookups = new ArrayList<String>(); + coverageEntries = new ArrayList<Integer>(); + coverages = new HashMap<String,GlyphCoverageTable>(); + subtableEntries = new ArrayList(); + subtables = new ArrayList<GlyphSubtable>(); + alternates = new ArrayList<Integer>(); + ligatures = new ArrayList<Ligature>(); + substitutes = new ArrayList<Integer>(); + pairs = new ArrayList<PairValues>(); + pairSets = new ArrayList<PairValues[]>(); + anchors = new ArrayList<Anchor>(); + markAnchors = new ArrayList<MarkAnchor>(); + baseOrMarkAnchors = new ArrayList<Anchor[]>(); + ligatureAnchors = new ArrayList<Anchor[][]>(); + components = new ArrayList<Anchor[]>(); + attachmentAnchors = new ArrayList<Anchor[]>(); + ruleLookups = new ArrayList<RuleLookup>(); + glyphIdMax = -1; + cmPlatform = -1; + cmEncoding = -1; + cmLanguage = -1; + flIndex = -1; + flSequence = 0; + ltIndex = -1; + ltSequence = 0; + ltFlags = 0; + stSequence = 0; + stFormat = 0; + ctFormat = -1; + ctIndex = -1; + rlSequence = -1; + rlLookup = -1; + psIndex = -1; + vf1 = -1; + vf2 = -1; + g2 = -1; + xCoord = Integer.MIN_VALUE; + yCoord = Integer.MIN_VALUE; + markClass = -1; + defaultScriptTag = DEFAULT_SCRIPT_TAG; + scriptTag = null; + defaultLanguageTag = DEFAULT_LANGUAGE_TAG; + languageTag = null; + featureTag = null; + v1 = null; + v2 = null; + upem = -1; + } + public void parse ( String filename ) { + parse ( new File ( filename ) ); + } + public void parse ( File f ) { + assert f != null; + try { + SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParser sp = spf.newSAXParser(); + sp.parse ( f, new Handler() ); + } catch ( FactoryConfigurationError e ) { + throw new RuntimeException ( e.getMessage() ); + } catch ( ParserConfigurationException e ) { + throw new RuntimeException ( e.getMessage() ); + } catch ( SAXException e ) { + throw new RuntimeException ( e.getMessage() ); + } catch ( IOException e ) { + throw new RuntimeException ( e.getMessage() ); + } + } + public GlyphSequence mapCharsToGlyphs ( String s ) { + Integer[] ca = UTF32.toUTF32 ( s, 0, true ); + int ng = ca.length; + IntBuffer cb = IntBuffer.allocate ( ng ); + IntBuffer gb = IntBuffer.allocate ( ng ); + for ( Integer c : ca ) { + int g = mapCharToGlyph ( (int) c ); + if ( g >= 0 ) { + cb.put ( c ); + gb.put ( g ); + } else { + throw new IllegalArgumentException ( "character " + CharUtilities.format ( c ) + " has no corresponding glyph" ); + } + } + cb.rewind(); + gb.rewind(); + return new GlyphSequence ( cb, gb, null ); + } + public int mapCharToGlyph ( int c ) { + if ( cmap != null ) { + Integer g = cmap.get ( Integer.valueOf ( c ) ); + if ( g != null ) { + return (int) g; + } else { + return -1; + } + } else { + return -1; + } + } + public int getGlyph ( String gid ) { + return mapGlyphId0 ( gid ); + } + public GlyphSequence getGlyphSequence ( String[] gids ) { + assert gids != null; + int ng = gids.length; + IntBuffer cb = IntBuffer.allocate ( ng ); + IntBuffer gb = IntBuffer.allocate ( ng ); + for ( String gid : gids ) { + int g = mapGlyphId0 ( gid ); + if ( g >= 0 ) { + int c = mapGlyphIdToChar ( gid ); + if ( c < 0 ) { + c = CharUtilities.NOT_A_CHARACTER; + } + cb.put ( c ); + gb.put ( g ); + } else { + throw new IllegalArgumentException ( "unmapped glyph id \"" + gid + "\"" ); + } + } + cb.rewind(); + gb.rewind(); + return new GlyphSequence ( cb, gb, null ); + } + public int[] getWidths ( String[] gids ) { + assert gids != null; + int ng = gids.length; + int[] widths = new int [ ng ]; + int i = 0; + for ( String gid : gids ) { + int g = mapGlyphId0 ( gid ); + int w = 0; + if ( g >= 0 ) { + if ( ( hmtx != null ) && ( g < hmtx.length ) ) { + int[] mtx = hmtx [ g ]; + assert mtx != null; + assert mtx.length > 0; + w = mtx[0]; + } + } + widths [ i++ ] = w; + } + assert i == ng; + return widths; + } + public int[] getWidths() { + if ( this.widths == null ) { + if ( ( hmtx != null ) && ( upem > 0 ) ) { + int[] widths = new int [ hmtx.length ]; + for ( int i = 0, n = widths.length; i < n; i++ ) { + widths [ i ] = getPDFWidth ( hmtx [ i ] [ 0 ], upem ); + } + this.widths = widths; + } + } + return this.widths; + } + public static int getPDFWidth ( int tw, int upem ) { + // N.B. The following is copied (with minor edits) from TTFFile to insure same results + int pw; + if ( tw < 0 ) { + long rest1 = tw % upem; + long storrest = 1000 * rest1; + long ledd2 = ( storrest != 0 ) ? ( rest1 / storrest ) : 0; + pw = - ( ( -1000 * tw ) / upem - (int) ledd2 ); + } else { + pw = ( tw / upem ) * 1000 + ( ( tw % upem ) * 1000 ) / upem; + } + return pw; + } + public GlyphDefinitionTable getGDEF() { + return gdef; + } + public GlyphSubstitutionTable getGSUB() { + return gsub; + } + public GlyphPositioningTable getGPOS() { + return gpos; + } + public static synchronized TTXFile getFromCache ( String filename ) { + assert cache != null; + TTXFile f; + if ( ( f = (TTXFile) cache.get ( filename ) ) == null ) { + f = new TTXFile(); + f.parse ( filename ); + cache.put ( filename, f ); + } + return f; + } + public static synchronized void clearCache() { + cache.clear(); + } + private class Handler extends DefaultHandler { + private Handler() { + } + @Override + public void startDocument() { + } + @Override + public void endDocument() { + } + @Override + public void setDocumentLocator ( Locator locator ) { + TTXFile.this.locator = locator; + } + @Override + public void startElement ( String uri, String localName, String qName, Attributes attrs ) throws SAXException { + String[] en = makeExpandedName ( uri, localName, qName ); + if ( en[0] != null ) { + unsupportedElement ( en ); + } else if ( en[1].equals ( "Alternate" ) ) { + String[] pn = new String[] { null, "AlternateSet" }; + if ( isParent ( pn ) ) { + String glyph = attrs.getValue ( "glyph" ); + if ( glyph == null ) { + missingRequiredAttribute ( en, "glyph" ); + } + int gid = mapGlyphId ( glyph, en ); + alternates.add ( Integer.valueOf ( gid ) ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "AlternateSet" ) ) { + String[] pn = new String[] { null, "AlternateSubst" }; + if ( isParent ( pn ) ) { + String glyph = attrs.getValue ( "glyph" ); + if ( glyph == null ) { + missingRequiredAttribute ( en, "glyph" ); + } + int gid = mapGlyphId ( glyph, en ); + coverageEntries.add ( Integer.valueOf ( gid ) ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "AlternateSubst" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = 1; + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "BacktrackCoverage" ) ) { + String[] pn1 = new String[] { null, "ChainContextSubst" }; + String[] pn2 = new String[] { null, "ChainContextPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + int ci = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + ci = Integer.parseInt ( index ); + } + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = ci; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "BaseAnchor" ) ) { + String[] pn = new String[] { null, "BaseRecord" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "BaseArray" ) ) { + String[] pn = new String[] { null, "MarkBasePos" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "BaseCoverage" ) ) { + String[] pn = new String[] { null, "MarkBasePos" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "BaseRecord" ) ) { + String[] pn = new String[] { null, "BaseArray" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ChainContextPos" ) || en[1].equals ( "ChainContextSubst" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + case 3: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Class" ) ) { + String[] pn = new String[] { null, "MarkRecord" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + assert markClass == -1; + markClass = v; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ClassDef" ) ) { + String[] pn1 = new String[] { null, "GlyphClassDef" }; + String[] pn2 = new String[] { null, "MarkAttachClassDef" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String glyph = attrs.getValue ( "glyph" ); + if ( glyph == null ) { + missingRequiredAttribute ( en, "glyph" ); + } + String glyphClass = attrs.getValue ( "class" ); + if ( glyphClass == null ) { + missingRequiredAttribute ( en, "class" ); + } + if ( ! glyphIds.containsKey ( glyph ) ) { + unsupportedGlyph ( en, glyph ); + } else if ( isParent ( pn1 ) ) { + if ( glyphClasses.containsKey ( glyph ) ) { + duplicateGlyphClass ( en, glyph, glyphClass ); + } else { + glyphClasses.put ( glyph, Integer.parseInt(glyphClass) ); + } + } else if ( isParent ( pn2 ) ) { + if ( glyphClasses.containsKey ( glyph ) ) { + duplicateGlyphClass ( en, glyph, glyphClass ); + } else { + glyphClasses.put ( glyph, Integer.parseInt(glyphClass) ); + } + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "ComponentRecord" ) ) { + String[] pn = new String[] { null, "LigatureAttach" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + assert anchors.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Coverage" ) ) { + String[] pn1 = new String[] { null, "CursivePos" }; + String[] pn2 = new String[] { null, "LigCaretList" }; + String[] pn3 = new String[] { null, "MultipleSubst" }; + String[] pn4 = new String[] { null, "PairPos" }; + String[] pn5 = new String[] { null, "SinglePos" }; + String[][] pnx = new String[][] { pn1, pn2, pn3, pn4, pn5 }; + if ( isParent ( pnx ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "CursivePos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + assert attachmentAnchors.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "DefaultLangSys" ) ) { + String[] pn = new String[] { null, "Script" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } else { + assertLanguageFeaturesClear(); + assert languageTag == null; + languageTag = defaultLanguageTag; + } + } else if ( en[1].equals ( "EntryAnchor" ) ) { + String[] pn = new String[] { null, "EntryExitRecord" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "EntryExitRecord" ) ) { + String[] pn = new String[] { null, "CursivePos" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ExitAnchor" ) ) { + String[] pn = new String[] { null, "EntryExitRecord" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Feature" ) ) { + String[] pn = new String[] { null, "FeatureRecord" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } else { + assertFeatureLookupsClear(); + } + } else if ( en[1].equals ( "FeatureIndex" ) ) { + String[] pn1 = new String[] { null, "DefaultLangSys" }; + String[] pn2 = new String[] { null, "LangSys" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + if ( languageFeatures.size() == 0 ) { + languageFeatures.add ( null ); + } + if ( ( v >= 0 ) && ( v < 65535 ) ) { + languageFeatures.add ( makeFeatureId ( v ) ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "FeatureList" ) ) { + String[] pn1 = new String[] { null, "GSUB" }; + String[] pn2 = new String[] { null, "GPOS" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( ! isParent ( pnx ) ) { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "FeatureRecord" ) ) { + String[] pn = new String[] { null, "FeatureList" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + int fi = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + fi = Integer.parseInt ( index ); + } + assertFeatureClear(); + assert flIndex == -1; + flIndex = fi; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "FeatureTag" ) ) { + String[] pn = new String[] { null, "FeatureRecord" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + assert featureTag == null; + featureTag = value; + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "GDEF" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( isParent ( pn ) ) { + assertSubtablesClear(); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "GPOS" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( isParent ( pn ) ) { + assertCoveragesClear(); + assertSubtablesClear(); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "GSUB" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( isParent ( pn ) ) { + assertCoveragesClear(); + assertSubtablesClear(); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Glyph" ) ) { + String[] pn1 = new String[] { null, "Coverage" }; + String[] pn2 = new String[] { null, "InputCoverage" }; + String[] pn3 = new String[] { null, "LookAheadCoverage" }; + String[] pn4 = new String[] { null, "BacktrackCoverage" }; + String[] pn5 = new String[] { null, "MarkCoverage" }; + String[] pn6 = new String[] { null, "Mark1Coverage" }; + String[] pn7 = new String[] { null, "Mark2Coverage" }; + String[] pn8 = new String[] { null, "BaseCoverage" }; + String[] pn9 = new String[] { null, "LigatureCoverage" }; + String[][] pnx = new String[][] { pn1, pn2, pn3, pn4, pn5, pn6, pn7, pn8, pn9 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + int gid = mapGlyphId ( value, en ); + coverageEntries.add ( Integer.valueOf ( gid ) ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "GlyphClassDef" ) ) { + String[] pn = new String[] { null, "GDEF" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + // force format 1 since TTX always writes entries as non-range entries + if ( sf != 1 ) { + sf = 1; + } + stFormat = sf; + assert glyphClasses.isEmpty(); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "GlyphID" ) ) { + String[] pn = new String[] { null, "GlyphOrder" }; + if ( isParent ( pn ) ) { + String id = attrs.getValue ( "id" ); + int gid = -1; + if ( id == null ) { + missingRequiredAttribute ( en, "id" ); + } else { + gid = Integer.parseInt ( id ); + } + String name = attrs.getValue ( "name" ); + if ( name == null ) { + missingRequiredAttribute ( en, "name" ); + } + if ( glyphIds.containsKey ( name ) ) { + duplicateGlyph ( en, name, gid ); + } else { + if ( gid > glyphIdMax ) { + glyphIdMax = gid; + } + glyphIds.put ( name, gid ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "GlyphOrder" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "InputCoverage" ) ) { + String[] pn1 = new String[] { null, "ChainContextSubst" }; + String[] pn2 = new String[] { null, "ChainContextPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + int ci = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + ci = Integer.parseInt ( index ); + } + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = ci; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "LangSys" ) ) { + String[] pn = new String[] { null, "LangSysRecord" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } else { + assertLanguageFeaturesClear(); + } + } else if ( en[1].equals ( "LangSysRecord" ) ) { + String[] pn = new String[] { null, "Script" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LangSysTag" ) ) { + String[] pn = new String[] { null, "LangSysRecord" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + assert languageTag == null; + languageTag = value; + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigCaretList" ) ) { + String[] pn = new String[] { null, "GDEF" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Ligature" ) ) { + String[] pn = new String[] { null, "LigatureSet" }; + if ( isParent ( pn ) ) { + String components = attrs.getValue ( "components" ); + if ( components == null ) { + missingRequiredAttribute ( en, "components" ); + } + int[] cids = mapGlyphIds ( components, en ); + String glyph = attrs.getValue ( "glyph" ); + if ( glyph == null ) { + missingRequiredAttribute ( en, "glyph" ); + } + int gid = mapGlyphId ( glyph, en ); + ligatures.add ( new Ligature ( gid, cids ) ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureAnchor" ) ) { + String[] pn = new String[] { null, "ComponentRecord" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureArray" ) ) { + String[] pn = new String[] { null, "MarkLigPos" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureAttach" ) ) { + String[] pn = new String[] { null, "LigatureArray" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + assert components.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureCoverage" ) ) { + String[] pn = new String[] { null, "MarkLigPos" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureSet" ) ) { + String[] pn = new String[] { null, "LigatureSubst" }; + if ( isParent ( pn ) ) { + String glyph = attrs.getValue ( "glyph" ); + if ( glyph == null ) { + missingRequiredAttribute ( en, "glyph" ); + } + int gid = mapGlyphId ( glyph, en ); + coverageEntries.add ( Integer.valueOf ( gid ) ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LigatureSubst" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = 1; + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LookAheadCoverage" ) ) { + String[] pn1 = new String[] { null, "ChainContextSubst" }; + String[] pn2 = new String[] { null, "ChainContextPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + int ci = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + ci = Integer.parseInt ( index ); + } + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = ci; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "Lookup" ) ) { + String[] pn = new String[] { null, "LookupList" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + int li = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + li = Integer.parseInt ( index ); + } + assertLookupClear(); + assert ltIndex == -1; + ltIndex = li; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LookupFlag" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int lf = 0; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + lf = Integer.parseInt ( value ); + } + assert ltFlags == 0; + ltFlags = lf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "LookupList" ) ) { + String[] pn1 = new String[] { null, "GSUB" }; + String[] pn2 = new String[] { null, "GPOS" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( ! isParent ( pnx ) ) { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "LookupListIndex" ) ) { + String[] pn1 = new String[] { null, "Feature" }; + String[] pn2 = new String[] { null, "SubstLookupRecord" }; + String[] pn3 = new String[] { null, "PosLookupRecord" }; + String[][] pnx = new String[][] { pn1, pn2, pn3 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + String[][] pny = new String[][] { pn2, pn3 }; + if ( isParent ( pny ) ) { + assert rlLookup == -1; + assert v != -1; + rlLookup = v; + } else { + featureLookups.add ( makeLookupId ( v ) ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "LookupType" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark1Array" ) ) { + String[] pn = new String[] { null, "MarkMarkPos" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark1Coverage" ) ) { + String[] pn = new String[] { null, "MarkMarkPos" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark2Anchor" ) ) { + String[] pn = new String[] { null, "Mark2Record" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark2Array" ) ) { + String[] pn = new String[] { null, "MarkMarkPos" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark2Coverage" ) ) { + String[] pn = new String[] { null, "MarkMarkPos" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Mark2Record" ) ) { + String[] pn = new String[] { null, "Mark2Array" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkAnchor" ) ) { + String[] pn = new String[] { null, "MarkRecord" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } + assert xCoord == Integer.MIN_VALUE; + assert yCoord == Integer.MIN_VALUE; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkArray" ) ) { + String[] pn1 = new String[] { null, "MarkBasePos" }; + String[] pn2 = new String[] { null, "MarkLigPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( ! isParent ( pnx ) ) { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "MarkAttachClassDef" ) ) { + String[] pn = new String[] { null, "GDEF" }; + if ( isParent ( pn ) ) { + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + // force format 1 since TTX always writes entries as non-range entries + if ( sf != 1 ) { + sf = 1; + } + stFormat = sf; + assert glyphClasses.isEmpty(); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkBasePos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + assert markAnchors.size() == 0; + assert baseOrMarkAnchors.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkCoverage" ) ) { + String[] pn1 = new String[] { null, "MarkBasePos" }; + String[] pn2 = new String[] { null, "MarkLigPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String format = attrs.getValue ( "Format" ); + int cf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + cf = Integer.parseInt ( format ); + switch ( cf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, cf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = cf; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "MarkLigPos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + assert markAnchors.size() == 0; + assert ligatureAnchors.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkMarkPos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + assert markAnchors.size() == 0; + assert baseOrMarkAnchors.size() == 0; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "MarkRecord" ) ) { + String[] pn1 = new String[] { null, "MarkArray" }; + String[] pn2 = new String[] { null, "Mark1Array" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "MultipleSubst" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "PairPos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "PairSet" ) ) { + String[] pn = new String[] { null, "PairPos" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + int psi = -1; + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + psi = Integer.parseInt ( index ); + } + assert psIndex == -1; + psIndex = psi; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "PairValueRecord" ) ) { + String[] pn = new String[] { null, "PairSet" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + assertPairClear(); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "PosLookupRecord" ) ) { + String[] pn1 = new String[] { null, "ChainContextSubst" }; + String[] pn2 = new String[] { null, "ChainContextPos" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "ReqFeatureIndex" ) ) { + String[] pn1 = new String[] { null, "DefaultLangSys" }; + String[] pn2 = new String[] { null, "LangSys" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + String fid; + if ( ( v >= 0 ) && ( v < 65535 ) ) { + fid = makeFeatureId ( v ); + } else { + fid = null; + } + assertLanguageFeaturesClear(); + languageFeatures.add ( fid ); + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "Script" ) ) { + String[] pn = new String[] { null, "ScriptRecord" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ScriptList" ) ) { + String[] pn1 = new String[] { null, "GSUB" }; + String[] pn2 = new String[] { null, "GPOS" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( ! isParent ( pnx ) ) { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "ScriptRecord" ) ) { + String[] pn = new String[] { null, "ScriptList" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ScriptTag" ) ) { + String[] pn = new String[] { null, "ScriptRecord" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + assert scriptTag == null; + scriptTag = value; + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "SecondGlyph" ) ) { + String[] pn = new String[] { null, "PairValueRecord" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + int gid = mapGlyphId ( value, en ); + assert g2 == -1; + g2 = gid; + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Sequence" ) ) { + String[] pn = new String[] { null, "MultipleSubst" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + int i = Integer.parseInt ( index ); + if ( i != subtableEntries.size() ) { + invalidIndex ( en, i, subtableEntries.size() ); + } + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "SequenceIndex" ) ) { + String[] pn1 = new String[] { null, "PosLookupRecord" }; + String[] pn2 = new String[] { null, "SubstLookupRecord" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + assert rlSequence == -1; + assert v != -1; + rlSequence = v; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "SinglePos" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "SingleSubst" ) ) { + String[] pn = new String[] { null, "Lookup" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + String format = attrs.getValue ( "Format" ); + int sf = -1; + if ( format == null ) { + missingRequiredAttribute ( en, "Format" ); + } else { + sf = Integer.parseInt ( format ); + switch ( sf ) { + case 1: + case 2: + break; + default: + unsupportedFormat ( en, sf ); + break; + } + } + assertCoverageClear(); + ctIndex = 0; + ctFormat = 1; + assertSubtableClear(); + assert sf >= 0; + stFormat = sf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "SubstLookupRecord" ) ) { + String[] pn = new String[] { null, "ChainContextSubst" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Substitute" ) ) { + String[] pn = new String[] { null, "Sequence" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( index == null ) { + missingRequiredAttribute ( en, "index" ); + } else { + int i = Integer.parseInt ( index ); + if ( i != substitutes.size() ) { + invalidIndex ( en, i, substitutes.size() ); + } + } + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + int gid = mapGlyphId ( value, en ); + substitutes.add ( Integer.valueOf ( gid ) ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Substitution" ) ) { + String[] pn = new String[] { null, "SingleSubst" }; + if ( isParent ( pn ) ) { + String in = attrs.getValue ( "in" ); + int igid = -1; + int ogid = -1; + if ( in == null ) { + missingRequiredAttribute ( en, "in" ); + } else { + igid = mapGlyphId ( in, en ); + } + String out = attrs.getValue ( "out" ); + if ( out == null ) { + missingRequiredAttribute ( en, "out" ); + } else { + ogid = mapGlyphId ( out, en ); + } + coverageEntries.add ( Integer.valueOf ( igid ) ); + subtableEntries.add ( Integer.valueOf ( ogid ) ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Value" ) ) { + String[] pn = new String[] { null, "SinglePos" }; + if ( isParent ( pn ) ) { + String index = attrs.getValue ( "index" ); + if ( vf1 < 0 ) { + missingParameter ( en, "value format" ); + } else { + subtableEntries.add ( parseValue ( en, attrs, vf1 ) ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Value1" ) ) { + String[] pn = new String[] { null, "PairValueRecord" }; + if ( isParent ( pn ) ) { + if ( vf1 < 0 ) { + missingParameter ( en, "value format 1" ); + } else { + assert v1 == null; + v1 = parseValue ( en, attrs, vf1 ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Value2" ) ) { + String[] pn = new String[] { null, "PairValueRecord" }; + if ( isParent ( pn ) ) { + if ( vf2 < 0 ) { + missingParameter ( en, "value format 2" ); + } else { + assert v2 == null; + v2 = parseValue ( en, attrs, vf2 ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ValueFormat" ) ) { + String[] pn = new String[] { null, "SinglePos" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int vf = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + vf = Integer.parseInt ( value ); + } + assert vf1 == -1; + vf1 = vf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ValueFormat1" ) ) { + String[] pn = new String[] { null, "PairPos" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int vf = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + vf = Integer.parseInt ( value ); + } + assert vf1 == -1; + vf1 = vf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "ValueFormat2" ) ) { + String[] pn = new String[] { null, "PairPos" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int vf = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + vf = Integer.parseInt ( value ); + } + assert vf2 == -1; + vf2 = vf; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "Version" ) ) { + String[] pn1 = new String[] { null, "GDEF" }; + String[] pn2 = new String[] { null, "GPOS" }; + String[] pn3 = new String[] { null, "GSUB" }; + String[][] pnx = new String[][] { pn1, pn2, pn3 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "XCoordinate" ) ) { + String[] pn1 = new String[] { null, "BaseAnchor" }; + String[] pn2 = new String[] { null, "EntryAnchor" }; + String[] pn3 = new String[] { null, "ExitAnchor" }; + String[] pn4 = new String[] { null, "LigatureAnchor" }; + String[] pn5 = new String[] { null, "MarkAnchor" }; + String[] pn6 = new String[] { null, "Mark2Anchor" }; + String[][] pnx = new String[][] { pn1, pn2, pn3, pn4, pn5, pn6 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + int x = 0; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + x = Integer.parseInt ( value ); + } + assert xCoord == Integer.MIN_VALUE; + xCoord = x; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "YCoordinate" ) ) { + String[] pn1 = new String[] { null, "BaseAnchor" }; + String[] pn2 = new String[] { null, "EntryAnchor" }; + String[] pn3 = new String[] { null, "ExitAnchor" }; + String[] pn4 = new String[] { null, "LigatureAnchor" }; + String[] pn5 = new String[] { null, "MarkAnchor" }; + String[] pn6 = new String[] { null, "Mark2Anchor" }; + String[][] pnx = new String[][] { pn1, pn2, pn3, pn4, pn5, pn6 }; + if ( isParent ( pnx ) ) { + String value = attrs.getValue ( "value" ); + int y = 0; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + y = Integer.parseInt ( value ); + } + assert yCoord == Integer.MIN_VALUE; + yCoord = y; + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "checkSumAdjustment" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "cmap" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "cmap_format_0" ) ) { + String[] pn = new String[] { null, "cmap" }; + if ( isParent ( pn ) ) { + String platformID = attrs.getValue ( "platformID" ); + if ( platformID == null ) { + missingRequiredAttribute ( en, "platformID" ); + } + String platEncID = attrs.getValue ( "platEncID" ); + if ( platEncID == null ) { + missingRequiredAttribute ( en, "platEncID" ); + } + String language = attrs.getValue ( "language" ); + if ( language == null ) { + missingRequiredAttribute ( en, "language" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "cmap_format_4" ) ) { + String[] pn = new String[] { null, "cmap" }; + if ( isParent ( pn ) ) { + String platformID = attrs.getValue ( "platformID" ); + int pid = -1; + if ( platformID == null ) { + missingRequiredAttribute ( en, "platformID" ); + } else { + pid = Integer.parseInt ( platformID ); + } + String platEncID = attrs.getValue ( "platEncID" ); + int eid = -1; + if ( platEncID == null ) { + missingRequiredAttribute ( en, "platEncID" ); + } else { + eid = Integer.parseInt ( platEncID ); + } + String language = attrs.getValue ( "language" ); + int lid = -1; + if ( language == null ) { + missingRequiredAttribute ( en, "language" ); + } else { + lid = Integer.parseInt ( language ); + } + assert cmapEntries.size() == 0; + assert cmPlatform == -1; + assert cmEncoding == -1; + assert cmLanguage == -1; + cmPlatform = pid; + cmEncoding = eid; + cmLanguage = lid; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "created" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "flags" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "fontDirectionHint" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "fontRevision" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "glyphDataFormat" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "head" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "hmtx" ) ) { + String[] pn = new String[] { null, "ttFont" }; + if ( ! isParent ( pn ) ) { + notPermittedInElementContext ( en, getParent(), pn ); + } else if ( glyphIdMax > 0 ) { + hmtxEntries.setSize ( glyphIdMax + 1 ); + } + } else if ( en[1].equals ( "indexToLocFormat" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "lowestRecPPEM" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "macStyle" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "magicNumber" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "map" ) ) { + String[] pn1 = new String[] { null, "cmap_format_0" }; + String[] pn2 = new String[] { null, "cmap_format_4" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pnx ) ) { + String code = attrs.getValue ( "code" ); + int cid = -1; + if ( code == null ) { + missingRequiredAttribute ( en, "code" ); + } else { + code = code.toLowerCase(); + if ( code.startsWith ( "0x" ) ) { + cid = Integer.parseInt ( code.substring ( 2 ), 16 ); + } else { + cid = Integer.parseInt ( code, 10 ); + } + } + String name = attrs.getValue ( "name" ); + int gid = -1; + if ( name == null ) { + missingRequiredAttribute ( en, "name" ); + } else { + gid = mapGlyphId ( name, en ); + } + if ( ( cmPlatform == 3 ) && ( cmEncoding == 1 ) ) { + cmapEntries.add ( new int[] { cid, gid } ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "modified" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "mtx" ) ) { + String[] pn = new String[] { null, "hmtx" }; + if ( isParent ( pn ) ) { + String name = attrs.getValue ( "name" ); + int gid = -1; + if ( name == null ) { + missingRequiredAttribute ( en, "name" ); + } else { + gid = mapGlyphId ( name, en ); + } + String width = attrs.getValue ( "width" ); + int w = -1; + if ( width == null ) { + missingRequiredAttribute ( en, "width" ); + } else { + w = Integer.parseInt ( width ); + } + String lsb = attrs.getValue ( "lsb" ); + int l = -1; + if ( lsb == null ) { + missingRequiredAttribute ( en, "lsb" ); + } else { + l = Integer.parseInt ( lsb ); + } + hmtxEntries.set ( gid, new int[] { w, l } ); + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "tableVersion" ) ) { + String[] pn1 = new String[] { null, "cmap" }; + String[] pn2 = new String[] { null, "head" }; + String[][] pnx = new String[][] { pn1, pn2 }; + if ( isParent ( pn1 ) ) { // child of cmap + String version = attrs.getValue ( "version" ); + if ( version == null ) { + missingRequiredAttribute ( en, "version" ); + } + } else if ( isParent ( pn2 ) ) { // child of head + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pnx ); + } + } else if ( en[1].equals ( "ttFont" ) ) { + String[] pn = new String[] { null, null }; + if ( isParent ( pn ) ) { + String sfntVersion = attrs.getValue ( "sfntVersion" ); + if ( sfntVersion == null ) { + missingRequiredAttribute ( en, "sfntVersion" ); + } + String ttLibVersion = attrs.getValue ( "ttLibVersion" ); + if ( ttLibVersion == null ) { + missingRequiredAttribute ( en, "ttLibVersion" ); + } + } else { + notPermittedInElementContext ( en, getParent(), null ); + } + } else if ( en[1].equals ( "unitsPerEm" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + int v = -1; + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } else { + v = Integer.parseInt ( value ); + } + assert upem == -1; + upem = v; + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "xMax" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "xMin" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "yMax" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else if ( en[1].equals ( "yMin" ) ) { + String[] pn = new String[] { null, "head" }; + if ( isParent ( pn ) ) { + String value = attrs.getValue ( "value" ); + if ( value == null ) { + missingRequiredAttribute ( en, "value" ); + } + } else { + notPermittedInElementContext ( en, getParent(), pn ); + } + } else { + unsupportedElement ( en ); + } + elements.push ( en ); + } + @Override + public void endElement ( String uri, String localName, String qName ) throws SAXException { + if ( elements.empty() ) { + throw new SAXException ( "element stack is unbalanced, no elements on stack!" ); + } + String[] enParent = elements.peek(); + if ( enParent == null ) { + throw new SAXException ( "element stack is empty, elements are not balanced" ); + } + String[] en = makeExpandedName ( uri, localName, qName ); + if ( ! sameExpandedName ( enParent, en ) ) { + throw new SAXException ( "element stack is unbalanced, expanded name mismatch" ); + } + if ( en[0] != null ) { + unsupportedElement ( en ); + } else if ( isAnchorElement ( en[1] ) ) { + if ( xCoord == Integer.MIN_VALUE ) { + missingParameter ( en, "x coordinate" ); + } else if ( yCoord == Integer.MIN_VALUE ) { + missingParameter ( en, "y coordinate" ); + } else { + if ( en[1].equals ( "EntryAnchor" ) ) { + if ( anchors.size() > 0 ) { + duplicateParameter ( en, "entry anchor" ); + } + } else if ( en[1].equals ( "ExitAnchor" ) ) { + if ( anchors.size() > 1 ) { + duplicateParameter ( en, "exit anchor" ); + } else if ( anchors.size() == 0 ) { + anchors.add ( null ); + } + } + anchors.add ( new GlyphPositioningTable.Anchor ( xCoord, yCoord ) ); + xCoord = yCoord = Integer.MIN_VALUE; + } + } else if ( en[1].equals ( "AlternateSet" ) ) { + subtableEntries.add ( extractAlternates() ); + } else if ( en[1].equals ( "AlternateSubst" ) ) { + if ( ! sortEntries ( coverageEntries, subtableEntries ) ) { + mismatchedEntries ( en, coverageEntries.size(), subtableEntries.size() ); + } + addGSUBSubtable ( GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_ALTERNATE, extractCoverage() ); + } else if ( en[1].equals ( "BacktrackCoverage" ) ) { + String ck = makeCoverageKey ( "bk", ctIndex ); + if ( coverages.containsKey ( ck ) ) { + duplicateCoverageIndex ( en, ctIndex ); + } else { + coverages.put ( ck, extractCoverage() ); + } + } else if ( en[1].equals ( "BaseCoverage" ) ) { + coverages.put ( "base", extractCoverage() ); + } else if ( en[1].equals ( "BaseRecord" ) ) { + baseOrMarkAnchors.add ( extractAnchors() ); + } else if ( en[1].equals ( "ChainContextPos" ) || en[1].equals ( "ChainContextSubst" ) ) { + GlyphCoverageTable coverage = null; + if ( stFormat == 3 ) { + GlyphCoverageTable igca[] = getCoveragesWithPrefix ( "in" ); + GlyphCoverageTable bgca[] = getCoveragesWithPrefix ( "bk" ); + GlyphCoverageTable lgca[] = getCoveragesWithPrefix ( "la" ); + if ( ( igca.length == 0 ) || hasMissingCoverage ( igca ) ) { + missingCoverage ( en, "input", igca.length ); + } else if ( hasMissingCoverage ( bgca ) ) { + missingCoverage ( en, "backtrack", bgca.length ); + } else if ( hasMissingCoverage ( lgca ) ) { + missingCoverage ( en, "lookahead", lgca.length ); + } else { + GlyphTable.Rule r = new GlyphTable.ChainedCoverageSequenceRule ( extractRuleLookups(), igca.length, igca, bgca, lgca ); + GlyphTable.RuleSet rs = new GlyphTable.HomogeneousRuleSet ( new GlyphTable.Rule[] {r} ); + GlyphTable.RuleSet[] rsa = new GlyphTable.RuleSet[] {rs}; + coverage = igca [ 0 ]; + subtableEntries.add ( rsa ); + } + } else { + unsupportedFormat ( en, stFormat ); + } + if ( en[1].equals ( "ChainContextPos" ) ) { + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_CHAINED_CONTEXTUAL, coverage ); + } else if ( en[1].equals ( "ChainContextSubst" ) ) { + addGSUBSubtable ( GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_CHAINED_CONTEXTUAL, coverage ); + } + } else if ( en[1].equals ( "ComponentRecord" ) ) { + components.add ( extractAnchors() ); + } else if ( en[1].equals ( "Coverage" ) ) { + coverages.put ( "main", extractCoverage() ); + } else if ( en[1].equals ( "DefaultLangSys" ) || en[1].equals ( "LangSysRecord" ) ) { + if ( languageTag == null ) { + missingTag ( en, "language" ); + } else if ( languages.containsKey ( languageTag ) ) { + duplicateTag ( en, "language", languageTag ); + } else { + languages.put ( languageTag, extractLanguageFeatures() ); + languageTag = null; + } + } else if ( en[1].equals ( "CursivePos" ) ) { + GlyphCoverageTable ct = coverages.get ( "main" ); + if ( ct == null ) { + missingParameter ( en, "coverages" ); + } else if ( stFormat == 1 ) { + subtableEntries.add ( extractAttachmentAnchors() ); + } else { + unsupportedFormat ( en, stFormat ); + } + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_CURSIVE, ct ); + } else if ( en[1].equals ( "EntryExitRecord" ) ) { + int na = anchors.size(); + if ( na == 0 ) { + missingParameter ( en, "entry or exit anchor" ); + } else if ( na == 1 ) { + anchors.add ( null ); + } else if ( na > 2 ) { + duplicateParameter ( en, "entry or exit anchor" ); + } + attachmentAnchors.add ( extractAnchors() ); + } else if ( en[1].equals ( "BaseRecord" ) ) { + baseOrMarkAnchors.add ( extractAnchors() ); + } else if ( en[1].equals ( "FeatureRecord" ) ) { + if ( flIndex != flSequence ) { + mismatchedIndex ( en, "feature", flIndex, flSequence ); + } else if ( featureTag == null ) { + missingTag ( en, "feature" ); + } else { + String fid = makeFeatureId ( flIndex ); + features.put ( fid, extractFeature() ); + nextFeature(); + } + } else if ( en[1].equals ( "GDEF" ) ) { + if ( subtables.size() > 0 ) { + gdef = new GlyphDefinitionTable ( subtables ); + } + clearTable(); + } else if ( en[1].equals ( "GPOS" ) ) { + if ( subtables.size() > 0 ) { + gpos = new GlyphPositioningTable ( gdef, extractLookups(), subtables ); + } + clearTable(); + } else if ( en[1].equals ( "GSUB" ) ) { + if ( subtables.size() > 0 ) { + gsub = new GlyphSubstitutionTable ( gdef, extractLookups(), subtables ); + } + clearTable(); + } else if ( en[1].equals ( "GlyphClassDef" ) ) { + GlyphMappingTable mapping = extractClassDefMapping ( glyphClasses, stFormat, true ); + addGDEFSubtable ( GlyphDefinitionTable.GDEF_LOOKUP_TYPE_GLYPH_CLASS, mapping ); + } else if ( en[1].equals ( "InputCoverage" ) ) { + String ck = makeCoverageKey ( "in", ctIndex ); + if ( coverages.containsKey ( ck ) ) { + duplicateCoverageIndex ( en, ctIndex ); + } else { + coverages.put ( ck, extractCoverage() ); + } + } else if ( en[1].equals ( "LigatureAttach" ) ) { + ligatureAnchors.add ( extractComponents() ); + } else if ( en[1].equals ( "LigatureCoverage" ) ) { + coverages.put ( "liga", extractCoverage() ); + } else if ( en[1].equals ( "LigatureSet" ) ) { + subtableEntries.add ( extractLigatures() ); + } else if ( en[1].equals ( "LigatureSubst" ) ) { + if ( ! sortEntries ( coverageEntries, subtableEntries ) ) { + mismatchedEntries ( en, coverageEntries.size(), subtableEntries.size() ); + } + GlyphCoverageTable coverage = extractCoverage(); + addGSUBSubtable ( GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_LIGATURE, coverage ); + } else if ( en[1].equals ( "LookAheadCoverage" ) ) { + String ck = makeCoverageKey ( "la", ctIndex ); + if ( coverages.containsKey ( ck ) ) { + duplicateCoverageIndex ( en, ctIndex ); + } else { + coverages.put ( ck, extractCoverage() ); + } + } else if ( en[1].equals ( "Lookup" ) ) { + if ( ltIndex != ltSequence ) { + mismatchedIndex ( en, "lookup", ltIndex, ltSequence ); + } else { + nextLookup(); + } + } else if ( en[1].equals ( "MarkAttachClassDef" ) ) { + GlyphMappingTable mapping = extractClassDefMapping ( glyphClasses, stFormat, true ); + addGDEFSubtable ( GlyphDefinitionTable.GDEF_LOOKUP_TYPE_MARK_ATTACHMENT, mapping ); + } else if ( en[1].equals ( "MarkCoverage" ) ) { + coverages.put ( "mark", extractCoverage() ); + } else if ( en[1].equals ( "Mark1Coverage" ) ) { + coverages.put ( "mrk1", extractCoverage() ); + } else if ( en[1].equals ( "Mark2Coverage" ) ) { + coverages.put ( "mrk2", extractCoverage() ); + } else if ( en[1].equals ( "MarkBasePos" ) ) { + GlyphCoverageTable mct = coverages.get ( "mark" ); + GlyphCoverageTable bct = coverages.get ( "base" ); + if ( mct == null ) { + missingParameter ( en, "mark coverages" ); + } else if ( bct == null ) { + missingParameter ( en, "base coverages" ); + } else if ( stFormat == 1 ) { + MarkAnchor[] maa = extractMarkAnchors(); + Anchor[][] bam = extractBaseOrMarkAnchors(); + subtableEntries.add ( bct ); + subtableEntries.add ( computeClassCount ( bam ) ); + subtableEntries.add ( maa ); + subtableEntries.add ( bam ); + } else { + unsupportedFormat ( en, stFormat ); + } + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_BASE, mct ); + } else if ( en[1].equals ( "MarkLigPos" ) ) { + GlyphCoverageTable mct = coverages.get ( "mark" ); + GlyphCoverageTable lct = coverages.get ( "liga" ); + if ( mct == null ) { + missingParameter ( en, "mark coverages" ); + } else if ( lct == null ) { + missingParameter ( en, "ligature coverages" ); + } else if ( stFormat == 1 ) { + MarkAnchor[] maa = extractMarkAnchors(); + Anchor[][][] lam = extractLigatureAnchors(); + subtableEntries.add ( lct ); + subtableEntries.add ( computeLigaturesClassCount ( lam ) ); + subtableEntries.add ( computeLigaturesComponentCount ( lam ) ); + subtableEntries.add ( maa ); + subtableEntries.add ( lam ); + } else { + unsupportedFormat ( en, stFormat ); + } + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_LIGATURE, mct ); + } else if ( en[1].equals ( "MarkMarkPos" ) ) { + GlyphCoverageTable mct1 = coverages.get ( "mrk1" ); + GlyphCoverageTable mct2 = coverages.get ( "mrk2" ); + if ( mct1 == null ) { + missingParameter ( en, "mark coverages 1" ); + } else if ( mct2 == null ) { + missingParameter ( en, "mark coverages 2" ); + } else if ( stFormat == 1 ) { + MarkAnchor[] maa = extractMarkAnchors(); + Anchor[][] mam = extractBaseOrMarkAnchors(); + subtableEntries.add ( mct2 ); + subtableEntries.add ( computeClassCount ( mam ) ); + subtableEntries.add ( maa ); + subtableEntries.add ( mam ); + } else { + unsupportedFormat ( en, stFormat ); + } + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_MARK_TO_MARK, mct1 ); + } else if ( en[1].equals ( "MarkRecord" ) ) { + if ( markClass == -1 ) { + missingParameter ( en, "mark class" ); + } else if ( anchors.size() == 0 ) { + missingParameter ( en, "mark anchor" ); + } else if ( anchors.size() > 1 ) { + duplicateParameter ( en, "mark anchor" ); + } else { + markAnchors.add ( new GlyphPositioningTable.MarkAnchor ( markClass, anchors.get(0) ) ); + markClass = -1; + anchors.clear(); + } + } else if ( en[1].equals ( "Mark2Record" ) ) { + baseOrMarkAnchors.add ( extractAnchors() ); + } else if ( en[1].equals ( "MultipleSubst" ) ) { + GlyphCoverageTable coverage = coverages.get ( "main" ); + addGSUBSubtable ( GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_MULTIPLE, coverage, extractSequenceEntries() ); + } else if ( en[1].equals ( "PairPos" ) ) { + assertSubtableEntriesClear(); + if ( stFormat == 1 ) { + if ( pairSets.size() == 0 ) { + missingParameter ( en, "pair set" ); + } else { + subtableEntries.add ( extractPairSets() ); + } + } else if ( stFormat == 2 ) { + unsupportedFormat ( en, stFormat ); + } + GlyphCoverageTable coverage = coverages.get ( "main" ); + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_PAIR, coverage ); + vf1 = vf2 = -1; psIndex = -1; + } else if ( en[1].equals ( "PairSet" ) ) { + if ( psIndex != pairSets.size() ) { + invalidIndex ( en, psIndex, pairSets.size() ); + } else { + pairSets.add ( extractPairs() ); + } + } else if ( en[1].equals ( "PairValueRecord" ) ) { + if ( g2 == -1 ) { + missingParameter ( en, "second glyph" ); + } else if ( ( v1 == null ) && ( v2 == null ) ) { + missingParameter ( en, "first or second value" ); + } else { + pairs.add ( new PairValues ( g2, v1, v2 ) ); + clearPair(); + } + } else if ( en[1].equals ( "PosLookupRecord" ) || en[1].equals ( "SubstLookupRecord" ) ) { + if ( rlSequence < 0 ) { + missingParameter ( en, "sequence index" ); + } else if ( rlLookup < 0 ) { + missingParameter ( en, "lookup index" ); + } else { + ruleLookups.add ( new GlyphTable.RuleLookup ( rlSequence, rlLookup ) ); + rlSequence = rlLookup = -1; + } + } else if ( en[1].equals ( "Script" ) ) { + if ( scriptTag == null ) { + missingTag ( en, "script" ); + } else if ( scripts.containsKey ( scriptTag ) ) { + duplicateTag ( en, "script", scriptTag ); + } else { + scripts.put ( scriptTag, extractLanguages() ); + scriptTag = null; + } + } else if ( en[1].equals ( "Sequence" ) ) { + subtableEntries.add ( extractSubstitutes() ); + } else if ( en[1].equals ( "SinglePos" ) ) { + int nv = subtableEntries.size(); + if ( stFormat == 1 ) { + if ( nv < 0 ) { + missingParameter ( en, "value" ); + } else if ( nv > 1 ) { + duplicateParameter ( en, "value" ); + } + } else if ( stFormat == 2 ) { + GlyphPositioningTable.Value[] pva = (GlyphPositioningTable.Value[]) subtableEntries.toArray ( new GlyphPositioningTable.Value [ nv ] ); + subtableEntries.clear(); + subtableEntries.add ( pva ); + } + GlyphCoverageTable coverage = coverages.get ( "main" ); + addGPOSSubtable ( GlyphPositioningTable.GPOS_LOOKUP_TYPE_SINGLE, coverage ); + vf1 = -1; + } else if ( en[1].equals ( "SingleSubst" ) ) { + if ( ! sortEntries ( coverageEntries, subtableEntries ) ) { + mismatchedEntries ( en, coverageEntries.size(), subtableEntries.size() ); + } + GlyphCoverageTable coverage = extractCoverage(); + addGSUBSubtable ( GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_SINGLE, coverage ); + } else if ( en[1].equals ( "cmap" ) ) { + cmap = getCMAP(); + gmap = getGMAP(); + cmapEntries.clear(); + } else if ( en[1].equals ( "cmap_format_4" ) ) { + cmPlatform = cmEncoding = cmLanguage = -1; + } else if ( en[1].equals ( "hmtx" ) ) { + hmtx = getHMTX(); + hmtxEntries.clear(); + } else if ( en[1].equals ( "ttFont" ) ) { + if ( cmap == null ) { + missingParameter ( en, "cmap" ); + } + if ( hmtx == null ) { + missingParameter ( en, "hmtx" ); + } + } + elements.pop(); + } + @Override + public void characters ( char[] chars, int start, int length ) { + } + private String[] getParent() { + if ( ! elements.empty() ) { + return elements.peek(); + } else { + return new String[] { null, null }; + } + } + private boolean isParent ( Object enx ) { + if ( enx instanceof String[][] ) { + for ( String[] en : (String[][]) enx ) { + if ( isParent ( en ) ) { + return true; + } + } + return false; + } else if ( enx instanceof String[] ) { + String[] en = (String[]) enx; + if ( ! elements.empty() ) { + String[] pn = elements.peek(); + return ( pn != null ) && sameExpandedName ( en, pn ); + } else if ( ( en[0] == null ) && ( en[1] == null ) ) { + return true; + } else { + return false; + } + } else { + return false; + } + } + private boolean isAnchorElement ( String ln ) { + if ( ln.equals ( "BaseAnchor" ) ) { + return true; + } else if ( ln.equals ( "EntryAnchor" ) ) { + return true; + } else if ( ln.equals ( "ExitAnchor" ) ) { + return true; + } else if ( ln.equals ( "LigatureAnchor" ) ) { + return true; + } else if ( ln.equals ( "MarkAnchor" ) ) { + return true; + } else if ( ln.equals ( "Mark2Anchor" ) ) { + return true; + } else { + return false; + } + } + private Map<Integer,Integer> getCMAP() { + Map<Integer,Integer> cmap = new TreeMap(); + for ( int[] cme : cmapEntries ) { + Integer c = Integer.valueOf ( cme[0] ); + Integer g = Integer.valueOf ( cme[1] ); + cmap.put ( c, g ); + } + return cmap; + } + private Map<Integer,Integer> getGMAP() { + Map<Integer,Integer> gmap = new TreeMap(); + for ( int[] cme : cmapEntries ) { + Integer c = Integer.valueOf ( cme[0] ); + Integer g = Integer.valueOf ( cme[1] ); + gmap.put ( g, c ); + } + return gmap; + } + private int[][] getHMTX() { + int ne = hmtxEntries.size(); + int[][] hmtx = new int [ ne ] [ 2 ]; + for ( int i = 0; i < ne; i++ ) { + int[] ea = hmtxEntries.get(i); + if ( ea != null ) { + hmtx [ i ] [ 0 ] = ea[0]; + hmtx [ i ] [ 1 ] = ea[1]; + } + } + return hmtx; + } + private GlyphClassTable extractClassDefMapping ( Map<String,Integer> glyphClasses, int format, boolean clearSourceMap ) { + GlyphClassTable ct; + if ( format == 1 ) { + ct = extractClassDefMapping1 ( extractClassMappings ( glyphClasses, clearSourceMap ) ); + } else if ( format == 2 ) { + ct = extractClassDefMapping2 ( extractClassMappings ( glyphClasses, clearSourceMap ) ); + } else { + ct = null; + } + return ct; + } + private GlyphClassTable extractClassDefMapping1 ( int[][] cma ) { + List entries = new ArrayList<Integer>(); + int s = -1; + int l = -1; + Integer zero = Integer.valueOf(0); + for ( int[] m : cma ) { + int g = m[0]; + int c = m[1]; + if ( s < 0 ) { + s = g; + l = g - 1; + entries.add ( Integer.valueOf ( s ) ); + } + while ( g > ( l + 1 ) ) { + entries.add ( zero ); + l++; + } + assert l == ( g - 1 ); + entries.add ( Integer.valueOf ( c ) ); + l = g; + } + return GlyphClassTable.createClassTable ( entries ); + } + private GlyphClassTable extractClassDefMapping2 ( int[][] cma ) { + List entries = new ArrayList<Integer>(); + int s = -1; + int e = s; + int l = -1; + for ( int[] m : cma ) { + int g = m[0]; + int c = m[1]; + if ( c != l ) { + if ( s >= 0 ) { + entries.add ( new GlyphClassTable.MappingRange ( s, e, l ) ); + } + s = e = g; + } else { + e = g; + } + l = c; + } + return GlyphClassTable.createClassTable ( entries ); + } + private int[][] extractClassMappings ( Map<String,Integer> glyphClasses, boolean clearSourceMap ) { + int nc = glyphClasses.size(); + int i = 0; + int[][] cma = new int [ nc ] [ 2 ]; + for ( Map.Entry<String,Integer> e : glyphClasses.entrySet() ) { + Integer gid = glyphIds.get ( e.getKey() ); + assert gid != null; + int[] m = cma [ i ]; + m [ 0 ] = (int) gid; + m [ 1 ] = (int) e.getValue(); + i++; + } + if ( clearSourceMap ) { + glyphClasses.clear(); + } + return sortClassMappings ( cma ); + } + private int[][] sortClassMappings ( int[][] cma ) { + Arrays.sort ( cma, new Comparator<int[]>() { + public int compare ( int[] m1, int[] m2 ) { + assert m1.length > 0; + assert m2.length > 0; + if ( m1[0] < m2[0] ) { + return -1; + } else if ( m1[0] > m2[0] ) { + return 1; + } else { + return 0; + } + } + } + ); + return cma; + } + // sort coverage entries and subtable entries together + private boolean sortEntries ( List cel, List sel ) { + assert cel != null; + assert sel != null; + if ( cel.size() == sel.size() ) { + int np = cel.size(); + Object[][] pa = new Object [ np ] [ 2 ]; + for ( int i = 0; i < np; i++ ) { + pa [ i ] [ 0 ] = cel.get ( i ); + pa [ i ] [ 1 ] = sel.get ( i ); + } + Arrays.sort ( pa, new Comparator<Object[]>() { + public int compare ( Object[] p1, Object[] p2 ) { + assert p1.length == 2; + assert p2.length == 2; + int c1 = (Integer) p1[0]; + int c2 = (Integer) p2[0]; + if ( c1 < c2 ) { + return -1; + } else if ( c1 > c2 ) { + return 1; + } else { + return 0; + } + } + } + ); + cel.clear(); + sel.clear(); + for ( int i = 0; i < np; i++ ) { + cel.add ( pa [ i ] [ 0 ] ); + sel.add ( pa [ i ] [ 1 ] ); + } + assert cel.size() == sel.size(); + return true; + } else { + return false; + } + } + private String makeCoverageKey ( String prefix, int index ) { + assert prefix != null; + assert prefix.length() == 2; + assert index < 100; + return prefix + CharUtilities.padLeft ( Integer.toString ( index, 10 ), 2, '0' ); + } + private List extractCoverageEntries() { + List entries = new ArrayList<Integer> ( coverageEntries ); + clearCoverage(); + return entries; + } + private void clearCoverageEntries() { + coverageEntries.clear(); + ctFormat = -1; + ctIndex = -1; + } + private void assertCoverageEntriesClear() { + assert coverageEntries.size() == 0; + } + private GlyphCoverageTable extractCoverage() { + assert ( ctFormat == 1 ) || ( ctFormat == 2 ); + assert ctIndex >= 0; + GlyphCoverageTable coverage = GlyphCoverageTable.createCoverageTable ( extractCoverageEntries() ); + clearCoverage(); + return coverage; + } + private void clearCoverages() { + coverages.clear(); + } + private void assertCoverageClear() { + assert ctFormat == -1; + assert ctIndex == -1; + assertCoverageEntriesClear(); + } + private void clearCoverage() { + ctFormat = -1; + ctIndex = -1; + clearCoverageEntries(); + } + private void assertCoveragesClear() { + assert coverages.size() == 0; + } + private GlyphCoverageTable[] getCoveragesWithPrefix ( String prefix ) { + assert prefix != null; + int prefixLength = prefix.length(); + Set<String> keys = coverages.keySet(); + int mi = -1; // maximum coverage table index + for ( String k : keys ) { + if ( k.startsWith ( prefix ) ) { + int i = Integer.parseInt ( k.substring ( prefixLength ) ); + if ( i > mi ) { + mi = i; + } + } + } + GlyphCoverageTable[] gca = new GlyphCoverageTable [ mi + 1 ]; + for ( String k : keys ) { + if ( k.startsWith ( prefix ) ) { + int i = Integer.parseInt ( k.substring ( prefixLength ) ); + if ( i >= 0 ) { + gca [ i ] = coverages.get ( k ); + } + } + } + return gca; + } + private boolean hasMissingCoverage ( GlyphCoverageTable[] gca ) { + assert gca != null; + int nc = 0; + for ( int i = 0, n = gca.length; i < n; i++ ) { + if ( gca [ i ] != null ) { + nc++; + } + } + return nc != gca.length; + } + private String makeFeatureId ( int fid ) { + assert fid >= 0; + return "f" + fid; + } + private String makeLookupId ( int lid ) { + assert lid >= 0; + return "lu" + lid; + } + private void clearScripts() { + scripts.clear(); + } + private List<String> extractLanguageFeatures() { + List<String> lfl = new ArrayList<String>(languageFeatures); + clearLanguageFeatures(); + return lfl; + } + private void assertLanguageFeaturesClear() { + assert languageFeatures.size() == 0; + } + private void clearLanguageFeatures() { + languageFeatures.clear(); + } + private Map<String,List<String>> extractLanguages() { + Map<String,List<String>> lm = new HashMap ( languages ); + clearLanguages(); + return lm; + } + private void clearLanguages() { + languages.clear(); + } + private void assertFeatureLookupsClear() { + assert featureLookups.size() == 0; + } + private List extractFeatureLookups() { + List lookups = new ArrayList<String> ( featureLookups ); + clearFeatureLookups(); + return lookups; + } + private void clearFeatureLookups() { + featureLookups.clear(); + } + private void assertFeatureClear() { + assert flIndex == -1; + assert featureTag == null; + assertFeatureLookupsClear(); + } + private Object[] extractFeature() { + Object[] fa = new Object [ 2 ]; + fa[0] = featureTag; + fa[1] = extractFeatureLookups(); + clearFeature(); + return fa; + } + private void clearFeature() { + flIndex = -1; + featureTag = null; + clearFeatureLookups(); + } + private void nextFeature() { + flSequence++; + } + private void clearFeatures() { + features.clear(); + } + private void clearSubtableInLookup() { + stFormat = 0; + clearCoverages(); + } + private void clearSubtablesInLookup() { + clearSubtableInLookup(); + stSequence = 0; + } + private void clearSubtablesInTable() { + clearSubtablesInLookup(); + subtables.clear(); + } + private void nextSubtableInLookup() { + stSequence++; + clearSubtableInLookup(); + } + private void assertLookupClear() { + assert ltIndex == -1; + assert ltFlags == 0; + } + private void clearLookup() { + ltIndex = -1; + ltFlags = 0; + clearSubtablesInLookup(); + } + private Map<GlyphTable.LookupSpec,List<String>> extractLookups() { + Map<GlyphTable.LookupSpec,List<String>> lookups = new LinkedHashMap<GlyphTable.LookupSpec,List<String>>(); + for ( String st : scripts.keySet() ) { + Map<String,List<String>> lm = scripts.get ( st ); + if ( lm != null ) { + for ( String lt : lm.keySet() ) { + List<String> fids = lm.get ( lt ); + if ( fids != null ) { + for ( String fid : fids ) { + if ( fid != null ) { + Object[] fa = features.get ( fid ); + if ( fa != null ) { + assert fa.length == 2; + String ft = (String) fa[0]; + List<String> lids = (List<String>) fa[1]; + if ( ( lids != null ) && ( lids.size() > 0 ) ) { + GlyphTable.LookupSpec ls = new GlyphTable.LookupSpec ( st, lt, ft ); + lookups.put ( ls, lids ); + } + } + } + } + } + } + } + } + clearScripts(); + clearLanguages(); + clearFeatures(); + return lookups; + } + private void clearLookups() { + clearLookup(); + clearSubtablesInTable(); + ltSequence = 0; + flSequence = 0; + } + private void nextLookup() { + ltSequence++; + clearLookup(); + } + private void clearTable() { + clearLookups(); + } + private void assertSubtableClear() { + assert stFormat == 0; + assertCoverageEntriesClear(); + } + private void assertSubtablesClear() { + assertSubtableClear(); + assert subtables.size() == 0; + } + private void clearSubtableEntries() { + subtableEntries.clear(); + } + private void assertSubtableEntriesClear() { + assert subtableEntries.size() == 0; + } + private List extractSubtableEntries() { + List entries = new ArrayList ( subtableEntries ); + clearSubtableEntries(); + return entries; + } + private int[] extractAlternates() { + int[] aa = new int [ alternates.size() ]; + int i = 0; + for ( Integer a : alternates ) { + aa[i++] = (int) a; + } + clearAlternates(); + return aa; + } + private void clearAlternates() { + alternates.clear(); + } + private LigatureSet extractLigatures() { + LigatureSet ls = new LigatureSet ( ligatures ); + clearLigatures(); + return ls; + } + private void clearLigatures() { + ligatures.clear(); + } + private int[] extractSubstitutes() { + int[] aa = new int [ substitutes.size() ]; + int i = 0; + for ( Integer a : substitutes ) { + aa[i++] = (int) a; + } + clearSubstitutes(); + return aa; + } + private void clearSubstitutes() { + substitutes.clear(); + } + private List extractSequenceEntries() { + List sequences = extractSubtableEntries(); + int[][] sa = new int [ sequences.size() ] []; + int i = 0; + for ( Object s : sequences ) { + if ( s instanceof int[] ) { + sa[i++] = (int[]) s; + } + } + List entries = new ArrayList(); + entries.add ( sa ); + return entries; + } + private RuleLookup[] extractRuleLookups() { + RuleLookup[] lookups = (RuleLookup[]) ruleLookups.toArray ( new RuleLookup [ ruleLookups.size() ] ); + clearRuleLookups(); + return lookups; + } + private void clearRuleLookups() { + ruleLookups.clear(); + } + private GlyphPositioningTable.Value parseValue ( String[] en, Attributes attrs, int format ) throws SAXException { + String xPlacement = attrs.getValue ( "XPlacement" ); + int xp = 0; + if ( xPlacement != null ) { + xp = Integer.parseInt ( xPlacement ); + } else if ( ( format & GlyphPositioningTable.Value.X_PLACEMENT ) != 0 ) { + missingParameter ( en, "xPlacement" ); + } + String yPlacement = attrs.getValue ( "YPlacement" ); + int yp = 0; + if ( yPlacement != null ) { + yp = Integer.parseInt ( yPlacement ); + } else if ( ( format & GlyphPositioningTable.Value.Y_PLACEMENT ) != 0 ) { + missingParameter ( en, "yPlacement" ); + } + String xAdvance = attrs.getValue ( "XAdvance" ); + int xa = 0; + if ( xAdvance != null ) { + xa = Integer.parseInt ( xAdvance ); + } else if ( ( format & GlyphPositioningTable.Value.X_ADVANCE ) != 0 ) { + missingParameter ( en, "xAdvance" ); + } + String yAdvance = attrs.getValue ( "YAdvance" ); + int ya = 0;; + if ( yAdvance != null ) { + ya = Integer.parseInt ( yAdvance ); + } else if ( ( format & GlyphPositioningTable.Value.Y_ADVANCE ) != 0 ) { + missingParameter ( en, "yAdvance" ); + } + return new GlyphPositioningTable.Value ( xp, yp, xa, ya, null, null, null, null ); + } + private void assertPairClear() { + assert g2 == -1; + assert v1 == null; + assert v2 == null; + } + private void clearPair() { + g2 = -1; + v1 = null; + v2 = null; + } + private void assertPairsClear() { + assert pairs.size() == 0; + } + private void clearPairs() { + pairs.clear(); + psIndex = -1; + } + private PairValues[] extractPairs() { + PairValues[] pva = (PairValues[]) pairs.toArray ( new PairValues [ pairs.size() ] ); + clearPairs(); + return pva; + } + private void assertPairSetsClear() { + assert pairSets.size() == 0; + } + private void clearPairSets() { + pairSets.clear(); + } + private PairValues[][] extractPairSets() { + PairValues[][] pvm = (PairValues[][]) pairSets.toArray ( new PairValues [ pairSets.size() ][] ); + clearPairSets(); + return pvm; + } + private Anchor[] extractAnchors() { + Anchor[] aa = (Anchor[]) anchors.toArray ( new Anchor [ anchors.size() ] ); + anchors.clear(); + return aa; + } + private MarkAnchor[] extractMarkAnchors() { + MarkAnchor[] maa = new MarkAnchor [ markAnchors.size() ]; + maa = (MarkAnchor[]) markAnchors.toArray ( new MarkAnchor [ maa.length ] ); + markAnchors.clear(); + return maa; + } + private Anchor[][] extractBaseOrMarkAnchors() { + int na = baseOrMarkAnchors.size(); + int ncMax = 0; + for ( Anchor[] aa : baseOrMarkAnchors ) { + if ( aa != null ) { + int nc = aa.length; + if ( nc > ncMax ) { + ncMax = nc; + } + } + } + Anchor[][] am = new Anchor [ na ][ ncMax ]; + for ( int i = 0; i < na; i++ ) { + Anchor[] aa = baseOrMarkAnchors.get(i); + if ( aa != null ) { + for ( int j = 0; j < ncMax; j++ ) { + if ( j < aa.length ) { + am [ i ] [ j ] = aa [ j ]; + } + } + } + } + baseOrMarkAnchors.clear(); + return am; + } + private Integer computeClassCount ( Anchor[][] am ) { + int ncMax = 0; + for ( int i = 0, n = am.length; i < n; i++ ) { + Anchor[] aa = am [ i ]; + if ( aa != null ) { + int nc = aa.length; + if ( nc > ncMax ) { + ncMax = nc; + } + } + } + return Integer.valueOf ( ncMax ); + } + private Anchor[][] extractComponents() { + Anchor[][] cam = new Anchor [ components.size() ][]; + cam = (Anchor[][]) components.toArray ( new Anchor [ cam.length ][] ); + components.clear(); + return cam; + } + private Anchor[][][] extractLigatureAnchors() { + int na = ligatureAnchors.size(); + int ncMax = 0; + int nxMax = 0; + for ( Anchor[][] cm : ligatureAnchors ) { + if ( cm != null ) { + int nx = cm.length; + if ( nx > nxMax ) { + nxMax = nx; + } + for ( Anchor[] aa : cm ) { + if ( aa != null ) { + int nc = aa.length; + if ( nc > ncMax ) { + ncMax = nc; + } + } + } + + } + } + Anchor[][][] lam = new Anchor [ na ] [ nxMax ] [ ncMax ]; + for ( int i = 0; i < na; i++ ) { + Anchor[][] cm = ligatureAnchors.get(i); + if ( cm != null ) { + for ( int j = 0; j < nxMax; j++ ) { + if ( j < cm.length ) { + Anchor[] aa = cm [ j ]; + if ( aa != null ) { + for ( int k = 0; k < ncMax; k++ ) { + if ( k < aa.length ) { + lam [ i ] [ j ] [ k ] = aa [ k ]; + } + } + } + } + } + } + } + ligatureAnchors.clear(); + return lam; + } + private Integer computeLigaturesClassCount ( Anchor[][][] lam ) { + int ncMax = 0; + if ( lam != null ) { + for ( Anchor[][] cm : lam ) { + if ( cm != null ) { + for ( Anchor[] aa : cm ) { + if ( aa != null ) { + int nc = aa.length;; + if ( nc > ncMax ) { + ncMax = nc; + } + } + } + } + } + } + return Integer.valueOf ( ncMax ); + } + private Integer computeLigaturesComponentCount ( Anchor[][][] lam ) { + int nxMax = 0; + if ( lam != null ) { + for ( Anchor[][] cm : lam ) { + if ( cm != null ) { + int nx = cm.length;; + if ( nx > nxMax ) { + nxMax = nx; + } + } + } + } + return Integer.valueOf ( nxMax ); + } + private Anchor[] extractAttachmentAnchors() { + int na = attachmentAnchors.size(); + Anchor[] aa = new Anchor [ na * 2 ]; + for ( int i = 0; i < na; i++ ) { + Anchor[] ea = attachmentAnchors.get(i); + int ne = ea.length; + if ( ne > 0 ) { + aa [ ( i * 2 ) + 0 ] = ea[0]; + } + if ( ne > 1 ) { + aa [ ( i * 2 ) + 1 ] = ea[1]; + } + } + attachmentAnchors.clear(); + return aa; + } + private void addGDEFSubtable ( int stType, GlyphMappingTable mapping ) { + subtables.add ( GlyphDefinitionTable.createSubtable ( stType, makeLookupId ( ltSequence ), stSequence, ltFlags, stFormat, mapping, extractSubtableEntries() ) ); + nextSubtableInLookup(); + } + private void addGSUBSubtable ( int stType, GlyphCoverageTable coverage, List entries ) { + subtables.add ( GlyphSubstitutionTable.createSubtable ( stType, makeLookupId ( ltSequence ), stSequence, ltFlags, stFormat, coverage, entries ) ); + nextSubtableInLookup(); + } + private void addGSUBSubtable ( int stType, GlyphCoverageTable coverage ) { + addGSUBSubtable ( stType, coverage, extractSubtableEntries() ); + } + private void addGPOSSubtable ( int stType, GlyphCoverageTable coverage, List entries ) { + subtables.add ( GlyphPositioningTable.createSubtable ( stType, makeLookupId ( ltSequence ), stSequence, ltFlags, stFormat, coverage, entries ) ); + nextSubtableInLookup(); + } + private void addGPOSSubtable ( int stType, GlyphCoverageTable coverage ) { + addGPOSSubtable ( stType, coverage, extractSubtableEntries() ); + } + } + private int mapGlyphId0 ( String glyph ) { + assert glyphIds != null; + Integer gid = glyphIds.get ( glyph ); + if ( gid != null ) { + return (int) gid; + } else { + return -1; + } + } + private int mapGlyphId ( String glyph, String[] currentElement ) throws SAXException { + int g = mapGlyphId0 ( glyph ); + if ( g < 0 ) { + unsupportedGlyph ( currentElement, glyph ); + return -1; + } else { + return g; + } + } + private int[] mapGlyphIds ( String glyphs, String[] currentElement ) throws SAXException { + String[] ga = glyphs.split(","); + int[] gids = new int [ ga.length ]; + int i = 0; + for ( String glyph : ga ) { + gids[i++] = mapGlyphId ( glyph, currentElement ); + } + return gids; + } + private int mapGlyphIdToChar ( String glyph ) { + assert glyphIds != null; + Integer gid = glyphIds.get ( glyph ); + if ( gid != null ) { + if ( gmap != null ) { + Integer cid = gmap.get ( gid ); + if ( cid != null ) { + return cid.intValue(); + } + } + } + return -1; + } + private String formatLocator() { + if ( locator == null ) { + return "{null}"; + } else { + return "{" + locator.getSystemId() + ":" + locator.getLineNumber() + ":" + locator.getColumnNumber() + "}"; + } + } + private void unsupportedElement ( String[] en ) throws SAXException { + throw new SAXException ( formatLocator() + ": unsupported element " + formatExpandedName ( en ) ); + } + private void notPermittedInElementContext ( String[] en, String[] cn, Object xns ) throws SAXException { + assert en != null; + assert cn != null; + String s = "element " + formatExpandedName(en) + " not permitted in current element context " + formatExpandedName(cn); + if ( xns == null ) { + s += ", expected root context"; + } else if ( xns instanceof String[][] ) { + int nxn = 0; + s += ", expected one of { "; + for ( String[] xn : (String[][]) xns ) { + if ( nxn++ > 0 ) { + s += ", "; + } + s += formatExpandedName ( xn ); + } + s += " }"; + } else if ( xns instanceof String[] ) { + s += ", expected " + formatExpandedName ( (String[]) xns ); + } + throw new SAXException ( formatLocator() + ": " + s ); + } + private void missingRequiredAttribute ( String[] en, String name ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " missing required attribute " + name ); + } + private void duplicateGlyph ( String[] en, String name, int gid ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " contains duplicate name \"" + name + "\", with identifier value " + gid ); + } + private void unsupportedGlyph ( String[] en, String name ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " refers to unsupported glyph id \"" + name + "\"" ); + } + private void duplicateCMAPCharacter ( String[] en, int cid ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " contains duplicate cmap character code: " + CharUtilities.format ( cid ) ); + } + private void duplicateCMAPGlyph ( String[] en, int gid ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " contains duplicate cmap glyph code: " + gid ); + } + private void duplicateGlyphClass ( String[] en, String name, String glyphClass ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " contains duplicate glyph class for \"" + name + "\", with class value " + glyphClass ); + } + private void unsupportedFormat ( String[] en, int format ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " refers to unsupported table format \"" + format + "\"" ); + } + private void invalidIndex ( String[] en, int actual, int expected ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " specifies invalid index " + actual + ", expected " + expected ); + } + private void mismatchedIndex ( String[] en, String label, int actual, int expected ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " mismatched " + label + " index: got " + actual + ", expected " + expected ); + } + private void mismatchedEntries ( String[] en, int nce, int nse ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " mismatched coverage and subtable entry counts, # coverages " + nce + ", # entries " + nse ); + } + private void missingParameter ( String[] en, String label ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " missing " + label + " parameter" ); + } + private void duplicateParameter ( String[] en, String label ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " duplicate " + label + " parameter" ); + } + private void duplicateCoverageIndex ( String[] en, int index ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " duplicate coverage table index " + index ); + } + private void missingCoverage ( String[] en, String type, int expected ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " missing " + type + " coverage table, expected " + ( ( expected > 0 ) ? expected : 1 ) + " table(s)" ); + } + private void missingTag ( String[] en, String label ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " missing " + label + " tag" ); + } + private void duplicateTag ( String[] en, String label, String tag ) throws SAXException { + throw new SAXException ( formatLocator() + ": element " + formatExpandedName(en) + " duplicate " + label + " tag: " + tag ); + } + private static String[] makeExpandedName ( String uri, String localName, String qName ) { + if ( ( uri != null ) && ( uri.length() == 0 ) ) { + uri = null; + } + if ( ( localName != null ) && ( localName.length() == 0 ) ) { + localName = null; + } + if ( ( uri == null ) && ( localName == null ) ) { + uri = extractPrefix ( qName ); + localName = extractLocalName ( qName ); + } + return new String[] { uri, localName }; + } + private static String extractPrefix ( String qName ) { + String[] sa = qName.split(":"); + if ( sa.length == 2 ) { + return sa[0]; + } else { + return null; + } + } + private static String extractLocalName ( String qName ) { + String[] sa = qName.split(":"); + if ( sa.length == 2 ) { + return sa[1]; + } else if ( sa.length == 1 ) { + return sa[0]; + } else { + return null; + } + } + private static boolean sameExpandedName ( String[] n1, String[] n2 ) { + String u1 = n1[0]; + String u2 = n2[0]; + if ( ( u1 == null ) ^ ( u2 == null ) ) { + return false; + } + if ( ( u1 != null ) && ( u2 != null ) ) { + if ( ! u1.equals ( u2 ) ) { + return false; + } + } + String l1 = n1[1]; + String l2 = n2[1]; + if ( ( l1 == null ) ^ ( l2 == null ) ) { + return false; + } + if ( ( l1 != null ) && ( l2 != null ) ) { + if ( ! l1.equals ( l2 ) ) { + return false; + } + } + return true; + } + private static String formatExpandedName ( String[] n ) { + String u = ( n[0] != null ) ? n[0] : "null"; + String l = ( n[1] != null ) ? n[1] : "null"; + return "{" + u + "}" + l; + } +} diff --git a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFileTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFileTestCase.java new file mode 100644 index 000000000..b28eb49c1 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFileTestCase.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.fonts.ttx; + +import java.io.File; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class TTXFileTestCase { + + private static String ttxFilesRoot = "test/resources/complexscripts"; + + private static String[] ttxFiles = { + "arab/ttx/arab-001.ttx", + "arab/ttx/arab-002.ttx", + "arab/ttx/arab-003.ttx", + "arab/ttx/arab-004.ttx", + }; + + @Test + public void testTTXFiles() throws Exception { + for ( String tfn : ttxFiles ) { + try { + TTXFile tf = TTXFile.getFromCache ( ttxFilesRoot + File.separator + tfn ); + assertTrue ( tf != null ); + } catch ( Exception e ) { + fail ( e.getMessage() ); + } + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java new file mode 100644 index 000000000..cf5d846b4 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.scripts; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.complexscripts.scripts.arabic.ArabicTestCase; + +/** + * Test suite for script specific functionality related to complex scripts. + */ +@RunWith(Suite.class) +@SuiteClasses({ + ArabicTestCase.class +}) +public class ScriptsTestSuite { +} diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java new file mode 100644 index 000000000..ef1ea37bf --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.scripts.arabic; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.ObjectInputStream; +import java.nio.IntBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphSequence; + +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Tests for functionality related to the arabic script. + */ +public class ArabicTestCase implements ArabicTestConstants { + + @Test + public void testArabicWordForms() { + for ( String sfn : srcFiles ) { + try { + processWordForms ( new File ( datFilesDir ) ); + } catch ( Exception e ) { + fail ( e.getMessage() ); + } + } + } + + private void processWordForms ( File dfd ) { + String[] files = listWordFormFiles ( dfd ); + for ( String fn : files ) { + File dff = new File ( dfd, fn ); + processWordForms ( dff.getAbsolutePath() ); + } + } + + private String[] listWordFormFiles ( File dfd ) { + return dfd.list ( new FilenameFilter() { + public boolean accept ( File f, String name ) { + return hasPrefixFrom ( name, srcFiles ) && hasExtension ( name, WF_FILE_DAT_EXT ); + } + private boolean hasPrefixFrom ( String name, String[] prefixes ) { + for ( String p : prefixes ) { + if ( name.startsWith ( p ) ) { + return true; + } + } + return false; + } + private boolean hasExtension ( String name, String extension ) { + return name.endsWith ( "." + extension ); + } + } ); + } + + private void processWordForms ( String dpn ) { + FileInputStream fis = null; + try { + fis = new FileInputStream ( dpn ); + if ( fis != null ) { + ObjectInputStream ois = new ObjectInputStream ( fis ); + List<Object[]> data = (List<Object[]>) ois.readObject(); + if ( data != null ) { + processWordForms ( data ); + } + ois.close(); + } + } catch ( FileNotFoundException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( IOException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( Exception e ) { + throw new RuntimeException ( e.getMessage(), e ); + } finally { + if ( fis != null ) { + try { fis.close(); } catch ( Exception e ) {} + } + } + } + + private void processWordForms ( List<Object[]> data ) { + assert data != null; + assert data.size() > 0; + String script = null; + String language = null; + String tfn = null; + TTXFile tf = null; + GlyphSubstitutionTable gsub = null; + GlyphPositioningTable gpos = null; + int[] widths = null; + for ( Object[] d : data ) { + if ( script == null ) { + assert d.length >= 4; + script = (String) d[0]; + language = (String) d[1]; + tfn = (String) d[3]; + tf = TTXFile.getFromCache ( ttxFontsDir + File.separator + tfn ); + assertTrue ( tf != null ); + gsub = tf.getGSUB(); + assertTrue ( gsub != null ); + gpos = tf.getGPOS(); + assertTrue ( gpos != null ); + widths = tf.getWidths(); + assertTrue ( widths != null ); + } else { + assert tf != null; + assert gsub != null; + assert gpos != null; + assert tfn != null; + assert d.length >= 4; + String wf = (String) d[0]; + int[] iga = (int[]) d[1]; + int[] oga = (int[]) d[2]; + int[][] paa = (int[][]) d[3]; + GlyphSequence tigs = tf.mapCharsToGlyphs ( wf ); + assertSameGlyphs ( iga, getGlyphs ( tigs ), "input glyphs", wf, tfn ); + GlyphSequence togs = gsub.substitute ( tigs, script, language ); + assertSameGlyphs ( oga, getGlyphs ( togs ), "output glyphs", wf, tfn ); + int[][] tpaa = new int [ togs.getGlyphCount() ] [ 4 ]; + if ( gpos.position ( togs, script, language, 1000, widths, tpaa ) ) { + assertSameAdjustments ( paa, tpaa, wf, tfn ); + } else if ( paa != null ) { + assertEquals ( "unequal adjustment count, word form(" + wf + "), font (" + tfn + ")", paa.length, 0 ); + } + } + } + } + + private void assertSameGlyphs ( int[] expected, int[] actual, String label, String wf, String tfn ) { + assertEquals ( label + ": unequal glyph count, word form(" + wf + "), font (" + tfn + ")", expected.length, actual.length ); + for ( int i = 0, n = expected.length; i < n; i++ ) { + int e = expected[i]; + int a = actual[i]; + assertEquals ( label + ": unequal glyphs[" + i + "], word form(" + wf + "), font (" + tfn + ")", e, a ); + } + } + + private void assertSameAdjustments ( int[][] expected, int[][] actual, String wf, String tfn ) { + assertEquals ( "unequal adjustment count, word form(" + wf + "), font (" + tfn + ")", expected.length, actual.length ); + for ( int i = 0, n = expected.length; i < n; i++ ) { + int[] ea = expected[i]; + int[] aa = actual[i]; + assertEquals ( "bad adjustments length, word form(" + wf + "), font (" + tfn + ")", ea.length, aa.length ); + for ( int k = 0; k < 4; k++ ) { + int e = ea[k]; + int a = aa[k]; + assertEquals ( "unequal adjustment[" + i + "][" + k + "], word form(" + wf + "), font (" + tfn + ")", e, a ); + } + } + } + + private static int[] getGlyphs ( GlyphSequence gs ) { + IntBuffer gb = gs.getGlyphs(); + int[] ga = new int [ gb.limit() ]; + gb.rewind(); + gb.get ( ga ); + return ga; + } + +} diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java new file mode 100644 index 000000000..0669ff137 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.scripts.arabic; + +/** + * Constants for test functionality related to the arabic script. + */ +public interface ArabicTestConstants { + + final String WF_FILE_SCRIPT = "arab"; + final String WF_FILE_LANGUAGE = "dflt"; + + String srcFilesDir = "test/resources/complexscripts/arab/data"; + String datFilesDir = "test/resources/complexscripts/arab/data"; + + String[] srcFiles = { + "arab-001", // unpointed word forms + }; + + final String WF_FILE_SRC_EXT = "txt"; + final String WF_FILE_DAT_EXT = "ser"; + + String ttxFontsDir = "test/resources/complexscripts/arab/ttx"; + + String[] ttxFonts = { + "arab-001.ttx", // simplified arabic + "arab-002.ttx", // traditional arabic + "arab-003.ttx", // lateef + "arab-004.ttx", // scheherazade + }; + +} diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java new file mode 100644 index 000000000..4ae551344 --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.scripts.arabic; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.ObjectOutputStream; +import java.nio.IntBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.complexscripts.fonts.GlyphPositioningTable; +import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable; +import org.apache.fop.complexscripts.fonts.ttx.TTXFile; +import org.apache.fop.complexscripts.util.GlyphSequence; + +/** + * Tests for functionality related to the arabic script. + */ +public class GenerateArabicTestData implements ArabicTestConstants { + + public static void main ( String[] args ) { + boolean compile = false; + boolean help = false; + for ( String a : args ) { + if ( a.equals("-c") ) { + compile = true; + } + if ( a.equals("-?") ) { + help = true; + } + } + if ( help ) { + help(); + } else if ( compile ) { + compile(); + } + } + + private static void help() { + StringBuffer sb = new StringBuffer(); + sb.append ( "org.apache.fop.complexscripts.arabic.ArabicTestCase" ); + sb.append ( " [-compile]" ); + sb.append ( " [-?]" ); + System.out.println ( sb.toString() ); + } + + private static void compile() { + for ( String sfn : srcFiles ) { + try { + String spn = srcFilesDir + File.separator + sfn + "." + WF_FILE_SRC_EXT; + compile ( WF_FILE_SCRIPT, WF_FILE_LANGUAGE, spn ); + } catch ( Exception e ) { + System.err.println ( e.getMessage() ); + } + } + } + + private static void compile ( String script, String language, String spn ) { + int fno = 0; + for ( String tfn : ttxFonts ) { + TTXFile tf = TTXFile.getFromCache ( ttxFontsDir + File.separator + tfn ); + assert tf != null; + List data = compile ( script, language, spn, tfn, tf ); + output ( makeDataPathName ( spn, fno++ ), data ); + } + } + + private static List compile ( String script, String language, String spn, String tfn, TTXFile tf ) { + List<Object[]> data = new ArrayList<Object[]>(); + data.add ( new Object[] { script, language, spn, tfn } ); + GlyphSubstitutionTable gsub = tf.getGSUB(); + GlyphPositioningTable gpos = tf.getGPOS(); + int[] widths = tf.getWidths(); + if ( ( gsub != null ) && ( gpos != null ) ) { + FileInputStream fis = null; + try { + fis = new FileInputStream ( spn ); + if ( fis != null ) { + LineNumberReader lr = new LineNumberReader ( new InputStreamReader ( fis, Charset.forName ( "UTF-8" ) ) ); + String wf; + while ( ( wf = lr.readLine() ) != null ) { + GlyphSequence igs = tf.mapCharsToGlyphs ( wf ); + GlyphSequence ogs = gsub.substitute ( igs, script, language ); + int[][] paa = new int [ ogs.getGlyphCount() ] [ 4 ]; + if ( ! gpos.position ( ogs, script, language, 1000, widths, paa ) ) { + paa = null; + } + data.add ( new Object[] { wf, getGlyphs ( igs ), getGlyphs ( ogs ), paa } ); + } + lr.close(); + } + } catch ( FileNotFoundException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( IOException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( Exception e ) { + throw new RuntimeException ( e.getMessage(), e ); + } finally { + if ( fis != null ) { + try { fis.close(); } catch ( Exception e ) {} + } + } + } else { + assert gsub != null; + assert gpos != null; + } + System.err.println ( "compiled " + ( data.size() - 1 ) + " word forms using font " + tfn ); + return data; + } + + private static int[] getGlyphs ( GlyphSequence gs ) { + IntBuffer gb = gs.getGlyphs(); + int[] ga = new int [ gb.limit() ]; + gb.rewind(); + gb.get ( ga ); + return ga; + } + + private static String makeDataPathName ( String spn, int fno ) { + File f = new File ( spn ); + return datFilesDir + File.separator + stripExtension ( f.getName() ) + "-f" + fno + "." + WF_FILE_DAT_EXT; + } + + private static String stripExtension ( String s ) { + int i = s.lastIndexOf ( '.' ); + if ( i >= 0 ) { + return s.substring ( 0, i ); + } else { + return s; + } + } + + private static void output ( String dpn, List<Object[]> data ) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream ( dpn ); + if ( fos != null ) { + ObjectOutputStream oos = new ObjectOutputStream ( fos ); + oos.writeObject ( data ); + oos.close(); + } + } catch ( FileNotFoundException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( IOException e ) { + throw new RuntimeException ( e.getMessage(), e ); + } catch ( Exception e ) { + throw new RuntimeException ( e.getMessage(), e ); + } finally { + if ( fos != null ) { + try { fos.close(); } catch ( Exception e ) {} + } + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java new file mode 100644 index 000000000..385612b3a --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java @@ -0,0 +1,1564 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.util; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +// CSOFF: LineLengthCheck + +/** + * Test number converter functionality. + * + * @author Glenn Adams + */ +public class NumberConverterTestCase { + + static private String[][] formatDecimal = + { + { "1" }, + { "0", "0" }, + { "1", "1" }, + { "1000", "1000" }, + { "1000000", "1000000" }, + { "1000000000", "1000000000" }, + }; + + static private String[][] formatDecimalPadded = + { + { "001" }, + { "0", "000" }, + { "1", "001" }, + { "9", "009" }, + { "10", "010" }, + { "99", "099" }, + { "100", "100" }, + { "999", "999" }, + { "1000", "1000" }, + }; + + static private String[][] formatDecimalGrouped = + { + { "1", ",", "1" }, + { "0", "0" }, + { "1", "1" }, + { "1000", "1,0,0,0" }, + { "1000000", "1,0,0,0,0,0,0" }, + { "1000000000", "1,0,0,0,0,0,0,0,0,0" }, + }; + + static private String[][] formatDecimalGroupedPadded = + { + { "001", ",", "2" }, + { "0", "0,00" }, + { "1", "0,01" }, + { "9", "0,09" }, + { "10", "0,10" }, + { "99", "0,99" }, + { "100", "1,00" }, + { "999", "9,99" }, + { "1000", "10,00" }, + }; + + static private String[][] formatDecimalArabic = + { + { "\u0661" }, + { "0", "\u0660" }, + { "1", "\u0661" }, + { "2", "\u0662" }, + { "3", "\u0663" }, + { "4", "\u0664" }, + { "5", "\u0665" }, + { "6", "\u0666" }, + { "7", "\u0667" }, + { "8", "\u0668" }, + { "9", "\u0669" }, + { "10", "\u0661\u0660" }, + { "1000", "\u0661\u0660\u0660\u0660" }, + { "1000000", "\u0661\u0660\u0660\u0660\u0660\u0660\u0660" }, + { "1000000000", "\u0661\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660" }, + }; + + static private String[][] formatDecimalArabicPadded = + { + { "\u0660\u0660\u0661" }, + { "0", "\u0660\u0660\u0660" }, + { "1", "\u0660\u0660\u0661" }, + { "9", "\u0660\u0660\u0669" }, + { "10", "\u0660\u0661\u0660" }, + { "99", "\u0660\u0669\u0669" }, + { "100", "\u0661\u0660\u0660" }, + { "999", "\u0669\u0669\u0669" }, + { "1000", "\u0661\u0660\u0660\u0660" }, + }; + + static private String[][] formatDecimalArabicGrouped = + { + { "\u0661", "\u066c", "1" }, + { "0", "\u0660" }, + { "1", "\u0661" }, + { "1000", "\u0661\u066c\u0660\u066c\u0660\u066c\u0660" }, + { "1000000", "\u0661\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660" }, + { "1000000000", "\u0661\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660" }, + }; + + static private String[][] formatDecimalArabicGroupedPadded = + { + { "\u0660\u0660\u0661", "\u066c", "2" }, + { "0", "\u0660\u066c\u0660\u0660" }, + { "1", "\u0660\u066c\u0660\u0661" }, + { "9", "\u0660\u066c\u0660\u0669" }, + { "10", "\u0660\u066c\u0661\u0660" }, + { "99", "\u0660\u066c\u0669\u0669" }, + { "100", "\u0661\u066c\u0660\u0660" }, + { "999", "\u0669\u066c\u0669\u0669" }, + { "1000", "\u0661\u0660\u066c\u0660\u0660" }, + }; + + static private String[][] formatDecimalThai = + { + { "\u0E51" }, + { "0", "\u0E50" }, + { "1", "\u0E51" }, + { "2", "\u0E52" }, + { "3", "\u0E53" }, + { "4", "\u0E54" }, + { "5", "\u0E55" }, + { "6", "\u0E56" }, + { "7", "\u0E57" }, + { "8", "\u0E58" }, + { "9", "\u0E59" }, + { "10", "\u0E51\u0E50" }, + { "1000", "\u0E51\u0E50\u0E50\u0E50" }, + { "1000000", "\u0E51\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50" }, + { "1000000000", "\u0E51\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50" }, + }; + + static private String[][] formatDecimalThaiPadded = + { + { "\u0E50\u0E50\u0E51" }, + { "0", "\u0E50\u0E50\u0E50" }, + { "1", "\u0E50\u0E50\u0E51" }, + { "9", "\u0E50\u0E50\u0E59" }, + { "10", "\u0E50\u0E51\u0E50" }, + { "99", "\u0E50\u0E59\u0E59" }, + { "100", "\u0E51\u0E50\u0E50" }, + { "999", "\u0E59\u0E59\u0E59" }, + { "1000", "\u0E51\u0E50\u0E50\u0E50" }, + }; + + static private String[][] formatRomanLower = + { + { "i" }, + { "0", "0" }, + { "1", "i" }, + { "2", "ii" }, + { "3", "iii" }, + { "4", "iv" }, + { "5", "v" }, + { "6", "vi" }, + { "7", "vii" }, + { "8", "viii" }, + { "9", "ix" }, + { "10", "x" }, + { "20", "xx" }, + { "30", "xxx" }, + { "40", "xl" }, + { "50", "l" }, + { "60", "lx" }, + { "70", "lxx" }, + { "80", "lxxx" }, + { "90", "xc" }, + { "100", "c" }, + { "200", "cc" }, + { "300", "ccc" }, + { "400", "cd" }, + { "500", "d" }, + { "600", "dc" }, + { "700", "dcc" }, + { "800", "dccc" }, + { "900", "cm" }, + { "1000", "m" }, + { "2000", "mm" }, + { "2011", "mmxi" }, + { "4999", "mmmmcmxcix" }, + { "5000", "5000" }, + }; + + static private String[][] formatRomanUpper = + { + + { "I" }, + { "0", "0" }, + { "1", "I" }, + { "2", "II" }, + { "3", "III" }, + { "4", "IV" }, + { "5", "V" }, + { "6", "VI" }, + { "7", "VII" }, + { "8", "VIII" }, + { "9", "IX" }, + { "10", "X" }, + { "20", "XX" }, + { "30", "XXX" }, + { "40", "XL" }, + { "50", "L" }, + { "60", "LX" }, + { "70", "LXX" }, + { "80", "LXXX" }, + { "90", "XC" }, + { "100", "C" }, + { "200", "CC" }, + { "300", "CCC" }, + { "400", "CD" }, + { "500", "D" }, + { "600", "DC" }, + { "700", "DCC" }, + { "800", "DCCC" }, + { "900", "CM" }, + { "1000", "M" }, + { "2000", "MM" }, + { "2011", "MMXI" }, + { "4999", "MMMMCMXCIX" }, + { "5000", "5000" }, + }; + + static private String[][] formatRomanLargeLower = + { + { "i", null, null, null, "large" }, + { "0", "0" }, + { "1", "i" }, + { "2", "ii" }, + { "3", "iii" }, + { "4", "iv" }, + { "5", "v" }, + { "6", "vi" }, + { "7", "vii" }, + { "8", "viii" }, + { "9", "ix" }, + { "10", "x" }, + { "20", "xx" }, + { "30", "xxx" }, + { "40", "xl" }, + { "50", "l" }, + { "60", "lx" }, + { "70", "lxx" }, + { "80", "lxxx" }, + { "90", "xc" }, + { "100", "c" }, + { "200", "cc" }, + { "300", "ccc" }, + { "400", "cd" }, + { "500", "d" }, + { "600", "dc" }, + { "700", "dcc" }, + { "800", "dccc" }, + { "900", "cm" }, + { "1000", "m" }, + { "2000", "mm" }, + { "2011", "mmxi" }, + { "4999", "\u2180\u2181cmxcix" }, + { "5000", "\u2181" }, + { "5001", "\u2181i" }, + { "9999", "\u2180\u2182cmxcix" }, + { "10000", "\u2182" }, + { "10001", "\u2182i" }, + { "49999", "\u2182\u2187\u2180\u2182cmxcix" }, + { "99999", "\u2182\u2188\u2180\u2182cmxcix" }, + { "100000", "\u2188" }, + { "100001", "\u2188i" }, + { "199999", "\u2188\u2182\u2188\u2180\u2182cmxcix" }, + { "200000", "200000" }, + }; + + static private String[][] formatRomanLargeUpper = + { + { "I", null, null, null, "large" }, + { "0", "0" }, + { "1", "I" }, + { "2", "II" }, + { "3", "III" }, + { "4", "IV" }, + { "5", "V" }, + { "6", "VI" }, + { "7", "VII" }, + { "8", "VIII" }, + { "9", "IX" }, + { "10", "X" }, + { "20", "XX" }, + { "30", "XXX" }, + { "40", "XL" }, + { "50", "L" }, + { "60", "LX" }, + { "70", "LXX" }, + { "80", "LXXX" }, + { "90", "XC" }, + { "100", "C" }, + { "200", "CC" }, + { "300", "CCC" }, + { "400", "CD" }, + { "500", "D" }, + { "600", "DC" }, + { "700", "DCC" }, + { "800", "DCCC" }, + { "900", "CM" }, + { "1000", "M" }, + { "2000", "MM" }, + { "2011", "MMXI" }, + { "4999", "\u2180\u2181CMXCIX" }, + { "5000", "\u2181" }, + { "5001", "\u2181I" }, + { "9999", "\u2180\u2182CMXCIX" }, + { "10000", "\u2182" }, + { "10001", "\u2182I" }, + { "49999", "\u2182\u2187\u2180\u2182CMXCIX" }, + { "99999", "\u2182\u2188\u2180\u2182CMXCIX" }, + { "100000", "\u2188" }, + { "100001", "\u2188I" }, + { "199999", "\u2188\u2182\u2188\u2180\u2182CMXCIX" }, + { "200000", "200000" }, + }; + + static private String[][] formatRomanNumberFormsLower = + { + { "i", null, null, null, "unicode-number-forms" }, + { "0", "0" }, + { "1", "\u2170" }, + { "2", "\u2171" }, + { "3", "\u2172" }, + { "4", "\u2173" }, + { "5", "\u2174" }, + { "6", "\u2175" }, + { "7", "\u2176" }, + { "8", "\u2177" }, + { "9", "\u2178" }, + { "10", "\u2179" }, + { "11", "\u2179\u2170" }, + { "12", "\u2179\u2171" }, + { "13", "\u2179\u2172" }, + { "14", "\u2179\u2173" }, + { "15", "\u2179\u2174" }, + { "16", "\u2179\u2175" }, + { "17", "\u2179\u2176" }, + { "18", "\u2179\u2177" }, + { "19", "\u2179\u2178" }, + { "20", "\u2179\u2179" }, + { "30", "\u2179\u2179\u2179" }, + { "40", "\u2179\u217C" }, + { "50", "\u217C" }, + { "60", "\u217C\u2179" }, + { "70", "\u217C\u2179\u2179" }, + { "80", "\u217C\u2179\u2179\u2179" }, + { "90", "\u2179\u217D" }, + { "100", "\u217D" }, + { "200", "\u217D\u217D" }, + { "300", "\u217D\u217D\u217D" }, + { "400", "\u217D\u217E" }, + { "500", "\u217E" }, + { "600", "\u217E\u217D" }, + { "700", "\u217E\u217D\u217D" }, + { "800", "\u217E\u217D\u217D\u217D" }, + { "900", "\u217D\u217F" }, + { "999", "\u217D\u217F\u2179\u217D\u2178" }, + { "1000", "\u217F" }, + { "2000", "\u217F\u217F" }, + { "2011", "\u217F\u217F\u2179\u2170" }, + { "4999", "\u2180\u2181\u217D\u217F\u2179\u217D\u2178" }, + { "5000", "\u2181" }, + { "5001", "\u2181\u2170" }, + { "9999", "\u2180\u2182\u217D\u217F\u2179\u217D\u2178" }, + { "10000", "\u2182" }, + { "10001", "\u2182\u2170" }, + { "49999", "\u2182\u2187\u2180\u2182\u217D\u217F\u2179\u217D\u2178" }, + { "99999", "\u2182\u2188\u2180\u2182\u217D\u217F\u2179\u217D\u2178" }, + { "100000", "\u2188" }, + { "100001", "\u2188\u2170" }, + { "199999", "\u2188\u2182\u2188\u2180\u2182\u217D\u217F\u2179\u217D\u2178" }, + { "200000", "200000" }, + }; + + static private String[][] formatRomanNumberFormsUpper = + { + { "I", null, null, null, "unicode-number-forms" }, + { "0", "0" }, + { "1", "\u2160" }, + { "2", "\u2161" }, + { "3", "\u2162" }, + { "4", "\u2163" }, + { "5", "\u2164" }, + { "6", "\u2165" }, + { "7", "\u2166" }, + { "8", "\u2167" }, + { "9", "\u2168" }, + { "10", "\u2169" }, + { "11", "\u2169\u2160" }, + { "12", "\u2169\u2161" }, + { "13", "\u2169\u2162" }, + { "14", "\u2169\u2163" }, + { "15", "\u2169\u2164" }, + { "16", "\u2169\u2165" }, + { "17", "\u2169\u2166" }, + { "18", "\u2169\u2167" }, + { "19", "\u2169\u2168" }, + { "20", "\u2169\u2169" }, + { "30", "\u2169\u2169\u2169" }, + { "40", "\u2169\u216C" }, + { "50", "\u216C" }, + { "60", "\u216C\u2169" }, + { "70", "\u216C\u2169\u2169" }, + { "80", "\u216C\u2169\u2169\u2169" }, + { "90", "\u2169\u216D" }, + { "100", "\u216D" }, + { "200", "\u216D\u216D" }, + { "300", "\u216D\u216D\u216D" }, + { "400", "\u216D\u216E" }, + { "500", "\u216E" }, + { "600", "\u216E\u216D" }, + { "700", "\u216E\u216D\u216D" }, + { "800", "\u216E\u216D\u216D\u216D" }, + { "900", "\u216D\u216F" }, + { "999", "\u216D\u216F\u2169\u216D\u2168" }, + { "1000", "\u216F" }, + { "2000", "\u216F\u216F" }, + { "2011", "\u216F\u216F\u2169\u2160" }, + { "4999", "\u2180\u2181\u216D\u216F\u2169\u216D\u2168" }, + { "5000", "\u2181" }, + { "5001", "\u2181\u2160" }, + { "9999", "\u2180\u2182\u216D\u216F\u2169\u216D\u2168" }, + { "10000", "\u2182" }, + { "10001", "\u2182\u2160" }, + { "49999", "\u2182\u2187\u2180\u2182\u216D\u216F\u2169\u216D\u2168" }, + { "99999", "\u2182\u2188\u2180\u2182\u216D\u216F\u2169\u216D\u2168" }, + { "100000", "\u2188" }, + { "100001", "\u2188\u2160" }, + { "199999", "\u2188\u2182\u2188\u2180\u2182\u216D\u216F\u2169\u216D\u2168" }, + { "200000", "200000" }, + }; + + static private String[][] formatAlphabeticLatinLower = + { + { "a" }, + { "0", "0" }, + { "1", "a" }, + { "2", "b" }, + { "3", "c" }, + { "10", "j" }, + { "20", "t" }, + { "26", "z" }, + { "27", "aa" }, + { "28", "ab" }, + { "29", "ac" }, + { "52", "az" }, + { "53", "ba" }, + { "702", "zz" }, + { "703", "aaa" }, + { "999999", "bdwgm" }, + { "1000000", "bdwgn" }, + }; + + static private String[][] formatAlphabeticLatinUpper = + { + { "A" }, + { "0", "0" }, + { "1", "A" }, + { "2", "B" }, + { "3", "C" }, + { "10", "J" }, + { "20", "T" }, + { "26", "Z" }, + { "27", "AA" }, + { "28", "AB" }, + { "29", "AC" }, + { "52", "AZ" }, + { "53", "BA" }, + { "702", "ZZ" }, + { "703", "AAA" }, + { "999999", "BDWGM" }, + { "1000000", "BDWGN" }, + }; + + static private String[][] formatAlphabeticArabicHijai = + { + { "\u0627", null, null, "alphabetic" }, + { "0", "0" }, + { "1", "\u0623" }, + { "2", "\u0628" }, + { "3", "\u062A" }, + { "4", "\u062B" }, + { "5", "\u062C" }, + { "6", "\u062D" }, + { "7", "\u062E" }, + { "8", "\u062F" }, + { "9", "\u0630" }, + { "10", "\u0631" }, + { "11", "\u0632" }, + { "12", "\u0633" }, + { "13", "\u0634" }, + { "14", "\u0635" }, + { "15", "\u0636" }, + { "16", "\u0637" }, + { "17", "\u0638" }, + { "18", "\u0639" }, + { "19", "\u063A" }, + { "20", "\u0641" }, + { "21", "\u0642" }, + { "22", "\u0643" }, + { "23", "\u0644" }, + { "24", "\u0645" }, + { "25", "\u0646" }, + { "26", "\u0647" }, + { "27", "\u0648" }, + { "28", "\u0649" }, + { "29", "\u0623\u0623" }, + { "56", "\u0623\u0649" }, + { "57", "\u0628\u0623" }, + { "812", "\u0649\u0649" }, + { "813", "\u0623\u0623\u0623" }, + { "999999", "\u0623\u0638\u0636\u0635\u062E" }, + { "1000000", "\u0623\u0638\u0636\u0635\u062F" }, + }; + + static private String[][] formatAlphabeticArabicAbjadi = + { + { "\u0627", null, null, "traditional" }, + { "0", "0" }, + { "1", "\u0623" }, + { "2", "\u0628" }, + { "3", "\u062C" }, + { "4", "\u062F" }, + { "5", "\u0647" }, + { "6", "\u0648" }, + { "7", "\u0632" }, + { "8", "\u062D" }, + { "9", "\u0637" }, + { "10", "\u0649" }, + { "11", "\u0643" }, + { "12", "\u0644" }, + { "13", "\u0645" }, + { "14", "\u0646" }, + { "15", "\u0633" }, + { "16", "\u0639" }, + { "17", "\u0641" }, + { "18", "\u0635" }, + { "19", "\u0642" }, + { "20", "\u0631" }, + { "21", "\u0634" }, + { "22", "\u062A" }, + { "23", "\u062B" }, + { "24", "\u062E" }, + { "25", "\u0630" }, + { "26", "\u0636" }, + { "27", "\u0638" }, + { "28", "\u063A" }, + { "29", "\u0623\u0623" }, + { "56", "\u0623\u063A" }, + { "57", "\u0628\u0623" }, + { "812", "\u063A\u063A" }, + { "813", "\u0623\u0623\u0623" }, + { "999999", "\u0623\u0641\u0633\u0646\u0632" }, + { "1000000", "\u0623\u0641\u0633\u0646\u062D" }, + }; + + static private String[][] formatNumeralArabicAbjadi = + { + { "\u0623", null, null, "traditional" }, + { "0", "0" }, + { "1", "\u0623" }, + { "2", "\u0628" }, + { "3", "\u062C" }, + { "4", "\u062F" }, + { "5", "\u0647" }, + { "6", "\u0648" }, + { "7", "\u0632" }, + { "8", "\u062D" }, + { "9", "\u0637" }, + { "10", "\u0649" }, + { "11", "\u0649\u0623" }, + { "12", "\u0649\u0628" }, + { "13", "\u0649\u062C" }, + { "14", "\u0649\u062F" }, + { "15", "\u0649\u0647" }, + { "16", "\u0649\u0648" }, + { "17", "\u0649\u0632" }, + { "18", "\u0649\u062D" }, + { "19", "\u0649\u0637" }, + { "20", "\u0643" }, + { "30", "\u0644" }, + { "40", "\u0645" }, + { "50", "\u0646" }, + { "60", "\u0633" }, + { "70", "\u0639" }, + { "80", "\u0641" }, + { "90", "\u0635" }, + { "99", "\u0635\u0637" }, + { "100", "\u0642" }, + { "101", "\u0642\u0623" }, + { "200", "\u0631" }, + { "300", "\u0634" }, + { "400", "\u062A" }, + { "500", "\u062B" }, + { "600", "\u062E" }, + { "700", "\u0630" }, + { "800", "\u0636" }, + { "900", "\u0638" }, + { "999", "\u0638\u0635\u0637" }, + { "1000", "\u063A" }, + { "1999", "\u063A\u0638\u0635\u0637" }, + { "2000", "2000" }, + }; + + static private String[][] formatAlphabeticHebrew = + { + { "\u05D0", null, null, "alphabetic" }, + { "0", "0" }, + { "1", "\u05D0" }, + { "2", "\u05D1" }, + { "3", "\u05D2" }, + { "4", "\u05D3" }, + { "5", "\u05D4" }, + { "6", "\u05D5" }, + { "7", "\u05D6" }, + { "8", "\u05D7" }, + { "9", "\u05D8" }, + { "10", "\u05D9" }, + { "11", "\u05DB" }, + { "12", "\u05DC" }, + { "13", "\u05DE" }, + { "14", "\u05E0" }, + { "15", "\u05E1" }, + { "16", "\u05E2" }, + { "17", "\u05E4" }, + { "18", "\u05E6" }, + { "19", "\u05E7" }, + { "20", "\u05E8" }, + { "21", "\u05E9" }, + { "22", "\u05EA" }, + { "23", "\u05DA" }, + { "24", "\u05DD" }, + { "25", "\u05DF" }, + { "26", "\u05E3" }, + { "27", "\u05E5" }, + { "28", "\u05D0\u05D0" }, + { "54", "\u05D0\u05E5" }, + { "55", "\u05D1\u05D0" }, + { "756", "\u05E5\u05E5" }, + { "757", "\u05D0\u05D0\u05D0" }, + { "999999", "\u05D0\u05DA\u05E9\u05E7\u05E5" }, + { "1000000", "\u05D0\u05DA\u05E9\u05E8\u05D0" }, + }; + + static private String[][] formatNumeralHebrewGematria = + { + { "\u05D0", null, null, "traditional" }, + { "0", "0" }, + { "1", "\u05D0" }, + { "2", "\u05D1" }, + { "3", "\u05D2" }, + { "4", "\u05D3" }, + { "5", "\u05D4" }, + { "6", "\u05D5" }, + { "7", "\u05D6" }, + { "8", "\u05D7" }, + { "9", "\u05D8" }, + { "10", "\u05D9" }, + { "11", "\u05D9\u05D0" }, + { "12", "\u05D9\u05D1" }, + { "13", "\u05D9\u05D2" }, + { "14", "\u05D9\u05D3" }, + { "15", "\u05D8\u05F4\u05D5" }, + { "16", "\u05D8\u05F4\u05D6" }, + { "17", "\u05D9\u05D6" }, + { "18", "\u05D9\u05D7" }, + { "19", "\u05D9\u05D8" }, + { "20", "\u05DB" }, + { "30", "\u05DC" }, + { "40", "\u05DE" }, + { "50", "\u05E0" }, + { "60", "\u05E1" }, + { "70", "\u05E2" }, + { "80", "\u05E4" }, + { "90", "\u05E6" }, + { "99", "\u05E6\u05D8" }, + { "100", "\u05E7" }, + { "101", "\u05E7\u05D0" }, + { "200", "\u05E8" }, + { "300", "\u05E9" }, + { "400", "\u05EA" }, + { "500", "\u05EA\u05F4\u05E7" }, + { "600", "\u05EA\u05F4\u05E8" }, + { "700", "\u05EA\u05F4\u05E9" }, + { "800", "\u05EA\u05F4\u05EA" }, + { "900", "\u05EA\u05EA\u05F4\u05E7" }, + { "999", "\u05EA\u05EA\u05F4\u05E7\u05E6\u05D8" }, + { "1000", "\u05D0\u05F3" }, + { "1999", "\u05D0\u05F3\u05EA\u05EA\u05F4\u05E7\u05E6\u05D8" }, + { "2000", "2000" }, + }; + + static private String[][] formatAlphabeticThai = + { + { "\u0E01", null, null, "alphabetic" }, + { "0", "0" }, + { "1", "\u0E01" }, + { "2", "\u0E02" }, + { "3", "\u0E03" }, + { "10", "\u0E0A" }, + { "20", "\u0E14" }, + { "30", "\u0E1E" }, + { "40", "\u0E2A" }, + { "44", "\u0E2E" }, + { "45", "\u0E01\u0E01" }, + { "88", "\u0E01\u0E2E" }, + { "89", "\u0E02\u0E01" }, + { "1980", "\u0E2E\u0E2E" }, + { "1981", "\u0E01\u0E01\u0E01" }, + { "999999", "\u0E0B\u0E20\u0E17\u0E0B" }, + { "1000000", "\u0E0B\u0E20\u0E17\u0E0C" }, + }; + + static private String[][] formatWordEnglishLower = + { + { "w", null, null, null, null, "eng" }, + { "0", "zero" }, + { "1", "one" }, + { "2", "two" }, + { "3", "three" }, + { "4", "four" }, + { "5", "five" }, + { "6", "six" }, + { "7", "seven" }, + { "8", "eight" }, + { "9", "nine" }, + { "10", "ten" }, + { "99", "ninety nine" }, + { "100", "one hundred" }, + { "999", "nine hundred ninety nine" }, + { "1000", "one thousand" }, + { "999999", "nine hundred ninety nine thousand nine hundred ninety nine" }, + { "1000000", "one million" }, + { "999999999", "nine hundred ninety nine million nine hundred ninety nine thousand nine hundred ninety nine" }, + { "1000000000", "one billion" } + }; + + static private String[][] formatWordEnglishUpper = + { + { "W", null, null, null, null, "eng" }, + { "0", "ZERO" }, + { "1", "ONE" }, + { "2", "TWO" }, + { "3", "THREE" }, + { "4", "FOUR" }, + { "5", "FIVE" }, + { "6", "SIX" }, + { "7", "SEVEN" }, + { "8", "EIGHT" }, + { "9", "NINE" }, + { "10", "TEN" }, + { "99", "NINETY NINE" }, + { "100", "ONE HUNDRED" }, + { "999", "NINE HUNDRED NINETY NINE" }, + { "1000", "ONE THOUSAND" }, + { "999999", "NINE HUNDRED NINETY NINE THOUSAND NINE HUNDRED NINETY NINE" }, + { "1000000", "ONE MILLION" }, + { "999999999", "NINE HUNDRED NINETY NINE MILLION NINE HUNDRED NINETY NINE THOUSAND NINE HUNDRED NINETY NINE" }, + { "1000000000", "ONE BILLION" } + }; + + static private String[][] formatWordEnglishTitle = + { + { "Ww", null, null, null, null, "eng" }, + { "0", "Zero" }, + { "1", "One" }, + { "2", "Two" }, + { "3", "Three" }, + { "4", "Four" }, + { "5", "Five" }, + { "6", "Six" }, + { "7", "Seven" }, + { "8", "Eight" }, + { "9", "Nine" }, + { "10", "Ten" }, + { "99", "Ninety Nine" }, + { "100", "One Hundred" }, + { "999", "Nine Hundred Ninety Nine" }, + { "1000", "One Thousand" }, + { "999999", "Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine" }, + { "1000000", "One Million" }, + { "999999999", "Nine Hundred Ninety Nine Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine" }, + { "1000000000", "One Billion" } + }; + + static private String[][] formatWordSpanishLower = + { + { "w", null, null, null, null, "spa" }, + { "0", "cero" }, + { "1", "uno" }, + { "2", "dos" }, + { "3", "tres" }, + { "4", "cuatro" }, + { "5", "cinco" }, + { "6", "seise" }, + { "7", "siete" }, + { "8", "ocho" }, + { "9", "nueve" }, + { "10", "diez" }, + { "11", "once" }, + { "12", "doce" }, + { "13", "trece" }, + { "14", "catorce" }, + { "15", "quince" }, + { "16", "diecis\u00e9is" }, + { "17", "diecisiete" }, + { "18", "dieciocho" }, + { "19", "diecinueve" }, + { "20", "veinte" }, + { "21", "veintiuno" }, + { "22", "veintid\u00f3s" }, + { "23", "veintitr\u00e9s" }, + { "24", "veinticuatro" }, + { "25", "veinticinco" }, + { "26", "veintis\u00e9is" }, + { "27", "veintisiete" }, + { "28", "veintiocho" }, + { "29", "veintinueve" }, + { "30", "treinta" }, + { "31", "treinta y uno" }, + { "32", "treinta y dos" }, + { "40", "cuarenta" }, + { "41", "cuarenta y uno" }, + { "42", "cuarenta y dos" }, + { "50", "cincuenta" }, + { "51", "cincuenta y uno" }, + { "52", "cincuenta y dos" }, + { "60", "sesenta" }, + { "61", "sesenta y uno" }, + { "62", "sesenta y dos" }, + { "70", "setenta" }, + { "71", "setenta y uno" }, + { "72", "setenta y dos" }, + { "80", "ochenta" }, + { "81", "ochenta y uno" }, + { "82", "ochenta y dos" }, + { "90", "noventa" }, + { "91", "noventa y uno" }, + { "92", "noventa y dos" }, + { "99", "noventa y nueve" }, + { "100", "cien" }, + { "101", "ciento uno" }, + { "102", "ciento dos" }, + { "200", "doscientos" }, + { "300", "trescientos" }, + { "400", "cuatrocientos" }, + { "500", "quinientos" }, + { "600", "seiscientos" }, + { "700", "setecientos" }, + { "800", "ochocientos" }, + { "900", "novecientos" }, + { "999", "novecientos noventa y nueve" }, + { "1000", "mil" }, + { "1001", "mil uno" }, + { "1002", "mil dos" }, + { "2000", "dos mil" }, + { "2001", "dos mil uno" }, + { "100000", "cien mil" }, + { "100001", "cien mil uno" }, + { "999999", "novecientos noventa y nueve mil novecientos noventa y nueve" }, + { "1000000", "un mill\u00f3n" }, + { "999999999", "novecientos noventa y nueve millones novecientos noventa y nueve mil novecientos noventa y nueve" }, + { "1000000000", "mil millones" } + }; + + static private String[][] formatWordSpanishUpper = + { + { "W", null, null, null, null, "spa" }, + { "0", "CERO" }, + { "1", "UNO" }, + { "2", "DOS" }, + { "3", "TRES" }, + { "4", "CUATRO" }, + { "5", "CINCO" }, + { "6", "SEISE" }, + { "7", "SIETE" }, + { "8", "OCHO" }, + { "9", "NUEVE" }, + { "10", "DIEZ" }, + { "11", "ONCE" }, + { "12", "DOCE" }, + { "13", "TRECE" }, + { "14", "CATORCE" }, + { "15", "QUINCE" }, + { "16", "DIECIS\u00c9IS" }, + { "17", "DIECISIETE" }, + { "18", "DIECIOCHO" }, + { "19", "DIECINUEVE" }, + { "20", "VEINTE" }, + { "21", "VEINTIUNO" }, + { "22", "VEINTID\u00d3S" }, + { "23", "VEINTITR\u00c9S" }, + { "24", "VEINTICUATRO" }, + { "25", "VEINTICINCO" }, + { "26", "VEINTIS\u00c9IS" }, + { "27", "VEINTISIETE" }, + { "28", "VEINTIOCHO" }, + { "29", "VEINTINUEVE" }, + { "30", "TREINTA" }, + { "31", "TREINTA Y UNO" }, + { "32", "TREINTA Y DOS" }, + { "40", "CUARENTA" }, + { "41", "CUARENTA Y UNO" }, + { "42", "CUARENTA Y DOS" }, + { "50", "CINCUENTA" }, + { "51", "CINCUENTA Y UNO" }, + { "52", "CINCUENTA Y DOS" }, + { "60", "SESENTA" }, + { "61", "SESENTA Y UNO" }, + { "62", "SESENTA Y DOS" }, + { "70", "SETENTA" }, + { "71", "SETENTA Y UNO" }, + { "72", "SETENTA Y DOS" }, + { "80", "OCHENTA" }, + { "81", "OCHENTA Y UNO" }, + { "82", "OCHENTA Y DOS" }, + { "90", "NOVENTA" }, + { "91", "NOVENTA Y UNO" }, + { "92", "NOVENTA Y DOS" }, + { "99", "NOVENTA Y NUEVE" }, + { "100", "CIEN" }, + { "101", "CIENTO UNO" }, + { "102", "CIENTO DOS" }, + { "200", "DOSCIENTOS" }, + { "300", "TRESCIENTOS" }, + { "400", "CUATROCIENTOS" }, + { "500", "QUINIENTOS" }, + { "600", "SEISCIENTOS" }, + { "700", "SETECIENTOS" }, + { "800", "OCHOCIENTOS" }, + { "900", "NOVECIENTOS" }, + { "999", "NOVECIENTOS NOVENTA Y NUEVE" }, + { "1000", "MIL" }, + { "1001", "MIL UNO" }, + { "1002", "MIL DOS" }, + { "2000", "DOS MIL" }, + { "2001", "DOS MIL UNO" }, + { "100000", "CIEN MIL" }, + { "100001", "CIEN MIL UNO" }, + { "999999", "NOVECIENTOS NOVENTA Y NUEVE MIL NOVECIENTOS NOVENTA Y NUEVE" }, + { "1000000", "UN MILL\u00d3N" }, + { "999999999", "NOVECIENTOS NOVENTA Y NUEVE MILLONES NOVECIENTOS NOVENTA Y NUEVE MIL NOVECIENTOS NOVENTA Y NUEVE" }, + { "1000000000", "MIL MILLONES" } + }; + + static private String[][] formatWordSpanishTitle = + { + { "Ww", null, null, null, null, "spa" }, + { "0", "Cero" }, + { "1", "Uno" }, + { "2", "Dos" }, + { "3", "Tres" }, + { "4", "Cuatro" }, + { "5", "Cinco" }, + { "6", "Seise" }, + { "7", "Siete" }, + { "8", "Ocho" }, + { "9", "Nueve" }, + { "10", "Diez" }, + { "11", "Once" }, + { "12", "Doce" }, + { "13", "Trece" }, + { "14", "Catorce" }, + { "15", "Quince" }, + { "16", "Diecis\u00e9is" }, + { "17", "Diecisiete" }, + { "18", "Dieciocho" }, + { "19", "Diecinueve" }, + { "20", "Veinte" }, + { "21", "Veintiuno" }, + { "22", "Veintid\u00f3s" }, + { "23", "Veintitr\u00e9s" }, + { "24", "Veinticuatro" }, + { "25", "Veinticinco" }, + { "26", "Veintis\u00e9is" }, + { "27", "Veintisiete" }, + { "28", "Veintiocho" }, + { "29", "Veintinueve" }, + { "30", "Treinta" }, + { "31", "Treinta Y Uno" }, + { "32", "Treinta Y Dos" }, + { "40", "Cuarenta" }, + { "41", "Cuarenta Y Uno" }, + { "42", "Cuarenta Y Dos" }, + { "50", "Cincuenta" }, + { "51", "Cincuenta Y Uno" }, + { "52", "Cincuenta Y Dos" }, + { "60", "Sesenta" }, + { "61", "Sesenta Y Uno" }, + { "62", "Sesenta Y Dos" }, + { "70", "Setenta" }, + { "71", "Setenta Y Uno" }, + { "72", "Setenta Y Dos" }, + { "80", "Ochenta" }, + { "81", "Ochenta Y Uno" }, + { "82", "Ochenta Y Dos" }, + { "90", "Noventa" }, + { "91", "Noventa Y Uno" }, + { "92", "Noventa Y Dos" }, + { "99", "Noventa Y Nueve" }, + { "100", "Cien" }, + { "101", "Ciento Uno" }, + { "102", "Ciento Dos" }, + { "200", "Doscientos" }, + { "300", "Trescientos" }, + { "400", "Cuatrocientos" }, + { "500", "Quinientos" }, + { "600", "Seiscientos" }, + { "700", "Setecientos" }, + { "800", "Ochocientos" }, + { "900", "Novecientos" }, + { "999", "Novecientos Noventa Y Nueve" }, + { "1000", "Mil" }, + { "1001", "Mil Uno" }, + { "1002", "Mil Dos" }, + { "2000", "Dos Mil" }, + { "2001", "Dos Mil Uno" }, + { "100000", "Cien Mil" }, + { "100001", "Cien Mil Uno" }, + { "999999", "Novecientos Noventa Y Nueve Mil Novecientos Noventa Y Nueve" }, + { "1000000", "Un Mill\u00f3n" }, + { "999999999", "Novecientos Noventa Y Nueve Millones Novecientos Noventa Y Nueve Mil Novecientos Noventa Y Nueve" }, + { "1000000000", "Mil Millones" } + }; + + static private String[][] formatWordFrenchLower = + { + { "w", null, null, null, null, "fra" }, + { "0", "z\u00e9ro" }, + { "1", "un" }, + { "2", "deux" }, + { "3", "trois" }, + { "4", "quatre" }, + { "5", "cinq" }, + { "6", "six" }, + { "7", "sept" }, + { "8", "huit" }, + { "9", "neuf" }, + { "10", "dix" }, + { "11", "onze" }, + { "12", "douze" }, + { "13", "treize" }, + { "14", "quatorze" }, + { "15", "quinze" }, + { "16", "seize" }, + { "17", "dix-sept" }, + { "18", "dix-huit" }, + { "19", "dix-neuf" }, + { "20", "vingt" }, + { "21", "vingt et un" }, + { "22", "vingt-deux" }, + { "23", "vingt-trois" }, + { "24", "vingt-quatre" }, + { "25", "vingt-cinq" }, + { "26", "vingt-six" }, + { "27", "vingt-sept" }, + { "28", "vingt-huit" }, + { "29", "vingt-neuf" }, + { "30", "trente" }, + { "31", "trente et un" }, + { "32", "trente-deux" }, + { "40", "quarante" }, + { "41", "quarante et un" }, + { "42", "quarante-deux" }, + { "50", "cinquante" }, + { "51", "cinquante et un" }, + { "52", "cinquante-deux" }, + { "60", "soixante" }, + { "61", "soixante et un" }, + { "62", "soixante-deux" }, + { "70", "soixante-dix" }, + { "71", "soixante et onze" }, + { "72", "soixante-douze" }, + { "79", "soixante-dix-neuf" }, + { "80", "quatre-vingts" }, + { "81", "quatre-vingt-un" }, + { "82", "quatre-vingt-deux" }, + { "89", "quatre-vingt-neuf" }, + { "90", "quatre-vingt-dix" }, + { "91", "quatre-vingt-onze" }, + { "92", "quatre-vingt-douze" }, + { "99", "quatre-vingt-dix-neuf" }, + { "100", "cent" }, + { "101", "cent un" }, + { "102", "cent deux" }, + { "200", "deux cents" }, + { "201", "deux cent un" }, + { "202", "deux cent deux" }, + { "300", "trois cents" }, + { "301", "trois cent un" }, + { "400", "quatre cents" }, + { "401", "quatre cent un" }, + { "500", "cinq cents" }, + { "501", "cinq cent un" }, + { "600", "six cents" }, + { "601", "six cent un" }, + { "700", "sept cents" }, + { "701", "sept cent un" }, + { "800", "huit cents" }, + { "801", "huit cent un" }, + { "900", "neuf cents" }, + { "901", "neuf cent un" }, + { "999", "neuf cent quatre-vingt-dix-neuf" }, + { "1000", "mille" }, + { "1001", "mille un" }, + { "1002", "mille deux" }, + { "2000", "deux mille" }, + { "2001", "deux mille un" }, + { "100000", "cent mille" }, + { "100001", "cent mille un" }, + { "999999", "neuf cent quatre-vingt-dix-neuf mille neuf cent quatre-vingt-dix-neuf" }, + { "1000000", "un million" }, + { "999999999", "neuf cent quatre-vingt-dix-neuf millions neuf cent quatre-vingt-dix-neuf mille neuf cent quatre-vingt-dix-neuf" }, + { "1000000000", "un milliard" } + }; + + static private String[][] formatWordFrenchUpper = + { + { "W", null, null, null, null, "fra" }, + { "0", "Z\u00c9RO" }, + { "1", "UN" }, + { "2", "DEUX" }, + { "3", "TROIS" }, + { "4", "QUATRE" }, + { "5", "CINQ" }, + { "6", "SIX" }, + { "7", "SEPT" }, + { "8", "HUIT" }, + { "9", "NEUF" }, + { "10", "DIX" }, + { "11", "ONZE" }, + { "12", "DOUZE" }, + { "13", "TREIZE" }, + { "14", "QUATORZE" }, + { "15", "QUINZE" }, + { "16", "SEIZE" }, + { "17", "DIX-SEPT" }, + { "18", "DIX-HUIT" }, + { "19", "DIX-NEUF" }, + { "20", "VINGT" }, + { "21", "VINGT ET UN" }, + { "22", "VINGT-DEUX" }, + { "23", "VINGT-TROIS" }, + { "24", "VINGT-QUATRE" }, + { "25", "VINGT-CINQ" }, + { "26", "VINGT-SIX" }, + { "27", "VINGT-SEPT" }, + { "28", "VINGT-HUIT" }, + { "29", "VINGT-NEUF" }, + { "30", "TRENTE" }, + { "31", "TRENTE ET UN" }, + { "32", "TRENTE-DEUX" }, + { "40", "QUARANTE" }, + { "41", "QUARANTE ET UN" }, + { "42", "QUARANTE-DEUX" }, + { "50", "CINQUANTE" }, + { "51", "CINQUANTE ET UN" }, + { "52", "CINQUANTE-DEUX" }, + { "60", "SOIXANTE" }, + { "61", "SOIXANTE ET UN" }, + { "62", "SOIXANTE-DEUX" }, + { "70", "SOIXANTE-DIX" }, + { "71", "SOIXANTE ET ONZE" }, + { "72", "SOIXANTE-DOUZE" }, + { "79", "SOIXANTE-DIX-NEUF" }, + { "80", "QUATRE-VINGTS" }, + { "81", "QUATRE-VINGT-UN" }, + { "82", "QUATRE-VINGT-DEUX" }, + { "89", "QUATRE-VINGT-NEUF" }, + { "90", "QUATRE-VINGT-DIX" }, + { "91", "QUATRE-VINGT-ONZE" }, + { "92", "QUATRE-VINGT-DOUZE" }, + { "99", "QUATRE-VINGT-DIX-NEUF" }, + { "100", "CENT" }, + { "101", "CENT UN" }, + { "102", "CENT DEUX" }, + { "200", "DEUX CENTS" }, + { "201", "DEUX CENT UN" }, + { "202", "DEUX CENT DEUX" }, + { "300", "TROIS CENTS" }, + { "301", "TROIS CENT UN" }, + { "400", "QUATRE CENTS" }, + { "401", "QUATRE CENT UN" }, + { "500", "CINQ CENTS" }, + { "501", "CINQ CENT UN" }, + { "600", "SIX CENTS" }, + { "601", "SIX CENT UN" }, + { "700", "SEPT CENTS" }, + { "701", "SEPT CENT UN" }, + { "800", "HUIT CENTS" }, + { "801", "HUIT CENT UN" }, + { "900", "NEUF CENTS" }, + { "901", "NEUF CENT UN" }, + { "999", "NEUF CENT QUATRE-VINGT-DIX-NEUF" }, + { "1000", "MILLE" }, + { "1001", "MILLE UN" }, + { "1002", "MILLE DEUX" }, + { "2000", "DEUX MILLE" }, + { "2001", "DEUX MILLE UN" }, + { "100000", "CENT MILLE" }, + { "100001", "CENT MILLE UN" }, + { "999999", "NEUF CENT QUATRE-VINGT-DIX-NEUF MILLE NEUF CENT QUATRE-VINGT-DIX-NEUF" }, + { "1000000", "UN MILLION" }, + { "999999999", "NEUF CENT QUATRE-VINGT-DIX-NEUF MILLIONS NEUF CENT QUATRE-VINGT-DIX-NEUF MILLE NEUF CENT QUATRE-VINGT-DIX-NEUF" }, + { "1000000000", "UN MILLIARD" } + }; + + static private String[][] formatWordFrenchTitle = + { + { "Ww", null, null, null, null, "fra" }, + { "0", "Z\u00e9ro" }, + { "1", "Un" }, + { "2", "Deux" }, + { "3", "Trois" }, + { "4", "Quatre" }, + { "5", "Cinq" }, + { "6", "Six" }, + { "7", "Sept" }, + { "8", "Huit" }, + { "9", "Neuf" }, + { "10", "Dix" }, + { "11", "Onze" }, + { "12", "Douze" }, + { "13", "Treize" }, + { "14", "Quatorze" }, + { "15", "Quinze" }, + { "16", "Seize" }, + { "17", "Dix-sept" }, + { "18", "Dix-huit" }, + { "19", "Dix-neuf" }, + { "20", "Vingt" }, + { "21", "Vingt Et Un" }, + { "22", "Vingt-deux" }, + { "23", "Vingt-trois" }, + { "24", "Vingt-quatre" }, + { "25", "Vingt-cinq" }, + { "26", "Vingt-six" }, + { "27", "Vingt-sept" }, + { "28", "Vingt-huit" }, + { "29", "Vingt-neuf" }, + { "30", "Trente" }, + { "31", "Trente Et Un" }, + { "32", "Trente-deux" }, + { "40", "Quarante" }, + { "41", "Quarante Et Un" }, + { "42", "Quarante-deux" }, + { "50", "Cinquante" }, + { "51", "Cinquante Et Un" }, + { "52", "Cinquante-deux" }, + { "60", "Soixante" }, + { "61", "Soixante Et Un" }, + { "62", "Soixante-deux" }, + { "70", "Soixante-dix" }, + { "71", "Soixante Et Onze" }, + { "72", "Soixante-douze" }, + { "79", "Soixante-dix-neuf" }, + { "80", "Quatre-vingts" }, + { "81", "Quatre-vingt-un" }, + { "82", "Quatre-vingt-deux" }, + { "89", "Quatre-vingt-neuf" }, + { "90", "Quatre-vingt-dix" }, + { "91", "Quatre-vingt-onze" }, + { "92", "Quatre-vingt-douze" }, + { "99", "Quatre-vingt-dix-neuf" }, + { "100", "Cent" }, + { "101", "Cent Un" }, + { "102", "Cent Deux" }, + { "200", "Deux Cents" }, + { "201", "Deux Cent Un" }, + { "202", "Deux Cent Deux" }, + { "300", "Trois Cents" }, + { "301", "Trois Cent Un" }, + { "400", "Quatre Cents" }, + { "401", "Quatre Cent Un" }, + { "500", "Cinq Cents" }, + { "501", "Cinq Cent Un" }, + { "600", "Six Cents" }, + { "601", "Six Cent Un" }, + { "700", "Sept Cents" }, + { "701", "Sept Cent Un" }, + { "800", "Huit Cents" }, + { "801", "Huit Cent Un" }, + { "900", "Neuf Cents" }, + { "901", "Neuf Cent Un" }, + { "999", "Neuf Cent Quatre-vingt-dix-neuf" }, + { "1000", "Mille" }, + { "1001", "Mille Un" }, + { "1002", "Mille Deux" }, + { "2000", "Deux Mille" }, + { "2001", "Deux Mille Un" }, + { "100000", "Cent Mille" }, + { "100001", "Cent Mille Un" }, + { "999999", "Neuf Cent Quatre-vingt-dix-neuf Mille Neuf Cent Quatre-vingt-dix-neuf" }, + { "1000000", "Un Million" }, + { "999999999", "Neuf Cent Quatre-vingt-dix-neuf Millions Neuf Cent Quatre-vingt-dix-neuf Mille Neuf Cent Quatre-vingt-dix-neuf" }, + { "1000000000", "Un Milliard" } + }; + + /** + * Tests decimal from latin script. + * @throws Exception if the test fails + */ + @Test + public void testFormatDecimal() throws Exception { + performConversions ( formatDecimal ); + performConversions ( formatDecimalPadded ); + performConversions ( formatDecimalGrouped ); + performConversions ( formatDecimalGroupedPadded ); + } + + /** + * Tests decimal from arabic script. + * @throws Exception if the test fails + */ + @Test + public void testFormatDecimalArabic() throws Exception { + performConversions ( formatDecimalArabic ); + performConversions ( formatDecimalArabicPadded ); + performConversions ( formatDecimalArabicGrouped ); + performConversions ( formatDecimalArabicGroupedPadded ); + } + + /** + * Tests decimal from thai script. + * @throws Exception if the test fails + */ + @Test + public void testFormatDecimalThai() throws Exception { + performConversions ( formatDecimalThai ); + performConversions ( formatDecimalThaiPadded ); + } + + /** + * Tests roman numbers. + * @throws Exception if the test fails + */ + @Test + public void testFormatRoman() throws Exception { + performConversions ( formatRomanLower ); + performConversions ( formatRomanUpper ); + performConversions ( formatRomanLargeLower ); + performConversions ( formatRomanLargeUpper ); + performConversions ( formatRomanNumberFormsLower ); + performConversions ( formatRomanNumberFormsUpper ); + } + + /** + * Tests latin alphabetic sequence numerals. + * @throws Exception if the test fails + */ + @Test + public void testAlphabeticLatin() throws Exception { + performConversions ( formatAlphabeticLatinLower ); + performConversions ( formatAlphabeticLatinUpper ); + } + + /** + * Tests arabic alphabetic sequence numerals. + * @throws Exception if the test fails + */ + @Test + public void testAlphabeticArabic() throws Exception { + performConversions ( formatAlphabeticArabicHijai ); + performConversions ( formatAlphabeticArabicAbjadi ); + } + + /** + * Tests hebrew alphabetic sequence numerals. + * @throws Exception if the test fails + */ + @Test + public void testAlphabeticHebrew() throws Exception { + performConversions ( formatAlphabeticHebrew ); + } + + /** + * Tests latin alphabetic sequence numerals. + * @throws Exception if the test fails + */ + @Test + public void testAlphabeticThai() throws Exception { + performConversions ( formatAlphabeticThai ); + } + + /** + * Tests arabic numerals.. + * @throws Exception if the test fails + */ + @Test + public void testNumeralArabic() throws Exception { + performConversions ( formatNumeralArabicAbjadi ); + } + + /** + * Tests hebrew numerals. + * @throws Exception if the test fails + */ + @Test + public void testNumeralHebrew() throws Exception { + performConversions ( formatNumeralHebrewGematria ); + } + + /** + * Tests english word numerals. + * @throws Exception if the test fails + */ + @Test + public void testWordEnglish() throws Exception { + performConversions ( formatWordEnglishLower ); + performConversions ( formatWordEnglishUpper ); + performConversions ( formatWordEnglishTitle ); + } + + /** + * Tests spanish word numerals. + * @throws Exception if the test fails + */ + @Test + public void testWordSpanish() throws Exception { + performConversions ( formatWordSpanishLower ); + performConversions ( formatWordSpanishUpper ); + performConversions ( formatWordSpanishTitle ); + } + + /** + * Tests french word numerals. + * @throws Exception if the test fails + */ + @Test + public void testWordFrench() throws Exception { + performConversions ( formatWordFrenchLower ); + performConversions ( formatWordFrenchUpper ); + performConversions ( formatWordFrenchTitle ); + } + + /** + * Perform conversions according to test specification. + * @param ts test specification + */ + private void performConversions ( String[][] ts ) { + assert ts != null; + assert ts.length >= 2; + String[] args = ts[0]; + assert args != null; + assert args.length > 0; + String format = args[0]; + assert format.length() > 0; + char groupingSeparator; + if ( args.length > 1 ) { + String s = args[1]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + groupingSeparator = s.charAt(0); + } else { + groupingSeparator = 0; + } + } else { + groupingSeparator = 0; + } + int groupingSize; + if ( args.length > 2 ) { + String s = args[2]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + groupingSize = Integer.parseInt ( s ); + } else { + groupingSize = 0; + } + } else { + groupingSize = 0; + } + int letterValue; + if ( args.length > 3 ) { + String s = args[3]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + s = s.toLowerCase(); + if ( s.equals("alphabetic") ) { + letterValue = NumberConverter.LETTER_VALUE_ALPHABETIC; + } else if ( s.equals("traditional") ) { + letterValue = NumberConverter.LETTER_VALUE_TRADITIONAL; + } else { + letterValue = 0; + } + } else { + letterValue = 0; + } + } else { + letterValue = 0; + } + String features; + if ( args.length > 4 ) { + String s = args[4]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + features = s; + } else { + features = null; + } + } else { + features = null; + } + String language; + if ( args.length > 5 ) { + String s = args[5]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + language = s; + } else { + language = null; + } + } else { + language = null; + } + String country; + if ( args.length > 6 ) { + String s = args[6]; + if ( ( s != null ) && ( s.length() > 0 ) ) { + country = s; + } else { + country = null; + } + } else { + country = null; + } + NumberConverter nc = new NumberConverter ( format, groupingSeparator, groupingSize, letterValue, features, language, country ); + for ( int i = 1, nt = ts.length; i < nt; i++ ) { + String[] sa = ts[i]; + assert sa != null; + assert sa.length >= 2; + List<Long> numbers = new ArrayList<Long>(); + for ( int k = 0, nn = sa.length - 1; k < nn; k++ ) { + String s = sa[k]; + numbers.add ( Long.valueOf ( s ) ); + } + String expected = sa [ sa.length - 1 ]; + String actual = nc.convert ( numbers ); + assertEquals ( expected, actual ); + } + } + +} diff --git a/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java new file mode 100644 index 000000000..70bd568af --- /dev/null +++ b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.complexscripts.util; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Test suite for bidirectional functionality. + */ +@RunWith(Suite.class) +@SuiteClasses({ + NumberConverterTestCase.class +}) +public class UtilTestSuite { +} diff --git a/test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseConstructiveUserConfigTest.java index b94c47373..fbcd9a441 100644 --- a/test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java +++ b/test/java/org/apache/fop/config/BaseConstructiveUserConfigTest.java @@ -19,19 +19,20 @@ package org.apache.fop.config; -public abstract class BaseConstructiveUserConfigTestCase extends BaseUserConfigTestCase { +import static org.junit.Assert.fail; - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public BaseConstructiveUserConfigTestCase(String name) { - super(name); - } +import org.junit.Test; + +/** + * Super class of several user config cases. + */ +public abstract class BaseConstructiveUserConfigTest extends BaseUserConfigTest { /** * Test using a standard FOP font * @throws Exception checkstyle wants a comment here, even a silly one */ + @Test public void testUserConfig() throws Exception { try { initConfig(); diff --git a/test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseDestructiveUserConfigTest.java index 0d294d328..eb8d202c3 100644 --- a/test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java +++ b/test/java/org/apache/fop/config/BaseDestructiveUserConfigTest.java @@ -19,18 +19,21 @@ package org.apache.fop.config; +import static org.junit.Assert.fail; + import org.apache.fop.apps.FOPException; +import org.junit.Test; -public abstract class BaseDestructiveUserConfigTestCase extends BaseUserConfigTestCase { +/** + * Super class for several user configuration failure cases. + */ +public abstract class BaseDestructiveUserConfigTest extends BaseUserConfigTest { /** - * @see junit.framework.TestCase#TestCase(String) + * Test the user configuration failure. */ - public BaseDestructiveUserConfigTestCase(String name) { - super(name); - } - - public void testUserConfig() throws Exception { + @Test + public void testUserConfig() { try { initConfig(); convertFO(); diff --git a/test/java/org/apache/fop/config/BaseUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseUserConfigTest.java index 6ce833312..645aea536 100644 --- a/test/java/org/apache/fop/config/BaseUserConfigTestCase.java +++ b/test/java/org/apache/fop/config/BaseUserConfigTest.java @@ -23,38 +23,29 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import org.xml.sax.SAXException; - import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.render.pdf.BasePDFTestCase; +import org.apache.fop.render.pdf.BasePDFTest; +import org.xml.sax.SAXException; /** * Basic runtime test for FOP's font configuration. It is used to verify that * nothing obvious is broken after compiling. */ -public abstract class BaseUserConfigTestCase extends BasePDFTestCase { +public abstract class BaseUserConfigTest extends BasePDFTest { protected DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); /** logging instance */ - protected Log log = LogFactory.getLog(BaseUserConfigTestCase.class); + protected Log log = LogFactory.getLog(BaseUserConfigTest.class); /** - * @see junit.framework.TestCase#TestCase(String) - */ - public BaseUserConfigTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.render.pdf.BasePDFTestCase#init() + * @see org.apache.fop.render.pdf.BasePDFTest#init() */ protected void init() { // do nothing @@ -102,8 +93,8 @@ public abstract class BaseUserConfigTestCase extends BasePDFTestCase { */ protected abstract String getUserConfigFilename(); - /* - * @see junit.framework.TestCase#getName() + /** + * The name of this test. */ public String getName() { return getUserConfigFilename(); diff --git a/test/java/org/apache/fop/config/FOURIResolverTestCase.java b/test/java/org/apache/fop/config/FOURIResolverTestCase.java index e0f6d7f81..1ffe8b065 100644 --- a/test/java/org/apache/fop/config/FOURIResolverTestCase.java +++ b/test/java/org/apache/fop/config/FOURIResolverTestCase.java @@ -19,21 +19,23 @@ package org.apache.fop.config; -import java.net.MalformedURLException; +import static org.junit.Assert.fail; -import junit.framework.TestCase; +import java.net.MalformedURLException; import org.apache.fop.apps.FOURIResolver; +import org.junit.Test; /** * This tests some aspects of the {@link FOURIResolver} class. */ -public class FOURIResolverTestCase extends TestCase { +public class FOURIResolverTestCase { /** * Checks the {@link FOURIResolver#checkBaseURL(String)} method. * @throws Exception if an error occurs */ + @Test public void testCheckBaseURI() throws Exception { FOURIResolver resolver = new FOURIResolver(true); System.out.println(resolver.checkBaseURL("./test/config")); diff --git a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java index 00e9b181b..7e17291d6 100644 --- a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java +++ b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java @@ -19,18 +19,12 @@ package org.apache.fop.config; -/* +/** * this font is without a metrics-url or an embed-url */ -public class FontAttributesMissingTestCase extends BaseDestructiveUserConfigTestCase { - - public FontAttributesMissingTestCase(String name) { - super(name); - } +public class FontAttributesMissingTestCase extends BaseDestructiveUserConfigTest { - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_attributes_missing.xconf"; } diff --git a/test/java/org/apache/fop/config/FontBaseBadTestCase.java b/test/java/org/apache/fop/config/FontBaseBadTestCase.java index 792acf59a..eb49ca9fe 100644 --- a/test/java/org/apache/fop/config/FontBaseBadTestCase.java +++ b/test/java/org/apache/fop/config/FontBaseBadTestCase.java @@ -19,16 +19,12 @@ package org.apache.fop.config; -/* +/** * This font base does not exist and a relative font path is used. */ -public class FontBaseBadTestCase extends BaseDestructiveUserConfigTestCase { - - public FontBaseBadTestCase(String name) { - super(name); - } +public class FontBaseBadTestCase extends BaseDestructiveUserConfigTest { - /** {@inheritDoc} */ + @Override public String getUserConfigFilename() { return "test_fontbase_bad.xconf"; } diff --git a/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java b/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java index aa8b9e000..9e341f8b4 100644 --- a/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java +++ b/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java @@ -22,15 +22,9 @@ package org.apache.fop.config; /** * this font has an embed-url that does not exist on filesystem. */ -public class FontEmbedUrlBadTestCase extends BaseDestructiveUserConfigTestCase { +public class FontEmbedUrlBadTestCase extends BaseDestructiveUserConfigTest { - public FontEmbedUrlBadTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_embedurl_bad.xconf"; } diff --git a/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java index 6d41b0a13..e3f0a6a88 100644 --- a/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java +++ b/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java @@ -22,15 +22,9 @@ package org.apache.fop.config; /** * this font has a malformed embed-url */ -public class FontEmbedUrlMalformedTestCase extends BaseDestructiveUserConfigTestCase { +public class FontEmbedUrlMalformedTestCase extends BaseDestructiveUserConfigTest { - public FontEmbedUrlMalformedTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_embedurl_malformed.xconf"; } diff --git a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java index 166274452..352d43920 100644 --- a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java +++ b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java @@ -19,21 +19,12 @@ package org.apache.fop.config; -/* +/** * this font has a metrics-url that does not exist on filesystem */ -public class FontMetricsUrlBadTestCase extends BaseDestructiveUserConfigTestCase { - - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public FontMetricsUrlBadTestCase(String name) { - super(name); - } +public class FontMetricsUrlBadTestCase extends BaseDestructiveUserConfigTest { - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_metricsurl_bad.xconf"; } diff --git a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java index ae4dde886..ddf3ee8a6 100644 --- a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java +++ b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java @@ -19,18 +19,12 @@ package org.apache.fop.config; -/* +/** * this font has a malformed metrics-url */ -public class FontMetricsUrlMalformedTestCase extends BaseDestructiveUserConfigTestCase { - - public FontMetricsUrlMalformedTestCase(String name) { - super(name); - } +public class FontMetricsUrlMalformedTestCase extends BaseDestructiveUserConfigTest { - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_metricsurl_malformed.xconf"; } diff --git a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java index dcc0098be..8aa2acb81 100644 --- a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java +++ b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java @@ -19,18 +19,12 @@ package org.apache.fop.config; -/* +/** * this font has a missing font triplet attribute */ -public class FontTripletAttributeMissingTestCase extends BaseDestructiveUserConfigTestCase { - - public FontTripletAttributeMissingTestCase(String name) { - super(name); - } +public class FontTripletAttributeMissingTestCase extends BaseDestructiveUserConfigTest { - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_font_tripletattribute_missing.xconf"; } diff --git a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java index 403bf3282..cf9d19f99 100644 --- a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java +++ b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java @@ -19,15 +19,9 @@ package org.apache.fop.config; -public class FontsAutoDetectTestCase extends BaseConstructiveUserConfigTestCase { +public class FontsAutoDetectTestCase extends BaseConstructiveUserConfigTest { - public FontsAutoDetectTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override public String getUserConfigFilename() { return "test_fonts_autodetect.xconf"; } diff --git a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java index 3c0205d3d..3817e7966 100644 --- a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java +++ b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java @@ -22,15 +22,9 @@ package org.apache.fop.config; /** * tests font directory on system */ -public class FontsDirectoryRecursiveTestCase extends BaseConstructiveUserConfigTestCase { +public class FontsDirectoryRecursiveTestCase extends BaseConstructiveUserConfigTest { - public FontsDirectoryRecursiveTestCase(String name) { - super(name); - } - - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ + @Override protected String getUserConfigFilename() { return "test_fonts_directory_recursive.xconf"; } diff --git a/test/java/org/apache/fop/config/FontsSubstitutionTestCase.java b/test/java/org/apache/fop/config/FontsSubstitutionTestCase.java index 725f0d4d7..1499c9186 100644 --- a/test/java/org/apache/fop/config/FontsSubstitutionTestCase.java +++ b/test/java/org/apache/fop/config/FontsSubstitutionTestCase.java @@ -36,19 +36,9 @@ import org.apache.fop.render.PrintRenderer; * Tests the font substitution mechanism */ public class FontsSubstitutionTestCase extends - BaseConstructiveUserConfigTestCase { + BaseConstructiveUserConfigTest { - /** - * Main constructor - * @param name test case name - */ - public FontsSubstitutionTestCase(String name) { - super(name); - } - - /** - * {@inheritDoc} - */ + @Override protected byte[] convertFO(File foFile, FOUserAgent ua, boolean dumpPdfFile) throws Exception { PrintRenderer renderer = (PrintRenderer) ua.getRendererFactory() @@ -58,7 +48,8 @@ public class FontsSubstitutionTestCase extends FontManager fontManager = ua.getFactory().getFontManager(); FontCollection[] fontCollections = new FontCollection[] { new Base14FontCollection(fontManager.isBase14KerningEnabled()), - new CustomFontCollection(renderer.getFontResolver(), renderer.getFontList()) + new CustomFontCollection(renderer.getFontResolver(), renderer.getFontList(), + ua.isComplexScriptFeaturesEnabled()) }; fontManager.setup(fontInfo, fontCollections); FontTriplet triplet = new FontTriplet("Times", "italic", @@ -72,9 +63,7 @@ public class FontsSubstitutionTestCase extends return null; } - /** - * {@inheritDoc} - */ + @Override public String getUserConfigFilename() { return "test_fonts_substitution.xconf"; } diff --git a/test/java/org/apache/fop/config/UserConfigTestSuite.java b/test/java/org/apache/fop/config/UserConfigTestSuite.java index 168d87d51..374d41fab 100644 --- a/test/java/org/apache/fop/config/UserConfigTestSuite.java +++ b/test/java/org/apache/fop/config/UserConfigTestSuite.java @@ -19,35 +19,25 @@ package org.apache.fop.config; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * Test suite for font configuration. */ +@RunWith(Suite.class) +@SuiteClasses({ + FontBaseBadTestCase.class, + FontAttributesMissingTestCase.class, + FontTripletAttributeMissingTestCase.class, + FontMetricsUrlBadTestCase.class, + FontEmbedUrlBadTestCase.class, + FontMetricsUrlMalformedTestCase.class, + FontsDirectoryRecursiveTestCase.class, + FontsAutoDetectTestCase.class, + FontsSubstitutionTestCase.class, + FOURIResolverTestCase.class +}) public class UserConfigTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite( - "Basic functionality test suite for user configuration"); - //$JUnit-BEGIN$ - suite.addTest(new TestSuite(FontBaseBadTestCase.class)); - suite.addTest(new TestSuite(FontAttributesMissingTestCase.class)); - suite.addTest(new TestSuite(FontTripletAttributeMissingTestCase.class)); - suite.addTest(new TestSuite(FontMetricsUrlBadTestCase.class)); - suite.addTest(new TestSuite(FontEmbedUrlBadTestCase.class)); - suite.addTest(new TestSuite(FontMetricsUrlMalformedTestCase.class)); - suite.addTest(new TestSuite(FontEmbedUrlMalformedTestCase.class)); - suite.addTest(new TestSuite(FontsDirectoryRecursiveTestCase.class)); - suite.addTest(new TestSuite(FontsAutoDetectTestCase.class)); - suite.addTest(new TestSuite(FontsSubstitutionTestCase.class)); - suite.addTest(new TestSuite(FOURIResolverTestCase.class)); - //$JUnit-END$ - return suite; - } - } diff --git a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java index 45470aeee..23af20a1a 100644 --- a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java +++ b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java @@ -19,13 +19,16 @@ package org.apache.fop.datatypes; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; /** * Tests for URISpecification. */ -public class URISpecificationTestCase extends TestCase { +public class URISpecificationTestCase { + @Test public void testGetURL() throws Exception { String actual; @@ -42,6 +45,7 @@ public class URISpecificationTestCase extends TestCase { assertEquals("http://localhost/test", actual); } + @Test public void testEscapeURI() throws Exception { String actual; diff --git a/test/java/org/apache/fop/events/BasicEventTestCase.java b/test/java/org/apache/fop/events/BasicEventTestCase.java index c69dad081..87fc04329 100644 --- a/test/java/org/apache/fop/events/BasicEventTestCase.java +++ b/test/java/org/apache/fop/events/BasicEventTestCase.java @@ -19,12 +19,18 @@ package org.apache.fop.events; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.apache.fop.events.model.EventSeverity; +import org.junit.Test; -public class BasicEventTestCase extends TestCase { +public class BasicEventTestCase { + @Test public void testBasics() throws Exception { MyEventListener listener = new MyEventListener(); @@ -54,6 +60,7 @@ public class BasicEventTestCase extends TestCase { broadcaster.broadcastEvent(ev); } + @Test public void testEventProducer() throws Exception { MyEventListener listener = new MyEventListener(); diff --git a/test/java/org/apache/fop/events/EventChecker.java b/test/java/org/apache/fop/events/EventChecker.java index afef11d87..dac67a8cc 100644 --- a/test/java/org/apache/fop/events/EventChecker.java +++ b/test/java/org/apache/fop/events/EventChecker.java @@ -19,12 +19,12 @@ package org.apache.fop.events; -import junit.framework.Assert; +import static org.junit.Assert.fail; /** * Class that checks that an expected event is produced, and only this one. */ -class EventChecker extends Assert implements EventListener { +class EventChecker implements EventListener { private final String expectedEventID; @@ -36,11 +36,9 @@ class EventChecker extends Assert implements EventListener { public void processEvent(Event event) { // Always create the message to make sure there is no error in the formatting process - String msg = EventFormatter.format(event); - if (event.getEventID().equals(expectedEventID)) { + String id = event.getEventID(); + if (id.equals(expectedEventID)) { eventReceived = true; - } else { - fail("Unexpected event: id = " + event.getEventID() + ": " + msg); } } diff --git a/test/java/org/apache/fop/events/EventProcessingTestCase.java b/test/java/org/apache/fop/events/EventProcessingTestCase.java index 0c42ec5e1..8219fa71e 100644 --- a/test/java/org/apache/fop/events/EventProcessingTestCase.java +++ b/test/java/org/apache/fop/events/EventProcessingTestCase.java @@ -19,7 +19,9 @@ package org.apache.fop.events; -import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -29,9 +31,8 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.Test; +import org.xml.sax.SAXException; import org.apache.commons.io.output.NullOutputStream; @@ -39,87 +40,88 @@ import org.apache.xmlgraphics.util.MimeConstants; import org.apache.fop.ResourceEventProducer; import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.area.AreaEventProducer; import org.apache.fop.fo.FOValidationEventProducer; import org.apache.fop.fo.flow.table.TableEventProducer; -import org.apache.fop.fonts.FontEventProducer; import org.apache.fop.layoutmgr.BlockLevelEventProducer; import org.apache.fop.layoutmgr.inline.InlineLevelEventProducer; /** * Tests that the event notification system runs smoothly. */ -public class EventProcessingTestCase extends TestCase { +public class EventProcessingTestCase { private final FopFactory fopFactory = FopFactory.newInstance(); private final TransformerFactory tFactory = TransformerFactory.newInstance(); - private final File basedir; + private static final String BASE_DIR = "test/events/"; - public EventProcessingTestCase(String name) { - super(name); - String base = System.getProperty("basedir"); - if (base != null) { - basedir = new File(base); - } else { - basedir = new File("."); - } - } + /** The base directory of configuration files */ + public static final String CONFIG_BASE_DIR = "test/config/"; - private void doTest(String filename, String expectedEventID) - throws FOPException, TransformerException { - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, new NullOutputStream()); + public void doTest(InputStream inStream, String fopConf, String expectedEventID, String mimeType) + throws FOPException, TransformerException, IOException, SAXException { EventChecker eventChecker = new EventChecker(expectedEventID); - fop.getUserAgent().getEventBroadcaster().addEventListener(eventChecker); + if (fopConf != null) { + fopFactory.setUserConfig(fopConf); + } + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + userAgent.getEventBroadcaster().addEventListener(eventChecker); + Fop fop = fopFactory.newFop(mimeType, userAgent, new NullOutputStream()); Transformer transformer = tFactory.newTransformer(); - Source src = new StreamSource(new File(basedir, filename)); + Source src = new StreamSource(inStream); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); eventChecker.end(); } - public void testArea() throws FOPException, TransformerException { + public void doTest(String filename, String expectedEventID) throws + FOPException, TransformerException, IOException, SAXException { + doTest(new FileInputStream(BASE_DIR + filename), null, expectedEventID, + MimeConstants.MIME_PDF); + } + + @Test + public void testArea() throws TransformerException, IOException, SAXException { doTest("area.fo", AreaEventProducer.class.getName() + ".unresolvedIDReferenceOnPage"); } - public void testResource() throws FOPException, TransformerException { + @Test + public void testResource() throws FOPException, TransformerException, IOException, + SAXException { doTest("resource.fo", ResourceEventProducer.class.getName() + ".imageNotFound"); } - public void testValidation() throws FOPException, TransformerException { + @Test + public void testValidation() throws FOPException, TransformerException, IOException, + SAXException { doTest("validation.fo", FOValidationEventProducer.class.getName() + ".invalidPropertyValue"); } - public void testTable() throws FOPException, TransformerException { + @Test + public void testTable() throws FOPException, TransformerException, IOException, SAXException { doTest("table.fo", TableEventProducer.class.getName() + ".noTablePaddingWithCollapsingBorderModel"); } - public void testBlockLevel() throws FOPException, TransformerException { + @Test + public void testBlockLevel() throws FOPException, TransformerException, IOException, + SAXException { doTest("block-level.fo", BlockLevelEventProducer.class.getName() + ".overconstrainedAdjustEndIndent"); } - public void testInlineLevel() throws FOPException, TransformerException { + @Test + public void testInlineLevel() throws FOPException, TransformerException, IOException, + SAXException { doTest("inline-level.fo", InlineLevelEventProducer.class.getName() + ".lineOverflows"); } - - public void testFont() throws FOPException, TransformerException { - doTest("font.fo", - FontEventProducer.class.getName() + ".fontSubstituted"); - } - - - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(EventProcessingTestCase.class); - return suite; - } } diff --git a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java new file mode 100644 index 000000000..313379e02 --- /dev/null +++ b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java @@ -0,0 +1,531 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.fo.flow.BasicLink; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.BlockContainer; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Footnote; +import org.apache.fop.fo.flow.FootnoteBody; +import org.apache.fop.fo.flow.Inline; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.Leader; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.ListItemBody; +import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.flow.PageNumber; +import org.apache.fop.fo.flow.PageNumberCitation; +import org.apache.fop.fo.flow.PageNumberCitationLast; +import org.apache.fop.fo.flow.Wrapper; +import org.apache.fop.fo.flow.table.Table; +import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.fo.flow.table.TableCell; +import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TableFooter; +import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TableRow; +import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.Root; +import org.apache.fop.fo.pagination.StaticContent; + +/** + * Tests that {@link DelegatingFOEventHandler} does forward every event to its delegate + * event handler. + */ +public class DelegatingFOEventHandlerTestCase { + + private InputStream document; + + private List<String> expectedEvents; + + private List<String> actualEvents; + + private FODocumentParser documentParser; + + private class DelegatingFOEventHandlerTester extends FOEventHandler { + + DelegatingFOEventHandlerTester(FOUserAgent foUserAgent) { + super(foUserAgent); + } + + private final StringBuilder eventBuilder = new StringBuilder(); + + @Override + public void startDocument() throws SAXException { + actualEvents.add("start document"); + } + + @Override + public void endDocument() throws SAXException { + actualEvents.add("end document"); + } + + @Override + public void startRoot(Root root) { + startElement(root); + } + + @Override + public void endRoot(Root root) { + endElement(root); + } + + @Override + public void startPageSequence(PageSequence pageSeq) { + startElement(pageSeq); + } + + @Override + public void endPageSequence(PageSequence pageSeq) { + endElement(pageSeq); + } + + @Override + public void startPageNumber(PageNumber pagenum) { + startElement(pagenum); + } + + @Override + public void endPageNumber(PageNumber pagenum) { + endElement(pagenum); + } + + @Override + public void startPageNumberCitation(PageNumberCitation pageCite) { + startElement(pageCite); + } + + @Override + public void endPageNumberCitation(PageNumberCitation pageCite) { + endElement(pageCite); + } + + @Override + public void startPageNumberCitationLast(PageNumberCitationLast pageLast) { + startElement(pageLast); + } + + @Override + public void endPageNumberCitationLast(PageNumberCitationLast pageLast) { + endElement(pageLast); + } + + @Override + public void startFlow(Flow fl) { + startElement(fl); + } + + @Override + public void endFlow(Flow fl) { + endElement(fl); + } + + @Override + public void startBlock(Block bl) { + startElement(bl); + } + + @Override + public void endBlock(Block bl) { + endElement(bl); + } + + @Override + public void startBlockContainer(BlockContainer blc) { + startElement(blc); + } + + @Override + public void endBlockContainer(BlockContainer blc) { + endElement(blc); + } + + @Override + public void startInline(Inline inl) { + startElement(inl); + } + + @Override + public void endInline(Inline inl) { + endElement(inl); + } + + @Override + public void startTable(Table tbl) { + startElement(tbl); + } + + @Override + public void endTable(Table tbl) { + endElement(tbl); + } + + @Override + public void startColumn(TableColumn tc) { + startElement(tc); + } + + @Override + public void endColumn(TableColumn tc) { + endElement(tc); + } + + @Override + public void startHeader(TableHeader header) { + startElement(header); + } + + @Override + public void endHeader(TableHeader header) { + endElement(header); + } + + @Override + public void startFooter(TableFooter footer) { + startElement(footer); + } + + @Override + public void endFooter(TableFooter footer) { + endElement(footer); + } + + @Override + public void startBody(TableBody body) { + startElement(body); + } + + @Override + public void endBody(TableBody body) { + endElement(body); + } + + @Override + public void startRow(TableRow tr) { + startElement(tr); + } + + @Override + public void endRow(TableRow tr) { + endElement(tr); + } + + @Override + public void startCell(TableCell tc) { + startElement(tc); + } + + @Override + public void endCell(TableCell tc) { + endElement(tc); + } + + @Override + public void startList(ListBlock lb) { + startElement(lb); + } + + @Override + public void endList(ListBlock lb) { + endElement(lb); + } + + @Override + public void startListItem(ListItem li) { + startElement(li); + } + + @Override + public void endListItem(ListItem li) { + endElement(li); + } + + @Override + public void startListLabel(ListItemLabel listItemLabel) { + startElement(listItemLabel); + } + + @Override + public void endListLabel(ListItemLabel listItemLabel) { + endElement(listItemLabel); + } + + @Override + public void startListBody(ListItemBody listItemBody) { + startElement(listItemBody); + } + + @Override + public void endListBody(ListItemBody listItemBody) { + endElement(listItemBody); + } + + @Override + public void startStatic(StaticContent staticContent) { + startElement(staticContent); + } + + @Override + public void endStatic(StaticContent statisContent) { + endElement(statisContent); + } + + @Override + public void startLink(BasicLink basicLink) { + startElement(basicLink); + } + + @Override + public void endLink(BasicLink basicLink) { + endElement(basicLink); + } + + @Override + public void image(ExternalGraphic eg) { + startElement(eg); + endElement(eg); + } + + @Override + public void startInstreamForeignObject(InstreamForeignObject ifo) { + startElement(ifo); + } + + @Override + public void endInstreamForeignObject(InstreamForeignObject ifo) { + endElement(ifo); + } + + @Override + public void startFootnote(Footnote footnote) { + startElement(footnote); + } + + @Override + public void endFootnote(Footnote footnote) { + endElement(footnote); + } + + @Override + public void startFootnoteBody(FootnoteBody body) { + startElement(body); + } + + @Override + public void endFootnoteBody(FootnoteBody body) { + endElement(body); + } + + @Override + public void startLeader(Leader l) { + startElement(l); + } + + @Override + public void endLeader(Leader l) { + endElement(l); + } + + @Override + public void startWrapper(Wrapper wrapper) { + startElement(wrapper); + } + + @Override + public void endWrapper(Wrapper wrapper) { + endElement(wrapper); + } + + @Override + public void character(Character c) { + startElement(c); + endElement(c); + } + + private void startElement(FObj node) { + addEvent("start ", node); + } + + private void endElement(FObj node) { + addEvent("end ", node); + } + + private void addEvent(String event, FObj node) { + eventBuilder.append(event); + eventBuilder.append(node.getLocalName()); + addID(node); + actualEvents.add(eventBuilder.toString()); + eventBuilder.setLength(0); + } + + private void addID(FObj node) { + String id = node.getId(); + if (id != null && id.length() > 0) { + eventBuilder.append(" id=\""); + eventBuilder.append(id); + eventBuilder.append("\""); + } + } + } + + @Before + public void setUp() throws IOException { + setUpEvents(); + loadDocument(); + createDocumentParser(); + } + + private void setUpEvents() throws IOException { + loadDocument(); + loadExpectedEvents(); + actualEvents = new ArrayList<String>(expectedEvents.size()); + } + + private void loadDocument() { + document = getClass().getResourceAsStream("complete_document.fo"); + } + + private void loadExpectedEvents() throws IOException { + expectedEvents = new ArrayList<String>(); + InputStream xslt = getClass().getResourceAsStream("extract-events.xsl"); + try { + runXSLT(xslt); + } finally { + closeStream(xslt); + closeStream(document); + } + } + + private void runXSLT(InputStream xslt) { + Transformer transformer = createTransformer(xslt); + Source fo = new StreamSource(document); + Result result = createTransformOutputHandler(); + try { + transformer.transform(fo, result); + } catch (TransformerException e) { + throw new RuntimeException(e); + } + } + + private Transformer createTransformer(InputStream xslt) { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + try { + return transformerFactory.newTransformer(new StreamSource(xslt)); + } catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } + } + + private Result createTransformOutputHandler() { + return new SAXResult(new DefaultHandler() { + + private final StringBuilder event = new StringBuilder(); + + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException { + event.setLength(0); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + event.append(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + expectedEvents.add(event.toString()); + } + + }); + } + + private void closeStream(InputStream stream) { + try { + stream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void createDocumentParser() { + documentParser = FODocumentParser.newInstance(new FOEventHandlerFactory() { + + public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) { + return new DelegatingFOEventHandler( + new DelegatingFOEventHandlerTester(foUserAgent)) { + }; + } + }); + } + + @Test + public void testFOEventHandler() throws Exception { + documentParser.parse(document); + assertArrayEquals(expectedEvents.toArray(), actualEvents.toArray()); + } + + @After + public void unloadDocument() throws IOException { + document.close(); + } + + /** + * Prints the given list to {@code System.out}, each element on a new line. For + * debugging purpose. + * + * @param list a list + */ + public void printList(List<?> list) { + for (Object element : list) { + System.out.println(element); + } + } + +} diff --git a/test/java/org/apache/fop/fo/FODocumentParser.java b/test/java/org/apache/fop/fo/FODocumentParser.java new file mode 100644 index 000000000..a7574e49d --- /dev/null +++ b/test/java/org/apache/fop/fo/FODocumentParser.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo; + +import java.io.InputStream; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.events.EventListener; + +/** + * Parse an FO document and run the corresponding FO events through a given + * {@link FOEventHandler} instance. That instance is created using the helper + * {@link FOEventHandlerFactory}. + * + * <p>An instance of this class may not be used in multiple threads concurrently.<p> + * + * <p>An instance of this class may be used multiple times if the given + * {@link FOEventHandler} implementation can be used multiple times. + */ +public final class FODocumentParser { + + private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); + + private static final FopFactory FOP_FACTORY = FopFactory.newInstance(); + + private final FOEventHandlerFactory foEventHandlerFactory; + + private Fop fop; + + private Transformer transformer; + + private EventListener eventListener; + + /** + * A factory to create custom instances of {@link FOEventHandler}. + */ + public static interface FOEventHandlerFactory { + + /** + * Creates a new {@code FOEventHandler} instance parameterized with the given FO user agent. + * + * @param foUserAgent an FO user agent + * @return a new {@code FOEventHandler} instance + */ + FOEventHandler newFOEventHandler(FOUserAgent foUserAgent); + } + + private FODocumentParser(FOEventHandlerFactory foeEventHandlerFactory) { + this.foEventHandlerFactory = foeEventHandlerFactory; + } + + /** + * Creates and returns a new FO document parser. The given factory will be used to + * customize the handler that will receive FO events, using the + * {@link FOUserAgent#setFOEventHandlerOverride(FOEventHandler)} method. + * + * @param foEventHandlerFactory the factory to be used to create {@code + * FOEventHandler} instances + * @return a new parser + */ + public static FODocumentParser newInstance(FOEventHandlerFactory foEventHandlerFactory) { + return new FODocumentParser(foEventHandlerFactory); + } + + /** + * Sets the event listener to be used if events occurs when parsing the document. + * + * @param eventListener an event listener + */ + public void setEventListener(EventListener eventListener) { + this.eventListener = eventListener; + } + + /** + * Runs FOP on the given document. + * + * @param document XSL-FO document to parse + * @throws FOPException if an error occurs when initializing FOP + * @throws LoadingException if an error occurs when parsing the document + */ + public void parse(InputStream document) throws FOPException, LoadingException { + parse(document, createFOUserAgent()); + } + + /** + * Runs FOP on the given document with the supplied {@link FOUserAgent}. + * + * @param document XSL-FO document to parse + * @param foUserAgent The user agent + * @throws FOPException if an error occurs when initializing FOP + * @throws LoadingException if an error occurs when parsing the document + */ + public void parse(InputStream document, FOUserAgent foUserAgent) + throws FOPException, LoadingException { + fop = FOP_FACTORY.newFop(foUserAgent); + createTransformer(); + runTransformer(document); + } + + /** + * Creates a new {@link FOUserAgent}. + * @return It + */ + public FOUserAgent createFOUserAgent() { + FOUserAgent userAgent = FOP_FACTORY.newFOUserAgent(); + FOEventHandler foEventHandler = foEventHandlerFactory.newFOEventHandler(userAgent); + userAgent.setFOEventHandlerOverride(foEventHandler); + if (eventListener != null) { + userAgent.getEventBroadcaster().addEventListener(eventListener); + } + return userAgent; + } + + private void createTransformer() { + try { + transformer = TRANSFORMER_FACTORY.newTransformer(); + } catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } + } + + private void runTransformer(InputStream input) throws LoadingException, FOPException { + Source source = new StreamSource(input); + Result result = new SAXResult(fop.getDefaultHandler()); + try { + transformer.transform(source, result); + } catch (TransformerException e) { + Throwable cause = e.getCause(); + throw new LoadingException(cause == null ? e : cause); + } + } +} diff --git a/test/java/org/apache/fop/fo/FONodeMocks.java b/test/java/org/apache/fop/fo/FONodeMocks.java new file mode 100644 index 000000000..1310d4a78 --- /dev/null +++ b/test/java/org/apache/fop/fo/FONodeMocks.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; + +/** + * A helper class for creating mocks of {@link FONode} and its descendants. + */ +public final class FONodeMocks { + + private FONodeMocks() { } + + /** + * Creates and returns a mock {@link FONode} configured with a mock + * {@link FOEventHandler}. The FO event handler returns a mock {@link FOUserAgent}, + * which in turn returns a mock {@link FopFactory}, which returns a mock + * {@link ImageManager}. + * + * @return a mock FO node + */ + public static FONode mockFONode() { + FONode mockFONode = mock(FONode.class); + mockGetFOEventHandler(mockFONode); + return mockFONode; + } + + private static void mockGetFOEventHandler(FONode mockFONode) { + FOEventHandler mockFOEventHandler = mock(FOEventHandler.class); + mockGetUserAgent(mockFOEventHandler); + when(mockFONode.getFOEventHandler()).thenReturn(mockFOEventHandler); + } + + private static void mockGetUserAgent(FOEventHandler mockFOEventHandler) { + FOUserAgent mockFOUserAgent = mock(FOUserAgent.class); + mockGetFactory(mockFOUserAgent); + when(mockFOEventHandler.getUserAgent()).thenReturn(mockFOUserAgent); + } + + private static void mockGetFactory(FOUserAgent mockFOUserAgent) { + FopFactory mockFopFactory = mock(FopFactory.class); + mockGetImageManager(mockFopFactory); + when(mockFOUserAgent.getFactory()).thenReturn(mockFopFactory); + } + + private static void mockGetImageManager(FopFactory mockFopFactory) { + try { + ImageManager mockImageManager = mock(ImageManager.class); + when(mockImageManager.getImageInfo(anyString(), any(ImageSessionContext.class))) + .thenReturn(null); + when(mockFopFactory.getImageManager()).thenReturn(mockImageManager); + } catch (ImageException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java b/test/java/org/apache/fop/fo/LoadingException.java index e83e5ca04..a5d509209 100644 --- a/test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java +++ b/test/java/org/apache/fop/fo/LoadingException.java @@ -17,26 +17,18 @@ /* $Id$ */ -package org.apache.fop.config; +package org.apache.fop.fo; -/* - * this font has a metrics-url that does not exist on filesystem +/** + * This class specifies an exceptional condition that occurred while an XSL-FO document + * was being parsed. */ -public class FontsDirectoryBadTestCase extends BaseDestructiveUserConfigTestCase { +public class LoadingException extends Exception { - public FontsDirectoryBadTestCase(String name) { - super(name); - } + private static final long serialVersionUID = 7529029475875542916L; - /** - * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename() - */ - public String getUserConfigFilename() { - return "test_fonts_directory_bad.xconf"; + LoadingException(Throwable cause) { + super(cause); } - /** get test FOP config File */ - protected String getFontFOFilePath() { - return "test/xml/bugtests/font-dir.fo"; - } } diff --git a/test/java/org/apache/fop/fo/complete_document.fo b/test/java/org/apache/fop/fo/complete_document.fo new file mode 100644 index 000000000..5a34e9e9a --- /dev/null +++ b/test/java/org/apache/fop/fo/complete_document.fo @@ -0,0 +1,176 @@ +<?xml version="1.0" standalone="no"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id$ --> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> + + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="400pt" page-width="300pt" margin="20pt" margin-top="10pt"> + <fo:region-body margin-top="20pt"/> + <fo:region-before extent="15pt"/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:static-content flow-name="xsl-region-before"> + <fo:block id="1" font-size="7pt" text-align-last="justify" padding-bottom="2pt" + border-bottom="0.25pt solid black">This is the page header<fo:leader/>Page <fo:page-number + id="2"/></fo:block> + </fo:static-content> + <fo:static-content flow-name="xsl-footnote-separator"> + <fo:block id="3"><fo:leader leader-length="100pt" leader-pattern="rule"/></fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body"> + <fo:block id="4">This is a link to the <fo:wrapper id="5" color="blue"><fo:basic-link id="6" + internal-destination="second-start">next page-sequence</fo:basic-link></fo:wrapper> + (which starts on page <fo:page-number-citation id="7" ref-id="second-start"/> and ends on + page <fo:page-number-citation-last id="8" ref-id="second-end"/>).</fo:block> + <fo:block id="9" font-family="sans-serif" font-weight="bold" space-before="1em" + space-after="0.2em" role="H1"><fo:block id="10">A Title Block</fo:block></fo:block> + <fo:block id="11">This block of text contains a footnote<fo:footnote id="12"><fo:inline id="13" + baseline-shift="super" font-size="70%">1</fo:inline><fo:footnote-body id="14"><fo:block + id="15">A footnote with a link to the <fo:wrapper id="16" color="blue"><fo:basic-link + id="17" external-destination="http://xmlgraphics.apache.org/fop/">FOP + website</fo:basic-link></fo:wrapper></fo:block></fo:footnote-body></fo:footnote> + call.</fo:block> + <fo:table id="18" space-before="1em" width="100%" table-layout="fixed"> + <fo:table-column id="19" column-width="proportional-column-width(1)"/> + <fo:table-column id="20" column-width="proportional-column-width(2)"/> + <fo:table-header id="21"> + <fo:table-row id="22"> + <fo:table-cell id="23" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="24">Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="25" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="26">Header 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-header> + <fo:table-footer id="27"> + <fo:table-row id="28"> + <fo:table-cell id="29" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="30">Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="31" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="32">Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-footer> + <fo:table-body id="33"> + <fo:table-row id="34"> + <fo:table-cell id="35" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="36">Cell 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="37" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="38">Cell 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row id="39"> + <fo:table-cell id="40" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="41">Cell 2.1</fo:block> + </fo:table-cell> + <fo:table-cell id="42" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="43">Cell 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block-container id="44" space-before="1.2em"> + <fo:block-container id="45" absolute-position="absolute" top="6pt" right="2.5pt" + inline-progression-dimension="37%" padding="3pt 1pt 2pt 3pt" border="1.5pt solid + darkblue"> + <fo:block id="46" color="darkblue" font-size="80%">This is an absolutely positioned + block-container. Nullam interdum mattis ipsum sit amet molestie.</fo:block> + </fo:block-container> + <fo:block id="47" end-indent="37% + 15pt">Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer vel lacinia diam. Etiam venenatis magna vel libero imperdiet + rhoncus.</fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:static-content id="48" flow-name="xsl-region-before"> + <fo:block id="49" font-size="7pt" text-align-last="justify" padding-bottom="2pt" + border-bottom="0.25pt solid black">This is the page header<fo:leader id="50"/>Page + <fo:page-number id="51"/></fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body" text-align="justify" space-before.minimum="8pt" + space-before.optimum="10pt" space-before.maximum="12pt"> + <fo:block id="second-start">Starting a new page-sequence.</fo:block> + <fo:block id="52" text-align="center">The <fo:external-graphic id="53" + src="test/resources/images/fop-logo-color-24bit.png" + inline-progression-dimension.maximum="50%" content-width="scale-to-fit" + alignment-adjust="-46%" alignment-baseline="middle" fox:alt-text="FOP Logo"/> + logo.</fo:block> + <fo:list-block id="54" provisional-distance-between-starts="15pt" + provisional-label-separation="0" space-before="inherit"> + <fo:list-item id="55"> + <fo:list-item-label id="56" end-indent="label-end()"> + <fo:block id="57">1.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="58" start-indent="body-start()"> + <fo:block id="59">First item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item id="60"> + <fo:list-item-label id="61" end-indent="label-end()"> + <fo:block id="62">2.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="63" start-indent="body-start()"> + <fo:block id="64">Second item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item id="65"> + <fo:list-item-label id="66" end-indent="label-end()"> + <fo:block id="67">3.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="68" start-indent="body-start()"> + <fo:block id="69">Third item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block id="70" text-align="center"><fo:instream-foreign-object id="71" + inline-progression-dimension.maximum="50%" content-width="scale-to-fit" + fox:alt-text="An inline SVG"> + <svg xmlns="http://www.w3.org/2000/svg" width="319" height="286.6"> + <g style="fill-opacity:0.7; stroke:black; stroke-width:3" + transform="translate(0, 286.6) scale(1, -1) translate(100, 100)"> + <circle cx="50" cy="86.6" r="80" style="fill:red;"/> + <circle cx="0" cy="0" r="80" style="fill:green;"/> + <circle cx="100" cy="0" r="80" style="fill:blue;"/> + </g> + </svg> + </fo:instream-foreign-object></fo:block> + <fo:block id="72" space-before="inherit">A block containing an <fo:inline id="73" + border="0.5pt solid black" padding="2pt" padding-bottom="0">inline</fo:inline> + element.</fo:block> + <fo:block id="74" space-before="inherit">A block containing a fancy <fo:character id="75" + border="1pt solid black" padding="0 2pt 1pt 2pt" font-family="Symbol" character="♦"/> + character.</fo:block> + <fo:block id="76" space-before="inherit" text-align-last="justify">A leader with special + content: <fo:leader id="77" leader-pattern="use-content"><fo:inline id="78"><fo:character + id="79" character=" "/><fo:inline id="80" border="0.5pt solid black" + padding-left="2pt" padding-right="2pt"><fo:character id="81" baseline-shift="-10%" + character="•"/></fo:inline></fo:inline></fo:leader>.</fo:block> + <fo:block id="second-end" space-before="inherit">Ending the page-sequence.</fo:block> + </fo:flow> + </fo:page-sequence> + +</fo:root> diff --git a/test/java/org/apache/fop/fo/extract-events.xsl b/test/java/org/apache/fop/fo/extract-events.xsl new file mode 100644 index 000000000..6cf42c984 --- /dev/null +++ b/test/java/org/apache/fop/fo/extract-events.xsl @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + exclude-result-prefixes="fo"> + + <xsl:output indent="yes" omit-xml-declaration="yes"/> + + <xsl:template match="/"> + <event> + <xsl:text>start document</xsl:text> + </event> + <xsl:apply-templates/> + <event> + <xsl:text>end document</xsl:text> + </event> + </xsl:template> + + <xsl:template match="fo:root"> + <event>start root</event> + <xsl:apply-templates select="fo:page-sequence"/> + <event>end root</event> + </xsl:template> + + <xsl:template match="fo:*"> + <xsl:call-template name="process.node"> + <xsl:with-param name="id"> + <xsl:apply-templates select="@id"/> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + + <!-- Those elements do not retrieve the id property. + This will have to be fixed at some point. --> + <xsl:template match="fo:footnote|fo:footnote-body"> + <xsl:call-template name="process.node"/> + </xsl:template> + + <xsl:template name="process.node"> + <xsl:param name="id" select="''"/> + <event> + <xsl:text>start </xsl:text> + <xsl:value-of select="local-name()"/> + <xsl:value-of select="$id"/> + </event> + <xsl:apply-templates/> + <event> + <xsl:text>end </xsl:text> + <xsl:value-of select="local-name()"/> + <xsl:value-of select="$id"/> + </event> + </xsl:template> + + <xsl:template match="@id"> + <xsl:text> id="</xsl:text> + <xsl:value-of select="."/> + <xsl:text>"</xsl:text> + </xsl:template> + + <xsl:template match="text()"/> + +</xsl:stylesheet> diff --git a/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java index 90d89d702..fb6ec6a25 100644 --- a/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java @@ -19,33 +19,37 @@ package org.apache.fop.fo.flow.table; +import java.io.FileInputStream; import java.util.Iterator; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FODocumentParser; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.fotreetest.FOTreeUnitTester; +import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.util.ConsoleEventListenerForTests; /** * Superclass for testcases related to tables, factoring the common stuff. */ -abstract class AbstractTableTestCase extends FOTreeUnitTester { +abstract class AbstractTableTest { - private FOTreeUnitTester.FOEventHandlerFactory tableHandlerFactory; + private FODocumentParser documentParser; private TableHandler tableHandler; - public AbstractTableTestCase() throws Exception { - super(); - tableHandlerFactory = new FOEventHandlerFactory() { - public FOEventHandler createFOEventHandler(FOUserAgent foUserAgent) { + protected void setUp(String filename) throws Exception { + createDocumentParser(); + documentParser.setEventListener(new ConsoleEventListenerForTests(filename)); + documentParser.parse(new FileInputStream("test/fotree/unittests/" + filename)); + } + + private void createDocumentParser() { + documentParser = FODocumentParser.newInstance(new FOEventHandlerFactory() { + public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) { tableHandler = new TableHandler(foUserAgent); return tableHandler; } - }; - } - - protected void setUp(String filename) throws Exception { - setUp(filename, tableHandlerFactory); + }); } protected TableHandler getTableHandler() { diff --git a/test/java/org/apache/fop/fo/flow/table/AllTests.java b/test/java/org/apache/fop/fo/flow/table/AllTests.java new file mode 100644 index 000000000..d4b5e8f6f --- /dev/null +++ b/test/java/org/apache/fop/fo/flow/table/AllTests.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.flow.table; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * All test to be added in FOTreeTestSuite + * + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CollapsedConditionalBorderTestCase.class, + IllegalRowSpanTestCase.class, + RowGroupBuilderTestCase.class, + TableColumnColumnNumberTestCase.class, + TooManyColumnsTestCase.class }) +public final class AllTests { +} diff --git a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java index 8bddfd095..7c0301ca7 100644 --- a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java @@ -19,10 +19,14 @@ package org.apache.fop.fo.flow.table; +import static org.junit.Assert.assertEquals; + import java.awt.Color; import java.util.Iterator; import java.util.List; +import org.junit.Test; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode.FONodeIterator; import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; @@ -32,7 +36,7 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; * conditionality into account. The resolved borders are generated by the * collapsed-conditional-borders_test-generator.py Python script. */ -public class CollapsedConditionalBorderTestCase extends AbstractTableTestCase { +public class CollapsedConditionalBorderTestCase extends AbstractTableTest { private final Integer border0pt = new Integer(0); @@ -104,10 +108,6 @@ public class CollapsedConditionalBorderTestCase extends AbstractTableTestCase { {{border8pt, Color.black}, {border6pt, Color.blue}, {border8pt, Color.black}, {border6pt, Color.blue}, {border4pt, Color.black}, {border4pt, Color.black}, {border4pt, Color.red}, {border8pt, Color.black}, {border8pt, Color.black}, {border8pt, Color.black}, {border8pt, Color.black}, {border4pt, Color.blue}, {border4pt, Color.red}, {border6pt, Color.magenta}, {border6pt, Color.magenta}, {border6pt, Color.magenta}} }; - public CollapsedConditionalBorderTestCase() throws Exception { - super(); - } - private static GridUnit getGridUnit(TablePart part) { return (GridUnit) ((List) ((List) part.getRowGroups().get(0)).get(0)).get(0); } @@ -130,6 +130,7 @@ public class CollapsedConditionalBorderTestCase extends AbstractTableTestCase { (Color) resolvedBorder[1]); } + @Test public void testCollapsedConditionalBorders() throws Exception { setUp("table/collapsed-conditional-borders.fo"); int tableNum = 0; @@ -154,6 +155,7 @@ public class CollapsedConditionalBorderTestCase extends AbstractTableTestCase { } while (tableIterator.hasNext()); } + @Test public void testCollapsedConditionalBordersHeaderFooter() throws Exception { setUp("table/collapsed-conditional-borders_header-footer.fo"); int tableNum = 0; diff --git a/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java b/test/java/org/apache/fop/fo/flow/table/ErrorCheckTest.java index 5dbb66a12..b30c64c07 100644 --- a/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/ErrorCheckTest.java @@ -19,23 +19,24 @@ package org.apache.fop.fo.flow.table; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.fop.fo.LoadingException; import org.apache.fop.fo.ValidationException; /** * Abstract class for testing erroneous files, checking that a ValidationException is thrown. */ -abstract class ErrorCheckTestCase extends AbstractTableTestCase { - - public ErrorCheckTestCase() throws Exception { - super(); - } +abstract class ErrorCheckTest extends AbstractTableTest { protected void launchTest(String filename) throws Exception { try { setUp(filename); - fail(); - } catch (ValidationException e) { + fail("Expected ValidationException to be thrown"); + } catch (LoadingException e) { // TODO check location + assertTrue(e.getCause() instanceof ValidationException); } } diff --git a/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java b/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java index bc3d2b4c8..b2e7a2c9d 100644 --- a/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java @@ -19,28 +19,30 @@ package org.apache.fop.fo.flow.table; +import org.junit.Test; + /** * Testcase checking that cells spanning further than their parent element aren't * accepted. */ -public class IllegalRowSpanTestCase extends ErrorCheckTestCase { - - public IllegalRowSpanTestCase() throws Exception { - super(); - } +public class IllegalRowSpanTestCase extends ErrorCheckTest { + @Test public void testBody1() throws Exception { launchTest("table/illegal-row-span_body_1.fo"); } + @Test public void testBody2() throws Exception { launchTest("table/illegal-row-span_body_2.fo"); } + @Test public void testHeader() throws Exception { launchTest("table/illegal-row-span_header.fo"); } + @Test public void testFooter() throws Exception { launchTest("table/illegal-row-span_footer.fo"); } diff --git a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java index 6d2c4f85c..361517a66 100644 --- a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java @@ -19,18 +19,21 @@ package org.apache.fop.fo.flow.table; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import java.util.Iterator; import java.util.List; +import org.junit.Test; + /** * Tests that RowGroupBuilder returns, for each part of a table, the expected number of * row-groups with the expected number or rows in each. */ -public class RowGroupBuilderTestCase extends AbstractTableTestCase { - - public RowGroupBuilderTestCase() throws Exception { - super(); - } +public class RowGroupBuilderTestCase extends AbstractTableTest { /** * Checks that the given table-body(header,footer) will return row groups as expected. @@ -137,34 +140,42 @@ public class RowGroupBuilderTestCase extends AbstractTableTestCase { checkNextTableRowGroups(tableIter, new int[] {2}, new int[] {1, 3}, new int[][] {{2, 1, 3}}); } + @Test public void testWithRowsSimple() throws Exception { checkSimple("table/RowGroupBuilder_simple.fo"); } + @Test public void testWithRowsSpans() throws Exception { checkSpans("table/RowGroupBuilder_spans.fo"); } + @Test public void testNoRowSimple() throws Exception { checkSimple("table/RowGroupBuilder_no-row_simple.fo"); } + @Test public void testNoRowSpans() throws Exception { checkSpans("table/RowGroupBuilder_no-row_spans.fo"); } + @Test public void testNoColWithRowsSimple() throws Exception { checkSimple("table/RowGroupBuilder_no-col_simple.fo"); } + @Test public void testNoColWithRowsSpans() throws Exception { checkSpans("table/RowGroupBuilder_no-col_spans.fo"); } + @Test public void testNoColNoRowSimple() throws Exception { checkSimple("table/RowGroupBuilder_no-col_no-row_simple.fo"); } + @Test public void testNoColNoRowSpans() throws Exception { checkSpans("table/RowGroupBuilder_no-col_no-row_spans.fo"); } diff --git a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java index dc61b1dc2..a21806559 100644 --- a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java @@ -19,13 +19,17 @@ package org.apache.fop.fo.flow.table; +import static org.junit.Assert.assertEquals; + import java.util.Iterator; +import org.junit.Test; + import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.FObj; -public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { +public class TableColumnColumnNumberTestCase extends AbstractTableTest { /** * A percentBaseContext that mimics the behaviour of TableLM for computing the widths @@ -47,10 +51,6 @@ public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { private TablePercentBaseContext percentBaseContext = new TablePercentBaseContext(); - public TableColumnColumnNumberTestCase() throws Exception { - super(); - } - private void checkColumn(Table t, int number, boolean isImplicit, int spans, int repeated, int width) { TableColumn c = t.getColumn(number - 1); // TODO a repeated column has a correct number only for its first occurrence @@ -61,6 +61,7 @@ public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { assertEquals(width, c.getColumnWidth().getValue(percentBaseContext)); } + @Test public void testColumnNumber() throws Exception { setUp("table/table-column_column-number.fo"); Iterator tableIter = getTableIterator(); @@ -97,6 +98,7 @@ public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { } } + @Test public void testImplicitColumns() throws Exception { setUp("table/implicit_columns_column-number.fo"); percentBaseContext.setUnitaryWidth(100000); diff --git a/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java b/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java index 0c7effd5b..76a5d196d 100644 --- a/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java @@ -19,33 +19,36 @@ package org.apache.fop.fo.flow.table; +import org.junit.Test; -public class TooManyColumnsTestCase extends ErrorCheckTestCase { - - public TooManyColumnsTestCase() throws Exception { - super(); - } +public class TooManyColumnsTestCase extends ErrorCheckTest { + @Test public void testBody1() throws Exception { launchTest("table/too-many-columns_body_1.fo"); } + @Test public void testBody2() throws Exception { launchTest("table/too-many-columns_body_2.fo"); } + @Test public void testBody3() throws Exception { launchTest("table/too-many-columns_body_3.fo"); } + @Test public void testBody4() throws Exception { launchTest("table/too-many-columns_body_4.fo"); } + @Test public void testHeader() throws Exception { launchTest("table/too-many-columns_header.fo"); } + @Test public void testFooter() throws Exception { launchTest("table/too-many-columns_footer.fo"); } diff --git a/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java b/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java new file mode 100644 index 000000000..1a5e38291 --- /dev/null +++ b/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.flow.table; + +/** + * This class aims at easing testing, by preventing the event notification system from + * getting in the way just to issue an Unimplemented Feature warning. + */ +public final class UnimplementedWarningNeutralizer { + + private UnimplementedWarningNeutralizer() { } + + /** + * Neutralizes Unimplemented Feature events from the {@link TableAndCaption} and + * {@link TableCaption} classes. + */ + public static void neutralizeUnimplementedWarning() { + TableAndCaption.notImplementedWarningGiven = true; + TableCaption.notImplementedWarningGiven = true; + } +} diff --git a/test/java/org/apache/fop/fo/pagination/AllTests.java b/test/java/org/apache/fop/fo/pagination/AllTests.java new file mode 100644 index 000000000..40990cb06 --- /dev/null +++ b/test/java/org/apache/fop/fo/pagination/AllTests.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.pagination; + +import org.junit.runners.Suite; +import org.junit.runner.RunWith; + +/** + * All test to be added in FOTreeTestSuite + * + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ PageSequenceMasterTestCase.class, + RepeatablePageMasterAlternativesTestCase.class}) +public final class AllTests { +} diff --git a/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java new file mode 100644 index 000000000..ad4f991ac --- /dev/null +++ b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.pagination; + +import static org.junit.Assert.fail; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.layoutmgr.BlockLevelEventProducer; +import org.junit.Test; +import org.xml.sax.Locator; + + +/** + * Unit Test for PageSequenceMaster + * + */ +public class PageSequenceMasterTestCase { + + /** + * Test that block level events are produced in line with + * XSL:FO - 6.4.8 fo:page-sequence-master - + * "It is an error if the entire sequence of sub-sequence-specifiers children is exhausted + * while some areas returned by an fo:flow are not placed. Implementations may recover, + * if possible, by re-using the sub-sequence-specifier that was last used to generate a page." + * + * @throws Exception exception + */ + @Test + public void testGetNextSimplePageMasterExhausted() throws Exception { + + //Test when the last sub-sequence specifier is not repeatable + testGetNextSimplePageMasterExhausted(true); + + //Test when the last sub-sequence specifier is repeatable + testGetNextSimplePageMasterExhausted(false); + + } + + private void testGetNextSimplePageMasterExhausted(boolean canResume) throws Exception { + + SimplePageMaster spm = mock(SimplePageMaster.class); + SubSequenceSpecifier mockSinglePageMasterReference + = mock(SubSequenceSpecifier.class); + BlockLevelEventProducer mockBlockLevelEventProducer = mock(BlockLevelEventProducer.class); + + // subject under test + PageSequenceMaster pageSequenceMaster = createPageSequenceMaster( + mockBlockLevelEventProducer); + pageSequenceMaster.addSubsequenceSpecifier(mockSinglePageMasterReference); + + //Setup to mock the exhaustion of the last sub-sequence specifier + when(mockSinglePageMasterReference.getNextPageMaster(anyBoolean(), anyBoolean(), + anyBoolean(), anyBoolean())).thenReturn(null, spm); + + //Need this for the method to return normally + when(mockSinglePageMasterReference.canProcess(anyString())).thenReturn(true); + + when(mockSinglePageMasterReference.isReusable()).thenReturn(canResume); + + pageSequenceMaster.getNextSimplePageMaster(false, false, false, false, null); + + verify(mockBlockLevelEventProducer).pageSequenceMasterExhausted((Locator)anyObject(), + anyString(), eq(canResume), (Locator)anyObject()); + } + + /** + * Test that PageProductionException is thrown if the final simple-page-master + * cannot handle the main-flow of the page sequence + * @throws Exception exception + */ + @Test + public void testGetNextSimplePageMasterException() throws Exception { + + final String mainFlowRegionName = "main"; + final String emptyFlowRegionName = "empty"; + + // This will represent a page master that does not map to the main flow + // of the page sequence + SimplePageMaster mockEmptySPM = mock(SimplePageMaster.class); + Region mockRegion = mock(Region.class); + SinglePageMasterReference mockSinglePageMasterReference + = mock(SinglePageMasterReference.class); + BlockLevelEventProducer mockBlockLevelEventProducer = mock(BlockLevelEventProducer.class); + + LayoutMasterSet mockLayoutMasterSet = mock(LayoutMasterSet.class); + //The layout master set should return the empty page master + when(mockLayoutMasterSet.getSimplePageMaster(anyString())).thenReturn(mockEmptySPM); + when(mockEmptySPM.getRegion(anyInt())).thenReturn(mockRegion); + + when(mockRegion.getRegionName()).thenReturn(emptyFlowRegionName); + + when(mockSinglePageMasterReference.getNextPageMaster(anyBoolean(), anyBoolean(), + anyBoolean(), anyBoolean())) + .thenReturn(null, mockEmptySPM); + + PageSequenceMaster pageSequenceMaster = createPageSequenceMaster(mockLayoutMasterSet, + mockBlockLevelEventProducer); + + pageSequenceMaster.startOfNode(); + pageSequenceMaster.addSubsequenceSpecifier(mockSinglePageMasterReference); + + try { + pageSequenceMaster.getNextSimplePageMaster(false, false, false, false, + mainFlowRegionName); + fail("The next simple page master does not refer to the main flow"); + } catch (PageProductionException ppe) { + //Passed test + } + } + + + private PageSequenceMaster createPageSequenceMaster( + BlockLevelEventProducer blockLevelEventProducer) throws FOPException { + + return createPageSequenceMaster(mock(LayoutMasterSet.class), blockLevelEventProducer); + } + + private PageSequenceMaster createPageSequenceMaster(LayoutMasterSet layoutMasterSet, + BlockLevelEventProducer blockLevelEventProducer) throws FOPException { + FONode mockParent = mock(FONode.class); + Root mockRoot = mock(Root.class); + + //Stub generic components + when(mockParent.getRoot()).thenReturn(mockRoot); + when(mockRoot.getLayoutMasterSet()).thenReturn(layoutMasterSet); + + PageSequenceMaster psm = new PageSequenceMaster(mockParent, blockLevelEventProducer); + psm.startOfNode(); + + return psm; + } + +} + diff --git a/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java new file mode 100644 index 000000000..5ac4860dc --- /dev/null +++ b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.pagination; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.NumericProperty; +import org.apache.fop.fo.properties.Property; + +import org.junit.Test; + +/** + * Unit Test for RepeatablePageMasterAlternatives + * + */ +public class RepeatablePageMasterAlternativesTestCase implements Constants { + + /** + * + * @throws Exception exception + */ + @Test + public void testIsInfinite1() throws Exception { + // Create fixture + Property maximumRepeats = mock(Property.class); + ConditionalPageMasterReference cpmr = createCPMR("empty"); + + when(maximumRepeats.getEnum()).thenReturn(EN_NO_LIMIT); + + RepeatablePageMasterAlternatives objectUnderTest + = createRepeatablePageMasterAlternatives(cpmr, maximumRepeats); + + assertTrue("is infinite", objectUnderTest.isInfinite()); + } + + /** + * + * @throws Exception exception + */ + @Test + public void testIsInfinite2() throws Exception { + // Create fixture + Property maximumRepeats = mock(Property.class); + ConditionalPageMasterReference cpmr = createCPMR("empty"); + + NumericProperty numericProperty = mock(NumericProperty.class); + + final int maxRepeatNum = 0; + assertTrue(maxRepeatNum != EN_NO_LIMIT); + + when(maximumRepeats.getEnum()).thenReturn(maxRepeatNum); + when(maximumRepeats.getNumeric()).thenReturn(numericProperty); + + RepeatablePageMasterAlternatives objectUnderTest + = createRepeatablePageMasterAlternatives(createCPMR("empty"), + maximumRepeats); + + assertTrue("is infinite", !objectUnderTest.isInfinite()); + } + + /** + * Test that an infinite sequence of empty page masters has + * willTerminiate() returning false + * @throws Exception exception + */ + @Test + public void testCanProcess1() throws Exception { + // Create fixture + Property maximumRepeats = mock(Property.class); + ConditionalPageMasterReference cpmr = createCPMR("empty"); + + when(maximumRepeats.getEnum()).thenReturn(EN_NO_LIMIT); + when(cpmr.isValid(anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean())) + .thenReturn(true); + + RepeatablePageMasterAlternatives objectUnderTest + = createRepeatablePageMasterAlternatives(cpmr, maximumRepeats); + + //Fixture assertion + assertTrue("Should be infinite", objectUnderTest.isInfinite()); + + //Test assertion + assertTrue("Infinite sequences that do not process the main flow will " + + " not terminate", + !objectUnderTest.canProcess("main-flow")); + } + /** + * Test that a finite sequence of simple page masters has + * willTerminate() returning true + * + * @throws Exception exception + */ + @Test + public void testCanProcess2() throws Exception { + // Create fixture + Property maximumRepeats = mock(Property.class); + NumericProperty numericProperty = mock(NumericProperty.class); + + final int maxRepeatNum = 0; + + when(maximumRepeats.getEnum()).thenReturn(maxRepeatNum); + when(maximumRepeats.getNumeric()).thenReturn(numericProperty); + + RepeatablePageMasterAlternatives objectUnderTest + = createRepeatablePageMasterAlternatives(createCPMR("empty"), + maximumRepeats); + + //Fixture assertion + assertTrue("Should be finite sequence", !objectUnderTest.isInfinite()); + + //Test assertion + assertTrue("Finite sequences will terminate", + objectUnderTest.canProcess("main-flow")); + } + + private ConditionalPageMasterReference createCPMR(String regionName) { + ConditionalPageMasterReference cpmr = mock(ConditionalPageMasterReference.class); + SimplePageMaster master = mock(SimplePageMaster.class); + Region region = mock(Region.class); + when(master.getRegion(anyInt())).thenReturn(region); + when(region.getRegionName()).thenReturn(regionName); + when(cpmr.getMaster()).thenReturn(master); + + return cpmr; + } + + private RepeatablePageMasterAlternatives createRepeatablePageMasterAlternatives( + ConditionalPageMasterReference cpmr, Property maximumRepeats) throws Exception { + + PropertyList pList = mock(PropertyList.class); + + when(pList.get(anyInt())).thenReturn(maximumRepeats); + + PageSequenceMaster parent = mock(PageSequenceMaster.class); + when(parent.getName()).thenReturn("fo:page-sequence-master"); + + RepeatablePageMasterAlternatives sut = new RepeatablePageMasterAlternatives(parent); + + sut.startOfNode(); + sut.bind(pList); + sut.addConditionalPageMasterReference(cpmr); + return sut; + } + +} + diff --git a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java new file mode 100644 index 000000000..cd5d545ff --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FONodeMocks; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.flow.AbstractGraphics; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.InstreamForeignObject; + + +/** + * Tests that the fox:alt-text property is correctly set on objects that support it. + */ +public class AltTextHolderTestCase { + + private final String altText = "alternative text"; + + @Test + public void externalGraphicHasAltText() throws FOPException { + testAltTextGetter(new ExternalGraphic(mockFONode())); + } + + @Test + public void instreamForeignObjectHasAltText() throws FOPException { + testAltTextGetter(new InstreamForeignObject(mockFONode())); + } + + private FONode mockFONode() { + FONode mockFONode = FONodeMocks.mockFONode(); + FOUserAgent mockFOUserAgent = mockFONode.getFOEventHandler().getUserAgent(); + when(mockFOUserAgent.isAccessibilityEnabled()).thenReturn(true); + return mockFONode; + } + + private void testAltTextGetter(AbstractGraphics g) throws FOPException { + g.bind(mockPropertyList()); + assertEquals(altText, g.getAltText()); + } + + private PropertyList mockPropertyList() throws PropertyException { + PropertyList mockPropertyList = PropertyListMocks.mockPropertyList(); + Property mockAltText = mock(Property.class); + when(mockAltText.getString()).thenReturn(altText); + when(mockPropertyList.get(Constants.PR_X_ALT_TEXT)).thenReturn(mockAltText); + return mockPropertyList; + } + +} diff --git a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java new file mode 100644 index 000000000..352a39713 --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FONodeMocks; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.flow.table.UnimplementedWarningNeutralizer; + +/** + * This tests that all the FONodes that implement CommonAccessibilityHolder correctly configure + * the CommonAccessibility property. + */ +public class CommonAccessibilityHolderTestCase { + + private static final List<Class<? extends CommonAccessibilityHolder>> IMPLEMENTATIONS + = new ArrayList<Class<? extends CommonAccessibilityHolder>>(); + + private final String role = "role"; + + private final String sourceDocument = "source document"; + + static { + /* This triggers 'unimplemented feature' FO validation events so that the event system is + * not triggered when testing, avoiding extra convoluted dependency stubbing. */ + UnimplementedWarningNeutralizer.neutralizeUnimplementedWarning(); + + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.BasicLink.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Block.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.bookmarks.Bookmark.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.bookmarks.BookmarkTitle.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ExternalGraphic.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Footnote.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.FootnoteBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.InitialPropertySet.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Inline.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.InstreamForeignObject.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Leader.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListBlock.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItem.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItemBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItemLabel.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumber.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumberCitation.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumberCitationLast.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.Root.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.Table.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableAndCaption.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableCaption.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableCell.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableFooter.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableHeader.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableRow.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.Title.class); + } + + /** + * Bind should be overridden to correctly configure the CommonAccessibility property + * @throws Exception - + */ + @Test + public void bindMustSetRoleAndSourceDoc() throws Exception { + final PropertyList mockPList = mockPropertyList(); + final FONode parent = FONodeMocks.mockFONode(); + for (Class<? extends CommonAccessibilityHolder> clazz : IMPLEMENTATIONS) { + Constructor<? extends CommonAccessibilityHolder> constructor + = clazz.getConstructor(FONode.class); + CommonAccessibilityHolder sut = constructor.newInstance(parent); + ((FONode)sut).bind(mockPList); + String errorMessage = "Test failed for " + clazz + ": "; + assertEquals(errorMessage, role, sut.getCommonAccessibility().getRole()); + assertEquals(errorMessage, sourceDocument, + sut.getCommonAccessibility().getSourceDocument()); + } + } + + private PropertyList mockPropertyList() throws PropertyException { + final PropertyList mockPList = PropertyListMocks.mockPropertyList(); + PropertyListMocks.mockTableProperties(mockPList); + PropertyListMocks.mockCommonBorderPaddingBackgroundProps(mockPList); + mockRoleProperty(mockPList); + mockSourceDocProperty(mockPList); + return mockPList; + } + + private void mockRoleProperty(PropertyList mockPList) throws PropertyException { + final Property mockRoleProperty = mock(Property.class); + when(mockRoleProperty.getString()).thenReturn(role); + when(mockPList.get(Constants.PR_ROLE)).thenReturn(mockRoleProperty); + } + + private void mockSourceDocProperty(PropertyList mockPList) throws PropertyException { + final Property mockSourceDocProperty = mock(Property.class); + when(mockSourceDocProperty.getString()).thenReturn(sourceDocument); + when(mockPList.get(Constants.PR_SOURCE_DOCUMENT)).thenReturn(mockSourceDocProperty); + } + +} diff --git a/test/java/org/apache/fop/fo/properties/PropertyListMocks.java b/test/java/org/apache/fop/fo/properties/PropertyListMocks.java new file mode 100644 index 000000000..380f6e5a8 --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/PropertyListMocks.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +/** + * A helper class for mocking a property list. + */ +public final class PropertyListMocks { + + private PropertyListMocks() { } + + /** + * Creates and returns a mock property list returning a generic default for the + * {@link PropertyList#get(int)} method. + * + * @return a mock property list + */ + public static PropertyList mockPropertyList() { + try { + final PropertyList mockPList = mock(PropertyList.class); + final Property mockGenericProperty = PropertyMocks.mockGenericProperty(); + when(mockPList.get(anyInt())).thenReturn(mockGenericProperty); + return mockPList; + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + + /** + * Overrides with working mock properties the values returned by + * {@link PropertyList#get(int)} for {@link Constants#PR_COLUMN_NUMBER}, + * {@link Constants#PR_NUMBER_COLUMNS_SPANNED}, + * {@link Constants#PR_NUMBER_ROWS_SPANNED} and {@link Constants#PR_BORDER_COLLAPSE}. + * + * @param mockPList a mock property list + */ + public static void mockTableProperties(PropertyList mockPList) { + try { + final Property mockNumberProperty = PropertyMocks.mockNumberProperty(); + when(mockPList.get(Constants.PR_COLUMN_NUMBER)).thenReturn(mockNumberProperty); + when(mockPList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)).thenReturn(mockNumberProperty); + when(mockPList.get(Constants.PR_NUMBER_ROWS_SPANNED)).thenReturn(mockNumberProperty); + + final Property borderCollapseProperty = mock(Property.class); + when(borderCollapseProperty.getEnum()).thenReturn(Constants.EN_SEPARATE); + when(mockPList.get(Constants.PR_BORDER_COLLAPSE)).thenReturn(borderCollapseProperty); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + + /** + * Overrides with a working mock property the value returned by + * {@link PropertyList#getBorderPaddingBackgroundProps()}. + * + * @param mockPList a mock property list + */ + public static void mockCommonBorderPaddingBackgroundProps(PropertyList mockPList) { + try { + final CommonBorderPaddingBackground mockCommonBorderPaddingBackground + = mock(CommonBorderPaddingBackground.class); + when(mockPList.getBorderPaddingBackgroundProps()) + .thenReturn(mockCommonBorderPaddingBackground); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/test/java/org/apache/fop/fo/properties/PropertyMocks.java b/test/java/org/apache/fop/fo/properties/PropertyMocks.java new file mode 100644 index 000000000..40c923249 --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/PropertyMocks.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.datatypes.Numeric; +import org.apache.fop.datatypes.PercentBaseContext; +import org.apache.fop.fo.Constants; + +/** + * Helper class to create mocks of various kinds of properties. + */ +public final class PropertyMocks { + + private PropertyMocks() { } + + /** + * Creates and returns a generic mock property returning decent defaults for the + * {@link Property#getString()}, {@link Property#getEnum()} and + * {@link Property#getLengthRange()} methods. + * + * @return a mock all-purpose property + */ + public static Property mockGenericProperty() { + final Property mockGenericProperty = mock(Property.class); + when(mockGenericProperty.getString()).thenReturn("A non-empty string"); + when(mockGenericProperty.getEnum()).thenReturn(Constants.EN_SPACE); + LengthRangeProperty lengthRangeProperty = mockLengthRangeProperty(); + when(mockGenericProperty.getLengthRange()).thenReturn(lengthRangeProperty); + return mockGenericProperty; + } + + private static LengthRangeProperty mockLengthRangeProperty() { + final LengthRangeProperty mockLengthRangeProperty = mock(LengthRangeProperty.class); + final Property optimum = mockOptimumProperty(); + when(mockLengthRangeProperty.getOptimum(any(PercentBaseContext.class))) + .thenReturn(optimum); + return mockLengthRangeProperty; + } + + /** + * Creates and returns a mock property returning a decent default for the + * {@link Property#getNumeric()} method. + * + * @return a mock number property + */ + public static Property mockNumberProperty() { + final Property mockNumberProperty = mock(Property.class); + final Numeric mockNumeric = mock(Numeric.class); + when(mockNumberProperty.getNumeric()).thenReturn(mockNumeric); + return mockNumberProperty; + } + + private static Property mockOptimumProperty() { + final Property optimum = mock(Property.class); + when(optimum.isAuto()).thenReturn(true); + return optimum; + } + +} diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java index 17d614829..49c447583 100644 --- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java +++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java @@ -19,16 +19,19 @@ package org.apache.fop.fonts; +import static org.junit.Assert.assertEquals; + import java.io.File; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; /** * */ -public class DejaVuLGCSerifTest extends TestCase { +public class DejaVuLGCSerifTestCase { - private FontResolver fontResolver = FontManager.createMinimalFontResolver(); + private FontResolver fontResolver = FontManager.createMinimalFontResolver(false); private CustomFont font; /** @@ -37,8 +40,9 @@ public class DejaVuLGCSerifTest extends TestCase { * @throws Exception * if the test fails. */ + @Before public void setUp() throws Exception { - File file = new File("test/resources/fonts/DejaVuLGCSerif.ttf"); + File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); font = FontLoader.loadFont(file, "", true, EmbeddingMode.AUTO, EncodingMode.AUTO, fontResolver); } @@ -46,6 +50,7 @@ public class DejaVuLGCSerifTest extends TestCase { /** * Simple test to see if font name was detected correctly. */ + @Test public void testFontName() { assertEquals("DejaVuLGCSerif", font.getFontName()); } diff --git a/test/java/org/apache/fop/fonts/EncodingModeTestCase.java b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java new file mode 100644 index 000000000..5fd9b4f37 --- /dev/null +++ b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EncodingModeTestCase { + + @Test + public void testGetName() { + assertEquals("auto", EncodingMode.AUTO.getName()); + assertEquals("single-byte", EncodingMode.SINGLE_BYTE.getName()); + assertEquals("cid", EncodingMode.CID.getName()); + } + + @Test + public void testGetValue() { + assertEquals(EncodingMode.AUTO, EncodingMode.getValue("auto")); + assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getValue("single-byte")); + assertEquals(EncodingMode.CID, EncodingMode.getValue("cid")); + } +} diff --git a/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java new file mode 100644 index 000000000..c17062e7b --- /dev/null +++ b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts; + +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.transform.TransformerException; + +import org.junit.Test; +import org.xml.sax.SAXException; + +import org.apache.xmlgraphics.util.MimeConstants; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.events.EventProcessingTestCase; + +/** + * Testing font events. + */ +public class FontEventProcessingTestCase { + + private EventProcessingTestCase eventsTests = new EventProcessingTestCase(); + + private static final String CONFIG_BASE_DIR = EventProcessingTestCase.CONFIG_BASE_DIR; + + @Test + public void testFont() throws FOPException, TransformerException, IOException, SAXException { + InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); + eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".fontSubstituted", + MimeConstants.MIME_PDF); + } + + @Test + public void testFontWithBadDirectory() throws FOPException, TransformerException, IOException, + SAXException { + InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); + eventsTests.doTest(inStream, CONFIG_BASE_DIR + "test_fonts_directory_bad.xconf", + FontEventProducer.class.getName() + ".fontDirectoryNotFound", + MimeConstants.MIME_PDF); + } + + @Test + public void testSVGFontStrokedAsShapes() throws FOPException, TransformerException, IOException, + SAXException { + // svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the + // missing font is stroked as shapes while the fonts that exists is stroked as text + InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo"); + eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes", + MimeConstants.MIME_PDF); + } + +} diff --git a/test/java/org/apache/fop/fonts/substituted-font.fo b/test/java/org/apache/fop/fonts/substituted-font.fo new file mode 100644 index 000000000..551527522 --- /dev/null +++ b/test/java/org/apache/fop/fonts/substituted-font.fo @@ -0,0 +1,14 @@ +<?xml version="1.0" standalone="no"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="420pt" page-width="320pt" margin="10pt"> + <fo:region-body background-color="#F0F0F0"/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block font-family="blah">This block uses an unknown font.</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/java/org/apache/fop/fonts/svg-fonts.fo b/test/java/org/apache/fop/fonts/svg-fonts.fo new file mode 100644 index 000000000..0c5f3f599 --- /dev/null +++ b/test/java/org/apache/fop/fonts/svg-fonts.fo @@ -0,0 +1,37 @@ +<?xml version="1.0" standalone="no"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page"> + <fo:region-body /> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page"> + <fo:flow flow-name="xsl-region-body"> + <fo:block> + <fo:instream-foreign-object> + <svg:svg width="250" height="50"> + <svg:font horiz-adv-x="1000"> + <svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100" + underline-thickness="50" /> + <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" /> + <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" /> + <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" /> + <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" /> + </svg:font> + <svg:font horiz-adv-x="1000"> + <!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path --> + <svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100" + underline-thickness="50" /> + <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" /> + <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" /> + <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" /> + <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" /> + </svg:font> + <svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text> + <svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text> + </svg:svg> + </fo:instream-foreign-object> + </fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java new file mode 100644 index 000000000..825f71ac1 --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts.truetype; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +/** + * Tests {@link GlyfTable}. + */ +public class GlyfTableTestCase { + + private final static class DirData { + + final long offset; + final long length; + + DirData(long offset, long length) { + this.offset = offset; + this.length = length; + } + } + + private FontFileReader subsetReader; + + private long[] glyphOffsets; + + private FontFileReader originalFontReader; + + @Before + public void setUp() throws IOException { + originalFontReader = new FontFileReader("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); + } + + /** + * Tests that composed glyphs are included in the glyph subset if a composite glyph is used. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testPopulateGlyphsWithComposites() throws IOException { + // Glyph 408 -> U+01D8 "uni01D8" this is a composite glyph. + int[] composedIndices = setupTest(408); + + int[] expected = new int[composedIndices.length]; + expected[1] = 6; + expected[5] = 2; + expected[6] = 4; + + assertArrayEquals(expected, composedIndices); + } + + /** + * Tests that no glyphs are added if there are no composite glyphs the subset. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testPopulateNoCompositeGlyphs() throws IOException { + int[] composedIndices = setupTest(36, 37, 38); // "A", "B", "C" + int[] expected = new int[composedIndices.length]; + + // There should be NO composite glyphs + assertArrayEquals(expected, composedIndices); + } + + /** + * Tests that glyphs aren't remapped twice if the glyph before a composite glyph has 0-length. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testGlyphsNotRemappedTwice() throws IOException { + int composedGlyph = 12; + // The order of these glyph indices, must NOT be changed! (see javadoc above) + int[] composedIndices = setupTest(1, 2, 3, 16, 2014, 4, 7, 8, 13, 2015, composedGlyph); + + // There are 2 composed glyphs within the subset + int[] expected = new int[composedIndices.length]; + expected[10] = composedGlyph; + + assertArrayEquals(expected, composedIndices); + } + + /** + * Tests that the correct glyph is included in the subset, when a composite glyph composed of a + * composite glyph is used. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testSingleRecursionStep() throws IOException { + // Glyph 2077 -> U+283F "uni283F" this is composed of a composite glyph (recursive). + int[] composedIndices = setupTest(2077); + + int[] expected = new int[composedIndices.length]; + expected[1] = 2; + + assertArrayEquals(expected, composedIndices); + } + + private int[] setupTest(int... glyphIndices) throws IOException { + Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>(); + int index = 0; + glyphs.put(0, index++); // Glyph 0 (.notdef) must ALWAYS be in the subset + + for (int glyphIndex : glyphIndices) { + glyphs.put(glyphIndex, index++); + } + setupSubsetReader(glyphs); + readLoca(); + + return retrieveIndicesOfComposedGlyphs(); + } + + private void setupSubsetReader(Map<Integer, Integer> glyphs) throws IOException { + TTFSubSetFile fontFile = new TTFSubSetFile(); + fontFile.readFont(originalFontReader, "Deja", glyphs); + byte[] subsetFont = fontFile.getFontSubset(); + InputStream intputStream = new ByteArrayInputStream(subsetFont); + subsetReader = new FontFileReader(intputStream); + } + + private void readLoca() throws IOException { + DirData loca = getTableData("loca"); + int numberOfGlyphs = (int) (loca.length - 4) / 4; + glyphOffsets = new long[numberOfGlyphs]; + subsetReader.seekSet(loca.offset); + + for (int i = 0; i < numberOfGlyphs; i++) { + glyphOffsets[i] = subsetReader.readTTFULong(); + } + } + + private int[] retrieveIndicesOfComposedGlyphs() throws IOException { + DirData glyf = getTableData("glyf"); + int[] composedGlyphIndices = new int[glyphOffsets.length]; + + for (int i = 0; i < glyphOffsets.length; i++) { + long glyphOffset = glyphOffsets[i]; + if (i != glyphOffsets.length - 1 && glyphOffset == glyphOffsets[i + 1]) { + continue; + } + subsetReader.seekSet(glyf.offset + glyphOffset); + short numberOfContours = subsetReader.readTTFShort(); + if (numberOfContours < 0) { + subsetReader.skip(8); + subsetReader.readTTFUShort(); // flags + int glyphIndex = subsetReader.readTTFUShort(); + composedGlyphIndices[i] = glyphIndex; + } + } + return composedGlyphIndices; + } + + private DirData getTableData(String tableName) throws IOException { + subsetReader.seekSet(0); + subsetReader.skip(12); + String name; + do { + name = subsetReader.readTTFString(4); + subsetReader.skip(4 * 3); + } while (!name.equals(tableName)); + + subsetReader.skip(-8); // We've found the table, go back to get the data we skipped over + return new DirData(subsetReader.readTTFLong(), subsetReader.readTTFLong()); + } + + private void assertArrayEquals(int[] expected, int[] actual) { + assertTrue(Arrays.equals(expected, actual)); + } +} diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java new file mode 100644 index 000000000..d6555c32e --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts.truetype; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + +import org.apache.fop.fonts.EmbeddingMode; +import org.apache.fop.fonts.EncodingMode; +import org.apache.fop.fonts.FontManager; +import org.apache.fop.fonts.FontResolver; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Test case for {@link TTFFontLoader}. + */ +public class TTFFontLoaderTestCase { + + @Test + public void testUseKerning() throws IOException { + boolean useComplexScriptFeatures = false; + File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); + String absoluteFilePath = file.toURI().toURL().toExternalForm(); + FontResolver resolver = FontManager.createMinimalFontResolver(useComplexScriptFeatures); + String fontName = "Deja Vu"; + boolean embedded = false; + boolean useKerning = true; + + TTFFontLoader fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, + EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resolver); + assertTrue(fontLoader.getFont().hasKerningInfo()); + useKerning = false; + + fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, EmbeddingMode.AUTO, + EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resolver); + assertFalse(fontLoader.getFont().hasKerningInfo()); + } +} diff --git a/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java new file mode 100644 index 000000000..93443a0d9 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts.type1; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.awt.Rectangle; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.junit.Test; + +/** + * Test case for {@link AFMParser}. + */ +public class AFMParserTestCase { + + private AFMParser sut = new AFMParser(); + + /** + * We're testing with two identical files except one has: + * EncodingScheme AdobeStandardEncoding + * the other has: + * EncodingScheme ExpectedEncoding + * Both files have the correct character metrics data, and we're checking that both are handled + * consistently with both encoding settings. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testMappingAgainstAdobeStandardEncoding() throws IOException { + InputStream expectedStream = getClass().getResourceAsStream( + "adobe-charset_unknown-encoding.afm"); + InputStream adobeStandardStream = getClass().getResourceAsStream( + "adobe-charset_adobe-encoding.afm"); + AFMFile expectedParser = sut.parse(expectedStream, null); + AFMFile adobeStandard = sut.parse(adobeStandardStream, null); + List<AFMCharMetrics> adobeMetrics = adobeStandard.getCharMetrics(); + checkCharMtrxList(true, expectedParser.getCharMetrics(), adobeMetrics); + + compareMetrics(adobeMetrics); + + nonAdobeCharsetUnknownEncoding(adobeMetrics); + + nonAdobeCharsetAdobeEncoding(adobeMetrics); + } + + private void compareMetrics(List<AFMCharMetrics> charMetrics) { + // in order to ensure that every character is parsed properly, we're going to check them + // against the AFM file (bboxes were created with a counter) + AdobeStandardEncoding[] standardEncoding = AdobeStandardEncoding.values(); + for (int i = 0; i < charMetrics.size(); i++) { + Rectangle expectedBbox = new Rectangle(i + 1, i + 1, 0, 0); + AFMCharMetrics thisMetric = charMetrics.get(i); + assertTrue(thisMetric.getBBox().equals(expectedBbox)); + assertEquals(thisMetric.getCharName(), standardEncoding[i].getAdobeName()); + } + } + + /** + * A non-adobe encoded file is tested, all the character codes are not AdobeStandardEncoding and + * the encoding is not AdobeStandardEncoding, we are checking a failure case here. Checking that + * the AdobeStandardEncoding isn't forced on other encodings. + * + * @param expected the AdobeStandardEncoding encoded character metrics list + * @throws IOException if an IO error occurs + */ + private void nonAdobeCharsetUnknownEncoding(List<AFMCharMetrics> expected) + throws IOException { + InputStream inStream = getClass().getResourceAsStream( + "notadobe-charset_unknown-encoding.afm"); + AFMFile afmFile = sut.parse(inStream, null); + List<AFMCharMetrics> unknownEncodingMetrics = afmFile.getCharMetrics(); + checkCharMtrxList(false, expected, unknownEncodingMetrics); + } + + /** + * This tests a poorly encoded file, it has AdobeStandardEncoding. We are checking that the + * metrics are correctly analysed against properly encoded char metrics. + * + * @param expected + * @throws IOException + */ + private void nonAdobeCharsetAdobeEncoding(List<AFMCharMetrics> expected) + throws IOException { + InputStream inStream = getClass().getResourceAsStream( + "notadobe-charset_adobe-encoding.afm"); + AFMFile afmFile = sut.parse(inStream, null); + List<AFMCharMetrics> correctedCharMetrics = afmFile.getCharMetrics(); + checkCharMtrxList(true, expected, correctedCharMetrics); + } + + private boolean charMetricsEqual(AFMCharMetrics o1, AFMCharMetrics o2) { + return o1.getCharCode() == o2.getCharCode() + && objectEquals(o1.getCharacter(), o2.getCharacter()) + && o1.getWidthX() == o2.getWidthX() + && o1.getWidthY() == o2.getWidthY() + && objectEquals(o1.getBBox(), o2.getBBox()); + } + + private void checkCharMtrxList(boolean expectedResult, List<AFMCharMetrics> expectedList, + List<AFMCharMetrics> actualList) { + assertEquals(expectedList.size(), actualList.size()); + for (int i = 0; i < expectedList.size(); i++) { + assertEquals(expectedResult, charMetricsEqual(expectedList.get(i), actualList.get(i))); + } + } + + private boolean objectEquals(Object o1, Object o2) { + return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2)); + } +} diff --git a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.txt b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.txt new file mode 100644 index 000000000..e39486a31 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.txt @@ -0,0 +1,213 @@ +# +# Name: Adobe Standard Encoding to Unicode +# Unicode version: 2.0 +# Table version: 1.0 +# Date: 2011 July 12 +# +# Copyright (c) 1991-2011 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). No +# claims are made as to fitness for any particular purpose. No warranties of +# any kind are expressed or implied. The recipient agrees to determine +# applicability of information provided. If this file has been provided on +# magnetic media by Unicode, Inc., the sole remedy for any claim will be +# exchange of defective media within 90 days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# Format: 4 tab-delimited fields: +# +# (1) The Unicode value (in hexadecimal) +# (2) The Adobe Standard Encoding code point (in hexadecimal) +# (3) # Unicode name +# (4) # PostScript character name +# +# General Notes: +# +# The Unicode values in this table were produced as the result of applying +# the algorithm described in the section "Populating a Unicode space" in the +# document "Unicode and Glyph Names," at +# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html +# to the characters encoded in Adobe Standard Encoding. Note that some +# Standard Encoding characters, such as "space", are mapped to 2 Unicode +# values. Refer to the above document for more details. +# +# 2011 July 12: The above link is no longer valid. For comparable, +# more current information, see the document, "Glyph", at: +# <http://www.adobe.com/devnet/opentype/archives/glyph.html> +# +# Revision History: +# +# [v1.0, 2011 July 12] +# Updated terms of use to current wording. +# Updated contact information and document link. +# No changes to the mapping data. +# +# [v0.2, 30 March 1999] +# Different algorithm to produce Unicode values (see notes above) results in +# some character codes being mapped to 2 Unicode values. Updated Unicode +# names to Unicode 2.0 names. +# +# [v0.1, 5 May 1995] First release. +# +# Use the Unicode reporting form <http://www.unicode.org/reporting.html> +# for any questions or comments or to report errors in the data. +# +0020 20 # SPACE # space +00A0 20 # NO-BREAK SPACE # space +0021 21 # EXCLAMATION MARK # exclam +0022 22 # QUOTATION MARK # quotedbl +0023 23 # NUMBER SIGN # numbersign +0024 24 # DOLLAR SIGN # dollar +0025 25 # PERCENT SIGN # percent +0026 26 # AMPERSAND # ampersand +2019 27 # RIGHT SINGLE QUOTATION MARK # quoteright +0028 28 # LEFT PARENTHESIS # parenleft +0029 29 # RIGHT PARENTHESIS # parenright +002A 2A # ASTERISK # asterisk +002B 2B # PLUS SIGN # plus +002C 2C # COMMA # comma +002D 2D # HYPHEN-MINUS # hyphen +00AD 2D # SOFT HYPHEN # hyphen +002E 2E # FULL STOP # period +002F 2F # SOLIDUS # slash +0030 30 # DIGIT ZERO # zero +0031 31 # DIGIT ONE # one +0032 32 # DIGIT TWO # two +0033 33 # DIGIT THREE # three +0034 34 # DIGIT FOUR # four +0035 35 # DIGIT FIVE # five +0036 36 # DIGIT SIX # six +0037 37 # DIGIT SEVEN # seven +0038 38 # DIGIT EIGHT # eight +0039 39 # DIGIT NINE # nine +003A 3A # COLON # colon +003B 3B # SEMICOLON # semicolon +003C 3C # LESS-THAN SIGN # less +003D 3D # EQUALS SIGN # equal +003E 3E # GREATER-THAN SIGN # greater +003F 3F # QUESTION MARK # question +0040 40 # COMMERCIAL AT # at +0041 41 # LATIN CAPITAL LETTER A # A +0042 42 # LATIN CAPITAL LETTER B # B +0043 43 # LATIN CAPITAL LETTER C # C +0044 44 # LATIN CAPITAL LETTER D # D +0045 45 # LATIN CAPITAL LETTER E # E +0046 46 # LATIN CAPITAL LETTER F # F +0047 47 # LATIN CAPITAL LETTER G # G +0048 48 # LATIN CAPITAL LETTER H # H +0049 49 # LATIN CAPITAL LETTER I # I +004A 4A # LATIN CAPITAL LETTER J # J +004B 4B # LATIN CAPITAL LETTER K # K +004C 4C # LATIN CAPITAL LETTER L # L +004D 4D # LATIN CAPITAL LETTER M # M +004E 4E # LATIN CAPITAL LETTER N # N +004F 4F # LATIN CAPITAL LETTER O # O +0050 50 # LATIN CAPITAL LETTER P # P +0051 51 # LATIN CAPITAL LETTER Q # Q +0052 52 # LATIN CAPITAL LETTER R # R +0053 53 # LATIN CAPITAL LETTER S # S +0054 54 # LATIN CAPITAL LETTER T # T +0055 55 # LATIN CAPITAL LETTER U # U +0056 56 # LATIN CAPITAL LETTER V # V +0057 57 # LATIN CAPITAL LETTER W # W +0058 58 # LATIN CAPITAL LETTER X # X +0059 59 # LATIN CAPITAL LETTER Y # Y +005A 5A # LATIN CAPITAL LETTER Z # Z +005B 5B # LEFT SQUARE BRACKET # bracketleft +005C 5C # REVERSE SOLIDUS # backslash +005D 5D # RIGHT SQUARE BRACKET # bracketright +005E 5E # CIRCUMFLEX ACCENT # asciicircum +005F 5F # LOW LINE # underscore +2018 60 # LEFT SINGLE QUOTATION MARK # quoteleft +0061 61 # LATIN SMALL LETTER A # a +0062 62 # LATIN SMALL LETTER B # b +0063 63 # LATIN SMALL LETTER C # c +0064 64 # LATIN SMALL LETTER D # d +0065 65 # LATIN SMALL LETTER E # e +0066 66 # LATIN SMALL LETTER F # f +0067 67 # LATIN SMALL LETTER G # g +0068 68 # LATIN SMALL LETTER H # h +0069 69 # LATIN SMALL LETTER I # i +006A 6A # LATIN SMALL LETTER J # j +006B 6B # LATIN SMALL LETTER K # k +006C 6C # LATIN SMALL LETTER L # l +006D 6D # LATIN SMALL LETTER M # m +006E 6E # LATIN SMALL LETTER N # n +006F 6F # LATIN SMALL LETTER O # o +0070 70 # LATIN SMALL LETTER P # p +0071 71 # LATIN SMALL LETTER Q # q +0072 72 # LATIN SMALL LETTER R # r +0073 73 # LATIN SMALL LETTER S # s +0074 74 # LATIN SMALL LETTER T # t +0075 75 # LATIN SMALL LETTER U # u +0076 76 # LATIN SMALL LETTER V # v +0077 77 # LATIN SMALL LETTER W # w +0078 78 # LATIN SMALL LETTER X # x +0079 79 # LATIN SMALL LETTER Y # y +007A 7A # LATIN SMALL LETTER Z # z +007B 7B # LEFT CURLY BRACKET # braceleft +007C 7C # VERTICAL LINE # bar +007D 7D # RIGHT CURLY BRACKET # braceright +007E 7E # TILDE # asciitilde +00A1 A1 # INVERTED EXCLAMATION MARK # exclamdown +00A2 A2 # CENT SIGN # cent +00A3 A3 # POUND SIGN # sterling +2044 A4 # FRACTION SLASH # fraction +2215 A4 # DIVISION SLASH # fraction +00A5 A5 # YEN SIGN # yen +0192 A6 # LATIN SMALL LETTER F WITH HOOK # florin +00A7 A7 # SECTION SIGN # section +00A4 A8 # CURRENCY SIGN # currency +0027 A9 # APOSTROPHE # quotesingle +201C AA # LEFT DOUBLE QUOTATION MARK # quotedblleft +00AB AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK # guillemotleft +2039 AC # SINGLE LEFT-POINTING ANGLE QUOTATION MARK # guilsinglleft +203A AD # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK # guilsinglright +FB01 AE # LATIN SMALL LIGATURE FI # fi +FB02 AF # LATIN SMALL LIGATURE FL # fl +2013 B1 # EN DASH # endash +2020 B2 # DAGGER # dagger +2021 B3 # DOUBLE DAGGER # daggerdbl +00B7 B4 # MIDDLE DOT # periodcentered +2219 B4 # BULLET OPERATOR # periodcentered +00B6 B6 # PILCROW SIGN # paragraph +2022 B7 # BULLET # bullet +201A B8 # SINGLE LOW-9 QUOTATION MARK # quotesinglbase +201E B9 # DOUBLE LOW-9 QUOTATION MARK # quotedblbase +201D BA # RIGHT DOUBLE QUOTATION MARK # quotedblright +00BB BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK # guillemotright +2026 BC # HORIZONTAL ELLIPSIS # ellipsis +2030 BD # PER MILLE SIGN # perthousand +00BF BF # INVERTED QUESTION MARK # questiondown +0060 C1 # GRAVE ACCENT # grave +00B4 C2 # ACUTE ACCENT # acute +02C6 C3 # MODIFIER LETTER CIRCUMFLEX ACCENT # circumflex +02DC C4 # SMALL TILDE # tilde +00AF C5 # MACRON # macron +02C9 C5 # MODIFIER LETTER MACRON # macron +02D8 C6 # BREVE # breve +02D9 C7 # DOT ABOVE # dotaccent +00A8 C8 # DIAERESIS # dieresis +02DA CA # RING ABOVE # ring +00B8 CB # CEDILLA # cedilla +02DD CD # DOUBLE ACUTE ACCENT # hungarumlaut +02DB CE # OGONEK # ogonek +02C7 CF # CARON # caron +2014 D0 # EM DASH # emdash +00C6 E1 # LATIN CAPITAL LETTER AE # AE +00AA E3 # FEMININE ORDINAL INDICATOR # ordfeminine +0141 E8 # LATIN CAPITAL LETTER L WITH STROKE # Lslash +00D8 E9 # LATIN CAPITAL LETTER O WITH STROKE # Oslash +0152 EA # LATIN CAPITAL LIGATURE OE # OE +00BA EB # MASCULINE ORDINAL INDICATOR # ordmasculine +00E6 F1 # LATIN SMALL LETTER AE # ae +0131 F5 # LATIN SMALL LETTER DOTLESS I # dotlessi +0142 F8 # LATIN SMALL LETTER L WITH STROKE # lslash +00F8 F9 # LATIN SMALL LETTER O WITH STROKE # oslash +0153 FA # LATIN SMALL LIGATURE OE # oe +00DF FB # LATIN SMALL LETTER SHARP S # germandbls diff --git a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java new file mode 100644 index 000000000..10ba42119 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts.type1; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test case for {@link AdobeStandardEncoding}. + */ +public class AdobeStandardEncodingTestCase { + + private static BufferedReader adobeStandardEncoding; + + /** + * Sets up the file reader, this file was retrieved from the url below. + * http://unicode.org/Public/MAPPINGS/VENDORS/ADOBE/stdenc.txt + * + * @throws FileNotFoundException if the file was not found + */ + @BeforeClass + public static void setupReader() throws FileNotFoundException { + InputStream inStream = AdobeStandardEncodingTestCase.class.getResourceAsStream( + "AdobeStandardEncoding.txt"); + adobeStandardEncoding = new BufferedReader(new InputStreamReader(inStream)); + } + + /** + * Probably the best way to test the encoding is by converting it back to format specified in + * the file, that way we can ensure data has been migrated properly. + * + * @throws IOException if an I/O error occurs + */ + @Test + public void testCorrectEncoding() throws IOException { + for (AdobeStandardEncoding encoding : AdobeStandardEncoding.values()) { + String expectedLine = getLine(); + String hexUnicode = toHexString(encoding.getUnicodeIndex(), 4); + String hexAdobe = toHexString(encoding.getAdobeCodePoint(), 2); + String actualLine = hexUnicode + "\t" + + hexAdobe + "\t# " + + encoding.getUnicodeName() + "\t# " + + encoding.getAdobeName(); + assertEquals(expectedLine, actualLine); + } + } + + private String getLine() throws IOException { + String line = "# The first few lines are comments, these should be ignored"; + while (line.startsWith("#")) { + line = adobeStandardEncoding.readLine(); + } + return line; + } + + private String toHexString(int number, int length) { + return String.format("%0" + length + "X", number); + } +} diff --git a/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java new file mode 100644 index 000000000..de9af2d33 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fonts.type1; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.awt.Rectangle; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.junit.Test; + +import org.apache.fop.fonts.NamedCharacter; +import org.apache.fop.fonts.type1.AFMParser.ValueHandler; + +/** + * Test case for {@link CharMetricsHandler}. + */ +public class CharMetricsHandlerTestCase { + + private static final String GOOD_LINE = "C 32 ; WX 32 ; N space ; B 1 1 1 1"; + + private static final AFMCharMetrics EXPECTED_CHM; + + static { + EXPECTED_CHM = new AFMCharMetrics(); + EXPECTED_CHM.setCharCode(32); + EXPECTED_CHM.setWidthX(32.0); + EXPECTED_CHM.setCharacter(new NamedCharacter("space")); + EXPECTED_CHM.setBBox(new Rectangle(1, 1, 0, 0)); + } + + @Test + public void testHandlers() throws IOException { + testEncodingWithMetricsLine("", GOOD_LINE); + testEncodingWithMetricsLine("WrongEncoding", GOOD_LINE); + testEncodingWithMetricsLine("AdobeStandardEncoding", GOOD_LINE); + } + + private void testEncodingWithMetricsLine(String encoding, String line) throws IOException { + Map<String, ValueHandler> valueParsers = mock(HashMap.class); + ValueHandler cHandler = mock(ValueHandler.class); + ValueHandler wxHandler = mock(ValueHandler.class); + ValueHandler nHandler = mock(ValueHandler.class); + ValueHandler bHandler = mock(ValueHandler.class); + when(valueParsers.get("C")).thenReturn(cHandler); + when(valueParsers.get("WX")).thenReturn(wxHandler); + when(valueParsers.get("N")).thenReturn(nHandler); + when(valueParsers.get("B")).thenReturn(bHandler); + + CharMetricsHandler handler = CharMetricsHandler.getHandler(valueParsers, encoding); + Stack<Object> stack = new Stack<Object>(); + handler.parse(line, stack, null); + + verify(valueParsers).get("C"); + verify(valueParsers).get("WX"); + verify(valueParsers).get("N"); + verify(valueParsers).get("B"); + verify(cHandler).parse("32", 0, new Stack<Object>()); + verify(wxHandler).parse("32", 0, new Stack<Object>()); + verify(nHandler).parse("space", 0, new Stack<Object>()); + verify(bHandler).parse("1 1 1 1", 0, new Stack<Object>()); + } +} diff --git a/test/java/org/apache/fop/fonts/type1/adobe-charset_adobe-encoding.afm b/test/java/org/apache/fop/fonts/type1/adobe-charset_adobe-encoding.afm new file mode 100644 index 000000000..50f8c3381 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/adobe-charset_adobe-encoding.afm @@ -0,0 +1,158 @@ +StartFontMetrics 2.0 +EncodingScheme AdobeStandardEncoding +StartCharMetrics 154 +C 32 ; WX 32 ; N space ; B 1 1 1 1 +C 32 ; WX 32 ; N space ; B 2 2 2 2 +C 33 ; WX 33 ; N exclam ; B 3 3 3 3 +C 34 ; WX 34 ; N quotedbl ; B 4 4 4 4 +C 35 ; WX 35 ; N numbersign ; B 5 5 5 5 +C 36 ; WX 36 ; N dollar ; B 6 6 6 6 +C 37 ; WX 37 ; N percent ; B 7 7 7 7 +C 38 ; WX 38 ; N ampersand ; B 8 8 8 8 +C 39 ; WX 39 ; N quoteright ; B 9 9 9 9 +C 40 ; WX 40 ; N parenleft ; B 10 10 10 10 +C 41 ; WX 41 ; N parenright ; B 11 11 11 11 +C 42 ; WX 42 ; N asterisk ; B 12 12 12 12 +C 43 ; WX 43 ; N plus ; B 13 13 13 13 +C 44 ; WX 44 ; N comma ; B 14 14 14 14 +C 45 ; WX 45 ; N hyphen ; B 15 15 15 15 +C 45 ; WX 45 ; N hyphen ; B 16 16 16 16 +C 46 ; WX 46 ; N period ; B 17 17 17 17 +C 47 ; WX 47 ; N slash ; B 18 18 18 18 +C 48 ; WX 48 ; N zero ; B 19 19 19 19 +C 49 ; WX 49 ; N one ; B 20 20 20 20 +C 50 ; WX 50 ; N two ; B 21 21 21 21 +C 51 ; WX 51 ; N three ; B 22 22 22 22 +C 52 ; WX 52 ; N four ; B 23 23 23 23 +C 53 ; WX 53 ; N five ; B 24 24 24 24 +C 54 ; WX 54 ; N six ; B 25 25 25 25 +C 55 ; WX 55 ; N seven ; B 26 26 26 26 +C 56 ; WX 56 ; N eight ; B 27 27 27 27 +C 57 ; WX 57 ; N nine ; B 28 28 28 28 +C 58 ; WX 58 ; N colon ; B 29 29 29 29 +C 59 ; WX 59 ; N semicolon ; B 30 30 30 30 +C 60 ; WX 60 ; N less ; B 31 31 31 31 +C 61 ; WX 61 ; N equal ; B 32 32 32 32 +C 62 ; WX 62 ; N greater ; B 33 33 33 33 +C 63 ; WX 63 ; N question ; B 34 34 34 34 +C 64 ; WX 64 ; N at ; B 35 35 35 35 +C 65 ; WX 65 ; N A ; B 36 36 36 36 +C 66 ; WX 66 ; N B ; B 37 37 37 37 +C 67 ; WX 67 ; N C ; B 38 38 38 38 +C 68 ; WX 68 ; N D ; B 39 39 39 39 +C 69 ; WX 69 ; N E ; B 40 40 40 40 +C 70 ; WX 70 ; N F ; B 41 41 41 41 +C 71 ; WX 71 ; N G ; B 42 42 42 42 +C 72 ; WX 72 ; N H ; B 43 43 43 43 +C 73 ; WX 73 ; N I ; B 44 44 44 44 +C 74 ; WX 74 ; N J ; B 45 45 45 45 +C 75 ; WX 75 ; N K ; B 46 46 46 46 +C 76 ; WX 76 ; N L ; B 47 47 47 47 +C 77 ; WX 77 ; N M ; B 48 48 48 48 +C 78 ; WX 78 ; N N ; B 49 49 49 49 +C 79 ; WX 79 ; N O ; B 50 50 50 50 +C 80 ; WX 80 ; N P ; B 51 51 51 51 +C 81 ; WX 81 ; N Q ; B 52 52 52 52 +C 82 ; WX 82 ; N R ; B 53 53 53 53 +C 83 ; WX 83 ; N S ; B 54 54 54 54 +C 84 ; WX 84 ; N T ; B 55 55 55 55 +C 85 ; WX 85 ; N U ; B 56 56 56 56 +C 86 ; WX 86 ; N V ; B 57 57 57 57 +C 87 ; WX 87 ; N W ; B 58 58 58 58 +C 88 ; WX 88 ; N X ; B 59 59 59 59 +C 89 ; WX 89 ; N Y ; B 60 60 60 60 +C 90 ; WX 90 ; N Z ; B 61 61 61 61 +C 91 ; WX 91 ; N bracketleft ; B 62 62 62 62 +C 92 ; WX 92 ; N backslash ; B 63 63 63 63 +C 93 ; WX 93 ; N bracketright ; B 64 64 64 64 +C 94 ; WX 94 ; N asciicircum ; B 65 65 65 65 +C 95 ; WX 95 ; N underscore ; B 66 66 66 66 +C 96 ; WX 96 ; N quoteleft ; B 67 67 67 67 +C 97 ; WX 97 ; N a ; B 68 68 68 68 +C 98 ; WX 98 ; N b ; B 69 69 69 69 +C 99 ; WX 99 ; N c ; B 70 70 70 70 +C 100 ; WX 100 ; N d ; B 71 71 71 71 +C 101 ; WX 101 ; N e ; B 72 72 72 72 +C 102 ; WX 102 ; N f ; B 73 73 73 73 +C 103 ; WX 103 ; N g ; B 74 74 74 74 +C 104 ; WX 104 ; N h ; B 75 75 75 75 +C 105 ; WX 105 ; N i ; B 76 76 76 76 +C 106 ; WX 106 ; N j ; B 77 77 77 77 +C 107 ; WX 107 ; N k ; B 78 78 78 78 +C 108 ; WX 108 ; N l ; B 79 79 79 79 +C 109 ; WX 109 ; N m ; B 80 80 80 80 +C 110 ; WX 110 ; N n ; B 81 81 81 81 +C 111 ; WX 111 ; N o ; B 82 82 82 82 +C 112 ; WX 112 ; N p ; B 83 83 83 83 +C 113 ; WX 113 ; N q ; B 84 84 84 84 +C 114 ; WX 114 ; N r ; B 85 85 85 85 +C 115 ; WX 115 ; N s ; B 86 86 86 86 +C 116 ; WX 116 ; N t ; B 87 87 87 87 +C 117 ; WX 117 ; N u ; B 88 88 88 88 +C 118 ; WX 118 ; N v ; B 89 89 89 89 +C 119 ; WX 119 ; N w ; B 90 90 90 90 +C 120 ; WX 120 ; N x ; B 91 91 91 91 +C 121 ; WX 121 ; N y ; B 92 92 92 92 +C 122 ; WX 122 ; N z ; B 93 93 93 93 +C 123 ; WX 123 ; N braceleft ; B 94 94 94 94 +C 124 ; WX 124 ; N bar ; B 95 95 95 95 +C 125 ; WX 125 ; N braceright ; B 96 96 96 96 +C 126 ; WX 126 ; N asciitilde ; B 97 97 97 97 +C 161 ; WX 161 ; N exclamdown ; B 98 98 98 98 +C 162 ; WX 162 ; N cent ; B 99 99 99 99 +C 163 ; WX 163 ; N sterling ; B 100 100 100 100 +C 164 ; WX 164 ; N fraction ; B 101 101 101 101 +C 164 ; WX 164 ; N fraction ; B 102 102 102 102 +C 165 ; WX 165 ; N yen ; B 103 103 103 103 +C 166 ; WX 166 ; N florin ; B 104 104 104 104 +C 167 ; WX 167 ; N section ; B 105 105 105 105 +C 168 ; WX 168 ; N currency ; B 106 106 106 106 +C 169 ; WX 169 ; N quotesingle ; B 107 107 107 107 +C 170 ; WX 170 ; N quotedblleft ; B 108 108 108 108 +C 171 ; WX 171 ; N guillemotleft ; B 109 109 109 109 +C 172 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 +C 173 ; WX 173 ; N guilsinglright ; B 111 111 111 111 +C 174 ; WX 174 ; N fi ; B 112 112 112 112 +C 175 ; WX 175 ; N fl ; B 113 113 113 113 +C 177 ; WX 177 ; N endash ; B 114 114 114 114 +C 178 ; WX 178 ; N dagger ; B 115 115 115 115 +C 179 ; WX 179 ; N daggerdbl ; B 116 116 116 116 +C 180 ; WX 180 ; N periodcentered ; B 117 117 117 117 +C 180 ; WX 180 ; N periodcentered ; B 118 118 118 118 +C 182 ; WX 182 ; N paragraph ; B 119 119 119 119 +C 183 ; WX 183 ; N bullet ; B 120 120 120 120 +C 184 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 +C 185 ; WX 185 ; N quotedblbase ; B 122 122 122 122 +C 186 ; WX 186 ; N quotedblright ; B 123 123 123 123 +C 187 ; WX 187 ; N guillemotright ; B 124 124 124 124 +C 188 ; WX 188 ; N ellipsis ; B 125 125 125 125 +C 189 ; WX 189 ; N perthousand ; B 126 126 126 126 +C 191 ; WX 191 ; N questiondown ; B 127 127 127 127 +C 193 ; WX 193 ; N grave ; B 128 128 128 128 +C 194 ; WX 194 ; N acute ; B 129 129 129 129 +C 195 ; WX 195 ; N circumflex ; B 130 130 130 130 +C 196 ; WX 196 ; N tilde ; B 131 131 131 131 +C 197 ; WX 197 ; N macron ; B 132 132 132 132 +C 197 ; WX 197 ; N macron ; B 133 133 133 133 +C 198 ; WX 198 ; N breve ; B 134 134 134 134 +C 199 ; WX 199 ; N dotaccent ; B 135 135 135 135 +C 200 ; WX 200 ; N dieresis ; B 136 136 136 136 +C 202 ; WX 202 ; N ring ; B 137 137 137 137 +C 203 ; WX 203 ; N cedilla ; B 138 138 138 138 +C 205 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 +C 206 ; WX 206 ; N ogonek ; B 140 140 140 140 +C 207 ; WX 207 ; N caron ; B 141 141 141 141 +C 208 ; WX 208 ; N emdash ; B 142 142 142 142 +C 225 ; WX 225 ; N AE ; B 143 143 143 143 +C 227 ; WX 227 ; N ordfeminine ; B 144 144 144 144 +C 232 ; WX 232 ; N Lslash ; B 145 145 145 145 +C 233 ; WX 233 ; N Oslash ; B 146 146 146 146 +C 234 ; WX 234 ; N OE ; B 147 147 147 147 +C 235 ; WX 235 ; N ordmasculine ; B 148 148 148 148 +C 241 ; WX 241 ; N ae ; B 149 149 149 149 +C 245 ; WX 245 ; N dotlessi ; B 150 150 150 150 +C 248 ; WX 248 ; N lslash ; B 151 151 151 151 +C 249 ; WX 249 ; N oslash ; B 152 152 152 152 +C 250 ; WX 250 ; N oe ; B 153 153 153 153 +C 251 ; WX 251 ; N germandbls ; B 154 154 154 154 +EndCharMetrics diff --git a/test/java/org/apache/fop/fonts/type1/adobe-charset_unknown-encoding.afm b/test/java/org/apache/fop/fonts/type1/adobe-charset_unknown-encoding.afm new file mode 100644 index 000000000..8edbe0d76 --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/adobe-charset_unknown-encoding.afm @@ -0,0 +1,158 @@ +StartFontMetrics 2.0 +EncodingScheme FontSpecific +StartCharMetrics 154 +C 32 ; WX 32 ; N space ; B 1 1 1 1 +C 32 ; WX 32 ; N space ; B 2 2 2 2 +C 33 ; WX 33 ; N exclam ; B 3 3 3 3 +C 34 ; WX 34 ; N quotedbl ; B 4 4 4 4 +C 35 ; WX 35 ; N numbersign ; B 5 5 5 5 +C 36 ; WX 36 ; N dollar ; B 6 6 6 6 +C 37 ; WX 37 ; N percent ; B 7 7 7 7 +C 38 ; WX 38 ; N ampersand ; B 8 8 8 8 +C 39 ; WX 39 ; N quoteright ; B 9 9 9 9 +C 40 ; WX 40 ; N parenleft ; B 10 10 10 10 +C 41 ; WX 41 ; N parenright ; B 11 11 11 11 +C 42 ; WX 42 ; N asterisk ; B 12 12 12 12 +C 43 ; WX 43 ; N plus ; B 13 13 13 13 +C 44 ; WX 44 ; N comma ; B 14 14 14 14 +C 45 ; WX 45 ; N hyphen ; B 15 15 15 15 +C 45 ; WX 45 ; N hyphen ; B 16 16 16 16 +C 46 ; WX 46 ; N period ; B 17 17 17 17 +C 47 ; WX 47 ; N slash ; B 18 18 18 18 +C 48 ; WX 48 ; N zero ; B 19 19 19 19 +C 49 ; WX 49 ; N one ; B 20 20 20 20 +C 50 ; WX 50 ; N two ; B 21 21 21 21 +C 51 ; WX 51 ; N three ; B 22 22 22 22 +C 52 ; WX 52 ; N four ; B 23 23 23 23 +C 53 ; WX 53 ; N five ; B 24 24 24 24 +C 54 ; WX 54 ; N six ; B 25 25 25 25 +C 55 ; WX 55 ; N seven ; B 26 26 26 26 +C 56 ; WX 56 ; N eight ; B 27 27 27 27 +C 57 ; WX 57 ; N nine ; B 28 28 28 28 +C 58 ; WX 58 ; N colon ; B 29 29 29 29 +C 59 ; WX 59 ; N semicolon ; B 30 30 30 30 +C 60 ; WX 60 ; N less ; B 31 31 31 31 +C 61 ; WX 61 ; N equal ; B 32 32 32 32 +C 62 ; WX 62 ; N greater ; B 33 33 33 33 +C 63 ; WX 63 ; N question ; B 34 34 34 34 +C 64 ; WX 64 ; N at ; B 35 35 35 35 +C 65 ; WX 65 ; N A ; B 36 36 36 36 +C 66 ; WX 66 ; N B ; B 37 37 37 37 +C 67 ; WX 67 ; N C ; B 38 38 38 38 +C 68 ; WX 68 ; N D ; B 39 39 39 39 +C 69 ; WX 69 ; N E ; B 40 40 40 40 +C 70 ; WX 70 ; N F ; B 41 41 41 41 +C 71 ; WX 71 ; N G ; B 42 42 42 42 +C 72 ; WX 72 ; N H ; B 43 43 43 43 +C 73 ; WX 73 ; N I ; B 44 44 44 44 +C 74 ; WX 74 ; N J ; B 45 45 45 45 +C 75 ; WX 75 ; N K ; B 46 46 46 46 +C 76 ; WX 76 ; N L ; B 47 47 47 47 +C 77 ; WX 77 ; N M ; B 48 48 48 48 +C 78 ; WX 78 ; N N ; B 49 49 49 49 +C 79 ; WX 79 ; N O ; B 50 50 50 50 +C 80 ; WX 80 ; N P ; B 51 51 51 51 +C 81 ; WX 81 ; N Q ; B 52 52 52 52 +C 82 ; WX 82 ; N R ; B 53 53 53 53 +C 83 ; WX 83 ; N S ; B 54 54 54 54 +C 84 ; WX 84 ; N T ; B 55 55 55 55 +C 85 ; WX 85 ; N U ; B 56 56 56 56 +C 86 ; WX 86 ; N V ; B 57 57 57 57 +C 87 ; WX 87 ; N W ; B 58 58 58 58 +C 88 ; WX 88 ; N X ; B 59 59 59 59 +C 89 ; WX 89 ; N Y ; B 60 60 60 60 +C 90 ; WX 90 ; N Z ; B 61 61 61 61 +C 91 ; WX 91 ; N bracketleft ; B 62 62 62 62 +C 92 ; WX 92 ; N backslash ; B 63 63 63 63 +C 93 ; WX 93 ; N bracketright ; B 64 64 64 64 +C 94 ; WX 94 ; N asciicircum ; B 65 65 65 65 +C 95 ; WX 95 ; N underscore ; B 66 66 66 66 +C 96 ; WX 96 ; N quoteleft ; B 67 67 67 67 +C 97 ; WX 97 ; N a ; B 68 68 68 68 +C 98 ; WX 98 ; N b ; B 69 69 69 69 +C 99 ; WX 99 ; N c ; B 70 70 70 70 +C 100 ; WX 100 ; N d ; B 71 71 71 71 +C 101 ; WX 101 ; N e ; B 72 72 72 72 +C 102 ; WX 102 ; N f ; B 73 73 73 73 +C 103 ; WX 103 ; N g ; B 74 74 74 74 +C 104 ; WX 104 ; N h ; B 75 75 75 75 +C 105 ; WX 105 ; N i ; B 76 76 76 76 +C 106 ; WX 106 ; N j ; B 77 77 77 77 +C 107 ; WX 107 ; N k ; B 78 78 78 78 +C 108 ; WX 108 ; N l ; B 79 79 79 79 +C 109 ; WX 109 ; N m ; B 80 80 80 80 +C 110 ; WX 110 ; N n ; B 81 81 81 81 +C 111 ; WX 111 ; N o ; B 82 82 82 82 +C 112 ; WX 112 ; N p ; B 83 83 83 83 +C 113 ; WX 113 ; N q ; B 84 84 84 84 +C 114 ; WX 114 ; N r ; B 85 85 85 85 +C 115 ; WX 115 ; N s ; B 86 86 86 86 +C 116 ; WX 116 ; N t ; B 87 87 87 87 +C 117 ; WX 117 ; N u ; B 88 88 88 88 +C 118 ; WX 118 ; N v ; B 89 89 89 89 +C 119 ; WX 119 ; N w ; B 90 90 90 90 +C 120 ; WX 120 ; N x ; B 91 91 91 91 +C 121 ; WX 121 ; N y ; B 92 92 92 92 +C 122 ; WX 122 ; N z ; B 93 93 93 93 +C 123 ; WX 123 ; N braceleft ; B 94 94 94 94 +C 124 ; WX 124 ; N bar ; B 95 95 95 95 +C 125 ; WX 125 ; N braceright ; B 96 96 96 96 +C 126 ; WX 126 ; N asciitilde ; B 97 97 97 97 +C 161 ; WX 161 ; N exclamdown ; B 98 98 98 98 +C 162 ; WX 162 ; N cent ; B 99 99 99 99 +C 163 ; WX 163 ; N sterling ; B 100 100 100 100 +C 164 ; WX 164 ; N fraction ; B 101 101 101 101 +C 164 ; WX 164 ; N fraction ; B 102 102 102 102 +C 165 ; WX 165 ; N yen ; B 103 103 103 103 +C 166 ; WX 166 ; N florin ; B 104 104 104 104 +C 167 ; WX 167 ; N section ; B 105 105 105 105 +C 168 ; WX 168 ; N currency ; B 106 106 106 106 +C 169 ; WX 169 ; N quotesingle ; B 107 107 107 107 +C 170 ; WX 170 ; N quotedblleft ; B 108 108 108 108 +C 171 ; WX 171 ; N guillemotleft ; B 109 109 109 109 +C 172 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 +C 173 ; WX 173 ; N guilsinglright ; B 111 111 111 111 +C 174 ; WX 174 ; N fi ; B 112 112 112 112 +C 175 ; WX 175 ; N fl ; B 113 113 113 113 +C 177 ; WX 177 ; N endash ; B 114 114 114 114 +C 178 ; WX 178 ; N dagger ; B 115 115 115 115 +C 179 ; WX 179 ; N daggerdbl ; B 116 116 116 116 +C 180 ; WX 180 ; N periodcentered ; B 117 117 117 117 +C 180 ; WX 180 ; N periodcentered ; B 118 118 118 118 +C 182 ; WX 182 ; N paragraph ; B 119 119 119 119 +C 183 ; WX 183 ; N bullet ; B 120 120 120 120 +C 184 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 +C 185 ; WX 185 ; N quotedblbase ; B 122 122 122 122 +C 186 ; WX 186 ; N quotedblright ; B 123 123 123 123 +C 187 ; WX 187 ; N guillemotright ; B 124 124 124 124 +C 188 ; WX 188 ; N ellipsis ; B 125 125 125 125 +C 189 ; WX 189 ; N perthousand ; B 126 126 126 126 +C 191 ; WX 191 ; N questiondown ; B 127 127 127 127 +C 193 ; WX 193 ; N grave ; B 128 128 128 128 +C 194 ; WX 194 ; N acute ; B 129 129 129 129 +C 195 ; WX 195 ; N circumflex ; B 130 130 130 130 +C 196 ; WX 196 ; N tilde ; B 131 131 131 131 +C 197 ; WX 197 ; N macron ; B 132 132 132 132 +C 197 ; WX 197 ; N macron ; B 133 133 133 133 +C 198 ; WX 198 ; N breve ; B 134 134 134 134 +C 199 ; WX 199 ; N dotaccent ; B 135 135 135 135 +C 200 ; WX 200 ; N dieresis ; B 136 136 136 136 +C 202 ; WX 202 ; N ring ; B 137 137 137 137 +C 203 ; WX 203 ; N cedilla ; B 138 138 138 138 +C 205 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 +C 206 ; WX 206 ; N ogonek ; B 140 140 140 140 +C 207 ; WX 207 ; N caron ; B 141 141 141 141 +C 208 ; WX 208 ; N emdash ; B 142 142 142 142 +C 225 ; WX 225 ; N AE ; B 143 143 143 143 +C 227 ; WX 227 ; N ordfeminine ; B 144 144 144 144 +C 232 ; WX 232 ; N Lslash ; B 145 145 145 145 +C 233 ; WX 233 ; N Oslash ; B 146 146 146 146 +C 234 ; WX 234 ; N OE ; B 147 147 147 147 +C 235 ; WX 235 ; N ordmasculine ; B 148 148 148 148 +C 241 ; WX 241 ; N ae ; B 149 149 149 149 +C 245 ; WX 245 ; N dotlessi ; B 150 150 150 150 +C 248 ; WX 248 ; N lslash ; B 151 151 151 151 +C 249 ; WX 249 ; N oslash ; B 152 152 152 152 +C 250 ; WX 250 ; N oe ; B 153 153 153 153 +C 251 ; WX 251 ; N germandbls ; B 154 154 154 154 +EndCharMetrics diff --git a/test/java/org/apache/fop/fonts/type1/notadobe-charset_adobe-encoding.afm b/test/java/org/apache/fop/fonts/type1/notadobe-charset_adobe-encoding.afm new file mode 100644 index 000000000..11cecb17f --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/notadobe-charset_adobe-encoding.afm @@ -0,0 +1,158 @@ +StartFontMetrics 2.0 +EncodingScheme AdobeStandardEncoding +StartCharMetrics 154 +C 33 ; WX 32 ; N space ; B 1 1 1 1 +C 33 ; WX 32 ; N space ; B 2 2 2 2 +C 34 ; WX 33 ; N exclam ; B 3 3 3 3 +C 35 ; WX 34 ; N quotedbl ; B 4 4 4 4 +C 36 ; WX 35 ; N numbersign ; B 5 5 5 5 +C 37 ; WX 36 ; N dollar ; B 6 6 6 6 +C 38 ; WX 37 ; N percent ; B 7 7 7 7 +C 39 ; WX 38 ; N ampersand ; B 8 8 8 8 +C 40 ; WX 39 ; N quoteright ; B 9 9 9 9 +C 41 ; WX 40 ; N parenleft ; B 10 10 10 10 +C 42 ; WX 41 ; N parenright ; B 11 11 11 11 +C 43 ; WX 42 ; N asterisk ; B 12 12 12 12 +C 44 ; WX 43 ; N plus ; B 13 13 13 13 +C 45 ; WX 44 ; N comma ; B 14 14 14 14 +C 46 ; WX 45 ; N hyphen ; B 15 15 15 15 +C 46 ; WX 45 ; N hyphen ; B 16 16 16 16 +C 47 ; WX 46 ; N period ; B 17 17 17 17 +C 48 ; WX 47 ; N slash ; B 18 18 18 18 +C 49 ; WX 48 ; N zero ; B 19 19 19 19 +C 50 ; WX 49 ; N one ; B 20 20 20 20 +C 51 ; WX 50 ; N two ; B 21 21 21 21 +C 52 ; WX 51 ; N three ; B 22 22 22 22 +C 53 ; WX 52 ; N four ; B 23 23 23 23 +C 54 ; WX 53 ; N five ; B 24 24 24 24 +C 55 ; WX 54 ; N six ; B 25 25 25 25 +C 56 ; WX 55 ; N seven ; B 26 26 26 26 +C 57 ; WX 56 ; N eight ; B 27 27 27 27 +C 58 ; WX 57 ; N nine ; B 28 28 28 28 +C 59 ; WX 58 ; N colon ; B 29 29 29 29 +C 60 ; WX 59 ; N semicolon ; B 30 30 30 30 +C 61 ; WX 60 ; N less ; B 31 31 31 31 +C 62 ; WX 61 ; N equal ; B 32 32 32 32 +C 63 ; WX 62 ; N greater ; B 33 33 33 33 +C 64 ; WX 63 ; N question ; B 34 34 34 34 +C 65 ; WX 64 ; N at ; B 35 35 35 35 +C 66 ; WX 65 ; N A ; B 36 36 36 36 +C 67 ; WX 66 ; N B ; B 37 37 37 37 +C 68 ; WX 67 ; N C ; B 38 38 38 38 +C 69 ; WX 68 ; N D ; B 39 39 39 39 +C 70 ; WX 69 ; N E ; B 40 40 40 40 +C 71 ; WX 70 ; N F ; B 41 41 41 41 +C 72 ; WX 71 ; N G ; B 42 42 42 42 +C 73 ; WX 72 ; N H ; B 43 43 43 43 +C 74 ; WX 73 ; N I ; B 44 44 44 44 +C 75 ; WX 74 ; N J ; B 45 45 45 45 +C 76 ; WX 75 ; N K ; B 46 46 46 46 +C 77 ; WX 76 ; N L ; B 47 47 47 47 +C 78 ; WX 77 ; N M ; B 48 48 48 48 +C 79 ; WX 78 ; N N ; B 49 49 49 49 +C 80 ; WX 79 ; N O ; B 50 50 50 50 +C 81 ; WX 80 ; N P ; B 51 51 51 51 +C 82 ; WX 81 ; N Q ; B 52 52 52 52 +C 83 ; WX 82 ; N R ; B 53 53 53 53 +C 84 ; WX 83 ; N S ; B 54 54 54 54 +C 85 ; WX 84 ; N T ; B 55 55 55 55 +C 86 ; WX 85 ; N U ; B 56 56 56 56 +C 87 ; WX 86 ; N V ; B 57 57 57 57 +C 88 ; WX 87 ; N W ; B 58 58 58 58 +C 89 ; WX 88 ; N X ; B 59 59 59 59 +C 90 ; WX 89 ; N Y ; B 60 60 60 60 +C 91 ; WX 90 ; N Z ; B 61 61 61 61 +C 92 ; WX 91 ; N bracketleft ; B 62 62 62 62 +C 93 ; WX 92 ; N backslash ; B 63 63 63 63 +C 94 ; WX 93 ; N bracketright ; B 64 64 64 64 +C 95 ; WX 94 ; N asciicircum ; B 65 65 65 65 +C 96 ; WX 95 ; N underscore ; B 66 66 66 66 +C 97 ; WX 96 ; N quoteleft ; B 67 67 67 67 +C 98 ; WX 97 ; N a ; B 68 68 68 68 +C 99 ; WX 98 ; N b ; B 69 69 69 69 +C 100 ; WX 99 ; N c ; B 70 70 70 70 +C 101 ; WX 100 ; N d ; B 71 71 71 71 +C 102 ; WX 101 ; N e ; B 72 72 72 72 +C 103 ; WX 102 ; N f ; B 73 73 73 73 +C 104 ; WX 103 ; N g ; B 74 74 74 74 +C 105 ; WX 104 ; N h ; B 75 75 75 75 +C 106 ; WX 105 ; N i ; B 76 76 76 76 +C 107 ; WX 106 ; N j ; B 77 77 77 77 +C 108 ; WX 107 ; N k ; B 78 78 78 78 +C 109 ; WX 108 ; N l ; B 79 79 79 79 +C 110 ; WX 109 ; N m ; B 80 80 80 80 +C 111 ; WX 110 ; N n ; B 81 81 81 81 +C 112 ; WX 111 ; N o ; B 82 82 82 82 +C 113 ; WX 112 ; N p ; B 83 83 83 83 +C 114 ; WX 113 ; N q ; B 84 84 84 84 +C 115 ; WX 114 ; N r ; B 85 85 85 85 +C 116 ; WX 115 ; N s ; B 86 86 86 86 +C 117 ; WX 116 ; N t ; B 87 87 87 87 +C 118 ; WX 117 ; N u ; B 88 88 88 88 +C 119 ; WX 118 ; N v ; B 89 89 89 89 +C 120 ; WX 119 ; N w ; B 90 90 90 90 +C 121 ; WX 120 ; N x ; B 91 91 91 91 +C 122 ; WX 121 ; N y ; B 92 92 92 92 +C 123 ; WX 122 ; N z ; B 93 93 93 93 +C 124 ; WX 123 ; N braceleft ; B 94 94 94 94 +C 125 ; WX 124 ; N bar ; B 95 95 95 95 +C 126 ; WX 125 ; N braceright ; B 96 96 96 96 +C 127 ; WX 126 ; N asciitilde ; B 97 97 97 97 +C 162 ; WX 161 ; N exclamdown ; B 98 98 98 98 +C 163 ; WX 162 ; N cent ; B 99 99 99 99 +C 164 ; WX 163 ; N sterling ; B 100 100 100 100 +C 165 ; WX 164 ; N fraction ; B 101 101 101 101 +C 165 ; WX 164 ; N fraction ; B 102 102 102 102 +C 166 ; WX 165 ; N yen ; B 103 103 103 103 +C 167 ; WX 166 ; N florin ; B 104 104 104 104 +C 168 ; WX 167 ; N section ; B 105 105 105 105 +C 169 ; WX 168 ; N currency ; B 106 106 106 106 +C 170 ; WX 169 ; N quotesingle ; B 107 107 107 107 +C 171 ; WX 170 ; N quotedblleft ; B 108 108 108 108 +C 172 ; WX 171 ; N guillemotleft ; B 109 109 109 109 +C 173 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 +C 174 ; WX 173 ; N guilsinglright ; B 111 111 111 111 +C 175 ; WX 174 ; N fi ; B 112 112 112 112 +C 176 ; WX 175 ; N fl ; B 113 113 113 113 +C 178 ; WX 177 ; N endash ; B 114 114 114 114 +C 179 ; WX 178 ; N dagger ; B 115 115 115 115 +C 180 ; WX 179 ; N daggerdbl ; B 116 116 116 116 +C 181 ; WX 180 ; N periodcentered ; B 117 117 117 117 +C 181 ; WX 180 ; N periodcentered ; B 118 118 118 118 +C 183 ; WX 182 ; N paragraph ; B 119 119 119 119 +C 184 ; WX 183 ; N bullet ; B 120 120 120 120 +C 185 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 +C 186 ; WX 185 ; N quotedblbase ; B 122 122 122 122 +C 187 ; WX 186 ; N quotedblright ; B 123 123 123 123 +C 188 ; WX 187 ; N guillemotright ; B 124 124 124 124 +C 189 ; WX 188 ; N ellipsis ; B 125 125 125 125 +C 190 ; WX 189 ; N perthousand ; B 126 126 126 126 +C 192 ; WX 191 ; N questiondown ; B 127 127 127 127 +C 194 ; WX 193 ; N grave ; B 128 128 128 128 +C 195 ; WX 194 ; N acute ; B 129 129 129 129 +C 196 ; WX 195 ; N circumflex ; B 130 130 130 130 +C 197 ; WX 196 ; N tilde ; B 131 131 131 131 +C 198 ; WX 197 ; N macron ; B 132 132 132 132 +C 198 ; WX 197 ; N macron ; B 133 133 133 133 +C 199 ; WX 198 ; N breve ; B 134 134 134 134 +C 200 ; WX 199 ; N dotaccent ; B 135 135 135 135 +C 201 ; WX 200 ; N dieresis ; B 136 136 136 136 +C 203 ; WX 202 ; N ring ; B 137 137 137 137 +C 204 ; WX 203 ; N cedilla ; B 138 138 138 138 +C 206 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 +C 207 ; WX 206 ; N ogonek ; B 140 140 140 140 +C 208 ; WX 207 ; N caron ; B 141 141 141 141 +C 209 ; WX 208 ; N emdash ; B 142 142 142 142 +C 226 ; WX 225 ; N AE ; B 143 143 143 143 +C 228 ; WX 227 ; N ordfeminine ; B 144 144 144 144 +C 233 ; WX 232 ; N Lslash ; B 145 145 145 145 +C 234 ; WX 233 ; N Oslash ; B 146 146 146 146 +C 235 ; WX 234 ; N OE ; B 147 147 147 147 +C 236 ; WX 235 ; N ordmasculine ; B 148 148 148 148 +C 242 ; WX 241 ; N ae ; B 149 149 149 149 +C 246 ; WX 245 ; N dotlessi ; B 150 150 150 150 +C 249 ; WX 248 ; N lslash ; B 151 151 151 151 +C 250 ; WX 249 ; N oslash ; B 152 152 152 152 +C 251 ; WX 250 ; N oe ; B 153 153 153 153 +C 252 ; WX 251 ; N germandbls ; B 154 154 154 154 +EndCharMetrics diff --git a/test/java/org/apache/fop/fonts/type1/notadobe-charset_unknown-encoding.afm b/test/java/org/apache/fop/fonts/type1/notadobe-charset_unknown-encoding.afm new file mode 100644 index 000000000..1714288ab --- /dev/null +++ b/test/java/org/apache/fop/fonts/type1/notadobe-charset_unknown-encoding.afm @@ -0,0 +1,158 @@ +StartFontMetrics 2.0 +EncodingScheme FontSpecific +StartCharMetrics 154 +C 33 ; WX 32 ; N space ; B 1 1 1 1 +C 33 ; WX 32 ; N space ; B 2 2 2 2 +C 34 ; WX 33 ; N exclam ; B 3 3 3 3 +C 35 ; WX 34 ; N quotedbl ; B 4 4 4 4 +C 36 ; WX 35 ; N numbersign ; B 5 5 5 5 +C 37 ; WX 36 ; N dollar ; B 6 6 6 6 +C 38 ; WX 37 ; N percent ; B 7 7 7 7 +C 39 ; WX 38 ; N ampersand ; B 8 8 8 8 +C 40 ; WX 39 ; N quoteright ; B 9 9 9 9 +C 41 ; WX 40 ; N parenleft ; B 10 10 10 10 +C 42 ; WX 41 ; N parenright ; B 11 11 11 11 +C 43 ; WX 42 ; N asterisk ; B 12 12 12 12 +C 44 ; WX 43 ; N plus ; B 13 13 13 13 +C 45 ; WX 44 ; N comma ; B 14 14 14 14 +C 46 ; WX 45 ; N hyphen ; B 15 15 15 15 +C 46 ; WX 45 ; N hyphen ; B 16 16 16 16 +C 47 ; WX 46 ; N period ; B 17 17 17 17 +C 48 ; WX 47 ; N slash ; B 18 18 18 18 +C 49 ; WX 48 ; N zero ; B 19 19 19 19 +C 50 ; WX 49 ; N one ; B 20 20 20 20 +C 51 ; WX 50 ; N two ; B 21 21 21 21 +C 52 ; WX 51 ; N three ; B 22 22 22 22 +C 53 ; WX 52 ; N four ; B 23 23 23 23 +C 54 ; WX 53 ; N five ; B 24 24 24 24 +C 55 ; WX 54 ; N six ; B 25 25 25 25 +C 56 ; WX 55 ; N seven ; B 26 26 26 26 +C 57 ; WX 56 ; N eight ; B 27 27 27 27 +C 58 ; WX 57 ; N nine ; B 28 28 28 28 +C 59 ; WX 58 ; N colon ; B 29 29 29 29 +C 60 ; WX 59 ; N semicolon ; B 30 30 30 30 +C 61 ; WX 60 ; N less ; B 31 31 31 31 +C 62 ; WX 61 ; N equal ; B 32 32 32 32 +C 63 ; WX 62 ; N greater ; B 33 33 33 33 +C 64 ; WX 63 ; N question ; B 34 34 34 34 +C 65 ; WX 64 ; N at ; B 35 35 35 35 +C 66 ; WX 65 ; N A ; B 36 36 36 36 +C 67 ; WX 66 ; N B ; B 37 37 37 37 +C 68 ; WX 67 ; N C ; B 38 38 38 38 +C 69 ; WX 68 ; N D ; B 39 39 39 39 +C 70 ; WX 69 ; N E ; B 40 40 40 40 +C 71 ; WX 70 ; N F ; B 41 41 41 41 +C 72 ; WX 71 ; N G ; B 42 42 42 42 +C 73 ; WX 72 ; N H ; B 43 43 43 43 +C 74 ; WX 73 ; N I ; B 44 44 44 44 +C 75 ; WX 74 ; N J ; B 45 45 45 45 +C 76 ; WX 75 ; N K ; B 46 46 46 46 +C 77 ; WX 76 ; N L ; B 47 47 47 47 +C 78 ; WX 77 ; N M ; B 48 48 48 48 +C 79 ; WX 78 ; N N ; B 49 49 49 49 +C 80 ; WX 79 ; N O ; B 50 50 50 50 +C 81 ; WX 80 ; N P ; B 51 51 51 51 +C 82 ; WX 81 ; N Q ; B 52 52 52 52 +C 83 ; WX 82 ; N R ; B 53 53 53 53 +C 84 ; WX 83 ; N S ; B 54 54 54 54 +C 85 ; WX 84 ; N T ; B 55 55 55 55 +C 86 ; WX 85 ; N U ; B 56 56 56 56 +C 87 ; WX 86 ; N V ; B 57 57 57 57 +C 88 ; WX 87 ; N W ; B 58 58 58 58 +C 89 ; WX 88 ; N X ; B 59 59 59 59 +C 90 ; WX 89 ; N Y ; B 60 60 60 60 +C 91 ; WX 90 ; N Z ; B 61 61 61 61 +C 92 ; WX 91 ; N bracketleft ; B 62 62 62 62 +C 93 ; WX 92 ; N backslash ; B 63 63 63 63 +C 94 ; WX 93 ; N bracketright ; B 64 64 64 64 +C 95 ; WX 94 ; N asciicircum ; B 65 65 65 65 +C 96 ; WX 95 ; N underscore ; B 66 66 66 66 +C 97 ; WX 96 ; N quoteleft ; B 67 67 67 67 +C 98 ; WX 97 ; N a ; B 68 68 68 68 +C 99 ; WX 98 ; N b ; B 69 69 69 69 +C 100 ; WX 99 ; N c ; B 70 70 70 70 +C 101 ; WX 100 ; N d ; B 71 71 71 71 +C 102 ; WX 101 ; N e ; B 72 72 72 72 +C 103 ; WX 102 ; N f ; B 73 73 73 73 +C 104 ; WX 103 ; N g ; B 74 74 74 74 +C 105 ; WX 104 ; N h ; B 75 75 75 75 +C 106 ; WX 105 ; N i ; B 76 76 76 76 +C 107 ; WX 106 ; N j ; B 77 77 77 77 +C 108 ; WX 107 ; N k ; B 78 78 78 78 +C 109 ; WX 108 ; N l ; B 79 79 79 79 +C 110 ; WX 109 ; N m ; B 80 80 80 80 +C 111 ; WX 110 ; N n ; B 81 81 81 81 +C 112 ; WX 111 ; N o ; B 82 82 82 82 +C 113 ; WX 112 ; N p ; B 83 83 83 83 +C 114 ; WX 113 ; N q ; B 84 84 84 84 +C 115 ; WX 114 ; N r ; B 85 85 85 85 +C 116 ; WX 115 ; N s ; B 86 86 86 86 +C 117 ; WX 116 ; N t ; B 87 87 87 87 +C 118 ; WX 117 ; N u ; B 88 88 88 88 +C 119 ; WX 118 ; N v ; B 89 89 89 89 +C 120 ; WX 119 ; N w ; B 90 90 90 90 +C 121 ; WX 120 ; N x ; B 91 91 91 91 +C 122 ; WX 121 ; N y ; B 92 92 92 92 +C 123 ; WX 122 ; N z ; B 93 93 93 93 +C 124 ; WX 123 ; N braceleft ; B 94 94 94 94 +C 125 ; WX 124 ; N bar ; B 95 95 95 95 +C 126 ; WX 125 ; N braceright ; B 96 96 96 96 +C 127 ; WX 126 ; N asciitilde ; B 97 97 97 97 +C 162 ; WX 161 ; N exclamdown ; B 98 98 98 98 +C 163 ; WX 162 ; N cent ; B 99 99 99 99 +C 164 ; WX 163 ; N sterling ; B 100 100 100 100 +C 165 ; WX 164 ; N fraction ; B 101 101 101 101 +C 165 ; WX 164 ; N fraction ; B 102 102 102 102 +C 166 ; WX 165 ; N yen ; B 103 103 103 103 +C 167 ; WX 166 ; N florin ; B 104 104 104 104 +C 168 ; WX 167 ; N section ; B 105 105 105 105 +C 169 ; WX 168 ; N currency ; B 106 106 106 106 +C 170 ; WX 169 ; N quotesingle ; B 107 107 107 107 +C 171 ; WX 170 ; N quotedblleft ; B 108 108 108 108 +C 172 ; WX 171 ; N guillemotleft ; B 109 109 109 109 +C 173 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 +C 174 ; WX 173 ; N guilsinglright ; B 111 111 111 111 +C 175 ; WX 174 ; N fi ; B 112 112 112 112 +C 176 ; WX 175 ; N fl ; B 113 113 113 113 +C 178 ; WX 177 ; N endash ; B 114 114 114 114 +C 179 ; WX 178 ; N dagger ; B 115 115 115 115 +C 180 ; WX 179 ; N daggerdbl ; B 116 116 116 116 +C 181 ; WX 180 ; N periodcentered ; B 117 117 117 117 +C 181 ; WX 180 ; N periodcentered ; B 118 118 118 118 +C 183 ; WX 182 ; N paragraph ; B 119 119 119 119 +C 184 ; WX 183 ; N bullet ; B 120 120 120 120 +C 185 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 +C 186 ; WX 185 ; N quotedblbase ; B 122 122 122 122 +C 187 ; WX 186 ; N quotedblright ; B 123 123 123 123 +C 188 ; WX 187 ; N guillemotright ; B 124 124 124 124 +C 189 ; WX 188 ; N ellipsis ; B 125 125 125 125 +C 190 ; WX 189 ; N perthousand ; B 126 126 126 126 +C 192 ; WX 191 ; N questiondown ; B 127 127 127 127 +C 194 ; WX 193 ; N grave ; B 128 128 128 128 +C 195 ; WX 194 ; N acute ; B 129 129 129 129 +C 196 ; WX 195 ; N circumflex ; B 130 130 130 130 +C 197 ; WX 196 ; N tilde ; B 131 131 131 131 +C 198 ; WX 197 ; N macron ; B 132 132 132 132 +C 198 ; WX 197 ; N macron ; B 133 133 133 133 +C 199 ; WX 198 ; N breve ; B 134 134 134 134 +C 200 ; WX 199 ; N dotaccent ; B 135 135 135 135 +C 201 ; WX 200 ; N dieresis ; B 136 136 136 136 +C 203 ; WX 202 ; N ring ; B 137 137 137 137 +C 204 ; WX 203 ; N cedilla ; B 138 138 138 138 +C 206 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 +C 207 ; WX 206 ; N ogonek ; B 140 140 140 140 +C 208 ; WX 207 ; N caron ; B 141 141 141 141 +C 209 ; WX 208 ; N emdash ; B 142 142 142 142 +C 226 ; WX 225 ; N AE ; B 143 143 143 143 +C 228 ; WX 227 ; N ordfeminine ; B 144 144 144 144 +C 233 ; WX 232 ; N Lslash ; B 145 145 145 145 +C 234 ; WX 233 ; N Oslash ; B 146 146 146 146 +C 235 ; WX 234 ; N OE ; B 147 147 147 147 +C 236 ; WX 235 ; N ordmasculine ; B 148 148 148 148 +C 242 ; WX 241 ; N ae ; B 149 149 149 149 +C 246 ; WX 245 ; N dotlessi ; B 150 150 150 150 +C 249 ; WX 248 ; N lslash ; B 151 151 151 151 +C 250 ; WX 249 ; N oslash ; B 152 152 152 152 +C 251 ; WX 250 ; N oe ; B 153 153 153 153 +C 252 ; WX 251 ; N germandbls ; B 154 154 154 154 +EndCharMetrics diff --git a/test/java/org/apache/fop/fotreetest/FOTreeTestCase.java b/test/java/org/apache/fop/fotreetest/FOTreeTestCase.java new file mode 100644 index 000000000..aa0cbe841 --- /dev/null +++ b/test/java/org/apache/fop/fotreetest/FOTreeTestCase.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fotreetest; + +import java.io.File; +import java.util.Collection; +import java.util.List; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +import org.apache.fop.DebugHelper; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.FopFactoryConfigurator; +import org.apache.fop.fotreetest.ext.TestElementMapping; +import org.apache.fop.layoutengine.LayoutEngineTestUtils; +import org.apache.fop.layoutengine.TestFilesConfiguration; +import org.apache.fop.util.ConsoleEventListenerForTests; + +/** + * Test driver class for FO tree tests. + */ +@RunWith(Parameterized.class) +public class FOTreeTestCase { + + @BeforeClass + public static void registerElementListObservers() { + DebugHelper.registerStandardElementListObservers(); + } + + /** + * Gets the parameters to run the FO tree test cases. + * @return a collection of file arrays containing the test files + */ + @Parameters + public static Collection<File[]> getParameters() { + TestFilesConfiguration.Builder builder = new TestFilesConfiguration.Builder(); + builder.testDir("test/fotree") + .singleProperty("fop.fotree.single") + .startsWithProperty("fop.fotree.starts-with") + .suffix(".fo") + .testSet("testcases") + .disabledProperty("fop.layoutengine.disabled", "test/fotree/disabled-testcases.xml") + .privateTestsProperty("fop.fotree.private"); + + TestFilesConfiguration testConfig = builder.build(); + return LayoutEngineTestUtils.getTestFiles(testConfig); + } + + private FopFactory fopFactory = FopFactory.newInstance(); + + private final File testFile; + + /** + * Main constructor + * + * @param testFile the FO file to test + */ + public FOTreeTestCase(File testFile) { + fopFactory.addElementMapping(new TestElementMapping()); + this.testFile = testFile; + } + + /** + * Runs a test. + * @throws Exception if a test or FOP itself fails + */ + @Test + public void runTest() throws Exception { + try { + ResultCollector collector = ResultCollector.getInstance(); + collector.reset(); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(false); + SAXParser parser = spf.newSAXParser(); + XMLReader reader = parser.getXMLReader(); + + // Resetting values modified by processing instructions + fopFactory.setBreakIndentInheritanceOnReferenceAreaBoundary( + FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE); + fopFactory.setSourceResolution(FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION); + + FOUserAgent ua = fopFactory.newFOUserAgent(); + ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString()); + ua.setFOEventHandlerOverride(new DummyFOEventHandler(ua)); + ua.getEventBroadcaster().addEventListener( + new ConsoleEventListenerForTests(testFile.getName())); + + // Used to set values in the user agent through processing instructions + reader = new PIListener(reader, ua); + + Fop fop = fopFactory.newFop(ua); + + reader.setContentHandler(fop.getDefaultHandler()); + reader.setDTDHandler(fop.getDefaultHandler()); + reader.setErrorHandler(fop.getDefaultHandler()); + reader.setEntityResolver(fop.getDefaultHandler()); + try { + reader.parse(testFile.toURI().toURL().toExternalForm()); + } catch (Exception e) { + collector.notifyError(e.getLocalizedMessage()); + throw e; + } + + List<String> results = collector.getResults(); + if (results.size() > 0) { + for (int i = 0; i < results.size(); i++) { + System.out.println((String) results.get(i)); + } + throw new IllegalStateException((String) results.get(0)); + } + } catch (Exception e) { + org.apache.commons.logging.LogFactory.getLog(this.getClass()).info( + "Error on " + testFile.getName()); + throw e; + } + } + + private static class PIListener extends XMLFilterImpl { + + private FOUserAgent userAgent; + + public PIListener(XMLReader parent, FOUserAgent userAgent) { + super(parent); + this.userAgent = userAgent; + } + + /** @see org.xml.sax.helpers.XMLFilterImpl */ + public void processingInstruction(String target, String data) throws SAXException { + if ("fop-useragent-break-indent-inheritance".equals(target)) { + userAgent.getFactory().setBreakIndentInheritanceOnReferenceAreaBoundary( + Boolean.valueOf(data).booleanValue()); + } else if ("fop-source-resolution".equals(target)) { + userAgent.getFactory().setSourceResolution(Float.parseFloat(data)); + } + super.processingInstruction(target, data); + } + + } + +} diff --git a/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java b/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java index 76faa21c9..604ff6e9e 100644 --- a/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java +++ b/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java @@ -19,129 +19,20 @@ package org.apache.fop.fotreetest; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.AndFileFilter; -import org.apache.commons.io.filefilter.IOFileFilter; -import org.apache.commons.io.filefilter.NameFileFilter; -import org.apache.commons.io.filefilter.PrefixFileFilter; -import org.apache.commons.io.filefilter.SuffixFileFilter; -import org.apache.commons.io.filefilter.TrueFileFilter; - -import org.apache.fop.DebugHelper; -import org.apache.fop.fo.flow.table.CollapsedConditionalBorderTestCase; -import org.apache.fop.fo.flow.table.IllegalRowSpanTestCase; -import org.apache.fop.fo.flow.table.RowGroupBuilderTestCase; -import org.apache.fop.fo.flow.table.TableColumnColumnNumberTestCase; -import org.apache.fop.fo.flow.table.TooManyColumnsTestCase; -import org.apache.fop.layoutengine.LayoutEngineTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; /** * JUnit test suit for running layout engine test under JUnit control. */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + org.apache.fop.fo.flow.table.AllTests.class, + org.apache.fop.fo.pagination.AllTests.class, + org.apache.fop.fotreetest.FOTreeTestCase.class, + org.apache.fop.fo.properties.CommonAccessibilityHolderTestCase.class, + org.apache.fop.fo.DelegatingFOEventHandlerTestCase.class +}) public final class FOTreeTestSuite { - static { - DebugHelper.registerStandardElementListObservers(); - } - - private FOTreeTestSuite() { - //don't instantiate! - } - - /** - * @return the test suite with all the tests (one for each XML file) - * @throws IOException in case of an I/O problem - */ - public static Test suite() throws IOException { - TestSuite suite = new TestSuite(); - addXMLTestCases(suite); - addUnitTestCases(suite); - return suite; - } - - private static void addXMLTestCases(TestSuite suite) throws IOException { - File mainDir = new File("test/fotree"); - - final FOTreeTester tester = new FOTreeTester(); - - IOFileFilter filter; - String single = System.getProperty("fop.fotree.single"); - String startsWith = System.getProperty("fop.fotree.starts-with"); - if (single != null) { - filter = new NameFileFilter(single); - } else if (startsWith != null) { - filter = new PrefixFileFilter(startsWith); - filter = new AndFileFilter(filter, new SuffixFileFilter(".fo")); - } else { - filter = new SuffixFileFilter(".fo"); - filter = LayoutEngineTestSuite.decorateWithDisabledList(filter); - } - Collection files = FileUtils.listFiles(new File(mainDir, "testcases"), - filter, TrueFileFilter.INSTANCE); - String privateTests = System.getProperty("fop.fotree.private"); - if ("true".equalsIgnoreCase(privateTests)) { - Collection privateFiles = FileUtils.listFiles( - new File(mainDir, "private-testcases"), - filter, TrueFileFilter.INSTANCE); - files.addAll(privateFiles); - } - Iterator i = files.iterator(); - while (i.hasNext()) { - File f = (File)i.next(); - addTestCase(suite, tester, f); - } - } - - private static void addTestCase(TestSuite suite, - final FOTreeTester tester, final File f) { - suite.addTest(new FOTreeTestCase(f.getName()) { - public void runTest() throws Exception { - try { - prepare(tester, f); - testMain(); - } catch (Exception e) { - org.apache.commons.logging.LogFactory.getLog(this.getClass()).info( - "Error on " + f.getName()); - throw e; - } - } - }); - } - - private static void addUnitTestCases(TestSuite suite) { - suite.addTestSuite(TooManyColumnsTestCase.class); - suite.addTestSuite(IllegalRowSpanTestCase.class); - suite.addTestSuite(RowGroupBuilderTestCase.class); - suite.addTestSuite(TableColumnColumnNumberTestCase.class); - suite.addTestSuite(CollapsedConditionalBorderTestCase.class); - } - - private static class FOTreeTestCase extends TestCase { - - private FOTreeTester tester; - private File testFile; - - public FOTreeTestCase(String name) { - super(name); - } - - public void prepare(FOTreeTester tester, File testFile) { - //super(testFile.getName()); - this.tester = tester; - this.testFile = testFile; - } - - public void testMain() throws Exception { - tester.runTest(testFile); - } - } } diff --git a/test/java/org/apache/fop/fotreetest/FOTreeTester.java b/test/java/org/apache/fop/fotreetest/FOTreeTester.java deleted file mode 100644 index ba9fde4f9..000000000 --- a/test/java/org/apache/fop/fotreetest/FOTreeTester.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.fotreetest; - -import java.io.File; -import java.util.List; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.apps.FopFactoryConfigurator; -import org.apache.fop.fotreetest.ext.TestElementMapping; -import org.apache.fop.util.ConsoleEventListenerForTests; - -/** - * Test driver class for FO tree tests. - */ -public class FOTreeTester { - - private FopFactory fopFactory = FopFactory.newInstance(); - - /** - * Main constructor - */ - public FOTreeTester() { - fopFactory.addElementMapping(new TestElementMapping()); - } - - /** - * Runs a test. - * @param testFile the test file. - * @throws Exception if a test or FOP itself fails - */ - public void runTest(File testFile) throws Exception { - ResultCollector collector = ResultCollector.getInstance(); - collector.reset(); - - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(false); - SAXParser parser = spf.newSAXParser(); - XMLReader reader = parser.getXMLReader(); - - //Resetting values modified by processing instructions - fopFactory.setBreakIndentInheritanceOnReferenceAreaBoundary( - FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE); - fopFactory.setSourceResolution(FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION); - - FOUserAgent ua = fopFactory.newFOUserAgent(); - ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString()); - ua.setFOEventHandlerOverride(new DummyFOEventHandler(ua)); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(testFile.getName())); - - //Used to set values in the user agent through processing instructions - reader = new PIListener(reader, ua); - - Fop fop = fopFactory.newFop(ua); - - reader.setContentHandler(fop.getDefaultHandler()); - reader.setDTDHandler(fop.getDefaultHandler()); - reader.setErrorHandler(fop.getDefaultHandler()); - reader.setEntityResolver(fop.getDefaultHandler()); - try { - reader.parse(testFile.toURI().toURL().toExternalForm()); - } catch (Exception e) { - collector.notifyError(e.getLocalizedMessage()); - throw e; - } - - List results = collector.getResults(); - if (results.size() > 0) { - for (int i = 0; i < results.size(); i++) { - System.out.println((String)results.get(i)); - } - throw new IllegalStateException((String)results.get(0)); - } - } - - private class PIListener extends XMLFilterImpl { - - private FOUserAgent userAgent; - - public PIListener(XMLReader parent, FOUserAgent userAgent) { - super(parent); - this.userAgent = userAgent; - } - - /** @see org.xml.sax.helpers.XMLFilterImpl */ - public void processingInstruction(String target, String data) throws SAXException { - if ("fop-useragent-break-indent-inheritance".equals(target)) { - userAgent.getFactory().setBreakIndentInheritanceOnReferenceAreaBoundary( - Boolean.valueOf(data).booleanValue()); - } else if ("fop-source-resolution".equals(target)) { - userAgent.getFactory().setSourceResolution(Float.parseFloat(data)); - } - super.processingInstruction(target, data); - } - - } - -} diff --git a/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java b/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java deleted file mode 100644 index 5513a89ab..000000000 --- a/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.fotreetest; - -import java.io.File; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import junit.framework.TestCase; - -import org.xml.sax.XMLReader; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.util.ConsoleEventListenerForTests; - - -/** - * Base class for unit-testing the FO tree building code. It performs the necessary setup - * to parse an FO file and register a proper {@link FOEventHandler}. That handler will be - * the entry point to test classes from the FObj hierarchy. - */ -public abstract class FOTreeUnitTester extends TestCase { - - private XMLReader foReader; - - private FopFactory fopFactory; - - /** - * Should be implemented by children testcases for properly setting up the custom - * FOEventHandler needed to test FObj classes. - */ - public abstract static class FOEventHandlerFactory { - - /** - * This method is called by FOTreeUnitTester when creating a {@link Fop} instance. - * That lets pass to the custom FOEventHandler the proper user agent that will be - * used by this instance. - * - * @param foUserAgent the user agent needed by the Fop instance that will be used - * to create the FO tree - * @return the appropriate FOEventHandler for performing the tests - */ - public abstract FOEventHandler createFOEventHandler(FOUserAgent foUserAgent); - } - - public FOTreeUnitTester() throws Exception { - // Stuff that needs to be set up only once and will be re-used for each test - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(false); - SAXParser parser; - parser = spf.newSAXParser(); - foReader = parser.getXMLReader(); - fopFactory = FopFactory.newInstance(); - } - - /** - * Launches FOP on the given FO file. - * - * @param filename path to the test FO file - * @param factory to create the appropriate FOEventHandler for performing tests - */ - public void setUp(String filename, FOEventHandlerFactory factory) throws Exception { - FOUserAgent ua = fopFactory.newFOUserAgent(); - ua.setFOEventHandlerOverride(factory.createFOEventHandler(ua)); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(filename)); - - Fop fop = fopFactory.newFop(ua); - - foReader.setContentHandler(fop.getDefaultHandler()); - foReader.setDTDHandler(fop.getDefaultHandler()); - foReader.setErrorHandler(fop.getDefaultHandler()); - foReader.setEntityResolver(fop.getDefaultHandler()); - - foReader.parse(new File("test/fotree/unittests/" + filename).toURI().toURL().toExternalForm()); - } -} diff --git a/test/java/org/apache/fop/fotreetest/ResultCollector.java b/test/java/org/apache/fop/fotreetest/ResultCollector.java index 3f6502803..d5b362704 100644 --- a/test/java/org/apache/fop/fotreetest/ResultCollector.java +++ b/test/java/org/apache/fop/fotreetest/ResultCollector.java @@ -19,6 +19,7 @@ package org.apache.fop.fotreetest; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -29,7 +30,7 @@ public class ResultCollector { private static ResultCollector instance = null; - private List results = new java.util.ArrayList(); + private List<String> results = new ArrayList<String>(); /** @return the ResultCollector singleton */ public static ResultCollector getInstance() { @@ -70,7 +71,7 @@ public class ResultCollector { } /** @return the list of results */ - public List getResults() { + public List<String> getResults() { return Collections.unmodifiableList(results); } } diff --git a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java index f4a76d7ed..5070984d1 100644 --- a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java +++ b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java @@ -61,7 +61,7 @@ public class AssertElement extends TestObj { ResultCollector collector = ResultCollector.getInstance(); String propName = attlist.getValue("property"); - String expected = attlist.getValue("expected"); + String expected = attlist.getValue("expected"); String component = null; int dotIndex = propName.indexOf('.'); if (dotIndex >= 0) { diff --git a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java index 1d9127d0c..eee0efac4 100644 --- a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java +++ b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java @@ -40,7 +40,7 @@ public class TestElementMapping extends ElementMapping { /** @see org.apache.fop.fo.ElementMapping#initialize() */ protected void initialize() { if (foObjs == null) { - foObjs = new java.util.HashMap(); + foObjs = new java.util.HashMap<String, Maker>(); foObjs.put("assert", new AssertMaker()); } } diff --git a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java index 97bfb4d5c..bab328911 100644 --- a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java +++ b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java @@ -19,12 +19,14 @@ package org.apache.fop.image.loader.batik; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.File; -import junit.framework.TestCase; - import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.xmlgraphics.image.loader.Image; @@ -35,23 +37,24 @@ import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; import org.apache.xmlgraphics.image.writer.ImageWriterUtil; +import org.junit.Test; /** * Tests for bundled ImageLoader implementations. */ -public class ImageLoaderTestCase extends TestCase { +public class ImageLoaderTestCase { private static final File DEBUG_TARGET_DIR = null; //new File("D:/"); private FopFactory fopFactory; - public ImageLoaderTestCase(String name) { - super(name); + public ImageLoaderTestCase() { fopFactory = FopFactory.newInstance(); fopFactory.setSourceResolution(72); fopFactory.setTargetResolution(300); } + @Test public void testSVG() throws Exception { String uri = "test/resources/images/img-w-size.svg"; @@ -90,6 +93,7 @@ public class ImageLoaderTestCase extends TestCase { assertEquals(16000, info.getSize().getHeightMpt()); } + @Test public void testSVGNoViewbox() throws Exception { String uri = "test/resources/images/circles.svg"; @@ -135,6 +139,7 @@ public class ImageLoaderTestCase extends TestCase { assertEquals(340158, info.getSize().getHeightMpt()); } + @Test public void testWMF() throws Exception { String uri = "test/resources/images/testChart.wmf"; @@ -162,6 +167,7 @@ public class ImageLoaderTestCase extends TestCase { assertEquals(612000, info.getSize().getHeightMpt()); } + @Test public void testSVGWithReferences() throws Exception { String uri = "test/resources/fop/svg/images.svg"; FopFactory ff = FopFactory.newInstance(); @@ -213,7 +219,4 @@ public class ImageLoaderTestCase extends TestCase { } assertFalse("Embedding JPG into SVG failed", same); } - - - } diff --git a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java index 057866eb9..691a2872e 100644 --- a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java +++ b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java @@ -19,6 +19,9 @@ package org.apache.fop.image.loader.batik; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.io.IOException; import javax.xml.transform.Source; @@ -26,42 +29,39 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMSource; -import junit.framework.TestCase; - -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - import org.apache.batik.dom.svg.SVGDOMImplementation; - -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; - import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.junit.Test; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; /** * Tests for bundled image preloader implementations. */ -public class ImagePreloaderTestCase extends TestCase { +public class ImagePreloaderTestCase { private FopFactory fopFactory; - public ImagePreloaderTestCase(String name) { - super(name); + public ImagePreloaderTestCase() { fopFactory = FopFactory.newInstance(); fopFactory.setSourceResolution(72); fopFactory.setTargetResolution(300); } + @Test public void testSVG() throws Exception { String uri = "test/resources/images/img-w-size.svg"; checkSVGFile(uri); } + @Test public void testSVGZ() throws Exception { String uri = "test/resources/images/img-w-size.svgz"; @@ -83,6 +83,7 @@ public class ImagePreloaderTestCase extends TestCase { assertEquals(16000, info.getSize().getHeightMpt()); } + @Test public void testSVGNoSize() throws Exception { String uri = "test/resources/images/img.svg"; FOUserAgent userAgent = fopFactory.newFOUserAgent(); @@ -99,6 +100,7 @@ public class ImagePreloaderTestCase extends TestCase { assertEquals(100000, info.getSize().getHeightMpt()); } + @Test public void testSVGWithDOM() throws Exception { String uri = "my:SVGImage"; FOUserAgent userAgent = fopFactory.newFOUserAgent(); @@ -143,6 +145,7 @@ public class ImagePreloaderTestCase extends TestCase { assertEquals(20000, info.getSize().getHeightMpt()); } + @Test public void testWMF() throws Exception { String uri = "test/resources/images/testChart.wmf"; diff --git a/test/java/org/apache/fop/intermediate/AbstractIFTest.java b/test/java/org/apache/fop/intermediate/AbstractIFTest.java new file mode 100644 index 000000000..2e7f37400 --- /dev/null +++ b/test/java/org/apache/fop/intermediate/AbstractIFTest.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.intermediate; + +import java.io.File; +import java.io.IOException; + +import javax.xml.XMLConstants; +import javax.xml.transform.Result; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.w3c.dom.Document; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFDocumentHandler; +import org.apache.fop.render.intermediate.IFSerializer; + +/** + * A common super-class for intermediate format test cases. + */ +abstract class AbstractIFTest extends AbstractIntermediateTest { + + private static final Schema IF_SCHEMA; + + static { + Schema ifSchema = null; + try { + SchemaFactory sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + sFactory.setErrorHandler(new ErrorHandler() { + + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + + public void warning(SAXParseException exception) throws SAXException { + throw exception; + } + + }); + File ifSchemaFile = new File( + "src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd"); + ifSchema = sFactory.newSchema(ifSchemaFile); + } catch (IllegalArgumentException iae) { + System.err.println("No suitable SchemaFactory for XML Schema validation found!"); + } catch (SAXException e) { + throw new ExceptionInInitializerError(e); + } + IF_SCHEMA = ifSchema; + } + + /** + * Creates a new test case. + * + * @param testFile the file containing the document and the tests + * @throws IOException if an I/O error occurs while loading the test case + */ + public AbstractIFTest(File testFile) throws IOException { + super(testFile); + } + + @Override + protected String getIntermediateFileExtension() { + return ".if.xml"; + } + + @Override + protected Document buildIntermediateDocument(Templates templates) throws Exception { + Transformer transformer = templates.newTransformer(); + setErrorListener(transformer); + + //Set up XMLRenderer to render to a DOM + DOMResult domResult = new DOMResult(); + + FOUserAgent userAgent = createUserAgent(); + + //Create an instance of the target renderer so the XMLRenderer can use its font setup + IFDocumentHandler targetHandler = userAgent.getRendererFactory().createDocumentHandler( + userAgent, getTargetMIME()); + + //Setup painter + IFSerializer serializer = new IFSerializer(); + serializer.setContext(new IFContext(userAgent)); + serializer.mimicDocumentHandler(targetHandler); + serializer.setResult(domResult); + + userAgent.setDocumentHandlerOverride(serializer); + + Fop fop = fopFactory.newFop(userAgent); + Result res = new SAXResult(fop.getDefaultHandler()); + transformer.transform(new DOMSource(testDoc), res); + + return (Document) domResult.getNode(); + } + + @Override + protected void validate(Document doc) throws SAXException, IOException { + if (IF_SCHEMA == null) { + return; //skip validation; + } + Validator validator = IF_SCHEMA.newValidator(); + validator.setErrorHandler(new ErrorHandler() { + + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + + public void warning(SAXParseException exception) throws SAXException { + //ignore + } + + }); + validator.validate(new DOMSource(doc)); + } + +} diff --git a/test/java/org/apache/fop/intermediate/AbstractIntermediateTestCase.java b/test/java/org/apache/fop/intermediate/AbstractIntermediateTest.java index 826a5c777..567d2adba 100644 --- a/test/java/org/apache/fop/intermediate/AbstractIntermediateTestCase.java +++ b/test/java/org/apache/fop/intermediate/AbstractIntermediateTest.java @@ -33,7 +33,9 @@ import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMSource; -import org.custommonkey.xmlunit.XMLTestCase; +import org.custommonkey.xmlunit.XMLAssert; +import org.junit.After; +import org.junit.Before; import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -44,24 +46,21 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; import org.apache.fop.events.model.EventSeverity; -import org.apache.fop.layoutengine.TestEnvironment; import org.apache.fop.util.ConsoleEventListenerForTests; /** * Abstract base class for intermediate format tests. */ -public abstract class AbstractIntermediateTestCase extends XMLTestCase { +public abstract class AbstractIntermediateTest { /** the test environment */ - protected static TestEnvironment env = new TestEnvironment(); + protected static TestAssistant testAssistant = new TestAssistant(); /** the FOP factory */ protected FopFactory fopFactory; - /** the main base directory for tests */ - protected File mainDir = new File("test/layoutengine"); /** the directory containing the tests */ - protected File testDir = new File(mainDir, "standard-testcases"); + protected File testDir = new File("test/layoutengine/standard-testcases"); /** the output directory for any files generated by the tests */ protected File outputDir; @@ -77,32 +76,29 @@ public abstract class AbstractIntermediateTestCase extends XMLTestCase { * @param testFile the test file to run * @throws IOException if an I/O error occurs while loading the test case */ - public AbstractIntermediateTestCase(File testFile) + public AbstractIntermediateTest(File testFile) throws IOException { - super(testFile.getName()); this.testFile = testFile; } - /** {@inheritDoc} */ - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { setupOutputDirectory(); - this.testDoc = env.loadTestCase(testFile); - this.fopFactory = env.getFopFactory(testDoc); - intermediate = buildIntermediateDocument(env.getTestcase2FOStylesheet()); + this.testDoc = testAssistant.loadTestCase(testFile); + this.fopFactory = testAssistant.getFopFactory(testDoc); + intermediate = buildIntermediateDocument(testAssistant.getTestcase2FOStylesheet()); if (outputDir != null) { - env.saveDOM(intermediate, new File(outputDir, - getName() + ".1" + getIntermediateFileExtension())); + testAssistant.saveDOM(intermediate, new File(outputDir, + testFile.getName() + ".1" + getIntermediateFileExtension())); } } - /** {@inheritDoc} */ - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { //Release memory this.intermediate = null; this.fopFactory = null; this.testDoc = null; - super.tearDown(); } /** @@ -148,7 +144,8 @@ public abstract class AbstractIntermediateTestCase extends XMLTestCase { userAgent.getEventBroadcaster().addEventListener( new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.FATAL)); } catch (MalformedURLException e) { - //ignore, won't happen + // Shouldn't happen + throw new AssertionError(); } return userAgent; } @@ -174,11 +171,12 @@ public abstract class AbstractIntermediateTestCase extends XMLTestCase { Source src = new DOMSource(intermediate); Document doc = parseAndRenderToIntermediateFormat(src); if (outputDir != null) { - File tgtFile = new File(outputDir, getName() + ".2" + getIntermediateFileExtension()); - env.saveDOM(doc, tgtFile); + File tgtFile = new File(outputDir, testFile.getName() + ".2" + + getIntermediateFileExtension()); + testAssistant.saveDOM(doc, tgtFile); } - assertXMLEqual(intermediate, doc); + XMLAssert.assertXMLEqual(intermediate, doc); } /** @@ -197,7 +195,7 @@ public abstract class AbstractIntermediateTestCase extends XMLTestCase { public void testParserToPDF() throws Exception { OutputStream out; if (outputDir != null) { - File tgtFile = new File(outputDir, getName() + ".pdf"); + File tgtFile = new File(outputDir, testFile.getName() + ".pdf"); out = new FileOutputStream(tgtFile); out = new BufferedOutputStream(out); } else { @@ -221,6 +219,13 @@ public abstract class AbstractIntermediateTestCase extends XMLTestCase { throws Exception; /** + * Run the test. + * + * @throws Exception if an error occurs during the test + */ + public abstract void runTest() throws Exception; + + /** * Sets an error listener which doesn't swallow errors like Xalan's default one. * @param transformer the transformer to set the error listener on */ diff --git a/test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java b/test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java index 3d029778d..1f8abb9be 100644 --- a/test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java +++ b/test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java @@ -22,6 +22,7 @@ package org.apache.fop.intermediate; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.util.Collection; import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -32,25 +33,39 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.TransformerHandler; -import org.w3c.dom.Document; - import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.AreaTreeModel; import org.apache.fop.area.AreaTreeParser; import org.apache.fop.area.RenderPagesModel; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.layoutengine.LayoutEngineTestUtils; import org.apache.fop.render.Renderer; import org.apache.fop.render.xml.XMLRenderer; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.w3c.dom.Document; /** * Tests the area tree parser. */ -public class AreaTreeParserTestCase extends AbstractIntermediateTestCase { +@RunWith(Parameterized.class) +public class AreaTreeParserTestCase extends AbstractIntermediateTest { /** + * Creates the parameters for this test. + * + * @return the list of file arrays populated with test files + * @throws IOException if an I/O error occurs while reading the test file + */ + @Parameters + public static Collection<File[]> getParameters() throws IOException { + return LayoutEngineTestUtils.getLayoutTestFiles(); + } + /** * Constructor for the test suite that is used for each test file. * @param testFile the test file to run * @throws IOException @@ -72,7 +87,7 @@ public class AreaTreeParserTestCase extends AbstractIntermediateTestCase { setErrorListener(transformer); //Set up XMLRenderer to render to a DOM - TransformerHandler handler = env.getTransformerFactory().newTransformerHandler(); + TransformerHandler handler = testAssistant.getTransformerFactory().newTransformerHandler(); DOMResult domResult = new DOMResult(); handler.setResult(domResult); @@ -82,10 +97,9 @@ public class AreaTreeParserTestCase extends AbstractIntermediateTestCase { Renderer targetRenderer = userAgent.getRendererFactory().createRenderer( userAgent, getTargetMIME()); - XMLRenderer renderer = new XMLRenderer(); + XMLRenderer renderer = new XMLRenderer(userAgent); renderer.mimicRenderer(targetRenderer); renderer.setContentHandler(handler); - renderer.setUserAgent(userAgent); userAgent.setRendererOverride(renderer); @@ -113,15 +127,13 @@ public class AreaTreeParserTestCase extends AbstractIntermediateTestCase { AreaTreeParser parser = new AreaTreeParser(); //Set up XMLRenderer to render to a DOM - TransformerHandler handler = env.getTransformerFactory().newTransformerHandler(); + TransformerHandler handler = testAssistant.getTransformerFactory().newTransformerHandler(); DOMResult domResult = new DOMResult(); handler.setResult(domResult); - XMLRenderer renderer = new XMLRenderer(); - renderer.setContentHandler(handler); - FOUserAgent userAgent = createUserAgent(); + XMLRenderer renderer = new XMLRenderer(userAgent); userAgent.setRendererOverride(renderer); - renderer.setUserAgent(userAgent); + renderer.setContentHandler(handler); FontInfo fontInfo = new FontInfo(); AreaTreeModel treeModel = new RenderPagesModel(userAgent, @@ -132,4 +144,17 @@ public class AreaTreeParserTestCase extends AbstractIntermediateTestCase { return (Document)domResult.getNode(); } + @Override + @Test + public void runTest() throws Exception { + try { + testParserToIntermediateFormat(); + testParserToPDF(); + } catch (Exception e) { + org.apache.commons.logging.LogFactory.getLog(this.getClass()).error( + "Error on " + testFile.getName()); + throw e; + } + } + } diff --git a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java index 661dbadf3..3fc855cef 100644 --- a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java +++ b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java @@ -19,53 +19,14 @@ package org.apache.fop.intermediate; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.fop.layoutengine.LayoutEngineTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * JUnit test suite for the area tree XML format */ +@RunWith(Suite.class) +@SuiteClasses({ AreaTreeParserTestCase.class }) public class AreaTreeXMLFormatTestSuite { - - /** - * @return the test suite with all the tests (one for each XML file) - * @throws IOException in case of an I/O problem - */ - public static Test suite() throws IOException { - TestSuite suite = new TestSuite(); - - Collection files = LayoutEngineTestSuite.getTestFiles(); - - Iterator i = files.iterator(); - while (i.hasNext()) { - File f = (File)i.next(); - addATTestCase(suite, f); - } - - return suite; - } - - private static void addATTestCase(TestSuite suite, - final File f) throws IOException { - suite.addTest(new AreaTreeParserTestCase(f) { - public void runTest() throws Exception { - try { - testParserToIntermediateFormat(); - testParserToPDF(); - } catch (Exception e) { - org.apache.commons.logging.LogFactory.getLog( - this.getClass()).error("Error on " + f.getName()); - throw e; - } - } - }); - } - } diff --git a/test/java/org/apache/fop/intermediate/IFCheck.java b/test/java/org/apache/fop/intermediate/IFCheck.java index dc5404818..dfd76f3b3 100644 --- a/test/java/org/apache/fop/intermediate/IFCheck.java +++ b/test/java/org/apache/fop/intermediate/IFCheck.java @@ -21,10 +21,12 @@ package org.apache.fop.intermediate; import org.w3c.dom.Document; +import org.apache.fop.check.Check; + /** * Check interface for intermediate format checks. */ -public interface IFCheck { +public interface IFCheck extends Check { /** * Called to perform the check. diff --git a/test/java/org/apache/fop/intermediate/IFChecksFactory.java b/test/java/org/apache/fop/intermediate/IFChecksFactory.java new file mode 100644 index 000000000..2eab74130 --- /dev/null +++ b/test/java/org/apache/fop/intermediate/IFChecksFactory.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.intermediate; + +import org.w3c.dom.Element; + +import org.apache.fop.check.ChecksFactory; +import org.apache.fop.layoutengine.EvalCheck; +import org.apache.fop.layoutengine.TrueCheck; + +/** + * A factory class for creating {@link IFCheck} instances. + */ +final class IFChecksFactory extends ChecksFactory<IFCheck> { + + IFChecksFactory() { + registerCheckFactory("true", new CheckFactory<IFCheck>() { + + public IFCheck createCheck(Element element) { + return new TrueCheck(element); + } + + }); + registerCheckFactory("eval", new CheckFactory<IFCheck>() { + + public IFCheck createCheck(Element element) { + return new EvalCheck(element); + } + + }); + } +} diff --git a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java index 226bfc64e..7c03a2898 100644 --- a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java +++ b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java @@ -19,6 +19,8 @@ package org.apache.fop.intermediate; +import static org.junit.Assert.fail; + import java.io.File; import javax.xml.transform.ErrorListener; @@ -29,7 +31,8 @@ import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; @@ -48,13 +51,12 @@ import org.apache.fop.render.intermediate.IFSerializer; /** * This test checks the correct mimicking of a different output format. */ -public class IFMimickingTestCase extends TestCase { +public class IFMimickingTestCase { private FopFactory fopFactory; - /** {@inheritDoc} */ - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { fopFactory = FopFactory.newInstance(); File configFile = new File("test/test-no-xml-metrics.xconf"); fopFactory.setUserConfig(configFile); @@ -64,6 +66,7 @@ public class IFMimickingTestCase extends TestCase { * Tests IF document handler mimicking with PDF output. * @throws Exception if an error occurs */ + @Test public void testMimickingPDF() throws Exception { doTestMimicking(MimeConstants.MIME_PDF); } @@ -72,6 +75,7 @@ public class IFMimickingTestCase extends TestCase { * Tests IF document handler mimicking with PostScript output. * @throws Exception if an error occurs */ + @Test public void testMimickingPS() throws Exception { doTestMimicking(MimeConstants.MIME_POSTSCRIPT); } @@ -80,6 +84,7 @@ public class IFMimickingTestCase extends TestCase { * Tests IF document handler mimicking with TIFF output. * @throws Exception if an error occurs */ + @Test public void testMimickingTIFF() throws Exception { doTestMimicking(MimeConstants.MIME_TIFF); } diff --git a/test/java/org/apache/fop/intermediate/IFParserTestCase.java b/test/java/org/apache/fop/intermediate/IFParserTestCase.java index 15fc74bc9..7d4fb7ad8 100644 --- a/test/java/org/apache/fop/intermediate/IFParserTestCase.java +++ b/test/java/org/apache/fop/intermediate/IFParserTestCase.java @@ -22,59 +22,56 @@ package org.apache.fop.intermediate; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.util.Collection; -import javax.xml.XMLConstants; -import javax.xml.transform.Result; import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamResult; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; import org.w3c.dom.Document; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.FontInfo; -import org.apache.fop.layoutengine.TestEnvironment; +import org.apache.fop.layoutengine.LayoutEngineTestUtils; import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFDocumentHandler; import org.apache.fop.render.intermediate.IFParser; -import org.apache.fop.render.intermediate.IFRenderer; import org.apache.fop.render.intermediate.IFSerializer; /** * Tests the intermediate format parser. */ -public class IFParserTestCase extends AbstractIntermediateTestCase { - - private static TestEnvironment env = new TestEnvironment(); - private static Schema ifSchema; - - private static Schema getIFSchema() throws SAXException { - if (ifSchema == null) { - SchemaFactory sFactory; - try { - sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - } catch (IllegalArgumentException iae) { - System.out.println("No suitable SchemaFactory for XML Schema validation found!"); - return null; - } - File ifSchemaFile = new File( - "src/documentation/intermediate-format-ng/fop-intermediate-format-ng.xsd"); - ifSchema = sFactory.newSchema(ifSchemaFile); +@RunWith(Parameterized.class) +public class IFParserTestCase extends AbstractIFTest { + + /** Set this to true to get the correspondence between test number and test file. */ + private static final boolean DEBUG = false; + + /** + * Gets the parameters for this test + * + * @return a collection of file arrays containing the test files + * @throws IOException if an error occurs when trying to read the test files + */ + @Parameters + public static Collection<File[]> getParameters() throws IOException { + Collection<File[]> testFiles = LayoutEngineTestUtils.getLayoutTestFiles(); + if (DEBUG) { + printFiles(testFiles); + } + return testFiles; + } + + private static void printFiles(Collection<File[]> files) { + int index = 0; + for (File[] file : files) { + assert file.length == 1; + System.out.println(String.format("%3d %s", index++, file[0])); } - return ifSchema; } /** @@ -87,76 +84,7 @@ public class IFParserTestCase extends AbstractIntermediateTestCase { } /** {@inheritDoc} */ - protected String getTargetMIME() { - return MimeConstants.MIME_PDF; - } - - /** {@inheritDoc} */ - protected String getIntermediateFileExtension() { - return ".if.xml"; - } - - /** {@inheritDoc} */ - protected Document buildIntermediateDocument(Templates templates) - throws Exception { - Transformer transformer = templates.newTransformer(); - setErrorListener(transformer); - - //Set up XMLRenderer to render to a DOM - DOMResult domResult = new DOMResult(); - - FOUserAgent userAgent = createUserAgent(); - - //Create an instance of the target renderer so the XMLRenderer can use its font setup - IFDocumentHandler targetHandler = userAgent.getRendererFactory().createDocumentHandler( - userAgent, getTargetMIME()); - - //Setup painter - IFSerializer serializer = new IFSerializer(); - serializer.setContext(new IFContext(userAgent)); - serializer.mimicDocumentHandler(targetHandler); - serializer.setResult(domResult); - - //Setup renderer - IFRenderer renderer = new IFRenderer(); - renderer.setUserAgent(userAgent); - - renderer.setDocumentHandler(serializer); - userAgent.setRendererOverride(renderer); - - Fop fop = fopFactory.newFop(userAgent); - Result res = new SAXResult(fop.getDefaultHandler()); - transformer.transform(new DOMSource(testDoc), res); - - return (Document)domResult.getNode(); - } - - /** {@inheritDoc} */ - protected void validate(Document doc) throws SAXException, IOException { - Schema schema = getIFSchema(); - if (schema == null) { - return; //skip validation; - } - Validator validator = schema.newValidator(); - validator.setErrorHandler(new ErrorHandler() { - - public void error(SAXParseException exception) throws SAXException { - throw exception; - } - - public void fatalError(SAXParseException exception) throws SAXException { - throw exception; - } - - public void warning(SAXParseException exception) throws SAXException { - //ignore - } - - }); - validator.validate(new DOMSource(doc)); - } - - /** {@inheritDoc} */ + @Override protected void parseAndRender(Source src, OutputStream out) throws Exception { IFParser parser = new IFParser(); @@ -170,6 +98,7 @@ public class IFParserTestCase extends AbstractIntermediateTestCase { } /** {@inheritDoc} */ + @Override protected Document parseAndRenderToIntermediateFormat(Source src) throws Exception { IFParser parser = new IFParser(); @@ -185,4 +114,16 @@ public class IFParserTestCase extends AbstractIntermediateTestCase { return (Document)domResult.getNode(); } + @Override + @Test + public void runTest() throws Exception { + try { + testParserToIntermediateFormat(); + testParserToPDF(); + } catch (Exception e) { + org.apache.commons.logging.LogFactory.getLog(this.getClass()).error( + "Error on " + testFile.getName()); + throw e; + } + } } diff --git a/test/java/org/apache/fop/intermediate/IFTestCase.java b/test/java/org/apache/fop/intermediate/IFTestCase.java new file mode 100644 index 000000000..562302ba4 --- /dev/null +++ b/test/java/org/apache/fop/intermediate/IFTestCase.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.intermediate; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; + +import javax.xml.transform.Source; +import javax.xml.transform.TransformerFactory; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + + +/** + * Test case for the IF output. + */ +@RunWith(Parameterized.class) +public class IFTestCase extends AbstractIFTest { + + /** + * Gets the files for this test. + * + * @return a collection of file arrays containing the files to test + * @throws IOException if an error occurs when reading the test files + */ + @Parameters + public static Collection<File[]> getParameters() throws IOException { + File testDir = new File("test/intermediate"); + String[] tests = testDir.list(new FilenameFilter() { + + public boolean accept(File dir, String name) { + return name.endsWith(".xml"); + } + }); + + Collection<File[]> parameters = new ArrayList<File[]>(); + for (String test : tests) { + parameters.add(new File[] { new File(testDir, test) }); + } + return parameters; + } + + private static IFTester ifTester; + + @BeforeClass + public static void setupTestEnvironment() { + File backupDir = new File("build/test-results/intermediate"); + backupDir.mkdirs(); + ifTester = new IFTester(TransformerFactory.newInstance(), backupDir); + } + + /** + * Creates a new test case. + * + * @param test the file containing the test case + * @param ifTester the helper instance that will perform checks + * @throws IOException if an I/O error occurs while loading the test case + */ + public IFTestCase(File test) throws IOException { + super(test); + this.testDir = test.getParentFile(); + } + + @Override + @Test + public void runTest() throws Exception { + Element testRoot = testAssistant.getTestRoot(testFile); + NodeList nodes = testRoot.getElementsByTagName("if-checks"); + if (nodes.getLength() == 0) { + throw new RuntimeException("No IF check found"); + } + Element ifChecks = (Element) nodes.item(0); + + Document doc = buildIntermediateDocument(testAssistant.getTestcase2FOStylesheet()); + ifTester.doIFChecks(testFile.getName(), ifChecks, doc); + } + + @Override + protected void parseAndRender(Source src, OutputStream out) throws Exception { + throw new IllegalStateException("Not applicable to this test"); + } + + @Override + protected Document parseAndRenderToIntermediateFormat(Source src) throws Exception { + throw new IllegalStateException("Not applicable to this test"); + } + +} diff --git a/test/java/org/apache/fop/intermediate/IFTester.java b/test/java/org/apache/fop/intermediate/IFTester.java index 7534309e7..46303d874 100644 --- a/test/java/org/apache/fop/intermediate/IFTester.java +++ b/test/java/org/apache/fop/intermediate/IFTester.java @@ -20,182 +20,63 @@ package org.apache.fop.intermediate; import java.io.File; -import java.lang.reflect.Constructor; -import java.util.Iterator; import java.util.List; -import java.util.Map; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; -import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.area.AreaTreeModel; -import org.apache.fop.area.AreaTreeParser; -import org.apache.fop.area.RenderPagesModel; -import org.apache.fop.events.model.EventSeverity; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.layoutengine.EvalCheck; -import org.apache.fop.layoutengine.TrueCheck; -import org.apache.fop.render.intermediate.IFContext; -import org.apache.fop.render.intermediate.IFRenderer; -import org.apache.fop.render.intermediate.IFSerializer; -import org.apache.fop.util.ConsoleEventListenerForTests; -import org.apache.fop.util.DelegatingContentHandler; /** * Does tests on the intermediate format. */ public class IFTester { - private static final Map IF_CHECK_CLASSES = new java.util.HashMap(); - - static { - IF_CHECK_CLASSES.put("true", TrueCheck.class); - IF_CHECK_CLASSES.put("eval", EvalCheck.class); - } - - private FopFactory fopFactory = FopFactory.newInstance(); + private final IFChecksFactory ifChecksFactory = new IFChecksFactory(); - private SAXTransformerFactory tfactory - = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + private final TransformerFactory tfactory; private File backupDir; /** - * Main constructor + * Main constructor. + * + * @param transformerFactory the factory used to serialize the intermediate format files * @param backupDir an optional directory in which to write the serialized - * intermediate format file (may be null) + * IF files (may be null) */ - public IFTester(File backupDir) { + public IFTester(TransformerFactory transformerFactory, File backupDir) { + this.tfactory = transformerFactory; this.backupDir = backupDir; } /** - * Factory method to create IF checks from DOM elements. - * @param el DOM element to create the check from - * @return The newly create check - */ - protected IFCheck createIFCheck(Element el) { - String name = el.getTagName(); - Class clazz = (Class)IF_CHECK_CLASSES.get(name); - if (clazz != null) { - try { - Constructor c = clazz.getDeclaredConstructor(new Class[] {Node.class}); - IFCheck instance = (IFCheck)c.newInstance(new Object[] {el}); - return instance; - } catch (Exception e) { - throw new RuntimeException("Error while instantiating check '" - + name + "': " + e.getMessage()); - } - } else { - throw new IllegalArgumentException("No check class found: " + name); - } - } - - private Document createIF(File testFile, Document areaTreeXML) throws TransformerException { - try { - FOUserAgent ua = fopFactory.newFOUserAgent(); - ua.setBaseURL(testFile.getParentFile().toURI().toURL().toExternalForm()); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); - - IFRenderer ifRenderer = new IFRenderer(); - ifRenderer.setUserAgent(ua); - - IFSerializer serializer = new IFSerializer(); - serializer.setContext(new IFContext(ua)); - DOMResult result = new DOMResult(); - serializer.setResult(result); - ifRenderer.setDocumentHandler(serializer); - - ua.setRendererOverride(ifRenderer); - FontInfo fontInfo = new FontInfo(); - //Construct the AreaTreeModel that will received the individual pages - final AreaTreeModel treeModel = new RenderPagesModel(ua, - null, fontInfo, null); - - //Iterate over all intermediate files - AreaTreeParser parser = new AreaTreeParser(); - ContentHandler handler = parser.getContentHandler(treeModel, ua); - - DelegatingContentHandler proxy = new DelegatingContentHandler() { - - public void endDocument() throws SAXException { - super.endDocument(); - //Signal the end of the processing. - //The renderer can finalize the target document. - treeModel.endDocument(); - } - - }; - proxy.setDelegateContentHandler(handler); - - Transformer transformer = tfactory.newTransformer(); - transformer.transform(new DOMSource(areaTreeXML), new SAXResult(proxy)); - - return (Document)result.getNode(); - } catch (Exception e) { - throw new TransformerException( - "Error while generating intermediate format file: " + e.getMessage(), e); - } - } - - /** * Runs the intermediate format checks. - * @param testFile the original test file + * @param testName the name of the test case * @param checksRoot the root element containing the IF checks - * @param areaTreeXML the area tree XML + * @param ifDocument the IF XML * @throws TransformerException if an error occurs while transforming the content */ - public void doIFChecks(File testFile, Element checksRoot, Document areaTreeXML) - throws TransformerException { - Document ifDocument = createIF(testFile, areaTreeXML); + public void doIFChecks(String testName, Element checksRoot, Document ifDocument) + throws TransformerException { if (this.backupDir != null) { Transformer transformer = tfactory.newTransformer(); Source src = new DOMSource(ifDocument); - File targetFile = new File(this.backupDir, testFile.getName() + ".if.xml"); + File targetFile = new File(this.backupDir, testName + ".if.xml"); Result res = new StreamResult(targetFile); transformer.transform(src, res); } - - //First create check before actually running them - List checks = new java.util.ArrayList(); - NodeList nodes = checksRoot.getChildNodes(); - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - if (node instanceof Element) { - checks.add(createIFCheck((Element)node)); - } - } - + List<IFCheck> checks = ifChecksFactory.createCheckList(checksRoot); if (checks.size() == 0) { - throw new RuntimeException("No checks are available!"); + throw new RuntimeException("No available IF check"); } - - //Run the actual tests now that we know that the checks themselves are ok - doIFChecks(checks, ifDocument); - } - - private void doIFChecks(List checks, Document ifDocument) { - Iterator i = checks.iterator(); - while (i.hasNext()) { - IFCheck check = (IFCheck)i.next(); + for (IFCheck check : checks) { check.check(ifDocument); } } diff --git a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java index 438ff7672..f960990b2 100644 --- a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java +++ b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java @@ -19,53 +19,14 @@ package org.apache.fop.intermediate; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.apache.fop.layoutengine.LayoutEngineTestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** - * JUnit test suite for the intermediate format + * A test suite for testing the Intermediate Format output. */ -public class IntermediateFormatTestSuite { - - /** - * @return the test suite with all the tests (one for each XML file) - * @throws IOException in case of an I/O problem - */ - public static Test suite() throws IOException { - TestSuite suite = new TestSuite(); - - Collection files = LayoutEngineTestSuite.getTestFiles(); - - Iterator i = files.iterator(); - while (i.hasNext()) { - File f = (File)i.next(); - addIFTestCase(suite, f); - } - - return suite; - } - - private static void addIFTestCase(TestSuite suite, - final File f) throws IOException { - suite.addTest(new IFParserTestCase(f) { - public void runTest() throws Exception { - try { - testParserToIntermediateFormat(); - testParserToPDF(); - } catch (Exception e) { - org.apache.commons.logging.LogFactory.getLog( - this.getClass()).error("Error on " + f.getName()); - throw e; - } - } - }); - } - +@RunWith(Suite.class) +@SuiteClasses({ IFTestCase.class }) +public final class IntermediateFormatTestSuite { } diff --git a/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java new file mode 100644 index 000000000..5d87df1a5 --- /dev/null +++ b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.intermediate; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * JUnit test suite for the intermediate format + */ +@RunWith(Suite.class) +@SuiteClasses({ IFParserTestCase.class }) +public final class LayoutIFTestSuite { +} diff --git a/test/java/org/apache/fop/layoutengine/TestEnvironment.java b/test/java/org/apache/fop/intermediate/TestAssistant.java index ad976ff8c..7fd08dc3d 100644 --- a/test/java/org/apache/fop/layoutengine/TestEnvironment.java +++ b/test/java/org/apache/fop/intermediate/TestAssistant.java @@ -17,7 +17,7 @@ /* $Id$ */ -package org.apache.fop.layoutengine; +package org.apache.fop.intermediate; import java.io.File; import java.io.IOException; @@ -30,12 +30,14 @@ import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.apache.xpath.XPathAPI; import org.apache.xpath.objects.XObject; @@ -43,9 +45,9 @@ import org.apache.xpath.objects.XObject; import org.apache.fop.apps.FopFactory; /** - * Test environment and helper code for running FOP tests. + * Helper class for running FOP tests. */ -public class TestEnvironment { +public class TestAssistant { // configure fopFactory as desired private FopFactory fopFactory = FopFactory.newInstance(); @@ -62,7 +64,7 @@ public class TestEnvironment { /** * Main constructor. */ - public TestEnvironment() { + public TestAssistant() { fopFactory.getFontManager().setBase14KerningEnabled(false); fopFactoryWithBase14Kerning.getFontManager().setBase14KerningEnabled(true); domBuilderFactory = DocumentBuilderFactory.newInstance(); @@ -89,7 +91,7 @@ public class TestEnvironment { * @return the stylesheet * @throws TransformerConfigurationException if an error occurs loading the stylesheet */ - public Templates getTestcase2ChecksStylesheet() throws TransformerConfigurationException { + private Templates getTestcase2ChecksStylesheet() throws TransformerConfigurationException { if (testcase2checks == null) { //Load and cache stylesheet Source src = new StreamSource(new File("test/layoutengine/testcase2checks.xsl")); @@ -98,6 +100,21 @@ public class TestEnvironment { return testcase2checks; } + /** + * Returns the element from the given XML file that encloses the tests. + * + * @param testFile a test case + * @return the parent element of the group(s) of checks + * @throws TransformerException if an error occurs while extracting the test element + */ + public Element getTestRoot(File testFile) throws TransformerException { + Transformer transformer = getTestcase2ChecksStylesheet().newTransformer(); + DOMResult res = new DOMResult(); + transformer.transform(new StreamSource(testFile), res); + Document doc = (Document) res.getNode(); + return doc.getDocumentElement(); + } + public FopFactory getFopFactory(boolean base14KerningEnabled) { FopFactory effFactory = (base14KerningEnabled ? fopFactoryWithBase14Kerning : fopFactory); return effFactory; diff --git a/test/java/org/apache/fop/layoutengine/ElementListCollector.java b/test/java/org/apache/fop/layoutengine/ElementListCollector.java index d6ed12047..1890ee86f 100644 --- a/test/java/org/apache/fop/layoutengine/ElementListCollector.java +++ b/test/java/org/apache/fop/layoutengine/ElementListCollector.java @@ -87,4 +87,4 @@ public class ElementListCollector implements Observer { } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/layoutengine/EvalCheck.java b/test/java/org/apache/fop/layoutengine/EvalCheck.java index 32d9e689b..8065512a7 100644 --- a/test/java/org/apache/fop/layoutengine/EvalCheck.java +++ b/test/java/org/apache/fop/layoutengine/EvalCheck.java @@ -42,16 +42,6 @@ public class EvalCheck implements LayoutEngineCheck, IFCheck { private PrefixResolver prefixResolver; /** - * Creates a new instance - * @param expected expected value - * @param xpath XPath statement that needs to be evaluated - */ - public EvalCheck(String expected, String xpath) { - this.expected = expected; - this.xpath = xpath; - } - - /** * Creates a new instance from a DOM node. * @param node DOM node that defines this check */ diff --git a/test/java/org/apache/fop/layoutengine/HyphenationLayoutTestCase.java b/test/java/org/apache/fop/layoutengine/HyphenationLayoutTestCase.java new file mode 100644 index 000000000..6b5ebbf71 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/HyphenationLayoutTestCase.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutengine; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +import org.junit.runners.Parameterized.Parameters; + +/** + * Class for testing the FOP's hyphenation layout engine using testcases specified in XML + * files. + */ +public class HyphenationLayoutTestCase extends LayoutEngineTestCase { + + /** + * Creates the parameters for this test. + * + * @return the list of file arrays populated with test files + * @throws IOException if an I/O error occurs while reading the test file + */ + @Parameters + public static Collection<File[]> getParameters() throws IOException { + return LayoutEngineTestUtils.getLayoutTestFiles("hyphenation-testcases"); + } + + /** + * Constructor + * @param testFile the file to test + */ + public HyphenationLayoutTestCase(File testFile) { + super(testFile); + } + +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java index 155db2263..ca979efe5 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java @@ -19,10 +19,12 @@ package org.apache.fop.layoutengine; +import org.apache.fop.check.Check; + /** * Defines the interface for check operations. */ -public interface LayoutEngineCheck { +public interface LayoutEngineCheck extends Check { /** * Called to perform the check. diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineChecksFactory.java b/test/java/org/apache/fop/layoutengine/LayoutEngineChecksFactory.java new file mode 100644 index 000000000..bea54c5f8 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineChecksFactory.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutengine; + +import org.w3c.dom.Element; + +import org.apache.fop.check.ChecksFactory; + +/** + * A factory class for creating {@link LayoutEngineCheck} instances. + */ +final class LayoutEngineChecksFactory extends ChecksFactory<LayoutEngineCheck> { + + LayoutEngineChecksFactory() { + registerCheckFactory("true", new CheckFactory<LayoutEngineCheck>() { + + public LayoutEngineCheck createCheck(Element element) { + return new TrueCheck(element); + } + + }); + registerCheckFactory("eval", new CheckFactory<LayoutEngineCheck>() { + + public LayoutEngineCheck createCheck(Element element) { + return new EvalCheck(element); + } + + }); + registerCheckFactory("element-list", new CheckFactory<LayoutEngineCheck>() { + + public LayoutEngineCheck createCheck(Element element) { + return new ElementListCheck(element); + } + + }); + registerCheckFactory("result", new CheckFactory<LayoutEngineCheck>() { + + public LayoutEngineCheck createCheck(Element element) { + return new ResultCheck(element); + } + + }); + } + +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java new file mode 100644 index 000000000..6a0d424e9 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutengine; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.TransformerHandler; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import org.apache.fop.DebugHelper; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.FormattingResults; +import org.apache.fop.area.AreaTreeModel; +import org.apache.fop.area.AreaTreeParser; +import org.apache.fop.area.RenderPagesModel; +import org.apache.fop.events.model.EventSeverity; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.intermediate.IFTester; +import org.apache.fop.intermediate.TestAssistant; +import org.apache.fop.layoutmgr.ElementListObserver; +import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFRenderer; +import org.apache.fop.render.intermediate.IFSerializer; +import org.apache.fop.render.xml.XMLRenderer; +import org.apache.fop.util.ConsoleEventListenerForTests; +import org.apache.fop.util.DelegatingContentHandler; + +/** + * Class for testing the FOP's layout engine using testcases specified in XML + * files. + */ +@RunWith(Parameterized.class) +public class LayoutEngineTestCase { + private static File areaTreeBackupDir; + + @BeforeClass + public static void makeDirAndRegisterDebugHelper() throws IOException { + DebugHelper.registerStandardElementListObservers(); + areaTreeBackupDir = new File("build/test-results/layoutengine"); + if (!areaTreeBackupDir.mkdirs() && !areaTreeBackupDir.exists()) { + throw new IOException("Failed to create the layout engine directory at " + + "build/test-results/layoutengine"); + } + } + + /** + * Creates the parameters for this test. + * + * @return the list of file arrays populated with test files + * @throws IOException if an I/O error occurs while reading the test file + */ + @Parameters + public static Collection<File[]> getParameters() throws IOException { + return LayoutEngineTestUtils.getLayoutTestFiles(); + } + + private TestAssistant testAssistant = new TestAssistant(); + + private LayoutEngineChecksFactory layoutEngineChecksFactory = new LayoutEngineChecksFactory(); + + private IFTester ifTester; + private File testFile; + + private TransformerFactory tfactory = TransformerFactory.newInstance(); + + /** + * Constructs a new instance. + * + * @param testFile the test file + */ + public LayoutEngineTestCase(File testFile) { + this.ifTester = new IFTester(tfactory, areaTreeBackupDir); + this.testFile = testFile; + } + + /** + * Runs a single layout engine test case. + * @throws TransformerException In case of an XSLT/JAXP problem + * @throws IOException In case of an I/O problem + * @throws SAXException In case of a problem during SAX processing + * @throws ParserConfigurationException In case of a problem with the XML parser setup + */ + @Test + public void runTest() throws TransformerException, SAXException, IOException, + ParserConfigurationException { + + DOMResult domres = new DOMResult(); + + ElementListCollector elCollector = new ElementListCollector(); + ElementListObserver.addObserver(elCollector); + + Fop fop; + FopFactory effFactory; + try { + Document testDoc = testAssistant.loadTestCase(testFile); + effFactory = testAssistant.getFopFactory(testDoc); + + //Setup Transformer to convert the testcase XML to XSL-FO + Transformer transformer = testAssistant.getTestcase2FOStylesheet().newTransformer(); + Source src = new DOMSource(testDoc); + + //Setup Transformer to convert the area tree to a DOM + TransformerHandler athandler; + athandler = testAssistant.getTransformerFactory().newTransformerHandler(); + athandler.setResult(domres); + + //Setup FOP for area tree rendering + FOUserAgent ua = effFactory.newFOUserAgent(); + ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString()); + ua.getEventBroadcaster().addEventListener( + new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); + + XMLRenderer atrenderer = new XMLRenderer(ua); + atrenderer.setContentHandler(athandler); + ua.setRendererOverride(atrenderer); + fop = effFactory.newFop(ua); + + SAXResult fores = new SAXResult(fop.getDefaultHandler()); + transformer.transform(src, fores); + } finally { + ElementListObserver.removeObserver(elCollector); + } + + Document doc = (Document)domres.getNode(); + if (areaTreeBackupDir != null) { + testAssistant.saveDOM(doc, + new File(areaTreeBackupDir, testFile.getName() + ".at.xml")); + } + FormattingResults results = fop.getResults(); + LayoutResult result = new LayoutResult(doc, elCollector, results); + checkAll(effFactory, testFile, result); + } + + /** + * Perform all checks on the area tree and, optionally, on the intermediate format. + * @param fopFactory the FOP factory + * @param testFile Test case XML file + * @param result The layout results + * @throws TransformerException if a problem occurs in XSLT/JAXP + */ + protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result) + throws TransformerException { + Element testRoot = testAssistant.getTestRoot(testFile); + + NodeList nodes; + //AT tests only when checks are available + nodes = testRoot.getElementsByTagName("at-checks"); + if (nodes.getLength() > 0) { + Element atChecks = (Element)nodes.item(0); + doATChecks(atChecks, result); + } + + //IF tests only when checks are available + nodes = testRoot.getElementsByTagName("if-checks"); + if (nodes.getLength() > 0) { + Element ifChecks = (Element)nodes.item(0); + Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree()); + ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument); + } + } + + private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML) + throws TransformerException { + try { + FOUserAgent ua = fopFactory.newFOUserAgent(); + ua.setBaseURL(testFile.getParentFile().toURI().toURL().toExternalForm()); + ua.getEventBroadcaster().addEventListener( + new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); + + IFRenderer ifRenderer = new IFRenderer(ua); + + IFSerializer serializer = new IFSerializer(); + serializer.setContext(new IFContext(ua)); + DOMResult result = new DOMResult(); + serializer.setResult(result); + ifRenderer.setDocumentHandler(serializer); + + ua.setRendererOverride(ifRenderer); + FontInfo fontInfo = new FontInfo(); + //Construct the AreaTreeModel that will received the individual pages + final AreaTreeModel treeModel = new RenderPagesModel(ua, + null, fontInfo, null); + + //Iterate over all intermediate files + AreaTreeParser parser = new AreaTreeParser(); + ContentHandler handler = parser.getContentHandler(treeModel, ua); + + DelegatingContentHandler proxy = new DelegatingContentHandler() { + + public void endDocument() throws SAXException { + super.endDocument(); + //Signal the end of the processing. + //The renderer can finalize the target document. + treeModel.endDocument(); + } + + }; + proxy.setDelegateContentHandler(handler); + + Transformer transformer = tfactory.newTransformer(); + transformer.transform(new DOMSource(areaTreeXML), new SAXResult(proxy)); + + return (Document)result.getNode(); + } catch (Exception e) { + throw new TransformerException( + "Error while generating intermediate format file: " + e.getMessage(), e); + } + } + + private void doATChecks(Element checksRoot, LayoutResult result) { + List<LayoutEngineCheck> checks = layoutEngineChecksFactory.createCheckList(checksRoot); + if (checks.size() == 0) { + throw new RuntimeException("No available area tree check"); + } + for (LayoutEngineCheck check : checks) { + check.check(result); + } + } + +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java index 32a48fb0b..2a70f255d 100644 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java @@ -19,204 +19,14 @@ package org.apache.fop.layoutengine; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamSource; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.AndFileFilter; -import org.apache.commons.io.filefilter.IOFileFilter; -import org.apache.commons.io.filefilter.NameFileFilter; -import org.apache.commons.io.filefilter.NotFileFilter; -import org.apache.commons.io.filefilter.PrefixFileFilter; -import org.apache.commons.io.filefilter.SuffixFileFilter; -import org.apache.commons.io.filefilter.TrueFileFilter; - -import org.apache.fop.DebugHelper; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * JUnit test suit for running layout engine test under JUnit control. */ +@RunWith(Suite.class) +@SuiteClasses({ LayoutEngineTestCase.class }) public class LayoutEngineTestSuite { - - static { - DebugHelper.registerStandardElementListObservers(); - } - - public static String[] readDisabledTestcases(File f) throws IOException { - List lines = new java.util.ArrayList(); - Source stylesheet = new StreamSource( - new File("test/layoutengine/disabled-testcase2filename.xsl")); - Source source = new StreamSource(f); - Result result = new SAXResult(new FilenameHandler(lines)); - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesheet); - transformer.transform(source, result); - } catch (TransformerConfigurationException tce) { - throw new RuntimeException(tce.getMessage()); - } catch (TransformerException te) { - throw new RuntimeException(te.getMessage()); - } - return (String[])lines.toArray(new String[lines.size()]); - } - - private static class FilenameHandler extends DefaultHandler { - private StringBuffer buffer = new StringBuffer(128); - private boolean readingFilename = false; - private List filenames; - - public FilenameHandler(List filenames) { - this.filenames = filenames; - } - - public void startElement(String namespaceURI, String localName, String qName, - Attributes atts) throws SAXException { - if (qName != null && qName.equals("file")) { - buffer.setLength(0); - readingFilename = true; - } else { - throw new RuntimeException( - "Unexpected element while reading disabled testcase file names: " + qName); - } - } - - public void endElement(String namespaceURI, String localName, String qName) - throws SAXException { - if (qName != null && qName.equals("file")) { - readingFilename = false; - filenames.add(buffer.toString()); - } else { - throw new RuntimeException( - "Unexpected element while reading disabled testcase file names: " + qName); - } - } - - public void characters(char[] ch, int start, int length) throws SAXException { - if (readingFilename) { - buffer.append(ch, start, length); - } - } - } - - public static IOFileFilter decorateWithDisabledList(IOFileFilter filter) throws IOException { - String disabled = System.getProperty("fop.layoutengine.disabled"); - if (disabled != null && disabled.length() > 0) { - filter = new AndFileFilter(new NotFileFilter( - new NameFileFilter(readDisabledTestcases(new File(disabled)))), - filter); - } - return filter; - } - - /** - * @return a Collection of File instances containing all the test cases set up for processing. - * @throws IOException if there's a problem gathering the list of test files - */ - public static Collection getTestFiles() throws IOException { - File mainDir = new File("test/layoutengine"); - IOFileFilter filter; - String single = System.getProperty("fop.layoutengine.single"); - String startsWith = System.getProperty("fop.layoutengine.starts-with"); - if (single != null) { - filter = new NameFileFilter(single); - } else if (startsWith != null) { - filter = new PrefixFileFilter(startsWith); - filter = new AndFileFilter(filter, new SuffixFileFilter(".xml")); - filter = decorateWithDisabledList(filter); - } else { - filter = new SuffixFileFilter(".xml"); - filter = decorateWithDisabledList(filter); - } - String testset = System.getProperty("fop.layoutengine.testset"); - if (testset == null) { - testset = "standard"; - } - Collection files = FileUtils.listFiles(new File(mainDir, testset + "-testcases"), - filter, TrueFileFilter.INSTANCE); - String privateTests = System.getProperty("fop.layoutengine.private"); - if ("true".equalsIgnoreCase(privateTests)) { - Collection privateFiles = FileUtils.listFiles( - new File(mainDir, "private-testcases"), - filter, TrueFileFilter.INSTANCE); - files.addAll(privateFiles); - } - return files; - } - - /** - * @return the test suite with all the tests (one for each XML file) - * @throws IOException in case of an I/O problem - */ - public static Test suite() throws IOException { - TestSuite suite = new TestSuite(); - - File backupDir = new File("build/test-results/layoutengine"); - backupDir.mkdirs(); - - Collection files = getTestFiles(); - - final LayoutEngineTester tester = new LayoutEngineTester(backupDir); - Iterator i = files.iterator(); - while (i.hasNext()) { - File f = (File)i.next(); - addTestCase(suite, tester, f); - } - - return suite; - } - - private static void addTestCase(TestSuite suite, - final LayoutEngineTester tester, final File f) { - suite.addTest(new LayoutEngineTestCase(f.getName()) { - public void runTest() throws Exception { - try { - prepare(tester, f); - testMain(); - } catch (Exception e) { - org.apache.commons.logging.LogFactory.getLog( - this.getClass()).error("Error on " + f.getName()); - throw e; - } - } - }); - } - - private static class LayoutEngineTestCase extends TestCase { - - private LayoutEngineTester tester; - private File testFile; - - public LayoutEngineTestCase(String name) { - super(name); - } - - public void prepare(LayoutEngineTester tester, File testFile) { - //super(testFile.getName()); - this.tester = tester; - this.testFile = testFile; - } - - public void testMain() throws Exception { - tester.runTest(testFile); - } - } } diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java new file mode 100644 index 000000000..935b86c3b --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java @@ -0,0 +1,203 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutengine; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.AndFileFilter; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.NameFileFilter; +import org.apache.commons.io.filefilter.NotFileFilter; +import org.apache.commons.io.filefilter.PrefixFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; + +/** + * Utility class for layout engine tests. + */ +public final class LayoutEngineTestUtils { + + private LayoutEngineTestUtils() { + } + + private static class FilenameHandler extends DefaultHandler { + private StringBuffer buffer = new StringBuffer(128); + private boolean readingFilename = false; + private List<String> filenames; + + public FilenameHandler(List<String> filenames) { + this.filenames = filenames; + } + + public void startElement(String namespaceURI, String localName, String qName, + Attributes atts) throws SAXException { + if (qName != null && qName.equals("file")) { + buffer.setLength(0); + readingFilename = true; + } else { + throw new RuntimeException( + "Unexpected element while reading disabled testcase file names: " + qName); + } + } + + public void endElement(String namespaceURI, String localName, String qName) + throws SAXException { + if (qName != null && qName.equals("file")) { + readingFilename = false; + filenames.add(buffer.toString()); + } else { + throw new RuntimeException( + "Unexpected element while reading disabled testcase file names: " + qName); + } + } + + public void characters(char[] ch, int start, int length) throws SAXException { + if (readingFilename) { + buffer.append(ch, start, length); + } + } + } + + /** + * Removes from {@code filter} any tests that have been disabled. + * + * @param filter the filter populated with tests + * @param disabled name of the file containing disabled test cases. If null or empty, + * no file is read + * @return {@code filter} minus any disabled tests + */ + public static IOFileFilter decorateWithDisabledList(IOFileFilter filter, String disabled) { + if (disabled != null && disabled.length() > 0) { + filter = new AndFileFilter(new NotFileFilter(new NameFileFilter( + LayoutEngineTestUtils.readDisabledTestcases(new File(disabled)))), filter); + } + return filter; + } + + private static String[] readDisabledTestcases(File f) { + List<String> lines = new ArrayList<String>(); + Source stylesheet = new StreamSource( + new File("test/layoutengine/disabled-testcase2filename.xsl")); + Source source = new StreamSource(f); + Result result = new SAXResult(new FilenameHandler(lines)); + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesheet); + transformer.transform(source, result); + } catch (TransformerConfigurationException tce) { + throw new RuntimeException(tce); + } catch (TransformerException te) { + throw new RuntimeException(te); + } + return (String[]) lines.toArray(new String[lines.size()]); + } + + /** + * Returns the test files matching the given configuration. + * + * @param testConfig the test configuration + * @return the applicable test cases + */ + public static Collection<File[]> getTestFiles(TestFilesConfiguration testConfig) { + File mainDir = testConfig.getTestDirectory(); + IOFileFilter filter; + String single = testConfig.getSingleTest(); + String startsWith = testConfig.getStartsWith(); + if (single != null) { + filter = new NameFileFilter(single); + } else if (startsWith != null) { + filter = new PrefixFileFilter(startsWith); + filter = new AndFileFilter(filter, new SuffixFileFilter(testConfig.getFileSuffix())); + filter = decorateWithDisabledList(filter, testConfig.getDisabledTests()); + } else { + filter = new SuffixFileFilter(testConfig.getFileSuffix()); + filter = decorateWithDisabledList(filter, testConfig.getDisabledTests()); + } + String testset = testConfig.getTestSet(); + + Collection<File> files = FileUtils.listFiles(new File(mainDir, testset), filter, + TrueFileFilter.INSTANCE); + if (testConfig.hasPrivateTests()) { + Collection<File> privateFiles = FileUtils.listFiles(new File(mainDir, + "private-testcases"), filter, TrueFileFilter.INSTANCE); + files.addAll(privateFiles); + } + + Collection<File[]> parametersForJUnit4 = new ArrayList<File[]>(); + for (File f : files) { + parametersForJUnit4.add(new File[] { f }); + } + + return parametersForJUnit4; + } + + /** + * This is a helper method that uses the standard parameters for FOP's layout engine tests and + * returns a set of test files. These pull in System parameters to configure the layout tests + * to run. + * + * @return A collection of file arrays that contain the test files + */ + public static Collection<File[]> getLayoutTestFiles() { + String testSet = System.getProperty("fop.layoutengine.testset"); + testSet = (testSet != null ? testSet : "standard") + "-testcases"; + return getLayoutTestFiles(testSet); + } + + /** + * This is a helper method that uses the standard parameters for FOP's layout engine tests, + * given a test set name returns a set of test files. + * + * @param testSetName the name of the test set + * @return A collection of file arrays that contain the test files + */ + public static Collection<File[]> getLayoutTestFiles(String testSetName) { + TestFilesConfiguration.Builder builder = new TestFilesConfiguration.Builder(); + + builder.testDir("test/layoutengine") + .singleProperty("fop.layoutengine.single") + .startsWithProperty("fop.layoutengine.starts-with") + .suffix(".xml") + .testSet(testSetName) + .disabledProperty("fop.layoutengine.disabled", + "test/layoutengine/disabled-testcases.xml") + .privateTestsProperty("fop.layoutengine.private"); + + TestFilesConfiguration testConfig = builder.build(); + return getTestFiles(testConfig); + } + +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java deleted file mode 100644 index 2c0cf8504..000000000 --- a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.layoutengine; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamSource; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.xml.sax.SAXException; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.apps.FormattingResults; -import org.apache.fop.events.model.EventSeverity; -import org.apache.fop.intermediate.IFTester; -import org.apache.fop.layoutmgr.ElementListObserver; -import org.apache.fop.render.xml.XMLRenderer; -import org.apache.fop.util.ConsoleEventListenerForTests; - -/** - * Class for testing the FOP's layout engine using testcases specified in XML - * files. - */ -public class LayoutEngineTester { - - private static final Map AT_CHECK_CLASSES = new java.util.HashMap(); - - private TestEnvironment env = new TestEnvironment(); - - private File areaTreeBackupDir; - private IFTester ifTester; - - static { - AT_CHECK_CLASSES.put("true", TrueCheck.class); - AT_CHECK_CLASSES.put("eval", EvalCheck.class); - AT_CHECK_CLASSES.put("element-list", ElementListCheck.class); - AT_CHECK_CLASSES.put("result", ResultCheck.class); - } - - /** - * Constructs a new instance. - * @param areaTreeBackupDir Optional directory that receives the generated - * area tree XML files. May be null. - */ - public LayoutEngineTester(File areaTreeBackupDir) { - this.areaTreeBackupDir = areaTreeBackupDir; - this.ifTester = new IFTester(areaTreeBackupDir); - } - - /** - * Runs a single layout engine test case. - * @param testFile Test case to run - * @throws TransformerException In case of an XSLT/JAXP problem - * @throws IOException In case of an I/O problem - * @throws SAXException In case of a problem during SAX processing - * @throws ParserConfigurationException In case of a problem with the XML parser setup - */ - public void runTest(File testFile) - throws TransformerException, SAXException, IOException, ParserConfigurationException { - - DOMResult domres = new DOMResult(); - - ElementListCollector elCollector = new ElementListCollector(); - ElementListObserver.addObserver(elCollector); - - Fop fop; - - try { - Document testDoc = env.loadTestCase(testFile); - FopFactory effFactory = env.getFopFactory(testDoc); - - //Setup Transformer to convert the testcase XML to XSL-FO - Transformer transformer = env.getTestcase2FOStylesheet().newTransformer(); - Source src = new DOMSource(testDoc); - - //Setup Transformer to convert the area tree to a DOM - TransformerHandler athandler; - athandler = env.getTransformerFactory().newTransformerHandler(); - athandler.setResult(domres); - - //Setup FOP for area tree rendering - FOUserAgent ua = effFactory.newFOUserAgent(); - ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString()); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN)); - - XMLRenderer atrenderer = new XMLRenderer(); - atrenderer.setUserAgent(ua); - atrenderer.setContentHandler(athandler); - ua.setRendererOverride(atrenderer); - fop = effFactory.newFop(ua); - - SAXResult fores = new SAXResult(fop.getDefaultHandler()); - transformer.transform(src, fores); - } finally { - ElementListObserver.removeObserver(elCollector); - } - - Document doc = (Document)domres.getNode(); - if (this.areaTreeBackupDir != null) { - env.saveDOM(doc, - new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml")); - } - FormattingResults results = fop.getResults(); - LayoutResult result = new LayoutResult(doc, elCollector, results); - checkAll(testFile, result); - } - - /** - * Factory method to create AT checks from DOM elements. - * @param el DOM element to create the check from - * @return The newly create check - */ - protected LayoutEngineCheck createATCheck(Element el) { - String name = el.getTagName(); - Class clazz = (Class)AT_CHECK_CLASSES.get(name); - if (clazz != null) { - try { - Constructor c = clazz.getDeclaredConstructor(new Class[] {Node.class}); - LayoutEngineCheck instance = (LayoutEngineCheck)c.newInstance(new Object[] {el}); - return instance; - } catch (Exception e) { - throw new RuntimeException("Error while instantiating check '" - + name + "': " + e.getMessage()); - } - } else { - throw new IllegalArgumentException("No check class found: " + name); - } - } - - - /** - * Perform all checks on the area tree and, optionally, on the intermediate format. - * @param testFile Test case XML file - * @param result The layout results - * @throws TransformerException if a problem occurs in XSLT/JAXP - */ - protected void checkAll(File testFile, LayoutResult result) throws TransformerException { - Transformer transformer = env.getTestcase2ChecksStylesheet().newTransformer(); - Source src = new StreamSource(testFile); - DOMResult res = new DOMResult(); - transformer.transform(src, res); - - Document doc = (Document)res.getNode(); - Element root = doc.getDocumentElement(); - - NodeList nodes; - //AT tests only when checks are available - nodes = root.getElementsByTagName("at-checks"); - if (nodes.getLength() > 0) { - Element atChecks = (Element)nodes.item(0); - doATChecks(atChecks, result); - } - - //IF tests only when checks are available - nodes = root.getElementsByTagName("if-checks"); - if (nodes.getLength() > 0) { - Element ifChecks = (Element)nodes.item(0); - ifTester.doIFChecks(testFile, ifChecks, result.getAreaTree()); - } - } - - private void doATChecks(Element checksRoot, LayoutResult result) { - //First create check before actually running them - List checks = new java.util.ArrayList(); - NodeList nodes = checksRoot.getChildNodes(); - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - if (node instanceof Element) { - checks.add(createATCheck((Element)node)); - } - } - - if (checks.size() == 0) { - throw new RuntimeException("No checks are available!"); - } - - //Run the actual tests now that we know that the checks themselves are ok - doATChecks(checks, result); - } - - private void doATChecks(List checks, LayoutResult result) { - Iterator i = checks.iterator(); - while (i.hasNext()) { - LayoutEngineCheck check = (LayoutEngineCheck)i.next(); - check.check(result); - } - } - -} diff --git a/test/java/org/apache/fop/layoutengine/ResultCheck.java b/test/java/org/apache/fop/layoutengine/ResultCheck.java index 54af77a43..3b3a9cd98 100644 --- a/test/java/org/apache/fop/layoutengine/ResultCheck.java +++ b/test/java/org/apache/fop/layoutengine/ResultCheck.java @@ -19,9 +19,10 @@ package org.apache.fop.layoutengine; -import org.apache.fop.apps.FormattingResults; import org.w3c.dom.Node; +import org.apache.fop.apps.FormattingResults; + /** * Simple check that requires a result property to evaluate to the expected value */ @@ -31,16 +32,6 @@ public class ResultCheck implements LayoutEngineCheck { private String property; /** - * Creates a new instance - * @param expected expected value - * @param property property of which the value needs to be evaluated - */ - public ResultCheck(String expected, String property) { - this.expected = expected; - this.property = property; - } - - /** * Creates a new instance from a DOM node. * @param node DOM node that defines this check */ @@ -49,9 +40,7 @@ public class ResultCheck implements LayoutEngineCheck { this.property = node.getAttributes().getNamedItem("property").getNodeValue(); } - /* (non-Javadoc) - * @see LayoutEngineCheck#check(LayoutResult) - */ + /** {@inheritDoc} */ public void check(LayoutResult result) { FormattingResults results = result.getResults(); String actual; @@ -68,7 +57,7 @@ public class ResultCheck implements LayoutEngineCheck { } - /** @see java.lang.Object#toString() */ + @Override public String toString() { return "Property: " + property; } diff --git a/test/java/org/apache/fop/layoutengine/TestFilesConfiguration.java b/test/java/org/apache/fop/layoutengine/TestFilesConfiguration.java new file mode 100644 index 000000000..656fc5f6f --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/TestFilesConfiguration.java @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutengine; + +import java.io.File; + +/** + * A class that contains the information needed to run a suite of layout engine and FO tree + * tests. + */ +public final class TestFilesConfiguration { + + private final File testDirectory; + private final String singleTest; + private final String testStartsWith; + private final String testFileSuffix; + private final String testSet; + private final String disabledTests; + private final boolean privateTests; + + private TestFilesConfiguration(Builder builder) { + this.testDirectory = new File(builder.testDirectory); + this.singleTest = builder.singleTest; + this.testStartsWith = builder.testStartsWith; + this.testFileSuffix = builder.testFileSuffix; + this.testSet = builder.testSet; + this.privateTests = builder.privateTests; + this.disabledTests = builder.disabledTests; + } + + /** + * Returns the directory of the tests. + * @return the test directory + */ + public File getTestDirectory() { + return testDirectory; + } + + /** + * Returns the name of the single test file to run. + * @return the single test file name + */ + public String getSingleTest() { + return singleTest; + } + + /** + * Returns the string that must prefix the test file names. + * @return the prefixing string + */ + public String getStartsWith() { + return testStartsWith; + } + + /** + * Returns the file suffix (i.e. ".xml" for XML files and ".fo" for FOs). + * @return the file suffix + */ + public String getFileSuffix() { + return testFileSuffix; + } + + /** + * Returns the directory set of tests to be run. + * @return the directory tests + */ + public String getTestSet() { + return testSet; + } + + /** + * Returns the name of the XML file containing the disabled tests. + * @return a file name, may be null + */ + public String getDisabledTests() { + return disabledTests; + } + + /** + * Whether any private tests should be invoked. + * @return true if private tests should be tested + */ + public boolean hasPrivateTests() { + return privateTests; + } + + /** + * A builder class that configures the data for running a suite of tests designed for the + * layout engine and FOTree. + */ + public static class Builder { + + private String testDirectory; + private String singleTest; + private String testStartsWith; + private String testFileSuffix; + private String testSet; + private String disabledTests; + private boolean privateTests; + + /** + * Configures the test directory. + * @param dir the test directory + * @return {@code this} + */ + public Builder testDir(String dir) { + testDirectory = dir; + return this; + } + + /** + * Configures the name of the single test to run. + * @param singleProperty name of the property that determines the single test case + * @return {@code this} + */ + public Builder singleProperty(String singleProperty) { + singleTest = getSystemProperty(singleProperty); + return this; + } + + /** + * Configures the prefix that all test cases must match. + * @param startsWithProperty name of the property that determines the common prefix + * @return {@code this} + */ + public Builder startsWithProperty(String startsWithProperty) { + testStartsWith = getSystemProperty(startsWithProperty); + return this; + } + + /** + * Configures the test file name suffix. + * @param suffix the suffixing string + * @return {@code this} + */ + public Builder suffix(String suffix) { + testFileSuffix = suffix; + return this; + } + + /** + * Configures the name of the directory containing the set of tests. + * @param testSet the directory of tests. If null, defaults to "standard-testcases" + * @return {@code this} + */ + public Builder testSet(String testSet) { + this.testSet = testSet != null ? testSet : "standard-testcases"; + return this; + } + + /** + * Configures whether any tests are disabled. + * @param disabledProperty name of the property that determines the file of + * disabled test cases + * @param defaultValue if the property was not defined, uses this file name + * instead + * @return {@code this} + */ + public Builder disabledProperty(String disabledProperty, String defaultValue) { + String property = getSystemProperty(disabledProperty); + disabledTests = property != null ? property : defaultValue; + return this; + } + + /** + * Configures whether private tests must be run or not. + * @param privateTestsProperty name of the property containing the boolean switch + * @return {@code this} + */ + public Builder privateTestsProperty(String privateTestsProperty) { + String property = getSystemProperty(privateTestsProperty); + this.privateTests = property != null && property.equalsIgnoreCase("true"); + return this; + } + + private String getSystemProperty(String property) { + return System.getProperty(property); + } + + /** + * Creates the configuration instance. + * @return a configuration instance configured by this builder + */ + public TestFilesConfiguration build() { + return new TestFilesConfiguration(this); + } + } +} diff --git a/test/java/org/apache/fop/layoutengine/TrueCheck.java b/test/java/org/apache/fop/layoutengine/TrueCheck.java index 94ae942de..77d76b91d 100644 --- a/test/java/org/apache/fop/layoutengine/TrueCheck.java +++ b/test/java/org/apache/fop/layoutengine/TrueCheck.java @@ -42,14 +42,6 @@ public class TrueCheck implements LayoutEngineCheck, IFCheck { private PrefixResolver prefixResolver; /** - * Creates a new instance - * @param xpath XPath statement that needs to be evaluated - */ - public TrueCheck(String xpath) { - this.xpath = xpath; - } - - /** * Creates a new instance from a DOM node. * @param node DOM node that defines this check */ diff --git a/test/java/org/apache/fop/layoutmgr/PageSequenceLayoutManagerTestCase.java b/test/java/org/apache/fop/layoutmgr/PageSequenceLayoutManagerTestCase.java new file mode 100644 index 000000000..eb2a4fc92 --- /dev/null +++ b/test/java/org/apache/fop/layoutmgr/PageSequenceLayoutManagerTestCase.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id:$ */ + +package org.apache.fop.layoutmgr; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.area.AreaTreeHandler; +import org.apache.fop.area.PageViewport; +import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.Region; +import org.apache.fop.fo.pagination.Root; +import org.apache.fop.fo.pagination.SimplePageMaster; +import org.junit.Test; + +public class PageSequenceLayoutManagerTestCase { + + private static final String MAIN_FLOW_NAME = "main"; + private static final String EMPTY_FLOW_NAME = "empty"; + + /** + * Blank pages can be created from empty pages + * + * @throws Exception + */ + @Test + public void testGetNextPageBlank() throws Exception { + + final Page expectedPage = createPageForRegionName(EMPTY_FLOW_NAME); + final Page[] providedPages = new Page[]{expectedPage}; + + testGetNextPage(providedPages, expectedPage, true); + } + + /** + * Empty pages should not be provided by the PageSequenceLayoutManager + * to layout the main flow + * + * @throws Exception + */ + @Test + public void testGetNextPageFirstEmpty() throws Exception { + + final Page emptyPage = createPageForRegionName(EMPTY_FLOW_NAME); + final Page expectedPage = createPageForRegionName(MAIN_FLOW_NAME); + final Page[] providedPages = new Page[]{emptyPage, expectedPage}; + + testGetNextPage(providedPages, expectedPage, false); + } + + private void testGetNextPage(final Page[] providedPages, Page expectedPage, boolean isBlank) { + + final Flow flow = mock(Flow.class); + final PageSequence pseq = mock(PageSequence.class); + final Root root = mock(Root.class); + final AreaTreeHandler ath = mock(AreaTreeHandler.class); + + when(flow.getFlowName()).thenReturn(MAIN_FLOW_NAME); + when(pseq.getMainFlow()).thenReturn(flow); + when(pseq.getRoot()).thenReturn(root); + + PageSequenceLayoutManager sut = new PageSequenceLayoutManager(ath, pseq) { + + @Override + protected Page createPage(int i, boolean b) { + return providedPages[i - 1]; + } + + @Override + protected void finishPage() { + //nop + } + + // Expose the protected method for testing + public Page makeNewPage(boolean isBlank) { + return super.makeNewPage(isBlank); + } + }; + + assertEquals(expectedPage, sut.makeNewPage(isBlank)); + } + + + private static Page createPageForRegionName(final String regionName) { + final Page page = mock(Page.class); + final SimplePageMaster spm = mock(SimplePageMaster.class); + final PageViewport pageViewport = mock(PageViewport.class); + final Region region = mock(Region.class); + + when(page.getSimplePageMaster()).thenReturn(spm); + when(page.getPageViewport()).thenReturn(pageViewport); + when(spm.getRegion(anyInt())).thenReturn(region); + + when(region.getRegionName()).thenReturn(regionName); + + return page; + } +} diff --git a/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java new file mode 100644 index 000000000..95d5c0a1d --- /dev/null +++ b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; + +/** + * Test case for {@link AbstractPDFStream}. + */ +public class AbstractPDFStreamTestCase extends PDFObjectTestCase { + + private AbstractPDFStream abstractStream; + + private String textData = "This is an arbitrary string for testing."; + + private static byte[] encodedBytes; + static { + int[] encoded = { 0x78, 0x9c, 0x0b, 0xc9, 0xc8, 0x2c, 0x56, 0x00, 0xa2, 0xc4, 0x3c, 0x85, + 0xc4, 0xa2, 0xa4, 0xcc, 0x92, 0xa2, 0xc4, 0xa2, 0x4a, 0x85, 0xe2, 0x92, 0xa2, 0xcc, + 0xbc, 0x74, 0x85, 0xb4, 0xfc, 0x22, 0x85, 0x92, 0xd4, 0xe2, 0x12, 0x20, 0x5b, 0x0f, + 0x00, 0x2d, 0x2b, 0x0e, 0xde, 0x0a }; + encodedBytes = new byte[encoded.length]; + int i = 0; + for (int in : encoded) { + encodedBytes[i++] = (byte) (in & 0xff); + } + } + private String startStream = "<< /Length 5 0 R /Filter /FlateDecode >>\n" + + "stream\n"; + + private String endStream = "endstream"; + + @Before + public void setUp() { + abstractStream = new AbstractPDFStream() { + + @Override + protected void outputRawStreamData(OutputStream out) throws IOException { + out.write(textData.getBytes()); + } + + @Override + protected int getSizeHint() throws IOException { + return textData.length(); + } + }; + abstractStream.setDocument(doc); + abstractStream.setParent(parent); + + pdfObjectUnderTest = abstractStream; + } + + /** + * Tests output() - ensure that this object is correctly formatted to the output stream. + * @throws IOException if an I/O error occurs + */ + @Test + public void testOutput() throws IOException { + // This differs from most other objects, if the object number = 0 an exception is thrown + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + abstractStream.setObjectNumber(1); + ByteArrayOutputStream expectedStream = new ByteArrayOutputStream(); + expectedStream.write(startStream.getBytes()); + expectedStream.write(encodedBytes); + expectedStream.write(endStream.getBytes()); + assertEquals(expectedStream.size(), abstractStream.output(outStream)); + assertEquals(expectedStream.toString(), outStream.toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java new file mode 100644 index 000000000..a9d7bf4f6 --- /dev/null +++ b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Tests the {@link FileIDGenerator} class. + */ +@RunWith(Parameterized.class) +public class FileIDGeneratorTestCase { + + /** The generator under test. */ + protected FileIDGenerator fileIDGenerator; + + private TestGetter initializer; + + @Parameters + public static Collection<TestGetter[]> getParameters() { + ArrayList<TestGetter[]> params = new ArrayList<TestGetter[]>(); + params.add(new TestGetter[] { new RandomFileIDGeneratorTest() }); + params.add(new TestGetter[] { new DigestFileIDGeneratorTest() }); + return params; + } + + public FileIDGeneratorTestCase(TestGetter initializer) { + this.initializer = initializer; + } + + @Before + public void setUp() throws Exception { + fileIDGenerator = initializer.getSut(); + } + + /** Tests that the getOriginalFileID method generates valid output. */ + @Test + public void testOriginal() { + byte[] fileID = fileIDGenerator.getOriginalFileID(); + fileIDMustBeValid(fileID); + } + + /** Tests that the getUpdatedFileID method generates valid output. */ + @Test + public void testUpdated() { + byte[] fileID = fileIDGenerator.getUpdatedFileID(); + fileIDMustBeValid(fileID); + } + + private void fileIDMustBeValid(byte[] fileID) { + assertNotNull(fileID); + assertEquals(16, fileID.length); + } + + /** Tests that multiple calls to getOriginalFileID method always return the same value. */ + @Test + public void testOriginalMultipleCalls() { + byte[] fileID1 = fileIDGenerator.getUpdatedFileID(); + byte[] fileID2 = fileIDGenerator.getUpdatedFileID(); + assertTrue(Arrays.equals(fileID1, fileID2)); + } + + /** Tests that getUpdatedFileID returns the same value as getOriginalFileID. */ + @Test + public void testUpdateEqualsOriginal() { + byte[] originalFileID = fileIDGenerator.getOriginalFileID(); + byte[] updatedFileID = fileIDGenerator.getUpdatedFileID(); + assertTrue(Arrays.equals(originalFileID, updatedFileID)); + } + + private static interface TestGetter { + FileIDGenerator getSut() throws Exception; + } + + /** + * Tests the random file ID generator. + */ + private static class RandomFileIDGeneratorTest implements TestGetter { + + public FileIDGenerator getSut() throws Exception { + return FileIDGenerator.getRandomFileIDGenerator(); + } + + } + + /** + * Tests the file ID generator based on an MD5 digest. + */ + private static class DigestFileIDGeneratorTest implements TestGetter { + + public FileIDGenerator getSut() throws Exception { + return FileIDGenerator.getDigestFileIDGenerator( + new PDFDocument("Apache FOP")); + } + + } + +} diff --git a/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java new file mode 100644 index 000000000..89d980029 --- /dev/null +++ b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.junit.Test; + +import org.apache.fop.pdf.xref.CompressedObjectReference; + +public class ObjectStreamManagerTestCase { + + private List<CompressedObjectReference> compressedObjectReferences; + + private MockPdfDocument pdfDocument; + + @Test + public void add() { + final int expectedCapacity = 100; + final int numCompressedObjects = expectedCapacity * 2 + 1; + createCompressObjectReferences(numCompressedObjects); + assertEquals(numCompressedObjects, compressedObjectReferences.size()); + int objectStreamNumber1 = assertSameObjectStream(0, expectedCapacity); + int objectStreamNumber2 = assertSameObjectStream(expectedCapacity, expectedCapacity * 2); + int objectStreamNumber3 = assertSameObjectStream(expectedCapacity * 2, numCompressedObjects); + assertDifferent(objectStreamNumber1, objectStreamNumber2, objectStreamNumber3); + assertEquals(objectStreamNumber3, pdfDocument.previous.getObjectNumber()); + } + + private void createCompressObjectReferences(int numObjects) { + pdfDocument = new MockPdfDocument(); + ObjectStreamManager sut = new ObjectStreamManager(pdfDocument); + for (int obNum = 1; obNum <= numObjects; obNum++) { + sut.add(createCompressedObject(obNum)); + } + compressedObjectReferences = sut.getCompressedObjectReferences(); + } + + private static class MockPdfDocument extends PDFDocument { + + private ObjectStream previous; + + public MockPdfDocument() { + super(""); + } + + public void assignObjectNumber(PDFObject obj) { + super.assignObjectNumber(obj); + if (obj instanceof ObjectStream) { + ObjectStream objStream = (ObjectStream) obj; + ObjectStream previous = (ObjectStream) objStream.get("Extends"); + if (previous == null) { + assertEquals(this.previous, previous); + } + this.previous = objStream; + } + } + } + + private CompressedObject createCompressedObject(final int objectNumber) { + return new CompressedObject() { + + public int getObjectNumber() { + return objectNumber; + } + + public int output(OutputStream outputStream) throws IOException { + throw new UnsupportedOperationException(); + } + }; + } + + private int assertSameObjectStream(int from, int to) { + int objectStreamNumber = getObjectStreamNumber(from); + for (int i = from + 1; i < to; i++) { + assertEquals(objectStreamNumber, getObjectStreamNumber(i)); + } + return objectStreamNumber; + } + + private int getObjectStreamNumber(int index) { + return compressedObjectReferences.get(index).getObjectStreamNumber(); + } + + private void assertDifferent(int objectStreamNumber1, int objectStreamNumber2, + int objectStreamNumber3) { + assertTrue(objectStreamNumber1 != objectStreamNumber2); + assertTrue(objectStreamNumber1 != objectStreamNumber3); + assertTrue(objectStreamNumber2 != objectStreamNumber3); + } +} diff --git a/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java new file mode 100644 index 000000000..317828e4b --- /dev/null +++ b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class ObjectStreamTestCase { + + private static final String OBJECT_CONTENT = "<<\n /Foo True\n /Bar False\n>>\n"; + + private PDFDocument pdfDocument; + + private ObjectStream objectStream; + + private List<MockCompressedObject> compressedObjects; + + @Before + public void setUp() throws Exception { + pdfDocument = new PDFDocument("PDFObjectStreamTestCase"); + objectStream = new ObjectStream(); + pdfDocument.assignObjectNumber(objectStream); + compressedObjects = Arrays.asList(new MockCompressedObject(), new MockCompressedObject()); + } + + @Test + public void testSingleObjectStream() throws IOException { + populateObjectStream(); + testOutput(); + } + + @Test + public void testObjectStreamCollection() throws IOException { + objectStream = new ObjectStream(objectStream); + pdfDocument.assignObjectNumber(objectStream); + populateObjectStream(); + testOutput(); + } + + @Test(expected = IllegalStateException.class) + public void directObjectsAreNotAllowed() throws Exception { + objectStream.addObject(new MockCompressedObject()); + } + + @Test(expected = NullPointerException.class) + public void nullObjectsAreNotAllowed() throws Exception { + objectStream.addObject(null); + } + + private void testOutput() throws IOException { + String expected = getExpectedOutput(); + String actual = getActualOutput(); + assertEquals(expected, actual); + } + + private void populateObjectStream() { + for (MockCompressedObject obj : compressedObjects) { + pdfDocument.assignObjectNumber(obj); + objectStream.addObject(obj); + } + } + + private String getExpectedOutput() { + int numObs = compressedObjects.size(); + int objectStreamNumber = objectStream.getObjectNumber(); + int offsetsLength = 9; + StringBuilder expected = new StringBuilder(); + expected.append("<<\n"); + ObjectStream previous = (ObjectStream) objectStream.get("Extends"); + if (previous != null) { + expected.append(" /Extends ").append(previous.getObjectNumber()).append(" 0 R\n"); + } + expected.append(" /Type /ObjStm\n") + .append(" /N ").append(numObs).append("\n") + .append(" /First ").append(offsetsLength).append('\n') + .append(" /Length ").append(OBJECT_CONTENT.length() * 2 + offsetsLength + 1).append('\n') + .append(">>\n") + .append("stream\n"); + int offset = 0; + int num = 1; + for (PDFObject ob : compressedObjects) { + expected.append(objectStreamNumber + num++).append(' ').append(offset).append('\n'); + offset += ob.toPDFString().length(); + } + for (PDFObject ob : compressedObjects) { + expected.append(ob.toPDFString()); + } + expected.append("\nendstream"); + return expected.toString(); + } + + private String getActualOutput() throws IOException { + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + objectStream.getFilterList().setDisableAllFilters(true); + objectStream.output(actual); + return actual.toString("US-ASCII"); + } + + private static class MockCompressedObject extends PDFObject implements CompressedObject { + + @Override + protected String toPDFString() { + return OBJECT_CONTENT; + } + } + +} diff --git a/test/java/org/apache/fop/pdf/PDFArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java new file mode 100644 index 000000000..418b2f1a9 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Test case for {@link PDFArray}. + */ +public class PDFArrayTestCase extends PDFObjectTestCase { + private PDFArray intArray; + private String intArrayOutput; + private PDFArray doubleArray; + private String doubleArrayOutput; + private PDFArray collectionArray; + private String collectionArrayOutput; + private PDFArray objArray; + private String objArrayOutput; + + /** A PDF object used solely for testing */ + private PDFNumber num; + + @Before + public void setUp() { + intArray = new PDFArray(parent, new int[] {1, 2, 3, 4, 5}); + intArrayOutput = "[1 2 3 4 5]"; + + doubleArray = new PDFArray(parent, new double[] {1.1, 2.2, 3.3, 4.4, 5.5}); + doubleArrayOutput = "[1.1 2.2 3.3 4.4 5.5]"; + + List<Object> strList = new ArrayList<Object>(); + strList.add("one"); + strList.add("two"); + strList.add("three"); + collectionArray = new PDFArray(parent, strList); + collectionArrayOutput = "[(one) (two) (three)]"; + + // Set arbitrary values here + num = new PDFNumber(); + num.setNumber(20); + num.setObjectNumber(4); + objArray = new PDFArray(parent, new Object[] {"one", 2, 3.0f, num}); + objArrayOutput = "[(one) 2 3 4 0 R]"; + + // set the document + intArray.setDocument(doc); + doubleArray.setDocument(doc); + collectionArray.setDocument(doc); + objArray.setDocument(doc); + + // Test the progenitor in the inheritance stack + objArray.setParent(parent); + pdfObjectUnderTest = objArray; + } + + private void intArrayContainsTests() { + for (int i = 1; i <= 5; i++) { + assertTrue(intArray.contains(i)); + } + assertFalse(intArray.contains(6)); + assertFalse(intArray.contains(0)); + } + + private void doubleArrayContainsTests() { + assertTrue(doubleArray.contains(1.1)); + assertTrue(doubleArray.contains(2.2)); + assertTrue(doubleArray.contains(3.3)); + assertTrue(doubleArray.contains(4.4)); + assertTrue(doubleArray.contains(5.5)); + assertFalse(doubleArray.contains(10.0)); + assertFalse(doubleArray.contains(0.0)); + } + + private void collectionArrayContainsTests() { + assertTrue(collectionArray.contains("one")); + assertTrue(collectionArray.contains("two")); + assertTrue(collectionArray.contains("three")); + assertFalse(collectionArray.contains("zero")); + assertFalse(collectionArray.contains("four")); + } + + private void objectArrayContainsTests() { + assertTrue(objArray.contains("one")); + assertTrue(objArray.contains(2)); + assertTrue(objArray.contains(3.0f)); + assertTrue(objArray.contains(num)); + assertFalse(objArray.contains("four")); + assertFalse(objArray.contains(0.0)); + } + + /** + * Test contains() - test whether this PDFArray contains an object. + */ + @Test + public void testContains() { + // Test some arbitrary values + intArrayContainsTests(); + doubleArrayContainsTests(); + collectionArrayContainsTests(); + objectArrayContainsTests(); + } + + /** + * Test length() - tests the length of an array. + */ + @Test + public void testLength() { + assertEquals(5, intArray.length()); + assertEquals(5, doubleArray.length()); + assertEquals(3, collectionArray.length()); + assertEquals(4, objArray.length()); + + // Test the count is incremented when an object is added (this only + // needs to be tested once) + intArray.add(6); + assertEquals(6, intArray.length()); + } + + /** + * Test set() - tests that a particular point has been properly set. + */ + @Test + public void testSet() { + PDFName name = new PDFName("zero test"); + objArray.set(0, name); + assertEquals(name, objArray.get(0)); + + objArray.set(1, "test"); + assertEquals("test", objArray.get(1)); + // This goes through the set(int, double) code path rather than set(int, Object) + objArray.set(2, 5); + assertEquals(5.0, objArray.get(2)); + try { + objArray.set(4, 2); + fail("out of bounds"); + } catch (IndexOutOfBoundsException e) { + // Pass + } + } + + /** + * Test get() - gets the object stored at a given index. + */ + @Test + public void testGet() { + // Test some arbitrary values + for (int i = 1; i <= 5; i++) { + assertEquals(i, intArray.get(i - 1)); + } + + assertEquals(1.1, doubleArray.get(0)); + assertEquals(2.2, doubleArray.get(1)); + assertEquals(3.3, doubleArray.get(2)); + assertEquals(4.4, doubleArray.get(3)); + assertEquals(5.5, doubleArray.get(4)); + + assertEquals("one", collectionArray.get(0)); + assertEquals("two", collectionArray.get(1)); + assertEquals("three", collectionArray.get(2)); + + assertEquals("one", objArray.get(0)); + assertEquals(2, objArray.get(1)); + assertEquals(0, Double.compare(3.0, (Float) objArray.get(2))); + assertEquals(num, objArray.get(3)); + } + + /** + * Tests add() - tests that objects are appended to the end of the array as expected. + */ + @Test + public void testAdd() { + intArray.add(new Integer(6)); + doubleArray.add(6.6); + // Test some arbitrary values + for (int i = 1; i <= 6; i++) { + assertEquals(i, intArray.get(i - 1)); + } + + assertEquals(1.1, doubleArray.get(0)); + assertEquals(2.2, doubleArray.get(1)); + assertEquals(3.3, doubleArray.get(2)); + assertEquals(4.4, doubleArray.get(3)); + assertEquals(5.5, doubleArray.get(4)); + assertEquals(6.6, doubleArray.get(5)); + + collectionArray.add(1); + assertEquals("one", collectionArray.get(0)); + assertEquals("two", collectionArray.get(1)); + assertEquals("three", collectionArray.get(2)); + assertEquals(1.0, collectionArray.get(3)); + + objArray.add("four"); + assertEquals("one", objArray.get(0)); + assertEquals(2, objArray.get(1)); + assertEquals(0, Double.compare(3.0, (Float) objArray.get(2))); + assertEquals("four", objArray.get(4)); + } + + /** + * Tests output() - tests that this object is properly streamed to the PDF document. + * @throws IOException error caused by I/O + */ + @Test + public void testOutput() throws IOException { + testOutputStreams(intArrayOutput, intArray); + testOutputStreams(doubleArrayOutput, doubleArray); + testOutputStreams(collectionArrayOutput, collectionArray); + testOutputStreams(objArrayOutput, objArray); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFDestsTestCase.java b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java new file mode 100644 index 000000000..08d841ede --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Test case for {@link PDFDests}. + */ +public class PDFDestsTestCase extends PDFObjectTestCase { + + private PDFDests dests = new PDFDests(); + private String expectedString = "<< /Names [(number) 10 (name) /Test#20name] >>\n"; + + @Before + public void setUp() { + List<PDFDestination> destinations = new ArrayList<PDFDestination>(); + PDFNumber number = new PDFNumber(); + number.setNumber(10); + PDFDestination testNumber = new PDFDestination("number", number); + testNumber.setDocument(doc); + destinations.add(testNumber); + PDFDestination testName = new PDFDestination("name", new PDFName("Test name")); + testName.setDocument(doc); + destinations.add(testName); + + dests = new PDFDests(destinations); + dests.setDocument(doc); + dests.setParent(parent); + pdfObjectUnderTest = dests; + } + + /** + * Populate the object with some arbitrary values and ensure they are wrapped properly. + * @throws IOException if an I/O error occurs + */ + @Test + public void testConstructor() throws IOException { + // Seems the only way to test this is by testing the output + testOutputStreams(expectedString, dests); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java new file mode 100644 index 000000000..3f84fac2e --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.apache.commons.io.output.CountingOutputStream; +import org.junit.Before; +import org.junit.Test; + + +/** + * Test case for {@link PDFDictionary}. + */ +public class PDFDictionaryTestCase extends PDFObjectTestCase { + /** The test subject */ + private PDFDictionary pdfDictUnderTest; + private PDFArray testArray; + private PDFNumber testNumber; + /** The order in which these objects are put into the dictionary MUST be maintained. */ + private String expectedOutput = "<<\n" + + " /String (TestValue)\n" + + " /int 10\n" + + " /double 3.1\n" + + " /array [1 (two) 20]\n" + + " /number 20\n" + + " /null null\n" + + ">>\n"; + + @Before + public void setUp() { + // A PDFNumber for testing, this DOES have a parent + testNumber = new PDFNumber(); + testNumber.setParent(parent); + testNumber.setNumber(20); + // An array for testing, this DOES NOT have a parent + testArray = new PDFArray(); + testArray.add(1); + testArray.add("two"); + testArray.add(testNumber); + // Populating the dictionary with a parent, document and the various objects + pdfDictUnderTest = new PDFDictionary(parent); + pdfDictUnderTest.setDocument(doc); + pdfDictUnderTest.put("String", "TestValue"); + pdfDictUnderTest.put("int", 10); + pdfDictUnderTest.put("double", Double.valueOf(3.1)); + pdfDictUnderTest.put("array", testArray); + pdfDictUnderTest.put("number", testNumber); + // null is a valid PDF object + pdfDictUnderTest.put("null", null); + // test that the interface is maintained + pdfObjectUnderTest = pdfDictUnderTest; + } + + /** + * Tests put() - tests that the object is put into the dictionary and it is handled if it is a + * {@link PDFObject}. + */ + @Test + public void testPut() { + // The "put()" commands have already been done in setUp(), so just test them. + assertEquals("TestValue", pdfDictUnderTest.get("String")); + assertEquals(10, pdfDictUnderTest.get("int")); + assertEquals(3.1, pdfDictUnderTest.get("double")); + // With PDFObjects, if they DO NOT have a parent, the dict becomes their parent. + assertEquals(testArray, pdfDictUnderTest.get("array")); + assertEquals(pdfDictUnderTest, testArray.getParent()); + // With PDFObjects, if they DO have a parent, the dict DOES NOT change the parent object. + assertEquals(testNumber, pdfDictUnderTest.get("number")); + // Test it doesn't explode when we try to get a non-existent entry + assertNull(pdfDictUnderTest.get("Not in dictionary")); + // Tests that we can over-write objects + pdfDictUnderTest.put("array", 10); + assertEquals(10, pdfDictUnderTest.get("array")); + // Test that nulls are handled appropriately + assertNull(pdfDictUnderTest.get("null")); + } + + /** + * Tests get() - tests that objects can be properly retrieved from the dictionary. + */ + @Test + public void testGet() { + // Tested fairly comprehensively in testPut(). + } + + /** + * Tests writeDictionary() - tests that the dictionary is properly written to the output-stream. + */ + @Test + public void testWriteDictionary() { + // Ensure that the objects stored in the dictionary are streamed in the correct format. + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + CountingOutputStream cout = new CountingOutputStream(outStream); + StringBuilder textBuffer = new StringBuilder(); + try { + pdfDictUnderTest.writeDictionary(cout, textBuffer); + PDFDocument.flushTextBuffer(textBuffer, cout); + assertEquals(expectedOutput, outStream.toString()); + } catch (IOException e) { + fail("IOException: " + e.getMessage()); + } + } + + /** + * Tests output() - test that this object can write itself to an output stream. + * @throws IOException error caused by I/O + */ + @Test + public void testOutput() throws IOException { + testOutputStreams(expectedOutput, pdfDictUnderTest); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java new file mode 100644 index 000000000..c7eff506e --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; + +import junit.framework.Assert; + +import org.junit.Test; + +import org.apache.commons.io.output.ByteArrayOutputStream; + +import org.apache.xmlgraphics.util.UnitConv; + +import org.apache.fop.svg.PDFDocumentGraphics2D; + +/** + * Tests for {@link PDFDocumentGraphics2D}. + */ +public class PDFDocumentGraphics2DTestCase { + + /** + * Does a smoke test on PDFDocumentGraphics2D making sure that nobody accidentally broke + * anything serious. It does not check the correctness of the produced PDF. + * @throws Exception if an error occurs + */ + @Test + public void smokeTest() throws Exception { + ByteArrayOutputStream baout = new ByteArrayOutputStream(); + PDFDocumentGraphics2D g2d = new PDFDocumentGraphics2D(false); + g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + + //Set up the document size + Dimension pageSize = new Dimension( + (int)Math.ceil(UnitConv.mm2pt(210)), + (int)Math.ceil(UnitConv.mm2pt(297))); //page size A4 (in pt) + g2d.setupDocument(baout, pageSize.width, pageSize.height); + + //A few rectangles rotated and with different color + Graphics2D copy = (Graphics2D)g2d.create(); + int c = 12; + for (int i = 0; i < c; i++) { + float f = ((i + 1) / (float)c); + Color col = new Color(0.0f, 1 - f, 0.0f); + copy.setColor(col); + copy.fillRect(70, 90, 50, 50); + copy.rotate(-2 * Math.PI / c, 70, 90); + } + copy.dispose(); + + //Some text + g2d.rotate(-0.25); + g2d.setColor(Color.RED); + g2d.setFont(new Font("sans-serif", Font.PLAIN, 36)); + g2d.drawString("Hello world!", 140, 140); + g2d.setColor(Color.RED.darker()); + g2d.setFont(new Font("serif", Font.PLAIN, 36)); + g2d.drawString("Hello world!", 140, 180); + + g2d.nextPage(); //Move to next page + + g2d.setFont(new Font("sans-serif", Font.PLAIN, 36)); + g2d.drawString("Welcome to page 2!", 140, 140); + + //Cleanup + g2d.finish(); + + String pdfString = baout.toString("ISO-8859-1"); + Assert.assertEquals("%%EOF not found", + pdfString.substring(pdfString.length() - 6), "%%EOF\n"); + } + +} diff --git a/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java new file mode 100644 index 000000000..8965635b9 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Test case for {@link PDFDocument} + */ +public class PDFDocumentTestCase { + + /** + * Test flushTextBuffer() - ensure that the text given will stream to the PDF document as + * expected. + * @throws IOException when an I/O error occurs + */ + @Test + public void testFlushTextBuffer() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StringBuilder textBuffer = new StringBuilder(); + String testString = "This is a test string, just some arbitrary data."; + textBuffer.append(testString); + + PDFDocument.flushTextBuffer(textBuffer, out); + assertEquals(testString, out.toString()); + + // Should reset the textBuffer + assertEquals(0, textBuffer.length()); + assertEquals("", textBuffer.toString()); + out.reset(); + + String[] strArray = { "Try ", "with ", "multiple ", "strings." }; + for (String str : strArray) { + textBuffer.append(str); + } + String fullString = textBuffer.toString(); + PDFDocument.flushTextBuffer(textBuffer, out); + assertEquals(fullString, out.toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java new file mode 100644 index 000000000..db10e656e --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java @@ -0,0 +1,503 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; + +/** + * Tests the {@link PDFEncryptionJCE} class. + */ +public class PDFEncryptionJCETestCase { + + private EncryptionTest test; + + private PDFEncryptionJCE encryptionObject; + + private static final class EncryptionTest { + + private int objectNumber = 1; + + private final PDFEncryptionParams encryptionParameters = new PDFEncryptionParams(); + + private byte[] data; + + private byte[] encryptedData; + + private final EncryptionDictionaryTester encryptionDictionaryTester; + + EncryptionTest() { + this(new EncryptionDictionaryTester()); + } + + EncryptionTest(EncryptionDictionaryTester encryptionDictionaryTester) { + encryptionParameters.setUserPassword("TestUserPassword"); + encryptionParameters.setOwnerPassword("TestOwnerPassword"); + setData(0x00, 0xAA, 0xFF, 0x55, 0xCC, 0x33, 0xF0); + this.encryptionDictionaryTester = encryptionDictionaryTester; + this.encryptionDictionaryTester.setLength( + encryptionParameters.getEncryptionLengthInBits()); + } + + int getObjectNumber() { + return objectNumber; + } + + EncryptionTest setObjectNumber(int objectNumber) { + this.objectNumber = objectNumber; + return this; + } + + byte[] getData() { + return data; + } + + EncryptionTest setData(int... data) { + /* + * Use an array of int to avoid having to cast some elements to byte in the + * method call. + */ + this.data = convertIntArrayToByteArray(data); + return this; + } + + byte[] getEncryptedData() { + return encryptedData; + } + + EncryptionTest setEncryptedData(int... encryptedData) { + this.encryptedData = convertIntArrayToByteArray(encryptedData); + return this; + } + + private byte[] convertIntArrayToByteArray(int[] intArray) { + byte[] byteArray = new byte[intArray.length]; + for (int i = 0; i < intArray.length; i++) { + byteArray[i] = (byte) intArray[i]; + } + return byteArray; + } + + PDFEncryptionParams getEncryptionParameters() { + return encryptionParameters; + } + + EncryptionTest setUserPassword(String userPassword) { + encryptionParameters.setUserPassword(userPassword); + return this; + } + + EncryptionTest setOwnerPassword(String ownerPassword) { + encryptionParameters.setOwnerPassword(ownerPassword); + return this; + } + + EncryptionTest setEncryptionLength(int encryptionLength) { + encryptionParameters.setEncryptionLengthInBits(encryptionLength); + encryptionDictionaryTester.setLength(encryptionLength); + return this; + } + + EncryptionTest disablePrint() { + encryptionParameters.setAllowPrint(false); + return this; + } + + EncryptionTest disableEditContent() { + encryptionParameters.setAllowEditContent(false); + return this; + } + + EncryptionTest disableCopyContent() { + encryptionParameters.setAllowCopyContent(false); + return this; + } + + EncryptionTest disableEditAnnotations() { + encryptionParameters.setAllowEditAnnotations(false); + return this; + } + + EncryptionTest disableFillInForms() { + encryptionParameters.setAllowFillInForms(false); + return this; + } + + EncryptionTest disableAccessContent() { + encryptionParameters.setAllowAccessContent(false); + return this; + } + + EncryptionTest disableAssembleDocument() { + encryptionParameters.setAllowAssembleDocument(false); + return this; + } + + EncryptionTest disablePrintHq() { + encryptionParameters.setAllowPrintHq(false); + return this; + } + + void testEncryptionDictionary(PDFEncryptionJCE encryptionObject) { + encryptionDictionaryTester.test(encryptionObject); + } + } + + private static final class EncryptionDictionaryTester { + + private int version = 1; + + private int revision = 2; + + private int length = 40; + + private int permissions = -4; + + private String ownerEntry + = "3EE8C4000CA44B2645EED029C9EA7D4FC63C6D9B89349E8FA5A40C7691AB96B5"; + + private String userEntry + = "D1810D9E6E488BA5D2DDCBB3F974F7472D0D5389F554DB55574A787DC5C59884"; + + EncryptionDictionaryTester setVersion(int version) { + this.version = version; + return this; + } + + EncryptionDictionaryTester setRevision(int revision) { + this.revision = revision; + return this; + } + + EncryptionDictionaryTester setLength(int length) { + this.length = length; + return this; + } + + EncryptionDictionaryTester setPermissions(int permissions) { + this.permissions = permissions; + return this; + } + + EncryptionDictionaryTester setOwnerEntry(String ownerEntry) { + this.ownerEntry = ownerEntry; + return this; + } + + EncryptionDictionaryTester setUserEntry(String userEntry) { + this.userEntry = userEntry; + return this; + } + + void test(PDFEncryptionJCE encryptionObject) { + byte[] encryptionDictionary = encryptionObject.toPDF(); + RegexTestedCharSequence dictionary = new RegexTestedCharSequence(encryptionDictionary); + + final String whitespace = "\\s+"; + final String digits = "\\d+"; + final String hexDigits = "\\p{XDigit}+"; + + dictionary.mustContain("/Filter" + whitespace + "/Standard\\b"); + + dictionary.mustContain("/V" + whitespace + "(" + digits + ")") + .withGroup1EqualTo(Integer.toString(version)); + + dictionary.mustContain("/R" + whitespace + "(" + digits + ")") + .withGroup1EqualTo(Integer.toString(revision)); + + dictionary.mustContain("/Length" + whitespace + "(" + digits + ")") + .withGroup1EqualTo(Integer.toString(length)); + + dictionary.mustContain("/P" + whitespace + "(-?" + digits + ")") + .withGroup1EqualTo(Integer.toString(permissions)); + + dictionary.mustContain("/O" + whitespace + "<(" + hexDigits + ")>") + .withGroup1EqualTo(ownerEntry); + + dictionary.mustContain("/U" + whitespace + "<(" + hexDigits + ")>") + .withGroup1EqualTo(userEntry); + } + } + + private static final class RegexTestedCharSequence { + + private final String string; + + private Matcher matcher; + + RegexTestedCharSequence(byte[] bytes) { + try { + string = new String(bytes, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + RegexTestedCharSequence mustContain(String regex) { + Pattern pattern = Pattern.compile(regex); + matcher = pattern.matcher(string); + assertTrue(matcher.find()); + return this; + } + + RegexTestedCharSequence withGroup1EqualTo(String expected) { + assertEquals(expected, matcher.group(1)); + return this; + } + } + + @Test + public final void testMake() { + PDFEncryption testEncryptionObj = createEncryptionObject(new PDFEncryptionParams()); + assertTrue(testEncryptionObj instanceof PDFEncryptionJCE); + assertEquals(1, ((PDFEncryptionJCE) testEncryptionObj).getObjectNumber()); + } + + @Test + public void testBasic() throws IOException { + test = new EncryptionTest(); + test.setData(0x00).setEncryptedData(0x56); + runEncryptionTests(); + + test.setData(0xAA).setEncryptedData(0xFC); + runEncryptionTests(); + + test.setData(0xFF).setEncryptedData(0xA9); + runEncryptionTests(); + + test = new EncryptionTest().setEncryptedData(0x56, 0x0C, 0xFC, 0xA5, 0xAB, 0x61, 0x73); + runEncryptionTests(); + } + + @Test + public void test128bit() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setVersion(2) + .setRevision(3) + .setPermissions(-4) + .setOwnerEntry("D9A98017F0500EF9B69738641C9B4CBA1229EDC3F2151BC6C9C4FB07B1CB315E") + .setUserEntry("D3EF424BFEA2E434000E1A74941CC87300000000000000000000000000000000"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(2) + .setEncryptionLength(128) + .setEncryptedData(0xE3, 0xCB, 0xB2, 0x55, 0xD9, 0x26, 0x55); + runEncryptionTests(); + } + + @Test + public void testDisableRev2Permissions() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setPermissions(-64) + .setUserEntry("3E65D0090746C4C37C5EF23C1BDB6323E00C24C4B2D744DD3BFB654CD58591A1"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(3) + .disablePrint() + .disableEditContent() + .disableCopyContent() + .disableEditAnnotations() + .setEncryptedData(0x66, 0xEE, 0xA7, 0x93, 0xC4, 0xB1, 0xB4); + runEncryptionTests(); + } + + @Test + public void testDisableRev3Permissions() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setVersion(2) + .setRevision(3) + .setPermissions(-3844) + .setOwnerEntry("8D4BCA4F4AB2BAB4E38F161D61F937EC50BE5EB30C2DC05EA409D252CD695E55") + .setUserEntry("0F01171E22C7FB27B079C132BA4277DE00000000000000000000000000000000"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(4) + .disableFillInForms() + .disableAccessContent() + .disableAssembleDocument() + .disablePrintHq() + .setEncryptedData(0x8E, 0x3C, 0xD2, 0x05, 0x50, 0x48, 0x82); + runEncryptionTests(); + } + + @Test + public void test128bitDisableSomePermissions() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setVersion(2) + .setRevision(3) + .setPermissions(-1304) + .setOwnerEntry("D9A98017F0500EF9B69738641C9B4CBA1229EDC3F2151BC6C9C4FB07B1CB315E") + .setUserEntry("62F0E4D8641D482E0F8E71A89270045A00000000000000000000000000000000"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(5) + .setEncryptionLength(128) + .disablePrint() + .disableCopyContent() + .disableFillInForms() + .disableAssembleDocument() + .setEncryptedData(0xF7, 0x85, 0x4F, 0xB0, 0x50, 0x5C, 0xDF); + runEncryptionTests(); + } + + @Test + public void testDifferentPasswords() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setOwnerEntry("D11C233C65E9DC872E858ABBD8B62198771167ADCE7AB8DC7AE0A1A7E21A1E25") + .setUserEntry("6F449167DB8DDF0D2DF4602DDBBA97ABF9A9101F632CC16AB0BE74EB9500B469"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(6) + .setUserPassword("ADifferentUserPassword") + .setOwnerPassword("ADifferentOwnerPassword") + .setEncryptedData(0x27, 0xAC, 0xB1, 0x6C, 0x42, 0xE0, 0xA8); + runEncryptionTests(); + } + + @Test + public void testNoOwnerPassword() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setOwnerEntry("5163AAF3EE74C76D7C223593A84C8702FEA8AA4493E4933FF5B5A5BBB20AE4BB") + .setUserEntry("42DDF1C1BF3AB04786D5038E7B0A723AE614D944E1DE91A922FC54F5F2345E00"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(7) + .setUserPassword("ADifferentUserPassword") + .setOwnerPassword("") + .setEncryptedData(0xEC, 0x2E, 0x5D, 0xC2, 0x7F, 0xAD, 0x58); + runEncryptionTests(); + } + + @Test + public void test128bitDisableSomePermissionsDifferentPasswords() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setVersion(2) + .setRevision(3) + .setPermissions(-2604) + .setOwnerEntry("F83CA049FAA2F774F8541F25E746A92EE2A7F060C46C91C693E673BF18FF7B36") + .setUserEntry("88A4C58F5385B5F08FACA0636D790EDF00000000000000000000000000000000"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(8) + .setUserPassword("ADifferentUserPassword") + .setOwnerPassword("ADifferentOwnerPassword") + .setEncryptionLength(128) + .disableEditContent() + .disableEditAnnotations() + .disableAccessContent() + .disablePrintHq() + .setEncryptedData(0x77, 0x54, 0x67, 0xA5, 0xCC, 0x73, 0xDE); + runEncryptionTests(); + } + + @Test + public void test128bitNoPermissionNoOwnerPassword() throws IOException { + EncryptionDictionaryTester encryptionDictionaryTester = new EncryptionDictionaryTester() + .setVersion(2) + .setRevision(3) + .setPermissions(-3904) + .setOwnerEntry("3EEB3FA5594CBD935BFB2F83FB184DD41FBCD7C36A04F1FFD0899B0DFFCFF96B") + .setUserEntry("D972B72DD2633F613B0DDB7511C719C500000000000000000000000000000000"); + test = new EncryptionTest(encryptionDictionaryTester) + .setObjectNumber(9) + .setUserPassword("ADifferentUserPassword") + .setOwnerPassword("") + .setEncryptionLength(128) + .disablePrint() + .disableEditContent() + .disableCopyContent() + .disableEditAnnotations() + .disableFillInForms() + .disableAccessContent() + .disableAssembleDocument() + .disablePrintHq() + .setEncryptedData(0x0C, 0xAD, 0x49, 0xC7, 0xE5, 0x05, 0xB8); + runEncryptionTests(); + } + + /** + * Creates an encryption object using a fixed file ID generator for test reproducibility. + * + * @param params the encryption parameters + * @return PDFEncryptionJCE the encryption object + */ + private PDFEncryptionJCE createEncryptionObject(PDFEncryptionParams params) { + PDFDocument doc = new PDFDocument("Apache FOP") { + + @Override + FileIDGenerator getFileIDGenerator() { + return new FileIDGenerator() { + + private final byte[] fixedFileID = new byte[] { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + + @Override + byte[] getOriginalFileID() { + return fixedFileID; + } + + @Override + byte[] getUpdatedFileID() { + return fixedFileID; + } + + }; + } + }; + return (PDFEncryptionJCE) PDFEncryptionJCE.make(1, params, doc); + } + + private void runEncryptionTests() throws IOException { + encryptionObject = createEncryptionObject(test.getEncryptionParameters()); + runEncryptTest(); + runFilterTest(); + runEncryptionDictionaryTest(); + } + + private void runEncryptTest() { + PDFText text = new PDFText(); + text.setObjectNumber(test.getObjectNumber()); + byte[] byteResult = encryptionObject.encrypt(test.getData(), text); + + assertTrue(Arrays.equals(test.getEncryptedData(), byteResult)); + } + + private void runFilterTest() throws IOException { + PDFStream stream = new PDFStream(); + stream.setDocument(encryptionObject.getDocumentSafely()); + stream.setObjectNumber(test.getObjectNumber()); + stream.setData(test.getData()); + encryptionObject.applyFilter(stream); + + StreamCache streamCache = stream.encodeStream(); + ByteArrayOutputStream testOutputStream = new ByteArrayOutputStream(); + streamCache.outputContents(testOutputStream); + + assertTrue(Arrays.equals(test.getEncryptedData(), testOutputStream.toByteArray())); + } + + private void runEncryptionDictionaryTest() { + test.testEncryptionDictionary(encryptionObject); + } + +} diff --git a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java new file mode 100644 index 000000000..4a570e7b5 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import org.apache.fop.fonts.CIDSubset; +import org.apache.fop.fonts.MultiByteFont; +import org.junit.Test; + +/** + * Test case for {@link PDFFactory}. + */ +public class PDFFactoryTestCase { + + /** + * This tests that when a font is subset embedded in a PDF, the font name is prefixed with a + * pseudo-random tag as per the PDF spec. + */ + @Test + public void testSubsetFontNamePrefix() { + class MockedFont extends MultiByteFont { + @Override + public int[] getWidths() { + return new int[] { 0 }; + } + + @Override + public CIDSubset getCIDSubset() { + return new CIDSubset(); + } + } + PDFDocument doc = new PDFDocument("Test"); + PDFFactory pdfFactory = new PDFFactory(doc); + MockedFont font = new MockedFont(); + + PDFFont pdfDejaVu = pdfFactory.makeFont("DejaVu", "DejaVu", "TTF", font, font); + assertEquals("/EAAAAA+DejaVu", pdfDejaVu.getBaseFont().toString()); + + PDFFont pdfArial = pdfFactory.makeFont("Arial", "Arial", "TTF", font, font); + assertEquals("/EAAAAB+Arial", pdfArial.getBaseFont().toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java new file mode 100644 index 000000000..2504d871a --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +public class PDFFilterListTestCase { + + @Test + public void testFilterList() { + PDFFilterList filterList = new PDFFilterList(); + assertFalse(filterList.isInitialized()); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFLibraryTestSuite.java b/test/java/org/apache/fop/pdf/PDFLibraryTestSuite.java new file mode 100644 index 000000000..c7a9dff89 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFLibraryTestSuite.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + + +/** + * Test suite for FOP's utility classes. + */ +@RunWith(Suite.class) +@SuiteClasses({ + PDFArrayTestCase.class, + PDFDictionaryTestCase.class, + PDFNumberTestCase.class, + PDFObjectTestCase.class, + PDFNameTestCase.class, + AbstractPDFStreamTestCase.class, + PDFDestsTestCase.class, + PDFDocumentTestCase.class, + PDFNullTestCase.class, + PDFNumsArrayTestCase.class, + PDFRectangleTestCase.class, + PDFReferenceTestCase.class, + VersionTestCase.class, + VersionControllerTestCase.class +}) +public class PDFLibraryTestSuite { +} diff --git a/test/java/org/apache/fop/pdf/PDFNameTestCase.java b/test/java/org/apache/fop/pdf/PDFNameTestCase.java new file mode 100644 index 000000000..80917f416 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFNameTestCase.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.apache.commons.io.output.CountingOutputStream; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; + +/** + * Test class for {@link PDFName}. + */ +public class PDFNameTestCase extends PDFObjectTestCase { + private PDFName pdfName; + + /** + * Sets up the local variables + */ + @Before + public void setUp() { + pdfName = new PDFName("TestName"); + pdfName.setParent(parent); + pdfName.setDocument(doc); + + pdfObjectUnderTest = pdfName; + } + + /** + * Tests escapeName() - tests that this method escapes the necessary characters. + */ + @Test + public void testEscapeName() { + try { + // Test for null, this is a programming error thus the NPE + PDFName.escapeName(null); + fail("NPE not thrown when null object given to escapeName()"); + } catch (NullPointerException e) { + // PASS + } + // All names are prefixed by "/", check the PDF spec for further details. + assertEquals("/Test", PDFName.escapeName("Test")); + // Check that if the name is already prefixed with "/" it doens't do it twice + assertEquals("/Test", PDFName.escapeName("/Test")); + // Test with a space in the middle + assertEquals("/Test#20test", PDFName.escapeName("Test test")); + // Test that all chars apart from ASCII '!' --> '~' are escaped + nonEscapedCharactersTests(); + escapedCharactersTests(); + } + + private void escapedCharactersTests() { + for (char i = 0; i < '!'; i++) { + String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase(); + str += Integer.toHexString(i & 0x0f).toUpperCase(); + assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i))); + } + for (char i = '~' + 1; i < 256; i++) { + String str = Integer.toHexString(i >>> 4 & 0x0f).toUpperCase(); + str += Integer.toHexString(i & 0x0f).toUpperCase(); + assertEquals("/#" + str, PDFName.escapeName(String.valueOf(i))); + } + checkCharacterIsEscaped('#'); + checkCharacterIsEscaped('%'); + checkCharacterIsEscaped('('); + checkCharacterIsEscaped(')'); + checkCharacterIsEscaped('<'); + checkCharacterIsEscaped('>'); + checkCharacterIsEscaped('['); + checkCharacterIsEscaped(']'); + checkCharacterIsEscaped('>'); + } + + private void checkCharacterIsEscaped(char c) { + String str = Integer.toHexString(c >>> 4 & 0x0f).toUpperCase(); + str += Integer.toHexString(c & 0x0f).toUpperCase(); + assertEquals("/#" + str, PDFName.escapeName(String.valueOf(c))); + } + + private void nonEscapedCharactersTests() { + charactersNotEscapedBetween('!', '"'); + charactersNotEscapedBetween('*', ';'); + charactersNotEscapedBetween('?', 'Z'); + charactersNotEscapedBetween('^', '~'); + } + + private void charactersNotEscapedBetween(char c1, char c2) { + for (char i = c1; i <= c2; i++) { + String str = String.valueOf(i); + String expected = !str.equals("/") ? "/" + str : str; + assertEquals(expected, PDFName.escapeName(str)); + } + } + + /** + * Tests toString() - this has been overridden to return the String that PDFName wraps. + */ + @Test + public void testToString() { + // The escape characters have already been tested in testEscapeName() so this doesn't need + // to be done twice. + PDFName test1 = new PDFName("test1"); + assertEquals("/test1", test1.toString()); + PDFName test2 = new PDFName("another test"); + assertEquals("/another#20test", test2.toString()); + try { + new PDFName(null); + fail("NPE not thrown when null passed to constructor"); + } catch (NullPointerException e) { + // PASS + } + } + + /** + * Tests output() - check that this object can stream itself in the correct format. + * @throws IOException error caused by I/O + */ + @Test + public void testOutput() throws IOException { + testOutputStreams("/TestName", pdfName); + testOutputStreams("/test#20test", new PDFName("test test")); + } + + /** + * Test outputInline() - this writes the object reference if it is a direct object (has an + * object number), or writes the String representation if there is no object number. + */ + @Test + public void testOutputInline() { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + CountingOutputStream cout = new CountingOutputStream(outStream); + StringBuilder textBuffer = new StringBuilder(); + try { + // test with no object number set. + pdfName.outputInline(outStream, textBuffer); + PDFDocument.flushTextBuffer(textBuffer, cout); + assertEquals("/TestName", outStream.toString()); + + outStream.reset(); + // test with object number set + pdfName.setObjectNumber(1); + pdfName.outputInline(outStream, textBuffer); + PDFDocument.flushTextBuffer(textBuffer, cout); + assertEquals("1 0 R", outStream.toString()); + } catch (IOException e) { + fail("IOException: " + e.getMessage()); + } + } +} diff --git a/test/java/org/apache/fop/pdf/PDFNullTestCase.java b/test/java/org/apache/fop/pdf/PDFNullTestCase.java new file mode 100644 index 000000000..98427cd20 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFNullTestCase.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Test case for {@link PDFNull}. + */ +public class PDFNullTestCase extends PDFObjectTestCase { + + /** + * Test outputInline() - test that "null" is printed to the output stream. + */ + @Test + public void testOutputInline() throws IOException { + PDFNull obj = PDFNull.INSTANCE; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StringBuilder text = new StringBuilder(); + obj.outputInline(out, text); + assertEquals("null", text.toString()); + + // Ensure previously written text is not discarded + obj.outputInline(out, text); + assertEquals("nullnull", text.toString()); + } +} diff --git a/test/java/org/apache/fop/util/PDFNumberTestCase.java b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java index 0f2fed138..ed660af8d 100644 --- a/test/java/org/apache/fop/util/PDFNumberTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java @@ -17,21 +17,35 @@ /* $Id$ */ -package org.apache.fop.util; +package org.apache.fop.pdf; -import org.apache.fop.pdf.PDFNumber; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; /** * This test tests PDFNumber's doubleOut() methods. */ -public class PDFNumberTestCase extends TestCase { +public class PDFNumberTestCase extends PDFObjectTestCase { + /** + * Sets up the local variables, most of these are inherited from PDFObjectTestCase + */ + @Before + public void setUp() { + pdfObjectUnderTest = new PDFNumber(); + pdfObjectUnderTest.setParent(parent); + pdfObjectUnderTest.setDocument(doc); + } /** * Tests PDFNumber.doubleOut(). * @throws Exception if the test fails */ + @Test public void testDoubleOut1() throws Exception { //Default is 6 decimal digits assertEquals("0", PDFNumber.doubleOut(0.0f)); @@ -109,6 +123,40 @@ public class PDFNumberTestCase extends TestCase { } catch (IllegalArgumentException iae) { //we want that } + try { + PDFNumber.doubleOut(null); + fail("NullPointer expected!"); + } catch (NullPointerException e) { + // PASS + } } + /** + * Tests both getNumber() and setNumber() - basic getter/setter methods... Why there isn't a + * constructor is beyond me... + */ + public void testGetSetNumber() { + PDFNumber pdfNum = new PDFNumber(); + // Check with a floating point number + pdfNum.setNumber(1.111f); + assertEquals(1.111f, pdfNum.getNumber()); + // try with an int + pdfNum.setNumber(2); + assertEquals(2, pdfNum.getNumber()); + // See what happens with a null... make sure it doesn't explode + pdfNum.setNumber(null); + assertEquals(null, pdfNum.getNumber()); + } + + /** + * Tests toPDFString() - this serializes PDFNumber to PDF format. + * @throws IOException error caused by I/O + */ + public void testToPDFString() throws IOException { + PDFNumber testSubject = new PDFNumber(); + testSubject.setNumber(1.0001); + testOutputStreams("1.0001", testSubject); + testSubject.setNumber(999); + testOutputStreams("999", testSubject); + } } diff --git a/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java new file mode 100644 index 000000000..e0dca33bf --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +/** + * Test case for {@link PDFNumsArray}. + */ +public class PDFNumsArrayTestCase extends PDFObjectTestCase { + private PDFNumsArray numsArray; + private String expectedString = "[0 /Test#20name 1 10]"; + + @Before + public void setUp() { + numsArray = new PDFNumsArray(parent); + numsArray.put(0, new PDFName("Test name")); + PDFNumber num = new PDFNumber(); + num.setNumber(10); + numsArray.put(1, num); + numsArray.setDocument(doc); + + pdfObjectUnderTest = numsArray; + } + + /** + * Test output() - ensure that this object is properly outputted to the PDF document. + * @throws IOException if an I/O error occurs + */ + @Test + public void testOutput() throws IOException { + testOutputStreams(expectedString, numsArray); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java index d41a0f0f3..10ffa3b27 100644 --- a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java +++ b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java @@ -19,47 +19,140 @@ package org.apache.fop.pdf; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import junit.framework.TestCase; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; /** * Tests the PDFObject class. */ -public class PDFObjectTestCase extends TestCase { +public class PDFObjectTestCase { + /** The document behind this object */ + protected final PDFDocument doc = new PDFDocument("test"); + /** The parent of this object */ + protected final PDFObject parent = new DummyPDFObject(); + /** The test subject */ + protected PDFObject pdfObjectUnderTest; + + private static class DummyPDFObject extends PDFObject { + + }; + + @Before + public void setUp() { + pdfObjectUnderTest = new DummyPDFObject(); + pdfObjectUnderTest.setDocument(doc); + pdfObjectUnderTest.setParent(parent); + } /** - * Tests date/time formatting in PDFObject. - * @throws Exception if an error occurs + * Tests setObjectNumber() + */ + @Test + public void testSetObjectNumber() { + pdfObjectUnderTest.setObjectNumber(1); + assertEquals(1, pdfObjectUnderTest.getObjectNumber()); + + pdfObjectUnderTest.setObjectNumber(5); + assertEquals(5, pdfObjectUnderTest.getObjectNumber()); + } + + /** + * Tests hasObjectNumber() - returns the object number of the underlying PDF object. + */ + @Test + public void testHasObjectNumber() { + assertFalse(pdfObjectUnderTest.hasObjectNumber()); + + pdfObjectUnderTest.setObjectNumber(1); + assertTrue(pdfObjectUnderTest.hasObjectNumber()); + } + + /** + * Tests getGeneration() - returns the generation number of the underlying PDF object. + */ + @Test + public void testGetGeneration() { + // Default should be 0 + assertEquals(0, pdfObjectUnderTest.getGeneration()); + // apparently there is no way to set this to anything other than 0 + } + + /** + * Tests setDocument() - returns the document to which this object is bound. + */ + @Test + public void testSetDocument() { + assertEquals(doc, pdfObjectUnderTest.getDocument()); + // assign a different document to the object and test (this should be immutable but isn't) + PDFDocument anotherDoc = new PDFDocument("another test"); + pdfObjectUnderTest.setDocument(anotherDoc); + assertEquals(anotherDoc, pdfObjectUnderTest.getDocument()); + } + + /** + * Tests setParent() - assigns the object a parent. + */ + @Test + public void testSetParent() { + assertEquals(parent, pdfObjectUnderTest.getParent()); + // assign another parent (this probably shouldn't me mutable) + DummyPDFObject anotherParent = new DummyPDFObject(); + pdfObjectUnderTest.setParent(anotherParent); + assertEquals(anotherParent, pdfObjectUnderTest.getParent()); + } + + /** + * Test getObjectID() - returns the PDF object ID. */ - public void testDateFormatting() throws Exception { - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); - cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07); - cal.set(Calendar.MILLISECOND, 0); - Date dt = cal.getTime(); - - MyPDFObject obj = new MyPDFObject(); - String s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT")); - assertEquals("D:20080207151107Z", s); - s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT+02:00")); - assertEquals("D:20080207171107+02'00'", s); - s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT+02:30")); - assertEquals("D:20080207174107+02'30'", s); - s = obj.formatDateTime(dt, TimeZone.getTimeZone("GMT-08:00")); - assertEquals("D:20080207071107-08'00'", s); + @Test + public void testGetObjectID() { + pdfObjectUnderTest.setObjectNumber(10); + // String is of the format "<object#> <generation#> obj\n" + assertEquals("10 0 obj\n", pdfObjectUnderTest.getObjectID()); } - private class MyPDFObject extends PDFObject { + /** + * Test referencePDF() - returns a {@link String} in PDF format to reference this object. + */ + @Test + public void testReferencePDF() { + try { + pdfObjectUnderTest.referencePDF(); + fail("The object number is not set, an exception should be thrown"); + } catch (IllegalArgumentException e) { + // PASS + } + pdfObjectUnderTest.setObjectNumber(10); + // Referencing this object is in the format "<obj#> <gen#> R" + assertEquals("10 0 R", pdfObjectUnderTest.referencePDF()); + } + /** + * Test makeReference() - returns this object represented as a {@link PDFReference}. + */ + @Test + public void testMakeReference() { + // Not very intelligent but, there's not much to test here + pdfObjectUnderTest.setObjectNumber(10); + PDFReference ref = pdfObjectUnderTest.makeReference(); + assertEquals(pdfObjectUnderTest.getObjectNumber(), ref.getObjectNumber()); + assertEquals(pdfObjectUnderTest, ref.getObject()); + assertEquals(pdfObjectUnderTest.referencePDF(), ref.toString()); } /** * Tests PDF object references. * @throws Exception if an error occurs */ + @Test public void testReference() throws Exception { PDFDictionary dict = new PDFDictionary(); dict.setObjectNumber(7); @@ -74,4 +167,31 @@ public class PDFObjectTestCase extends TestCase { assertEquals(ref.toString(), "8 0 R"); } + /** + * A generic method to test output() for sub-classes of (@link PDFObject}. The expected String + * should be formatted such that the object number and object descriptor aren't printed i.e. + * for a simple integer object in PDF: + * <pre> + * 1 0 obj ** ommited from expectedString + * 10 + * endobj ** ommited from expectedString + * </pre> + * Thus the expected string would be "10". + * @param expectedString the string that is expected. + * @param object the object being tested + * @throws IOException error with I/O + */ + protected void testOutputStreams(String expectedString, PDFObject object) throws IOException { + // Test both with and without object numbers + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + // Ensure that + object.setObjectNumber(0); + assertEquals(expectedString.length(), object.output(outStream)); + assertEquals(expectedString, outStream.toString()); + outStream.reset(); + object.setObjectNumber(1); + // Test the length of the output string is returned correctly. + assertEquals(expectedString.length(), object.output(outStream)); + assertEquals(expectedString, outStream.toString()); + } } diff --git a/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java new file mode 100644 index 000000000..24b6a1c71 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Test case for {@link PDFRectangle}. + */ +public class PDFRectangleTestCase { + + /** + * Test outputInline() - ensure properly formatted co-ords are printed to the output stream. + * @throws IOException if an I/O error occurs + */ + @Test + public void testOutputInline() throws IOException { + OutputStream out = new ByteArrayOutputStream(); + // These are arbitrary values thus have no meaning + PDFRectangle rect = new PDFRectangle(1, 2, 3, 4); + + StringBuilder textBuffer = new StringBuilder(); + // Ensure text before the outputInline() is maintained + textBuffer.append("Test "); + + rect.outputInline(out, textBuffer); + assertEquals("Test [1 2 3 4]", textBuffer.toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java new file mode 100644 index 000000000..a2c6193cf --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Test case for {@link PDFReference}. + */ +public class PDFReferenceTestCase { + + /** + * Tests outputInline() - ensure that this object is properly formatted when printed to the + * output stream. + * @throws IOException if an I/O error occurs + */ + @Test + public void testOutputInline() throws IOException { + PDFName name = new PDFName("Test name"); + name.setObjectNumber(2); + PDFReference pdfRef = new PDFReference(name); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StringBuilder textBuffer = new StringBuilder(); + // Ensure that text before outputInline() is kept + textBuffer.append("Text "); + + pdfRef.outputInline(out, textBuffer); + assertEquals("Text 2 0 R", textBuffer.toString()); + } + + /** + * Tests toString() - since this is used quite a lot, we have to ensure the format is correct. + */ + @Test + public void testToString() { + PDFName name = new PDFName("arbitrary"); + name.setObjectNumber(10); + PDFReference ref = new PDFReference(name); + assertEquals("10 0 R", ref.toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/PDFStreamTestCase.java b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java new file mode 100644 index 000000000..93dcea511 --- /dev/null +++ b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +public class PDFStreamTestCase { + + private PDFStream stream; + + @Before + public void createStream() { + stream = new PDFStream(); + stream.setObjectNumber(1); + PDFDocument pdfDocument = new PDFDocument("Apache FOP"); + stream.setDocument(pdfDocument); + } + + @Test + public void testFilterSetup() { + testGetFilterList(); + testSetupFilterList(); + } + + private void testGetFilterList() { + PDFFilterList filterList = stream.getFilterList(); + assertFalse(filterList.isInitialized()); + assertEquals(0, filterList.getFilters().size()); + } + + private void testSetupFilterList() { + stream.setupFilterList(); + PDFFilterList filterList = stream.getFilterList(); + assertTrue(filterList.isInitialized()); + assertEquals(1, filterList.getFilters().size()); + PDFFilter filter = filterList.getFilters().get(0); + assertEquals("/FlateDecode", filter.getName()); + } + + @Test + public void customFilter() { + PDFFilterList filters = stream.getFilterList(); + filters.addFilter("null"); + assertTrue(filters.isInitialized()); + assertEquals(1, filters.getFilters().size()); + PDFFilter filter = filters.getFilters().get(0); + assertEquals("", filter.getName()); + } + + @Test + public void testStream() throws IOException { + PDFFilterList filters = stream.getFilterList(); + filters.addFilter("null"); + byte[] bytes = createSampleData(); + stream.setData(bytes); + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + stream.outputRawStreamData(actual); + assertArrayEquals(bytes, actual.toByteArray()); + } + + @Test + public void testEncodeStream() throws IOException { + PDFFilterList filters = stream.getFilterList(); + filters.addFilter("null"); + byte[] bytes = createSampleData(); + stream.setData(bytes); + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + StreamCache streamCache = stream.encodeStream(); + streamCache.outputContents(actual); + assertArrayEquals(bytes, actual.toByteArray()); + } + + @Test + public void testEncodeAndWriteStream() throws IOException { + PDFFilterList filters = stream.getFilterList(); + filters.addFilter("null"); + byte[] bytes = createSampleData(); + stream.setData(bytes); + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + PDFNumber number = new PDFNumber(); + stream.encodeAndWriteStream(actual, number); + assertArrayEquals(createSampleStreamData(), actual.toByteArray()); + } + + private byte[] createSampleData() { + byte[] bytes = new byte[10]; + for (int i = 0; i < 10; i++) { + bytes[i] = (byte) i; + } + return bytes; + } + + private byte[] createSampleStreamData() throws IOException { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + stream.write("stream\n".getBytes("US-ASCII")); + stream.write(createSampleData()); + stream.write("\nendstream".getBytes("US-ASCII")); + return stream.toByteArray(); + } +} diff --git a/test/java/org/apache/fop/pdf/VersionControllerTestCase.java b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java new file mode 100644 index 000000000..74637c91f --- /dev/null +++ b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; + + +/** + * A test class for {@link VersionController}. + */ +public class VersionControllerTestCase { + + private PDFDocument doc; + + @Before + public void setUp() { + doc = new PDFDocument("test"); + } + + @Test + public void testGetVersion() { + // These do the same thing + for (Version version : Version.values()) { + if (version.compareTo(Version.V1_4) >= 0) { + VersionController fixedVC = VersionController.getFixedVersionController(version); + assertEquals(version, fixedVC.getPDFVersion()); + } + + VersionController dynamicVC = VersionController.getDynamicVersionController(version, + doc); + assertEquals(version, dynamicVC.getPDFVersion()); + } + } + + /** + * Tests that the setter methods work at setting the underlying version. + * Here there is a disparity between the two objects, the fixed version will + * throw an exception if the setter is invoked. The dynamic version will + * allow the version to be changed, if the new version is greater than the + * version already set. + */ + @Test + public void testSetVersion() { + // Create every type of expected PDFVersion + for (Version originalVersion : Version.values()) { + // Compare against every type of Version + for (Version setVersion : Version.values()) { + testDynamicController(originalVersion, setVersion); + testFixedController(originalVersion, setVersion); + } + + } + } + + /** + * The fixed implementation will throw an exception if an attempt is made to change its + * version. + * + * @param originalVersion the version given to the constructor when PDFVersion instantiated + * @param setVersion the version being set + */ + private void testFixedController(Version originalVersion, Version setVersion) { + if (originalVersion.compareTo(Version.V1_4) >= 0) { + VersionController fixedVC = VersionController + .getFixedVersionController(originalVersion); + try { + fixedVC.setPDFVersion(setVersion); + fail("The FixedVersionController should throw an exception if an attempt to change " + + "the version is made"); + } catch (IllegalStateException e) { + // PASS + } + // Changes are NOT allowed, the original version is immutable + assertEquals(originalVersion, fixedVC.getPDFVersion()); + // The document version is NEVER changed + assertEquals(Version.V1_4, doc.getPDFVersion()); + // the /Version parameter shouldn't be present in the document catalog + assertNull(doc.getRoot().get("Version")); + } else { + try { + VersionController.getFixedVersionController(originalVersion); + fail("Versions < 1.4 aren't allowed."); + } catch (IllegalArgumentException e) { + // PASS + } + } + } + + /** + * The dynamic implementation allows the version to be changed. However, the version given in + * the constructor will be the version set in the header of the PDF document. Any change to the + * version will then be made in the document catalog. + * + * @param originalVersion the version given to the constructor when PDFVersion instantiated + * @param setVersion the version being set + */ + private void testDynamicController(Version originalVersion, Version setVersion) { + VersionController testSubj = VersionController.getDynamicVersionController(originalVersion, + doc); + testSubj.setPDFVersion(setVersion); + PDFName nameVersion = new PDFName(setVersion.toString()); + + if (originalVersion.compareTo(setVersion) < 0) { + versionShouldChange(setVersion, testSubj, nameVersion); + } else { + versionShouldNotChange(originalVersion, testSubj); + } + doc.getRoot().put("Version", null); + } + + private void versionShouldNotChange(Version originalVersion, VersionController testSubj) { + assertEquals(originalVersion, testSubj.getPDFVersion()); + assertNull(doc.getRoot().get("Version")); + } + + private void versionShouldChange(Version setVersion, VersionController testSubj, + PDFName nameVersion) { + assertEquals(setVersion, testSubj.getPDFVersion()); + assertEquals(nameVersion.toString(), doc.getRoot().get("Version").toString()); + } +} diff --git a/test/java/org/apache/fop/pdf/VersionTestCase.java b/test/java/org/apache/fop/pdf/VersionTestCase.java new file mode 100644 index 000000000..9c90f0966 --- /dev/null +++ b/test/java/org/apache/fop/pdf/VersionTestCase.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * This is a test case for ({@link Version}. + */ +public class VersionTestCase { + + /** + * Test the <code>getValue()</code> method. This should return {@link Version} given a + * {@link String}. + */ + @Test + public void testGetValue() { + int index = 0; + for (Version version : Version.values()) { + assertEquals(version, Version.getValueOf("1." + index++)); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testGetValueIllegalArgument() { + Version.getValueOf("blah"); + } + + /** + * Tests that the <code>toString()</method> method returns the PDF version string of the proper + * format. + */ + @Test + public void testToString() { + // Test all the normal values + int index = 0; + for (Version version : Version.values()) { + assertTrue(version.toString().equals("1." + index++)); + } + } + + /** + * Tests that the <code>compareTo()</code> contract is obeyed. + */ + @Test + public void testCompareTo() { + // Ensure that the implicit comparison contract is satisfied + Version[] expected = { + Version.V1_0, + Version.V1_1, + Version.V1_2, + Version.V1_3, + Version.V1_4, + Version.V1_5, + Version.V1_6, + Version.V1_7 + }; + + Version[] actual = Version.values(); + + for (int i = 0; i < actual.length - 1; i++) { + assertEquals(-1, actual[i].compareTo(expected[i + 1])); + + assertEquals(0, actual[i].compareTo(expected[i])); + + assertEquals(1, actual[i + 1].compareTo(expected[i])); + } + } +} diff --git a/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java new file mode 100644 index 000000000..8b103d277 --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class CompressedObjectReferenceTestCase extends ObjectReferenceTest { + + @Test + public void testOutput() throws IOException { + runTest(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0), 0); + runTest(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0x1), 4); + runTest(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0xf3), 16); + runTest(Arrays.asList(0, 0, 0, 0, 0, 0, 0x5, 0xf7), 128); + runTest(Arrays.asList(0, 0, 0, 0, 0, 0x9, 0xfb, 0xd), 0xae); + runTest(Arrays.asList(0, 0, 0, 0, 0x11, 0xff, 0x15, 0xe9), 0xff); + } + + private void runTest(List<Integer> expectedObjectStreamBytes, int index) throws IOException { + int objectStreamNumber = (int) computeNumberFromBytes(expectedObjectStreamBytes); + sut = new CompressedObjectReference(0, objectStreamNumber, index); + byte[] expected = createExpectedOutput((byte) 2, expectedObjectStreamBytes, index); + byte[] actual = getActualOutput(); + assertArrayEquals(expected, actual); + } + +} diff --git a/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java new file mode 100644 index 000000000..df1b86e53 --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.junit.Before; + +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFInfo; +import org.apache.fop.pdf.PDFPages; +import org.apache.fop.pdf.PDFRoot; + +public abstract class CrossReferenceObjectTest { + + protected static final int STARTXREF = 12345; + + protected PDFDocument pdfDocument; + + protected TrailerDictionary trailerDictionary; + + private CrossReferenceObject crossReferenceObject; + + @Before + public void setUp() throws UnsupportedEncodingException { + pdfDocument = new PDFDocument("Apache FOP"); + Map<String, List<String>> filterMap = pdfDocument.getFilterMap(); + filterMap.put("default", Arrays.asList("null")); + PDFRoot root = new PDFRoot(1, new PDFPages(10)); + PDFInfo info = new PDFInfo(); + info.setObjectNumber(2); + byte[] fileID = + new byte[] {0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef}; + trailerDictionary = new TrailerDictionary(pdfDocument) + .setRoot(root) + .setInfo(info) + .setFileID(fileID, fileID); + } + + protected void runTest() throws IOException { + crossReferenceObject = createCrossReferenceObject(); + byte[] expected = createExpectedCrossReferenceData(); + byte[] actual = createActualCrossReferenceData(); + assertArrayEquals(expected, actual); + } + + protected abstract CrossReferenceObject createCrossReferenceObject(); + + protected abstract byte[] createExpectedCrossReferenceData() throws IOException; + + protected byte[] createActualCrossReferenceData() throws IOException { + ByteArrayOutputStream pdf = new ByteArrayOutputStream(); + crossReferenceObject.output(pdf); + pdf.close(); + return pdf.toByteArray(); + } + + protected byte[] getBytes(StringBuilder stringBuilder) { + return getBytes(stringBuilder.toString()); + } + + protected byte[] getBytes(String string) { + try { + return string.getBytes("US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /** + * Outputs the given byte array to a file with the given name. Use for debugging + * purpose. + */ + protected void streamToFile(byte[] bytes, String filename) throws IOException { + OutputStream output = new FileOutputStream(filename); + output.write(bytes); + output.close(); + } + +} diff --git a/test/java/org/apache/fop/pdf/xref/CrossReferenceStreamTestCase.java b/test/java/org/apache/fop/pdf/xref/CrossReferenceStreamTestCase.java new file mode 100644 index 000000000..3e609635d --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/CrossReferenceStreamTestCase.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class CrossReferenceStreamTestCase extends CrossReferenceObjectTest { + + private List<Long> uncompressedObjectOffsets; + + private List<CompressedObjectReference> compressedObjectReferences; + + @Test + public void testWithNoOffset() throws IOException { + List<Long> emptyList = Collections.emptyList(); + test(emptyList); + } + + @Test + public void testWithOffsets() throws IOException { + test(new ArrayList<Long>(Arrays.asList(0L, 1L, 2L, 3L, 4L))); + } + + @Test + public void testWithBigOffsets() throws IOException { + test(new ArrayList<Long>(Arrays.asList(0xffL, 0xffffL, 0xffffffffL, 0xffffffffffffffffL))); + } + + @Test + public void testWithObjectStreams1() throws IOException { + List<CompressedObjectReference> compressedObjectReferences = + Arrays.asList(new CompressedObjectReference(2, 1, 0)); + test(Arrays.asList(0L, null), compressedObjectReferences); + } + + @Test + public void testWithObjectStreams2() throws IOException { + int numIndirectObjects = 2; + int numCompressedObjects = 1; + List<Long> indirectObjectOffsets + = new ArrayList<Long>(numIndirectObjects + numCompressedObjects); + for (long i = 0; i < numIndirectObjects; i++) { + indirectObjectOffsets.add(i); + } + List<CompressedObjectReference> compressedObjectReferences + = new ArrayList<CompressedObjectReference>(); + for (int index = 0; index < numCompressedObjects; index++) { + indirectObjectOffsets.add(null); + int obNum = numIndirectObjects + index + 1; + compressedObjectReferences.add(new CompressedObjectReference(obNum, + numIndirectObjects, index)); + } + test(indirectObjectOffsets, compressedObjectReferences); + } + + private void test(List<Long> indirectObjectOffsets) throws IOException { + List<CompressedObjectReference> compressedObjectReferences = Collections.emptyList(); + test(indirectObjectOffsets, compressedObjectReferences); + } + + private void test(List<Long> indirectObjectOffsets, + List<CompressedObjectReference> compressedObjectReferences) throws IOException { + this.uncompressedObjectOffsets = indirectObjectOffsets; + this.compressedObjectReferences = compressedObjectReferences; + runTest(); + } + + @Override + protected CrossReferenceObject createCrossReferenceObject() { + return new CrossReferenceStream(pdfDocument, + uncompressedObjectOffsets.size() + 1, + trailerDictionary, + STARTXREF, + uncompressedObjectOffsets, + compressedObjectReferences); + } + + @Override + protected byte[] createExpectedCrossReferenceData() throws IOException { + List<ObjectReference> objectReferences + = new ArrayList<ObjectReference>(uncompressedObjectOffsets.size()); + for (Long offset : uncompressedObjectOffsets) { + objectReferences.add(offset == null ? null : new UncompressedObjectReference(offset)); + } + for (CompressedObjectReference ref : compressedObjectReferences) { + objectReferences.set(ref.getObjectNumber() - 1, ref); + } + int maxObjectNumber = objectReferences.size() + 1; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + StringBuilder expected = new StringBuilder(256); + expected.append(maxObjectNumber + " 0 obj\n") + .append("<<\n") + .append(" /Root 1 0 R\n") + .append(" /Info 2 0 R\n") + .append(" /ID [<0123456789ABCDEF> <0123456789ABCDEF>]\n") + .append(" /Type /XRef\n") + .append(" /Size ").append(Integer.toString(maxObjectNumber + 1)).append('\n') + .append(" /W [1 8 2]\n") + .append(" /Length ").append(Integer.toString((maxObjectNumber + 1) * 11 + 1)).append('\n') + .append(">>\n") + .append("stream\n"); + stream.write(getBytes(expected)); + DataOutputStream data = new DataOutputStream(stream); + data.write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, (byte) 0xff}); + for (ObjectReference objectReference : objectReferences) { + objectReference.output(data); + } + data.write(1); + data.writeLong(STARTXREF); + data.write(0); + data.write(0); + data.close(); + stream.write(getBytes("\nendstream\nendobj\n")); + return stream.toByteArray(); + } + +} diff --git a/test/java/org/apache/fop/pdf/xref/CrossReferenceTableTestCase.java b/test/java/org/apache/fop/pdf/xref/CrossReferenceTableTestCase.java new file mode 100644 index 000000000..ceff96a91 --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/CrossReferenceTableTestCase.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class CrossReferenceTableTestCase extends CrossReferenceObjectTest { + + private List<Long> offsets; + + @Test + public void testWithNoOffset() throws IOException { + List<Long> emptyList = Collections.emptyList(); + runTest(emptyList); + } + + @Test + public void testWithOffsets() throws IOException { + runTest(Arrays.asList(0L, 1L, 2L, 3L, 4L)); + } + + @Test + public void testWithBigOffsets() throws IOException { + runTest(Arrays.asList(0xffL, 0xffffL, 0x7fffffffL)); + } + + private void runTest(List<Long> offsets) throws IOException { + this.offsets = offsets; + runTest(); + } + + @Override + protected CrossReferenceObject createCrossReferenceObject() { + return new CrossReferenceTable(trailerDictionary, STARTXREF, offsets); + } + + @Override + protected byte[] createExpectedCrossReferenceData() throws IOException { + StringBuilder expected = new StringBuilder(256); + expected.append("xref\n0 ") + .append(offsets.size() + 1) + .append("\n0000000000 65535 f \n"); + for (Long objectReference : offsets) { + final String padding = "0000000000"; + String s = String.valueOf(objectReference).toString(); + String loc = padding.substring(s.length()) + s; + expected.append(loc).append(" 00000 n \n"); + } + expected.append("trailer\n<<\n") + .append(" /Root 1 0 R\n") + .append(" /Info 2 0 R\n") + .append(" /ID [<0123456789ABCDEF> <0123456789ABCDEF>]\n") + .append(" /Size ").append(Integer.toString(offsets.size() + 1)).append('\n') + .append(">>\n"); + return getBytes(expected); + } + +} diff --git a/test/java/org/apache/fop/pdf/xref/ObjectReferenceTest.java b/test/java/org/apache/fop/pdf/xref/ObjectReferenceTest.java new file mode 100644 index 000000000..fada2794c --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/ObjectReferenceTest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +abstract class ObjectReferenceTest { + + protected ObjectReference sut; + + protected long computeNumberFromBytes(List<Integer> expectedOffsetBytes) { + assert expectedOffsetBytes.size() <= 8; + long offset = 0; + for (int b : expectedOffsetBytes) { + offset = offset << 8 | b; + } + return offset; + } + + protected byte[] createExpectedOutput(byte field1, List<Integer> field2, int field3) { + assert field2.size() == 8; + assert (field3 & 0xffff) == field3; + byte[] expected = new byte[11]; + int index = 0; + expected[index++] = field1; + for (Integer b : field2) { + expected[index++] = b.byteValue(); + } + expected[index++] = (byte) ((field3 & 0xff00) >> 8); + expected[index++] = (byte) (field3 & 0xff); + return expected; + } + + protected byte[] getActualOutput() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(out); + sut.output(dataOutputStream); + dataOutputStream.close(); + return out.toByteArray(); + } + +} diff --git a/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java new file mode 100644 index 000000000..b147084e8 --- /dev/null +++ b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.pdf.xref; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class UncompressedObjectReferenceTestCase extends ObjectReferenceTest { + + @Test + public void test1ByteOffsets() throws IOException { + run1ByteOffsetTest(0x0); + run1ByteOffsetTest(0xf); + run1ByteOffsetTest(0x10); + run1ByteOffsetTest(0xff); + } + + private void run1ByteOffsetTest(int offset) throws IOException { + runIntegerOffsetTest(Arrays.asList(0, 0, 0, offset)); + } + + @Test + public void test2ByteOffsets() throws IOException { + runIntegerOffsetTest(Arrays.asList(0, 0, 1, 0xff)); + runIntegerOffsetTest(Arrays.asList(0, 0, 0xa0, 0xff)); + } + + @Test + public void test3ByteOffsets() throws IOException { + runIntegerOffsetTest(Arrays.asList(0, 2, 0x12, 0x34)); + runIntegerOffsetTest(Arrays.asList(0, 0xee, 0x56, 0x78)); + } + + @Test + public void test4ByteOffsets() throws IOException { + runIntegerOffsetTest(Arrays.asList(0x6, 0x12, 0x34, 0x56)); + runIntegerOffsetTest(Arrays.asList(0xf1, 0x9a, 0xbc, 0xde)); + } + + @Test + public void test5ByteOffsets() throws IOException { + runTest(Arrays.asList(0, 0, 0, 0x7, 0x78, 0x9a, 0xbc, 0xde)); + runTest(Arrays.asList(0, 0, 0, 0xbf, 0xf0, 0, 0x1, 0x2)); + } + + @Test + public void test8ByteOffsets() throws IOException { + runTest(Arrays.asList(0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8)); + runTest(Arrays.asList(0xf9, 0xe8, 0xd7, 0xc6, 0xb5, 0xa4, 0x93, 0x82)); + } + + private void runIntegerOffsetTest(List<Integer> expectedOffsetBytes) throws IOException { + List<Integer> expectedLongOffset = new ArrayList<Integer>(8); + expectedLongOffset.addAll(Arrays.asList(0, 0, 0, 0)); + expectedLongOffset.addAll(expectedOffsetBytes); + runTest(expectedLongOffset); + } + + private void runTest(List<Integer> expectedOffsetBytes) throws IOException { + long offset = computeNumberFromBytes(expectedOffsetBytes); + sut = new UncompressedObjectReference(offset); + byte[] expected = createExpectedOutput((byte) 1, expectedOffsetBytes, (byte) 0); + byte[] actual = getActualOutput(); + assertArrayEquals(expected, actual); + } + +} diff --git a/test/java/org/apache/fop/render/AbstractRenderingTest.java b/test/java/org/apache/fop/render/AbstractRenderingTest.java new file mode 100644 index 000000000..1f91f5b06 --- /dev/null +++ b/test/java/org/apache/fop/render/AbstractRenderingTest.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import java.util.MissingResourceException; + +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; + +/** + * Abstract base class for rendering (output) verification tests. + */ +public abstract class AbstractRenderingTest { + + private static final Map<String, String> MIME_MAP = new java.util.HashMap<String, String>(); + + static { + MIME_MAP.put(MimeConstants.MIME_PDF, ".pdf"); + MIME_MAP.put(MimeConstants.MIME_POSTSCRIPT, ".ps"); + MIME_MAP.put(MimeConstants.MIME_AFP, ".afp"); + } + + /** the JAXP TransformerFactory */ + protected TransformerFactory tFactory = TransformerFactory.newInstance(); + /** the FopFactory */ + protected FopFactory fopFactory = FopFactory.newInstance(); + + /** + * Renders a test file. + * @param ua the user agent (with override set!) + * @param resourceName the resource name for the FO file + * @param suffix a suffix for the output filename + * @param outputFormat MIME type of the requested output format + * @return the output file + * @throws Exception if an error occurs + */ + protected File renderFile(FOUserAgent ua, String resourceName, String suffix, + String outputFormat) throws Exception { + String extension = MIME_MAP.get(outputFormat); + assert extension != null; + File outputFile = new File("build/test-results/" + resourceName + suffix + extension); + File outputDir = outputFile.getParentFile(); + FileUtils.forceMkdir(outputDir); + + // Prepare input file + InputStream in = getClass().getResourceAsStream(resourceName); + if (in == null) { + throw new MissingResourceException(resourceName + " not found in resources", + getClass().getName(), null); + } + try { + Source src = new StreamSource(in); + + // Create output file + OutputStream out = new java.io.FileOutputStream(outputFile); + out = new java.io.BufferedOutputStream(out); + try { + Fop fop = fopFactory.newFop(outputFormat, ua, out); + SAXResult res = new SAXResult(fop.getDefaultHandler()); + + Transformer transformer = tFactory.newTransformer(); + transformer.transform(src, res); + } finally { + IOUtils.closeQuietly(out); + } + } finally { + IOUtils.closeQuietly(in); + } + return outputFile; + } + +} diff --git a/test/java/org/apache/fop/render/RendererFactoryTest.java b/test/java/org/apache/fop/render/RendererFactoryTestCase.java index 6b8e8f5f3..9ca4c2545 100644 --- a/test/java/org/apache/fop/render/RendererFactoryTest.java +++ b/test/java/org/apache/fop/render/RendererFactoryTestCase.java @@ -19,7 +19,10 @@ package org.apache.fop.render; -import junit.framework.TestCase; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; import org.apache.commons.io.output.NullOutputStream; @@ -38,8 +41,9 @@ import org.apache.fop.render.rtf.RTFHandler; /** * Tests for {@link RendererFactory}. */ -public class RendererFactoryTest extends TestCase { +public class RendererFactoryTestCase { + @Test public void testDocumentHandlerLevel() throws Exception { FopFactory fopFactory = FopFactory.newInstance(); RendererFactory factory = fopFactory.getRendererFactory(); @@ -49,7 +53,6 @@ public class RendererFactoryTest extends TestCase { ua = fopFactory.newFOUserAgent(); handler = factory.createDocumentHandler(ua, MimeConstants.MIME_PDF); - assertTrue(handler instanceof PDFDocumentHandler); ua = fopFactory.newFOUserAgent(); overrideHandler = new PDFDocumentHandler(); @@ -67,6 +70,7 @@ public class RendererFactoryTest extends TestCase { } } + @Test public void testRendererLevel() throws Exception { FopFactory fopFactory = FopFactory.newInstance(); RendererFactory factory = fopFactory.getRendererFactory(); @@ -98,6 +102,7 @@ public class RendererFactoryTest extends TestCase { } } + @Test public void testFOEventHandlerLevel() throws Exception { FopFactory fopFactory = FopFactory.newInstance(); RendererFactory factory = fopFactory.getRendererFactory(); diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java new file mode 100644 index 000000000..7c08e6d99 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.xml.sax.SAXException; + +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; + +/** + * Test case for {@link AFPRendererConfigurator}. + */ +public class AFPRendererConfiguratorTestCase { + private static FOUserAgent userAgent; + + private AFPRendererConfigurator sut; + + /** + * The FOUserAgent only needs to be created once. + */ + @BeforeClass + public static void createUserAgent() { + userAgent = FopFactory.newInstance().newFOUserAgent(); + } + + /** + * Assigns an FOUserAgen with a config file at <code>uri</code> + * + * @param uri the URI of the config file + */ + private void setConfigFile(String uri) { + String confTestsDir = "test/resources/conf/afp/"; + try { + userAgent.getFactory().setUserConfig(confTestsDir + uri); + sut = new AFPRendererConfigurator(userAgent); + } catch (IOException ioe) { + fail("IOException: " + ioe); + } catch (SAXException se) { + fail("SAXException: " + se); + } + } + + /** + * Test several config files relating to JPEG images in AFP. + * + * @throws FOPException if an error is thrown + */ + @Test + public void testJpegImageConfig() throws FOPException { + testJpegSettings("no_image_config.xconf", 1.0f, false); + testJpegSettings("can_embed_jpeg.xconf", 1.0f, true); + testJpegSettings("bitmap_encode_quality.xconf", 0.5f, false); + } + + private void testJpegSettings(String uri, float bitmapEncodingQual, boolean canEmbed) + throws FOPException { + AFPDocumentHandler docHandler = new AFPDocumentHandler(); + + setConfigFile(uri); + sut.configure(docHandler); + + AFPPaintingState paintingState = docHandler.getPaintingState(); + assertEquals(bitmapEncodingQual, paintingState.getBitmapEncodingQuality(), 0.01f); + assertEquals(canEmbed, paintingState.canEmbedJpeg()); + } +} diff --git a/test/java/org/apache/fop/render/afp/AFPTestSuite.java b/test/java/org/apache/fop/render/afp/AFPTestSuite.java new file mode 100644 index 000000000..117e7efcf --- /dev/null +++ b/test/java/org/apache/fop/render/afp/AFPTestSuite.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Test suite for FOP's AFP output. + */ +@RunWith(Suite.class) +@SuiteClasses({ + NoOperationTestCase.class, + AFPRendererConfiguratorTestCase.class }) +public class AFPTestSuite { +} diff --git a/test/java/org/apache/fop/render/afp/AbstractAFPTest.java b/test/java/org/apache/fop/render/afp/AbstractAFPTest.java new file mode 100644 index 000000000..916c68395 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/AbstractAFPTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.io.File; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.AbstractRenderingTest; + +/** + * Abstract base class for AFP verification tests. + */ +abstract class AbstractAFPTest extends AbstractRenderingTest { + + /** + * Renders a test file. + * @param ua the user agent (with override set!) + * @param resourceName the resource name for the FO file + * @param suffix a suffix for the output filename + * @return the output file + * @throws Exception if an error occurs + */ + protected File renderFile(FOUserAgent ua, String resourceName, String suffix) + throws Exception { + return renderFile(ua, resourceName, suffix, MimeConstants.MIME_AFP); + } + + +} diff --git a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java new file mode 100644 index 000000000..78578a2b6 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.commons.io.IOUtils; +import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.parser.MODCAParser; +import org.apache.fop.afp.parser.UnparsedStructuredField; +import org.apache.fop.apps.FOUserAgent; +import org.junit.Test; + +/** + * Tests generation of afp:no-operation (NOPs). + */ +public class NoOperationTestCase extends AbstractAFPTest { + + /** + * Tests afp:no-operation. + * @throws Exception if an error occurs + */ + @Test + public void testNoOperation() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File outputFile = renderFile(ua, "nops.fo", ""); + + InputStream in = new java.io.FileInputStream(outputFile); + try { + MODCAParser parser = new MODCAParser(in); + UnparsedStructuredField field = skipTo(parser, 0xD3A8A8); //Begin Document + + //NOP in fo:declarations + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:declarations", getNopText(field)); + + field = parser.readNextStructuredField(); + assertEquals(0xD3A8AD, field.getSfTypeID()); //Begin Named Page Group + + //NOPs in fo:page-sequence + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:page-sequence: start", getNopText(field)); + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:page-sequence: end", getNopText(field)); + + field = parser.readNextStructuredField(); + assertEquals(0xD3A8AF, field.getSfTypeID()); //Begin Page + + field = skipTo(parser, 0xD3A9C9); //End Active Environment Group + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:simple-page-master: first", getNopText(field)); + + field = skipTo(parser, 0xD3A9C9); //End Active Environment Group + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:simple-page-master: rest", getNopText(field)); + } finally { + IOUtils.closeQuietly(in); + } + + int counter = 0; + in = new java.io.FileInputStream(outputFile); + try { + MODCAParser parser = new MODCAParser(in); + while (true) { + UnparsedStructuredField field = parser.readNextStructuredField(); + if (field == null) { + break; + } + if (field.getSfTypeID() == 0xD3EEEE) { + counter++; + } + } + } finally { + IOUtils.closeQuietly(in); + } + assertEquals(6, counter); //decl, 2 * ps, 3 * page/spm + } + + private String getNopText(UnparsedStructuredField field) throws UnsupportedEncodingException { + byte[] data = field.getData(); + String text = new String(data, AFPConstants.EBCIDIC_ENCODING); + return text; + } + + private UnparsedStructuredField skipTo(MODCAParser parser, int typeID) throws IOException { + UnparsedStructuredField field = null; + do { + field = parser.readNextStructuredField(); + if (field.getSfTypeID() == typeID) { + return field; + } + } while (field != null); + fail("Structured field not found: " + Integer.toHexString(typeID)); + return null; + } + +} diff --git a/test/java/org/apache/fop/render/afp/nops.fo b/test/java/org/apache/fop/render/afp/nops.fo new file mode 100644 index 000000000..96c6e0d24 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/nops.fo @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:afp="http://xmlgraphics.apache.org/fop/extensions/afp"> + <fo:layout-master-set> + <fo:simple-page-master master-name="first" page-height="10.5cm" page-width="14.85cm" margin="2cm"> + <afp:no-operation name="spm">fo:simple-page-master: first</afp:no-operation> + <fo:region-body margin-top="2em "/> + <fo:region-before extent="2em"/> + </fo:simple-page-master> + <fo:simple-page-master master-name="rest" page-height="10.5cm" page-width="14.85cm" margin="2cm"> + <afp:no-operation name="spm">fo:simple-page-master: rest</afp:no-operation> + <fo:region-body margin-top="2em "/> + <fo:region-before extent="2em"/> + </fo:simple-page-master> + <fo:page-sequence-master master-name="main"> + <fo:repeatable-page-master-alternatives> + <fo:conditional-page-master-reference master-reference="first" page-position="first"/> + <fo:conditional-page-master-reference master-reference="rest"/> + </fo:repeatable-page-master-alternatives> + </fo:page-sequence-master> + </fo:layout-master-set> + + <fo:declarations> + <afp:no-operation name="declarations">fo:declarations</afp:no-operation> + </fo:declarations> + + <fo:page-sequence master-reference="main" id="doc1"> + <afp:no-operation name="ps">fo:page-sequence: start</afp:no-operation> + <fo:flow flow-name="xsl-region-body"> + <fo:block>Page 1</fo:block> + <fo:block>Page 1</fo:block> + <fo:block break-after="page"></fo:block> + <fo:block>Page 2</fo:block> + <fo:block>Page 2</fo:block> + <fo:block break-after="page"></fo:block> + <fo:block>Page 3</fo:block> + <fo:block>Page 3</fo:block> + </fo:flow> + <afp:no-operation name="ps">fo:page-sequence: end</afp:no-operation> + </fo:page-sequence> +</fo:root> diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTest.java b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java index 5cd23c17e..6e48845c1 100644 --- a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTest.java +++ b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java @@ -19,15 +19,19 @@ package org.apache.fop.render.extensions.prepress; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + import java.awt.Dimension; import java.awt.Rectangle; -import junit.framework.TestCase; +import org.junit.Test; /** * Tests for the fox:bleed, fox:crop-offset, fox:crop-box extension properties. */ -public class PageBoundariesTest extends TestCase { +public class PageBoundariesTestCase { private static final Dimension TEST_AREA_SIZE = new Dimension(20000, 15000); @@ -37,22 +41,8 @@ public class PageBoundariesTest extends TestCase { private static final String CROP_OFFSET = "8pt"; - /** - * Default constructor. - */ - public PageBoundariesTest() { - } - - /** - * Creates a test case with the given name. - * - * @param name name for the test case - */ - public PageBoundariesTest(String name) { - super(name); - } - /** Test for page boundaries. */ + @Test public void testBoundaries1() { PageBoundaries boundaries = new PageBoundaries(TEST_AREA_SIZE, BLEED, CROP_OFFSET, null); assertEquals(TEST_AREA, boundaries.getTrimBox()); @@ -73,6 +63,7 @@ public class PageBoundariesTest extends TestCase { } /** Test for page boundaries. */ + @Test public void testBoundaries2() { PageBoundaries boundaries = new PageBoundaries( TEST_AREA_SIZE, BLEED, null, null); @@ -86,6 +77,7 @@ public class PageBoundariesTest extends TestCase { } /** Two values for the properties. */ + @Test public void testBoundaries2Values() { PageBoundaries boundaries = new PageBoundaries( TEST_AREA_SIZE, "5pt 10pt", "6pt \t 12pt", null); @@ -103,6 +95,7 @@ public class PageBoundariesTest extends TestCase { } /** Three values for the properties. */ + @Test public void testBoundaries3Values() { PageBoundaries boundaries = new PageBoundaries( TEST_AREA_SIZE, "5pt 10pt 7pt", "6pt \t 12pt 14pt", null); @@ -120,6 +113,7 @@ public class PageBoundariesTest extends TestCase { } /** Four values for the properties. */ + @Test public void testBoundaries4Values() { PageBoundaries boundaries = new PageBoundaries( TEST_AREA_SIZE, "5pt 6pt 7pt 8pt", "9pt 10pt 11pt 12pt", null); @@ -137,6 +131,7 @@ public class PageBoundariesTest extends TestCase { } /** Test for the different values of crop-box. */ + @Test public void testCropBox() { PageBoundaries boundaries = new PageBoundaries(TEST_AREA_SIZE, BLEED, CROP_OFFSET, null); assertEquals(boundaries.getMediaBox(), boundaries.getCropBox()); @@ -155,6 +150,7 @@ public class PageBoundariesTest extends TestCase { } /** Test for default values returned when properties are null. */ + @Test public void testBoundariesNull() { PageBoundaries b = new PageBoundaries(TEST_AREA_SIZE, null, null, null); @@ -165,6 +161,7 @@ public class PageBoundariesTest extends TestCase { } /** Units must be specified. */ + @Test public void testBoundariesFail() { try { new PageBoundaries(TEST_AREA_SIZE, "0", null, null); diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTest.java b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java index cbf6f5226..ff07e63ce 100644 --- a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTest.java +++ b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java @@ -19,32 +19,21 @@ package org.apache.fop.render.extensions.prepress; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import java.awt.geom.Point2D; -import junit.framework.TestCase; +import org.junit.Test; /** * Tests for the fox:scale extension property. */ -public class PageScaleTest extends TestCase { - - /** - * Default constructor. - */ - public PageScaleTest() { - super(); - } - - /** - * Creates a test case with the given name. - * - * @param name name for the test case - */ - public PageScaleTest(String name) { - super(name); - } +public class PageScaleTestCase { /** 1 value is used for both x and y. */ + @Test public void testScale1() { Point2D res = PageScale.getScale(".5"); assertEquals(0.5, res.getX(), 0.0); @@ -52,6 +41,7 @@ public class PageScaleTest extends TestCase { } /** Two values, used resp. for x and y. */ + @Test public void testScale2() { Point2D res = PageScale.getScale("1. \t \n 1.2"); assertEquals(1.0, res.getX(), 0.0); @@ -59,6 +49,7 @@ public class PageScaleTest extends TestCase { } /** Scale must not contain units. */ + @Test public void testScaleFail() { try { PageScale.getScale("0.5mm 0.5cm"); @@ -69,6 +60,7 @@ public class PageScaleTest extends TestCase { } /** @{code null} is returned when scale is unspecified. */ + @Test public void testScaleNull() { Point2D res = PageScale.getScale(null); assertNull("Result should be null", res); diff --git a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java new file mode 100644 index 000000000..65c6b25a6 --- /dev/null +++ b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.intermediate; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InOrder; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.fo.FOElementMapping; +import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.fo.extensions.InternalElementMapping; +import org.apache.fop.util.XMLUtil; + +public class IFStructureTreeBuilderTestCase { + + private IFStructureTreeBuilder sut; + + @Before + public void setUp() { + sut = new IFStructureTreeBuilder(); + } + + @Test + public void startAndEndPageSequence() throws SAXException { + final ContentHandler handler = mock(ContentHandler.class); + + try { + sut.replayEventsForPageSequence(handler, 0); + fail("No page sequences created"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + sut.startPageSequence(null); + sut.endPageSequence(); + + sut.replayEventsForPageSequence(handler, 0); + + InOrder inOrder = inOrder(handler); + + inOrder.verify(handler).startPrefixMapping( + InternalElementMapping.STANDARD_PREFIX, InternalElementMapping.URI); + inOrder.verify(handler).startPrefixMapping( + ExtensionElementMapping.STANDARD_PREFIX, ExtensionElementMapping.URI); + inOrder.verify(handler).startElement(eq(IFConstants.NAMESPACE), + eq(IFConstants.EL_STRUCTURE_TREE), + eq(IFConstants.EL_STRUCTURE_TREE), + any(Attributes.class)); + inOrder.verify(handler).endElement(eq(IFConstants.NAMESPACE), + eq(IFConstants.EL_STRUCTURE_TREE), + eq(IFConstants.EL_STRUCTURE_TREE)); + inOrder.verify(handler).endPrefixMapping(ExtensionElementMapping.STANDARD_PREFIX); + inOrder.verify(handler).endPrefixMapping(InternalElementMapping.STANDARD_PREFIX); + } + + @Test + public void startNode() throws Exception { + final String[] attributes = {"struct-id", "1"}; + final String nodeName = "block"; + final ContentHandler handler = mock(ContentHandler.class); + + sut.startPageSequence(null); + sut.startNode(nodeName, createSimpleAttributes(attributes)); + sut.endPageSequence(); + + sut.replayEventsForPageSequence(handler, 0); + + verify(handler).startElement(eq(FOElementMapping.URI), eq(nodeName), + eq(FOElementMapping.STANDARD_PREFIX + ":" + nodeName), + AttributesMatcher.match(createSimpleAttributes(attributes))); + } + + @Test + public void endNode() throws Exception { + final String nodeName = "block"; + final ContentHandler handler = mock(ContentHandler.class); + + sut.startPageSequence(null); + sut.endNode(nodeName); + sut.endPageSequence(); + + sut.replayEventsForPageSequence(handler, 0); + + verify(handler).endElement(eq(FOElementMapping.URI), eq(nodeName), + eq(FOElementMapping.STANDARD_PREFIX + ":" + nodeName)); + } + + private static Attributes createSimpleAttributes(String... attributes) { + assert (attributes.length % 2 == 0); + final AttributesImpl atts = new AttributesImpl(); + for (int i = 0; i < attributes.length; i += 2) { + String key = attributes[i]; + String value = attributes[i + 1]; + atts.addAttribute("", key, key, XMLUtil.CDATA, value); + } + return atts; + } + + private static final class AttributesMatcher extends ArgumentMatcher<Attributes> { + + private final Attributes expected; + + private AttributesMatcher(Attributes expected) { + this.expected = expected; + } + + public static Attributes match(Attributes expected) { + return argThat(new AttributesMatcher(expected)); + } + + public boolean matches(Object attributes) { + return attributesEqual(expected, (Attributes) attributes); + } + + private static boolean attributesEqual(Attributes attributes1, Attributes attributes2) { + if (attributes1.getLength() != attributes2.getLength()) { + return false; + } + for (int i = 0; i < attributes1.getLength(); i++) { + if (attributes1.getLocalName(i) != attributes2.getLocalName(i)) { + return false; + } + if (attributes1.getQName(i) != attributes2.getQName(i)) { + return false; + } + if (attributes1.getType(i) != attributes2.getType(i)) { + return false; + } + if (attributes1.getURI(i) != attributes2.getURI(i)) { + return false; + } + if (attributes1.getValue(i) != attributes2.getValue(i)) { + return false; + } + } + return true; + } + } +} diff --git a/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java new file mode 100644 index 000000000..c5aad66d0 --- /dev/null +++ b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.intermediate; + + +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.render.intermediate.IFStructureTreeBuilder.SAXEventRecorder; +import org.apache.fop.util.XMLUtil; + +/** + * Tests {@link SAXEventRecorder}. + */ +public class SAXEventRecorderTestCase { + + private static final String URI = "http://www.example.com/"; + + private SAXEventRecorder sut; + + @Before + public void setUp() { + sut = new SAXEventRecorder(); + } + + @Test + public void testStartEvent() throws SAXException { + final String localName = "element"; + final String qName = "prefix:" + localName; + final Attributes attributes = new AttributesImpl(); + + sut.startElement(URI, localName, qName, attributes); + ContentHandler handler = mock(ContentHandler.class); + sut.replay(handler); + verify(handler).startElement(URI, localName, qName, attributes); + } + + @Test + public void testEndEvent() throws SAXException { + final String localName = "element"; + final String qName = "prefix:" + localName; + sut.endElement(URI, localName, qName); + ContentHandler handler = mock(ContentHandler.class); + sut.replay(handler); + verify(handler).endElement(URI, localName, qName); + } + + @Test + public void testStartPrefixMapping() throws SAXException { + final String prefix = "prefix"; + + sut.startPrefixMapping(URI, prefix); + ContentHandler handler = mock(ContentHandler.class); + sut.replay(handler); + verify(handler).startPrefixMapping(URI, prefix); + } + + @Test + public void testEndPrefixMapping() throws SAXException { + final String prefix = "prefix"; + + sut.endPrefixMapping(prefix); + ContentHandler handler = mock(ContentHandler.class); + sut.replay(handler); + verify(handler).endPrefixMapping(prefix); + } + + @Test + public void completeTest() throws SAXException { + final String localName1 = "element"; + final String qName1 = "prefix:" + localName1; + final Attributes attributes1 = createAttributes(URI, localName1, qName1, "value-1"); + final String localName2 = "element2"; + final String qName2 = "prefix:" + localName2; + final Attributes attributes2 = createAttributes(URI, localName2, qName2, "value-2"); + final ContentHandler handler = mock(ContentHandler.class); + final String extensionUrl = "http://www.example.com/extension"; + final String extensionPrefix = "ext"; + + sut.startPrefixMapping(extensionPrefix, extensionUrl); + sut.startElement(URI, localName1, qName1, attributes1); + sut.startElement(URI, localName2, qName2, attributes2); + sut.endElement(URI, localName2, qName2); + sut.endElement(URI, localName1, qName1); + sut.endPrefixMapping(extensionPrefix); + + sut.replay(handler); + + InOrder inOrder = inOrder(handler); + inOrder.verify(handler).startPrefixMapping(extensionPrefix, extensionUrl); + inOrder.verify(handler).startElement(URI, localName1, qName1, attributes1); + inOrder.verify(handler).startElement(URI, localName2, qName2, attributes2); + inOrder.verify(handler).endElement(URI, localName2, qName2); + inOrder.verify(handler).endElement(URI, localName1, qName1); + inOrder.verify(handler).endPrefixMapping(extensionPrefix); + } + + private static Attributes createAttributes(String uri, String localName, + String qName, String value) { + final AttributesImpl atts = new AttributesImpl(); + atts.addAttribute(uri, localName, qName, XMLUtil.CDATA, value); + return atts; + } + +} diff --git a/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java b/test/java/org/apache/fop/render/pdf/BasePDFTest.java index 7aaf61ea4..09db7538d 100644 --- a/test/java/org/apache/fop/render/pdf/BasePDFTestCase.java +++ b/test/java/org/apache/fop/render/pdf/BasePDFTest.java @@ -28,21 +28,19 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; -import org.xml.sax.SAXException; - import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.ByteArrayOutputStream; - -import org.apache.fop.AbstractFOPTestCase; +import org.apache.fop.AbstractFOPTest; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; +import org.xml.sax.SAXException; /** * Base class for automated tests that create PDF files */ -public class BasePDFTestCase extends AbstractFOPTestCase { +public class BasePDFTest extends AbstractFOPTest { /** the FopFactory */ protected final FopFactory fopFactory = FopFactory.newInstance(); @@ -52,10 +50,8 @@ public class BasePDFTestCase extends AbstractFOPTestCase { /** * Main constructor - * @param name the name of the test case */ - protected BasePDFTestCase(String name) { - super(name); + protected BasePDFTest() { init(); } diff --git a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java index 6585a0c39..fa6d9d89e 100644 --- a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java @@ -19,26 +19,22 @@ package org.apache.fop.render.pdf; +import static org.junit.Assert.fail; + import java.io.File; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.pdf.PDFConformanceException; +import org.junit.Test; /** * Tests PDF/A-1 functionality. */ -public class PDFAConformanceTestCase extends BasePDFTestCase { +public class PDFAConformanceTestCase extends BasePDFTest { private File foBaseDir = new File("test/xml/pdf-a"); private boolean dumpPDF = Boolean.getBoolean("PDFAConformanceTestCase.dumpPDF"); - /** - * Main constructor - * @param name the name of the test case - */ - public PDFAConformanceTestCase(String name) { - super(name); - } /** create an FOUserAgent for our tests * @return an initialized FOUserAgent @@ -53,6 +49,7 @@ public class PDFAConformanceTestCase extends BasePDFTestCase { * Test exception when PDF/A-1 is enabled and everything is as it should. * @throws Exception if the test fails */ + @Test public void testAllOk() throws Exception { File foFile = new File(foBaseDir, "minimal-pdf-a.fo"); convertFO(foFile, getUserAgent(), dumpPDF); @@ -62,6 +59,7 @@ public class PDFAConformanceTestCase extends BasePDFTestCase { * Test exception when PDF/A-1 is enabled together with encryption. * @throws Exception if the test fails */ + @Test public void testNoEncryption() throws Exception { final FOUserAgent ua = getUserAgent(); ua.getRendererOptions().put("owner-password", "mypassword"); //To enabled encryption @@ -78,6 +76,7 @@ public class PDFAConformanceTestCase extends BasePDFTestCase { * Test exception when PDF/A-1 is enabled and a font is used which is not embedded. * @throws Exception if the test fails */ + @Test public void testFontNotEmbedded() throws Exception { File foFile = new File(foBaseDir, "base14-font.fo"); try { @@ -92,6 +91,7 @@ public class PDFAConformanceTestCase extends BasePDFTestCase { * Test exception when PDF/A-1 is enabled and images. * @throws Exception if the test fails */ + @Test public void testImages() throws Exception { File foFile = new File(foBaseDir, "with-rgb-images.fo"); convertFO(foFile, getUserAgent(), dumpPDF); diff --git a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java index 886a2b97e..1606bf073 100644 --- a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java @@ -19,6 +19,9 @@ package org.apache.fop.render.pdf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + import java.util.Calendar; import java.util.TimeZone; @@ -32,14 +35,14 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema; - -import junit.framework.TestCase; +import org.junit.Test; /** * Test case for PDF/A metadata handling. */ -public class PDFAMetadataTestCase extends TestCase { +public class PDFAMetadataTestCase { + @Test public void testInfoUpdate() throws Exception { Metadata meta = new Metadata(); DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta); @@ -76,6 +79,7 @@ public class PDFAMetadataTestCase extends TestCase { assertEquals(cal2.getTime(), info.getModDate()); } + @Test public void testXMPUpdate() throws Exception { PDFDocument doc = new PDFDocument("SuperFOP"); PDFInfo info = doc.getInfo(); diff --git a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java index bd5c8ade1..fee2c07aa 100644 --- a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java @@ -19,16 +19,18 @@ package org.apache.fop.render.pdf; -import java.io.StringWriter; +import static org.junit.Assert.assertEquals; -import junit.framework.TestCase; +import java.io.StringWriter; import org.apache.fop.pdf.CMapBuilder; +import org.junit.Test; /** Simple sanity test of the PDFCmap class */ -public class PDFCMapTestCase extends TestCase { +public class PDFCMapTestCase { private static final String EOL = "\n"; + @Test public void testPDFCMapFillInPDF() throws Exception { final String expected = "%!PS-Adobe-3.0 Resource-CMap" + EOL diff --git a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java index b3098b859..122c23967 100644 --- a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java @@ -19,25 +19,24 @@ package org.apache.fop.render.pdf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.IOException; import java.util.StringTokenizer; import org.apache.fop.apps.FOUserAgent; +import org.junit.Ignore; +import org.junit.Test; /** Test that characters are correctly encoded in a generated PDF file */ -public class PDFEncodingTestCase extends BasePDFTestCase { +public class PDFEncodingTestCase extends BasePDFTest { private File foBaseDir = new File("test/xml/pdf-encoding"); private final boolean dumpPDF = Boolean.getBoolean("PDFEncodingTestCase.dumpPDF"); static final String INPUT_FILE = "test/xml/pdf-encoding/pdf-encoding-test.xconf"; static final String TEST_MARKER = "PDFE_TEST_MARK_"; - /** - * @param name the name of the test case - */ - public PDFEncodingTestCase(String name) { - super(name); - } /** * create an FOUserAgent for our tests @@ -57,6 +56,7 @@ public class PDFEncodingTestCase extends BasePDFTestCase { * Test using a standard FOP font * @throws Exception checkstyle wants a comment here, even a silly one */ + @Test public void testPDFEncodingWithStandardFont() throws Exception { /* If the PDF encoding is correct, a text dump of the generated PDF file contains this (excerpts) @@ -82,7 +82,10 @@ public class PDFEncodingTestCase extends BasePDFTestCase { * @throws Exception * checkstyle wants a comment here, even a silly one */ - public void DISABLEDtestPDFEncodingWithCustomFont() throws Exception { + @Ignore("This should be tested using PDFBox. If PDFBox can extract the text correctly," + + "everything is fine. The tests here are too unstable.") + @Test + public void testPDFEncodingWithCustomFont() throws Exception { /* If the PDF encoding is correct, a text dump of the generated PDF file contains this (excerpts) * ...Tm [(PDFE_TEST_MARK_2:) ( ) (This) ( ) (is) ...(acute:) ( ) (XX_\351_XX) ] TJ diff --git a/test/java/org/apache/fop/render/pdf/PDFRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/pdf/PDFRendererConfiguratorTestCase.java new file mode 100644 index 000000000..143f53ca0 --- /dev/null +++ b/test/java/org/apache/fop/render/pdf/PDFRendererConfiguratorTestCase.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.pdf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.events.Event; +import org.apache.fop.events.EventListener; +import org.apache.fop.pdf.PDFEncryptionParams; +import org.junit.Test; + +/** + * Tests that encryption length is properly set up. + */ +public class PDFRendererConfiguratorTestCase { + + private FOUserAgent foUserAgent; + + private PDFDocumentHandler documentHandler; + + private boolean eventTriggered; + + private class EncryptionEventFilter implements EventListener { + + private final int specifiedEncryptionLength; + + private final int correctedEncryptionLength; + + EncryptionEventFilter(int specifiedEncryptionLength, int correctedEncryptionLength) { + this.specifiedEncryptionLength = specifiedEncryptionLength; + this.correctedEncryptionLength = correctedEncryptionLength; + } + + public void processEvent(Event event) { + assertEquals(PDFEventProducer.class.getName() + ".incorrectEncryptionLength", + event.getEventID()); + assertEquals(specifiedEncryptionLength, event.getParam("originalValue")); + assertEquals(correctedEncryptionLength, event.getParam("correctedValue")); + eventTriggered = true; + } + } + + /** + * Non-multiple of 8 should be rounded. + * + * @throws Exception if an error occurs + */ + @Test + public void testRoundUp() throws Exception { + runTest("roundUp", 55, 56); + } + + /** + * Non-multiple of 8 should be rounded. + * + * @throws Exception if an error occurs + */ + @Test + public void testRoundDown() throws Exception { + runTest("roundDown", 67, 64); + } + + /** + * Encryption length must be at least 40. + * + * @throws Exception if an error occurs + */ + @Test + public void testBelow40() throws Exception { + runTest("below40", 32, 40); + } + + /** + * Encryption length must be at most 128. + * + * @throws Exception if an error occurs + */ + @Test + public void testAbove128() throws Exception { + runTest("above128", 233, 128); + } + + /** + * A correct value must be properly set up. + * + * @throws Exception if an error occurs + */ + @Test + public void testCorrectValue() throws Exception { + givenAConfigurationFile("correct", new EventListener() { + + public void processEvent(Event event) { + fail("No event was expected"); + } + }); + whenCreatingAndConfiguringDocumentHandler(); + thenEncryptionLengthShouldBe(128); + + } + + private void runTest(String configFilename, + final int specifiedEncryptionLength, + final int correctedEncryptionLength) throws Exception { + givenAConfigurationFile(configFilename, + new EncryptionEventFilter(specifiedEncryptionLength, correctedEncryptionLength)); + whenCreatingAndConfiguringDocumentHandler(); + assertTrue(eventTriggered); + } + + private void givenAConfigurationFile(String filename, EventListener eventListener) + throws Exception { + FopFactory fopFactory = FopFactory.newInstance(); + fopFactory.setUserConfig(new File("test/resources/org/apache/fop/render/pdf/" + + filename + ".xconf")); + foUserAgent = fopFactory.newFOUserAgent(); + foUserAgent.getEventBroadcaster().addEventListener(eventListener); + } + + private void whenCreatingAndConfiguringDocumentHandler() throws FOPException { + PDFDocumentHandlerMaker maker = new PDFDocumentHandlerMaker(); + documentHandler = (PDFDocumentHandler) maker.makeIFDocumentHandler(foUserAgent); + new PDFRendererConfigurator(foUserAgent).configure(documentHandler); + } + + private void thenEncryptionLengthShouldBe(int expectedEncryptionLength) { + PDFEncryptionParams encryptionParams = documentHandler.getPDFUtil().getEncryptionParams(); + assertEquals(expectedEncryptionLength, encryptionParams.getEncryptionLengthInBits()); + } +} diff --git a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java index 49b004e7c..dd67e97fa 100644 --- a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java @@ -19,25 +19,20 @@ package org.apache.fop.render.pdf; +import static org.junit.Assert.fail; + import java.io.File; import org.apache.fop.apps.FOUserAgent; +import org.junit.Test; /** * Tests the disables-srgb-colorspace setting. */ -public class PDFsRGBSettingsTestCase extends BasePDFTestCase { +public class PDFsRGBSettingsTestCase extends BasePDFTest { private File foBaseDir = new File("test/xml/pdf-a"); - /** - * Main constructor - * @param name name of the test case - */ - public PDFsRGBSettingsTestCase(String name) { - super(name); - } - private FOUserAgent getUserAgent(boolean enablePDFA) { final FOUserAgent a = fopFactory.newFOUserAgent(); if (enablePDFA) { @@ -51,6 +46,7 @@ public class PDFsRGBSettingsTestCase extends BasePDFTestCase { * Verify that the PDFRenderer complains if PDF/A or PDF/X is used when sRGB is disabled. * @throws Exception if the test fails */ + @Test public void testPDFAWithDisabledSRGB() throws Exception { File foFile = new File(foBaseDir, "minimal-pdf-a.fo"); try { diff --git a/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java new file mode 100644 index 000000000..2279e4fcc --- /dev/null +++ b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.pdf; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + + +/** + * A test suite for org.apache.fop.render.pdf.* + */ +@RunWith(Suite.class) +@SuiteClasses({ PDFRendererConfiguratorTestCase.class }) +public final class RenderPDFTestSuite { +} diff --git a/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java index 522d193ed..dcbc2d757 100644 --- a/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java +++ b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java @@ -19,22 +19,10 @@ package org.apache.fop.render.ps; +import static org.junit.Assert.assertEquals; + import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.MissingResourceException; - -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamSource; - -import junit.framework.TestCase; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.dsc.DSCException; @@ -44,19 +32,13 @@ import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.AbstractRenderingTest; /** * Abstract base class for PostScript verification tests. */ -public abstract class AbstractPostScriptTestCase extends TestCase { - - /** the JAXP TransformerFactory */ - protected TransformerFactory tFactory = TransformerFactory.newInstance(); - /** the FopFactory */ - protected FopFactory fopFactory = FopFactory.newInstance(); +public abstract class AbstractPostScriptTest extends AbstractRenderingTest { /** * Renders a test file. @@ -68,35 +50,7 @@ public abstract class AbstractPostScriptTestCase extends TestCase { */ protected File renderFile(FOUserAgent ua, String resourceName, String suffix) throws Exception { - File outputFile = new File("build/test-results/" + resourceName + suffix + ".ps"); - File outputDir = outputFile.getParentFile(); - FileUtils.forceMkdir(outputDir); - - // Prepare input file - InputStream in = getClass().getResourceAsStream(resourceName); - if (in == null) { - throw new MissingResourceException(resourceName + " not found in resources", - getClass().getName(), null); - } - try { - Source src = new StreamSource(in); - - // Create PostScript - OutputStream out = new java.io.FileOutputStream(outputFile); - out = new java.io.BufferedOutputStream(out); - try { - Fop fop = fopFactory.newFop(MimeConstants.MIME_POSTSCRIPT, ua, out); - SAXResult res = new SAXResult(fop.getDefaultHandler()); - - Transformer transformer = tFactory.newTransformer(); - transformer.transform(src, res); - } finally { - IOUtils.closeQuietly(out); - } - } finally { - IOUtils.closeQuietly(in); - } - return outputFile; + return renderFile(ua, resourceName, suffix, MimeConstants.MIME_POSTSCRIPT); } /** diff --git a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java index 72c677a0c..416372187 100644 --- a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java +++ b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java @@ -18,11 +18,15 @@ /* $Id$ */ package org.apache.fop.render.ps; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.io.InputStream; +import org.junit.Test; + import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.DSCConstants; @@ -40,12 +44,13 @@ import org.apache.fop.render.intermediate.IFContext; /** * Tests the image handling in PostScript output. */ -public class ImageHandlingTestCase extends AbstractPostScriptTestCase { +public class ImageHandlingTestCase extends AbstractPostScriptTest { /** * Tests JPEG handling. * @throws Exception if an error occurs */ + @Test public void testJPEGImageLevel3() throws Exception { innerTestJPEGImage(3); } @@ -54,6 +59,7 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase { * Tests JPEG handling. * @throws Exception if an error occurs */ + @Test public void testJPEGImageLevel2() throws Exception { innerTestJPEGImage(2); } @@ -68,7 +74,8 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase { ua.setDocumentHandlerOverride(handler); // Prepare output file - File outputFile = renderFile(ua, "ps-jpeg-image.fo", "-if-l" + psUtil.getLanguageLevel()); + File outputFile = renderFile(ua, "ps-jpeg-image.fo", + "-if-l" + psUtil.getLanguageLevel()); verifyPostScriptFile(outputFile, psUtil.getLanguageLevel()); } @@ -86,6 +93,7 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase { gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); + gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); PSResource form2 = new PSResource(PSResource.TYPE_FORM, "FOPForm:2"); checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE, form2); diff --git a/test/java/org/apache/fop/render/ps/PSTestSuite.java b/test/java/org/apache/fop/render/ps/PSTestSuite.java new file mode 100644 index 000000000..cf66d4776 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/PSTestSuite.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.ps; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Test suite for FOP's PostScript output. + */ +@RunWith(Suite.class) +@SuiteClasses({ + ImageHandlingTestCase.class, + ResourceOptimizationTestCase.class +}) +public class PSTestSuite { +} diff --git a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java index 862ad5205..e4cb743b4 100644 --- a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java +++ b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java @@ -19,6 +19,11 @@ package org.apache.fop.render.ps; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -26,6 +31,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Set; +import org.junit.Test; + import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.DSCConstants; @@ -51,12 +58,13 @@ import org.apache.fop.render.intermediate.IFContext; * Tests the PostScript resource optimization (selective de-duplication of * images that are used multiple times). */ -public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase { +public class ResourceOptimizationTestCase extends AbstractPostScriptTest { /** * Tests resource optimization. * @throws Exception if an error occurs */ + @Test public void testResourceOptimization() throws Exception { FOUserAgent ua = fopFactory.newFOUserAgent(); PSDocumentHandler handler = new PSDocumentHandler(); @@ -90,7 +98,7 @@ public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase { = (DSCCommentDocumentSuppliedResources)gotoDSCComment(parser, DSCConstants.DOCUMENT_SUPPLIED_RESOURCES); Set resources = supplied.getResources(); - assertEquals(4, resources.size()); + assertEquals(5, resources.size()); assertTrue(resources.contains(form1)); assertTrue("Expected barcode.eps as supplied resource", resources.contains(new PSResource(PSResource.TYPE_FILE, diff --git a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java index a7622bc0f..c5821fff1 100644 --- a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java +++ b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java @@ -27,18 +27,18 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; - -import junit.framework.TestCase; +import org.junit.Test; /** * Test for http://issues.apache.org/bugzilla/show_bug.cgi?id=39607 */ -public class Bug39607TestCase extends TestCase { +public class Bug39607TestCase { /** * Test for the NPE describes in bug 39607 * @throws Exception If an error occurs */ + @Test public void testForNPE() throws Exception { StringWriter writer = new StringWriter(); RtfFile f = new RtfFile(writer); diff --git a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java index 502604344..d8296fc33 100644 --- a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java +++ b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java @@ -19,24 +19,14 @@ package org.apache.fop.render.rtf; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** * Test suite for FOP's RTF library. */ +@RunWith(Suite.class) +@SuiteClasses({ Bug39607TestCase.class }) public class RichTextFormatTestSuite { - - /** - * Builds the test suite - * @return the test suite - */ - public static Test suite() { - TestSuite suite = new TestSuite( - "Test suite for RTF library"); - //$JUnit-BEGIN$ - suite.addTest(new TestSuite(Bug39607TestCase.class)); - //$JUnit-END$ - return suite; - } } diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java index fe5b4b6a3..3329b26b9 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java @@ -65,4 +65,4 @@ class DummyTableColumnsInfo implements ITableColumnsInfo { return false; } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java index adad2dfd0..3ce05c606 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java @@ -76,4 +76,4 @@ class ListInTable extends TestDocument { } } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java index 135dab131..f126b60c8 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java @@ -212,4 +212,4 @@ class NestedTable extends TestDocument { r.newTableCell(20 * MM_TO_TWIPS).newParagraph().newText(id + ":nested cell 2,2, 20mm."); } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java index a0772203b..2ca16c0e5 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java @@ -51,4 +51,4 @@ extends TestDocument { para.newLineBreak(); } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java index a1cd0b8d5..eff3aa7ff 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java @@ -75,4 +75,4 @@ class SimpleLists extends TestDocument { } } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java index 001634235..272284dcc 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java @@ -70,4 +70,4 @@ class SimpleTable extends TestDocument { sect.newParagraph().newText("This paragraph follows the table."); } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java index f6d1d37a8..5274dc32e 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java @@ -87,4 +87,4 @@ abstract class TestDocument { para.newText("generated on " + new Date()); para.close(); } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java index d91eadae8..4ab48acb0 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java @@ -65,4 +65,4 @@ class TextAttributes extends TestDocument { para.newText("This is back to normal\n"); } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java index bf79e4ba1..4359822f6 100644 --- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java +++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java @@ -65,4 +65,4 @@ class Whitespace extends TestDocument { p3.newText("a"); p3.newText("ng."); } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTest.java b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java index 8d2936127..42ca8dee6 100644 --- a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTest.java +++ b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java @@ -19,14 +19,15 @@ package org.apache.fop.text.linebreak; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + /** * JUnit test case for the LineBreakStatus class */ -public class LineBreakStatusTest extends TestCase { +public class LineBreakStatusTestCase { /* * These symbols are used to indicate the break action returned @@ -37,27 +38,9 @@ public class LineBreakStatusTest extends TestCase { private static final String BREAK_ACTION = "_%#@^!"; /** - * Creates the test with the given name. - * @param testName The name for this test. - */ - public LineBreakStatusTest(String testName) { - super(testName); - } - - /** - * Returns an TestSuite constructed from this class. - * @return the TestSuite - * @see junit.framework.TestSuite#TestSuite(class) - */ - public static Test suite() { - TestSuite suite = new TestSuite(LineBreakStatusTest.class); - - return suite; - } - - /** * Test of reset method, of class org.apache.commons.text.linebreak.LineBreakStatus. */ + @Test public void testReset() { System.out.println("testReset"); // TODO @@ -67,6 +50,7 @@ public class LineBreakStatusTest extends TestCase { * Test of nextChar method, of class org.apache.commons.text.linebreak.LineBreakStatus. * Runs tests for most of the Line Breaking Properties defined in the Unicode standard. */ + @Test public void testNextChar() { System.out.println("testNextChar"); @@ -320,6 +304,12 @@ public class LineBreakStatusTest extends TestCase { "^^^^^^" + "^" + "_^^^^" )); + // Unassigned codepoint: should yield same result as AL + assertTrue(testBreak( + "No" + "\u1F7E" + "break", + "^^" + "^" + "^^^^^" + )); + } /** diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTest.java b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java index 31ad950c7..015c1846f 100644 --- a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTest.java +++ b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java @@ -19,30 +19,28 @@ package org.apache.fop.text.linebreak; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; /** * TODO add javadoc * * */ -public class LineBreakUtilsTest extends TestCase { - - /** - * @param name - */ - public LineBreakUtilsTest(String name) { - super(name); - } +public class LineBreakUtilsTestCase { + @Test public void testLineBreakProperty() { assertEquals(LineBreakUtils.getLineBreakProperty('A'), LineBreakUtils.LINE_BREAK_PROPERTY_AL); assertEquals(LineBreakUtils.getLineBreakProperty('1'), LineBreakUtils.LINE_BREAK_PROPERTY_NU); assertEquals(LineBreakUtils.getLineBreakProperty('\n'), LineBreakUtils.LINE_BREAK_PROPERTY_LF); assertEquals(LineBreakUtils.getLineBreakProperty('\r'), LineBreakUtils.LINE_BREAK_PROPERTY_CR); assertEquals(LineBreakUtils.getLineBreakProperty('('), LineBreakUtils.LINE_BREAK_PROPERTY_OP); + assertEquals(LineBreakUtils.getLineBreakProperty('\u1F7E'), 0); } + @Test public void testLineBreakPair() { assertEquals( LineBreakUtils.getLineBreakPairProperty( @@ -63,7 +61,7 @@ public class LineBreakUtilsTest extends TestCase { LineBreakUtils.getLineBreakPairProperty( LineBreakUtils.LINE_BREAK_PROPERTY_AL, LineBreakUtils.LINE_BREAK_PROPERTY_OP), - LineBreakUtils.DIRECT_BREAK); + LineBreakUtils.INDIRECT_BREAK); assertEquals( LineBreakUtils.getLineBreakPairProperty( LineBreakUtils.LINE_BREAK_PROPERTY_LF, diff --git a/test/java/org/apache/fop/threading/AvalonAdapter.java b/test/java/org/apache/fop/threading/AvalonAdapter.java index bfe0a5010..5074d6b70 100644 --- a/test/java/org/apache/fop/threading/AvalonAdapter.java +++ b/test/java/org/apache/fop/threading/AvalonAdapter.java @@ -55,4 +55,4 @@ class AvalonAdapter implements EventListener { } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/threading/FOPTestbed.java b/test/java/org/apache/fop/threading/FOPTestbed.java index 8424260a9..f015479c7 100644 --- a/test/java/org/apache/fop/threading/FOPTestbed.java +++ b/test/java/org/apache/fop/threading/FOPTestbed.java @@ -319,4 +319,4 @@ public class FOPTestbed extends AbstractLogEnabled } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/threading/FOProcessorImpl.java b/test/java/org/apache/fop/threading/FOProcessorImpl.java index 3702d87e7..f379affcb 100644 --- a/test/java/org/apache/fop/threading/FOProcessorImpl.java +++ b/test/java/org/apache/fop/threading/FOProcessorImpl.java @@ -104,4 +104,4 @@ public class FOProcessorImpl extends AbstractLogEnabled public String getTargetFileExtension() { return this.fileExtension; } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/threading/IFProcessorImpl.java b/test/java/org/apache/fop/threading/IFProcessorImpl.java index 34873d76b..c83dc7088 100644 --- a/test/java/org/apache/fop/threading/IFProcessorImpl.java +++ b/test/java/org/apache/fop/threading/IFProcessorImpl.java @@ -121,4 +121,4 @@ public class IFProcessorImpl extends AbstractLogEnabled return this.fileExtension; } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/threading/Main.java b/test/java/org/apache/fop/threading/Main.java index 8363898ae..7ff0cec4f 100644 --- a/test/java/org/apache/fop/threading/Main.java +++ b/test/java/org/apache/fop/threading/Main.java @@ -71,4 +71,4 @@ public class Main { System.exit(-1); } } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/threading/Processor.java b/test/java/org/apache/fop/threading/Processor.java index 9c86fc382..2f37c02a1 100644 --- a/test/java/org/apache/fop/threading/Processor.java +++ b/test/java/org/apache/fop/threading/Processor.java @@ -44,4 +44,4 @@ public interface Processor { * @return the target file extension (for example ".pdf") */ String getTargetFileExtension(); -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/traits/BorderPropsTestCase.java b/test/java/org/apache/fop/traits/BorderPropsTestCase.java index be7714ba2..25227867b 100644 --- a/test/java/org/apache/fop/traits/BorderPropsTestCase.java +++ b/test/java/org/apache/fop/traits/BorderPropsTestCase.java @@ -19,25 +19,27 @@ package org.apache.fop.traits; -import java.awt.Color; +import static org.junit.Assert.assertEquals; -import junit.framework.TestCase; +import java.awt.Color; +import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; import org.apache.fop.fo.Constants; -import org.apache.fop.util.ColorExt; import org.apache.fop.util.ColorUtil; +import org.junit.Test; /** * Tests the BorderProps class. */ -public class BorderPropsTestCase extends TestCase { +public class BorderPropsTestCase { /** * Test serialization and deserialization to/from String. * @throws Exception if an error occurs */ + @Test public void testSerialization() throws Exception { Color col = new Color(1.0f, 1.0f, 0.5f, 1.0f); //Normalize: Avoid false alarms due to color conversion (rounding) @@ -50,10 +52,10 @@ public class BorderPropsTestCase extends TestCase { assertEquals(b1, b2); float[] cmyk = new float[] {1.0f, 1.0f, 0.5f, 1.0f}; - DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance(); - float[] rgb = cmykCs.toRGB(cmyk); - col = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], - "#CMYK", null, cmykCs, cmyk); + col = DeviceCMYKColorSpace.createCMYKColor(cmyk); + //Convert to sRGB with CMYK alternative as constructed by the cmyk() function + float[] rgb = col.getRGBColorComponents(null); + col = new ColorWithAlternatives(rgb[0], rgb[1], rgb[2], new Color[] {col}); b1 = new BorderProps(Constants.EN_INSET, 9999, col, BorderProps.SEPARATE); ser = b1.toString(); diff --git a/test/java/org/apache/fop/traits/MinOptMaxTest.java b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java index 17f46b7b0..73465fdcc 100644 --- a/test/java/org/apache/fop/traits/MinOptMaxTest.java +++ b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java @@ -19,20 +19,27 @@ package org.apache.fop.traits; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; /** - * Tests the {@link MinOptMaxTest} class. + * Tests the {@link MinOptMax} class. */ -public class MinOptMaxTest extends TestCase { +public class MinOptMaxTestCase { /** * Tests that the constant <code>MinOptMax.ZERO</code> is really zero. */ + @Test public void testZero() { assertEquals(MinOptMax.getInstance(0), MinOptMax.ZERO); } + @Test public void testNewStiffMinOptMax() { MinOptMax value = MinOptMax.getInstance(1); assertTrue(value.isStiff()); @@ -41,6 +48,7 @@ public class MinOptMaxTest extends TestCase { assertEquals(1, value.getMax()); } + @Test public void testNewMinOptMax() { MinOptMax value = MinOptMax.getInstance(1, 2, 3); assertTrue(value.isElastic()); @@ -52,6 +60,7 @@ public class MinOptMaxTest extends TestCase { /** * Test that it is possible to create stiff instances with the normal factory method. */ + @Test public void testNewMinOptMaxStiff() { MinOptMax value = MinOptMax.getInstance(1, 1, 1); assertTrue(value.isStiff()); @@ -60,6 +69,7 @@ public class MinOptMaxTest extends TestCase { assertEquals(1, value.getMax()); } + @Test public void testNewMinOptMaxMinGreaterOpt() { try { MinOptMax.getInstance(1, 0, 2); @@ -69,6 +79,7 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testNewMinOptMaxMaxSmallerOpt() { try { MinOptMax.getInstance(0, 1, 0); @@ -78,18 +89,21 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testShrinkablility() { assertEquals(0, MinOptMax.getInstance(1).getShrink()); assertEquals(1, MinOptMax.getInstance(1, 2, 2).getShrink()); assertEquals(2, MinOptMax.getInstance(1, 3, 3).getShrink()); } + @Test public void testStrechablilty() { assertEquals(0, MinOptMax.getInstance(1).getStretch()); assertEquals(1, MinOptMax.getInstance(1, 1, 2).getStretch()); assertEquals(2, MinOptMax.getInstance(1, 1, 3).getStretch()); } + @Test public void testPlus() { assertEquals(MinOptMax.ZERO, MinOptMax.ZERO.plus(MinOptMax.ZERO)); @@ -100,6 +114,7 @@ public class MinOptMaxTest extends TestCase { assertEquals(MinOptMax.getInstance(4, 5, 6), MinOptMax.getInstance(1, 2, 3).plus(3)); } + @Test public void testMinus() { assertEquals(MinOptMax.ZERO, MinOptMax.ZERO.minus(MinOptMax.ZERO)); @@ -110,6 +125,7 @@ public class MinOptMaxTest extends TestCase { assertEquals(MinOptMax.getInstance(1, 2, 3), MinOptMax.getInstance(5, 6, 7).minus(4)); } + @Test public void testMinusFail1() { try { MinOptMax.ZERO.minus(MinOptMax.getInstance(1, 2, 3)); @@ -119,6 +135,7 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testMinusFail2() { try { MinOptMax.getInstance(1, 2, 3).minus(MinOptMax.getInstance(1, 3, 3)); @@ -128,6 +145,7 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testMinusFail3() { try { MinOptMax.ZERO.minus(MinOptMax.getInstance(1, 1, 2)); @@ -137,6 +155,7 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testMinusFail4() { try { MinOptMax.getInstance(1, 2, 3).minus(MinOptMax.getInstance(1, 1, 3)); @@ -146,12 +165,14 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testMult() { assertEquals(MinOptMax.ZERO, MinOptMax.ZERO.mult(0)); assertEquals(MinOptMax.getInstance(1, 2, 3), MinOptMax.getInstance(1, 2, 3).mult(1)); assertEquals(MinOptMax.getInstance(2, 4, 6), MinOptMax.getInstance(1, 2, 3).mult(2)); } + @Test public void testMultFail() { try { MinOptMax.getInstance(1, 2, 3).mult(-1); @@ -161,12 +182,14 @@ public class MinOptMaxTest extends TestCase { } } + @Test public void testNonZero() { assertFalse(MinOptMax.ZERO.isNonZero()); assertTrue(MinOptMax.getInstance(1).isNonZero()); assertTrue(MinOptMax.getInstance(1, 2, 3).isNonZero()); } + @Test public void testExtendMinimum() { assertEquals(MinOptMax.getInstance(1, 1, 1), MinOptMax.ZERO.extendMinimum(1)); @@ -180,6 +203,7 @@ public class MinOptMaxTest extends TestCase { MinOptMax.getInstance(1, 2, 3).extendMinimum(4)); } + @Test public void testEquals() { MinOptMax number = MinOptMax.getInstance(1, 3, 5); assertEquals(number, number); @@ -191,6 +215,7 @@ public class MinOptMaxTest extends TestCase { assertFalse(number.equals(new Integer(1))); } + @Test public void testHashCode() { MinOptMax number = MinOptMax.getInstance(1, 2, 3); assertEquals(number.hashCode(), number.hashCode()); diff --git a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java index 3d7e72d87..c4b9446ac 100644 --- a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java +++ b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java @@ -19,20 +19,21 @@ package org.apache.fop.util; -import java.util.Map; - -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; -import org.xml.sax.helpers.LocatorImpl; +import java.util.Map; import org.apache.fop.events.model.EventSeverity; import org.apache.fop.util.text.AdvancedMessageFormat; +import org.junit.Test; +import org.xml.sax.helpers.LocatorImpl; /** * Tests for EventFormatter. */ -public class AdvancedMessageFormatTestCase extends TestCase { +public class AdvancedMessageFormatTestCase { + @Test public void testFormatting() throws Exception { String msg; AdvancedMessageFormat format; @@ -74,6 +75,7 @@ public class AdvancedMessageFormatTestCase extends TestCase { assertEquals("Multi-conditional: case1: value1", msg); } + @Test public void testObjectFormatting() throws Exception { String msg; AdvancedMessageFormat format; @@ -92,6 +94,7 @@ public class AdvancedMessageFormatTestCase extends TestCase { assertEquals("Here\'s a Locator: 12:7", msg); } + @Test public void testIfFormatting() throws Exception { String msg; AdvancedMessageFormat format; @@ -139,6 +142,7 @@ public class AdvancedMessageFormatTestCase extends TestCase { assertEquals("You are very, very nice!", msg); } + @Test public void testEqualsFormatting() throws Exception { String msg; AdvancedMessageFormat format; @@ -157,6 +161,7 @@ public class AdvancedMessageFormatTestCase extends TestCase { assertEquals("Error\nSome explanation!", msg); } + @Test public void testChoiceFormatting() throws Exception { String msg; AdvancedMessageFormat format; diff --git a/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java new file mode 100644 index 000000000..3afcc3a2e --- /dev/null +++ b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util; + +import static org.junit.Assert.assertEquals; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; +import org.apache.fop.util.bitmap.BitmapImageUtil; +import org.apache.fop.util.bitmap.MonochromeBitmapConverter; +import org.apache.xmlgraphics.image.writer.ImageWriterUtil; +import org.apache.xmlgraphics.util.WriterOutputStream; +import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream; +import org.junit.Test; + +/** + * Tests {@link BitmapImageUtil}. + */ +public class BitmapImageUtilTestCase { + + private static final boolean DEBUG = true; + private static final boolean TEST_PIXELS = false; + + /** + * Tests the convertTo* methods. + * @throws Exception if an error occurs + */ + @Test + public void testConvertToMono() throws Exception { + BufferedImage testImage = createTestImage(); + saveAsPNG(testImage, "test-image"); + + RenderedImage img; + Dimension scaled = new Dimension(320, 240); + + img = BitmapImageUtil.convertToGrayscale(testImage, null); + saveAsPNG(img, "out-gray"); + assertEquals(1, img.getColorModel().getNumComponents()); + assertEquals(8, img.getColorModel().getPixelSize()); + assertEquals(640, img.getWidth()); + assertEquals(480, img.getHeight()); + assertPixels("5757575757575757575757FFFFFFFFFF", img, 220, 34, 16); + + img = BitmapImageUtil.convertToGrayscale(testImage, scaled); + saveAsPNG(img, "out-gray-scaled"); + assertEquals(1, img.getColorModel().getNumComponents()); + assertEquals(8, img.getColorModel().getPixelSize()); + assertEquals(320, img.getWidth()); + assertEquals(240, img.getHeight()); + + img = BitmapImageUtil.convertToMonochrome(testImage, null); + saveAsPNG(img, "out-mono"); + assertEquals(1, img.getColorModel().getPixelSize()); + assertEquals(640, img.getWidth()); + assertEquals(480, img.getHeight()); + assertPixels("00000000000000000000000101010101", img, 220, 34, 16); + + if (isJAIAvailable()) { + img = BitmapImageUtil.convertToMonochrome(testImage, null, 0.5f); + saveAsPNG(img, "out-mono-jai-0.5"); + assertEquals(1, img.getColorModel().getPixelSize()); + assertEquals(640, img.getWidth()); + assertEquals(480, img.getHeight()); + assertPixels("00010000000100000001000101010101", img, 220, 34, 16); + + img = BitmapImageUtil.convertToMonochrome(testImage, null, 1.0f); + saveAsPNG(img, "out-mono-jai-1.0"); + assertEquals(1, img.getColorModel().getPixelSize()); + assertEquals(640, img.getWidth()); + assertEquals(480, img.getHeight()); + assertPixels("01000001000001000001000101010101", img, 220, 34, 16); + } + } + + private void assertPixels(String expected, RenderedImage img, int x, int y, int w) + throws IOException { + if (TEST_PIXELS) { + byte[] byteArray = (byte[])img.getData().getDataElements(x, y, w, 1, new byte[w]); + assertEquals(expected, toHex(byteArray)); + } + } + + private boolean isJAIAvailable() { + MonochromeBitmapConverter converter + = BitmapImageUtil.createDefaultMonochromeBitmapConverter(); + return converter.getClass().getName().contains("JAI"); + } + + private void saveAsPNG(RenderedImage img, String name) throws IOException { + if (DEBUG) { + File baseDir = new File("./build/test-results/bitmap-conversion"); + baseDir.mkdirs(); + ImageWriterUtil.saveAsPNG(img, new File(baseDir, name + ".png")); + } + } + + private String toHex(byte[] byteArray) throws IOException { + InputStream in = new java.io.ByteArrayInputStream(byteArray); + StringWriter writer = new StringWriter(); + WriterOutputStream wo = new WriterOutputStream(writer, "US-ASCII"); + ASCIIHexOutputStream hex = new ASCIIHexOutputStream(wo); + IOUtils.copyLarge(in, hex); + return writer.toString(); + } + + private BufferedImage createTestImage() { + BufferedImage buf = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = buf.createGraphics(); + g2d.setBackground(Color.WHITE); + g2d.clearRect(0, 0, buf.getWidth(), buf.getHeight()); + + //A few rectangles rotated and with different color + Graphics2D copy = (Graphics2D)g2d.create(); + copy.translate(170, 170); + int c = 12; + for (int i = 0; i < c; i++) { + float f = ((i + 1) / (float)c); + Color col = new Color(0.0f, 1 - f, 0.0f); + copy.setColor(col); + copy.fillRect(0, 0, 120, 120); + copy.rotate(-2 * Math.PI / c); + } + copy.dispose(); + + //the same in gray scales + copy = (Graphics2D)g2d.create(); + copy.translate(470, 310); + c = 12; + for (int i = 0; i < c; i++) { + float f = ((i + 1) / (float)c); + Color col = new Color(f, f, f); + copy.setColor(col); + copy.fillRect(0, 0, 120, 120); + copy.rotate(-2 * Math.PI / c); + } + copy.dispose(); + return buf; + } + +} diff --git a/test/java/org/apache/fop/util/ColorUtilTestCase.java b/test/java/org/apache/fop/util/ColorUtilTestCase.java index aefd2a76a..b16d72809 100644 --- a/test/java/org/apache/fop/util/ColorUtilTestCase.java +++ b/test/java/org/apache/fop/util/ColorUtilTestCase.java @@ -19,25 +19,33 @@ package org.apache.fop.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.awt.Color; import java.awt.color.ColorSpace; - -import junit.framework.TestCase; - -import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; +import java.net.URI; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; +import org.apache.xmlgraphics.java2d.color.ColorSpaces; +import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; +import org.apache.xmlgraphics.java2d.color.NamedColorSpace; +import org.apache.xmlgraphics.java2d.color.RenderingIntent; +import org.junit.Test; /** * Tests the ColorUtil class. */ -public class ColorUtilTestCase extends TestCase { +public class ColorUtilTestCase { /** * Test serialization to String. * @throws Exception if an error occurs */ + @Test public void testSerialization() throws Exception { Color col = new Color(1.0f, 1.0f, 0.5f, 1.0f); String s = ColorUtil.colorToString(col); @@ -55,6 +63,7 @@ public class ColorUtilTestCase extends TestCase { * Test deserialization from String. * @throws Exception if an error occurs */ + @Test public void testDeserialization() throws Exception { Color col = ColorUtil.parseColorString(null, "#ffff7f"); assertEquals(255, col.getRed()); @@ -73,23 +82,28 @@ public class ColorUtilTestCase extends TestCase { * Test equals(). * @throws Exception if an error occurs */ + @Test public void testEquals() throws Exception { Color col1 = ColorUtil.parseColorString(null, "#ff0000cc"); Color col2 = ColorUtil.parseColorString(null, "#ff0000cc"); assertEquals(col1, col2); col1 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"); + /* The following doesn't work since java.awt.Color from Sun doesn't round consistently col2 = ColorUtil.parseColorString(null, "cmyk(0.0,0.0,0.0,0.5)"); assertEquals(col1, col2); + */ col2 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.5,0.5,0.5,0.0)"); - assertFalse(col1.equals(col2)); + assertTrue(col1.equals(col2)); + assertFalse(org.apache.xmlgraphics.java2d.color.ColorUtil.isSameColor(col1, col2)); } /** * Tests the rgb() function. * @throws Exception if an error occurs */ + @Test public void testRGB() throws Exception { FopFactory fopFactory = FopFactory.newInstance(); FOUserAgent ua = fopFactory.newFOUserAgent(); @@ -107,33 +121,42 @@ public class ColorUtilTestCase extends TestCase { * Tests the fop-rgb-icc() function. * @throws Exception if an error occurs */ + @Test public void testRGBICC() throws Exception { FopFactory fopFactory = FopFactory.newInstance(); - ColorSpace cs = fopFactory.getColorSpace(null, - "src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm"); - assertNotNull(cs); - + URI sRGBLoc = new URI( + "file:src/java/org/apache/fop/pdf/sRGB%20Color%20Space%20Profile.icm"); + ColorSpace cs = fopFactory.getColorSpaceCache().get( + "sRGBAlt", null, sRGBLoc.toASCIIString(), RenderingIntent.AUTO); + assertNotNull("Color profile not found", cs); FOUserAgent ua = fopFactory.newFOUserAgent(); - ColorExt colActual; + ColorWithFallback colActual; //fop-rgb-icc() is used instead of rgb-icc() inside FOP! String colSpec = "fop-rgb-icc(1.0,0.0,0.0,sRGBAlt," - + "\"src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm\",1.0,0.0,0.0)"; - colActual = (ColorExt)ColorUtil.parseColorString(ua, colSpec); - //assertEquals(255, colActual.getRed()); //253 is returned - //assertEquals(24, colActual.getGreen()); //24 is returned + + "\"" + sRGBLoc.toASCIIString() + "\",1.0,0.0,0.0)"; + colActual = (ColorWithFallback)ColorUtil.parseColorString(ua, colSpec); + assertEquals(cs, colActual.getColorSpace()); + assertEquals(255, colActual.getRed(), 2f); //Java 5: 253, Java 6: 255 + assertEquals(0, colActual.getGreen(), 25f); //Java 5: 25, Java 6: 0 + assertEquals(0, colActual.getBlue()); //I don't understand the difference. Maybe Java's sRGB and HP's sRGB are somehow not //equivalent. This is only going to be a problem if anyone actually makes use of the //RGB fallback in any renderer. //TODO Anyone know what's going on here? - assertEquals(0, colActual.getBlue()); - assertEquals(cs, colActual.getColorSpace()); float[] comps = colActual.getColorComponents(null); assertEquals(3, comps.length); assertEquals(1f, comps[0], 0); assertEquals(0f, comps[1], 0); assertEquals(0f, comps[2], 0); + assertEquals(0, colActual.getAlternativeColors().length); + + Color fallback = colActual.getFallbackColor(); + assertTrue(fallback.getColorSpace().isCS_sRGB()); + assertEquals(255, fallback.getRed()); + assertEquals(0, fallback.getGreen()); + assertEquals(0, fallback.getBlue()); assertEquals(colSpec, ColorUtil.colorToString(colActual)); @@ -147,17 +170,19 @@ public class ColorUtilTestCase extends TestCase { * Tests the cmyk() function. * @throws Exception if an error occurs */ + @Test public void testCMYK() throws Exception { - ColorExt colActual; + ColorWithAlternatives colActual; String colSpec; colSpec = "cmyk(0.0, 0.0, 1.0, 0.0)"; - colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); + colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); assertEquals(255, colActual.getRed()); assertEquals(255, colActual.getGreen()); assertEquals(0, colActual.getBlue()); - assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); - float[] comps = colActual.getColorComponents(null); + Color alt = colActual.getAlternativeColors()[0]; + assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); + float[] comps = alt.getColorComponents(null); assertEquals(4, comps.length); assertEquals(0f, comps[0], 0); assertEquals(0f, comps[1], 0); @@ -167,12 +192,13 @@ public class ColorUtilTestCase extends TestCase { ColorUtil.colorToString(colActual)); colSpec = "cmyk(0.0274, 0.2196, 0.3216, 0.0)"; - colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); - assertEquals(248, colActual.getRed()); - assertEquals(199, colActual.getGreen()); - assertEquals(172, colActual.getBlue()); - assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); - comps = colActual.getColorComponents(null); + colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); + assertEquals(248, colActual.getRed(), 1); + assertEquals(199, colActual.getGreen(), 1); + assertEquals(172, colActual.getBlue(), 1); + alt = colActual.getAlternativeColors()[0]; + assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); + comps = alt.getColorComponents(null); assertEquals(0.0274f, comps[0], 0.001); assertEquals(0.2196f, comps[1], 0.001); assertEquals(0.3216f, comps[2], 0.001); @@ -181,12 +207,13 @@ public class ColorUtilTestCase extends TestCase { ColorUtil.colorToString(colActual)); colSpec = "fop-rgb-icc(1.0,1.0,0.0,#CMYK,,0.0,0.0,1.0,0.0)"; - colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); + colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); assertEquals(255, colActual.getRed()); assertEquals(255, colActual.getGreen()); assertEquals(0, colActual.getBlue()); - assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); - comps = colActual.getColorComponents(null); + alt = colActual.getAlternativeColors()[0]; + assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); + comps = alt.getColorComponents(null); assertEquals(4, comps.length); assertEquals(0f, comps[0], 0); assertEquals(0f, comps[1], 0); @@ -196,12 +223,13 @@ public class ColorUtilTestCase extends TestCase { ColorUtil.colorToString(colActual)); colSpec = "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"; - colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); - assertEquals(127, colActual.getRed()); - assertEquals(127, colActual.getGreen()); - assertEquals(127, colActual.getBlue()); - assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); - comps = colActual.getColorComponents(null); + colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); + assertEquals(127, colActual.getRed(), 1); + assertEquals(127, colActual.getGreen(), 1); + assertEquals(127, colActual.getBlue(), 1); + alt = colActual.getAlternativeColors()[0]; + assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); + comps = alt.getColorComponents(null); assertEquals(4, comps.length); assertEquals(0f, comps[0], 0); assertEquals(0f, comps[1], 0); @@ -209,6 +237,99 @@ public class ColorUtilTestCase extends TestCase { assertEquals(0.5f, comps[3], 0); assertEquals("fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)", ColorUtil.colorToString(colActual)); + + //Verify that the cmyk() and fop-rgb-icc(#CMYK) functions have the same results + ColorWithAlternatives colCMYK = (ColorWithAlternatives)ColorUtil.parseColorString( + null, "cmyk(0,0,0,0.5)"); + assertEquals(colCMYK.getAlternativeColors()[0], colActual.getAlternativeColors()[0]); + //The following doesn't work: + //assertEquals(colCMYK, colActual); + //java.awt.Color does not consistenly calculate the int RGB values: + //Color(ColorSpace cspace, float components[], float alpha): 0.5 --> 127 + //Color(float r, float g, float b): 0.5 --> 128 + if (!colCMYK.equals(colActual)) { + System.out.println("Info: java.awt.Color does not consistently calculate" + + " int RGB values from float RGB values."); + } } + /** + * Tests color for the #Separation pseudo-colorspace. + * @throws Exception if an error occurs + */ + @Test + public void testSeparationColor() throws Exception { + ColorWithFallback colActual; + String colSpec; + + colSpec = "fop-rgb-icc(1.0,0.8,0.0,#Separation,,Postgelb)"; + colActual = (ColorWithFallback)ColorUtil.parseColorString(null, colSpec); + assertEquals(255, colActual.getRed(), 5); + assertEquals(204, colActual.getGreen(), 3); + assertEquals(0, colActual.getBlue(), 12); + //sRGB results differ between JDKs + + Color fallback = colActual.getFallbackColor(); + assertEquals(255, fallback.getRed()); + assertEquals(204, fallback.getGreen()); + assertEquals(0, fallback.getBlue()); + + assertFalse(colActual.hasAlternativeColors()); + + assertTrue(colActual.getColorSpace() instanceof NamedColorSpace); + NamedColorSpace ncs; + ncs = (NamedColorSpace)colActual.getColorSpace(); + assertEquals("Postgelb", ncs.getColorName()); + float[] comps = colActual.getColorComponents(null); + assertEquals(1, comps.length); + assertEquals(1f, comps[0], 0); + assertEquals(colSpec, ColorUtil.colorToString(colActual)); + + } + + /** + * Tests the fop-rgb-named-color() function. + * @throws Exception if an error occurs + */ + @Test + public void testNamedColorProfile() throws Exception { + FopFactory fopFactory = FopFactory.newInstance(); + URI ncpLoc = new URI("file:test/resources/color/ncp-example.icc"); + ColorSpace cs = fopFactory.getColorSpaceCache().get( + "NCP", null, ncpLoc.toASCIIString(), RenderingIntent.AUTO); + assertNotNull("Color profile not found", cs); + + FOUserAgent ua = fopFactory.newFOUserAgent(); + ColorWithFallback colActual; + + //fop-rgb-named-color() is used instead of rgb-named-color() inside FOP! + String colSpec = "fop-rgb-named-color(1.0,0.8,0.0,NCP," + + "\"" + ncpLoc.toASCIIString() + "\",Postgelb)"; + colActual = (ColorWithFallback)ColorUtil.parseColorString(ua, colSpec); + assertEquals(255, colActual.getRed(), 2); + assertEquals(193, colActual.getGreen(), 2); + assertEquals(0, colActual.getBlue()); + + Color fallback = colActual.getFallbackColor(); + assertEquals(255, fallback.getRed()); + assertEquals(204, fallback.getGreen()); + assertEquals(0, fallback.getBlue()); + assertEquals(ColorSpace.getInstance(ColorSpace.CS_sRGB), fallback.getColorSpace()); + + float[] comps = fallback.getColorComponents(null); + assertEquals(3, comps.length); + assertEquals(1f, comps[0], 0); + assertEquals(0.8f, comps[1], 0); + assertEquals(0f, comps[2], 0); + + assertTrue(colActual.getColorSpace() instanceof NamedColorSpace); + NamedColorSpace ncs; + ncs = (NamedColorSpace)colActual.getColorSpace(); + assertEquals("Postgelb", ncs.getColorName()); + comps = colActual.getColorComponents(null); + assertEquals(1, comps.length); + assertEquals(1f, comps[0], 0); + + assertEquals(colSpec, ColorUtil.colorToString(colActual)); + } } diff --git a/test/java/org/apache/fop/util/ConsoleEventListenerForTests.java b/test/java/org/apache/fop/util/ConsoleEventListenerForTests.java index 97546b1c3..24a797648 100644 --- a/test/java/org/apache/fop/util/ConsoleEventListenerForTests.java +++ b/test/java/org/apache/fop/util/ConsoleEventListenerForTests.java @@ -86,4 +86,4 @@ public class ConsoleEventListenerForTests implements EventListener { String msg = EventFormatter.format(event); System.out.println(" [" + levelString + "] " + msg); } -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java index bebad4422..342488a93 100644 --- a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java +++ b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java @@ -19,6 +19,9 @@ package org.apache.fop.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + import java.util.LinkedList; import org.apache.fop.layoutmgr.ElementListUtils; @@ -26,18 +29,18 @@ import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; - -import junit.framework.TestCase; +import org.junit.Test; /** * Test class for ElementListUtils. */ -public class ElementListUtilsTestCase extends TestCase { +public class ElementListUtilsTestCase { /** * Tests ElementListUtils.removeLegalBreaks(). * @throws Exception if the test fails */ + @Test public void testRemoveElementPenalty1() throws Exception { LinkedList lst = new LinkedList(); lst.add(new KnuthBox(4000, null, false)); @@ -64,6 +67,7 @@ public class ElementListUtilsTestCase extends TestCase { * Tests ElementListUtils.removeLegalBreaks(). * @throws Exception if the test fails */ + @Test public void testRemoveElementPenalty2() throws Exception { LinkedList lst = new LinkedList(); lst.add(new KnuthBox(4000, null, false)); @@ -93,6 +97,7 @@ public class ElementListUtilsTestCase extends TestCase { * Tests ElementListUtils.removeLegalBreaksFromEnd(). * @throws Exception if the test fails */ + @Test public void testRemoveElementFromEndPenalty1() throws Exception { LinkedList lst = new LinkedList(); lst.add(new KnuthBox(4000, null, false)); @@ -119,6 +124,7 @@ public class ElementListUtilsTestCase extends TestCase { * Tests ElementListUtils.removeLegalBreaksFromEnd(). * @throws Exception if the test fails */ + @Test public void testRemoveElementFromEndPenalty2() throws Exception { LinkedList lst = new LinkedList(); lst.add(new KnuthBox(4000, null, false)); @@ -142,6 +148,4 @@ public class ElementListUtilsTestCase extends TestCase { assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getPenalty()); assertEquals(0, ((KnuthGlue)lst.get(6)).getWidth()); } - - -}
\ No newline at end of file +} diff --git a/test/java/org/apache/fop/util/LanguageTagsTestCase.java b/test/java/org/apache/fop/util/LanguageTagsTestCase.java new file mode 100644 index 000000000..f7383c720 --- /dev/null +++ b/test/java/org/apache/fop/util/LanguageTagsTestCase.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; + +import org.junit.Test; + +/** + * Tests {@link LanguageTags}. + */ +public class LanguageTagsTestCase { + + @Test(expected = NullPointerException.class) + public void toLanguageTagRejectsNull() { + LanguageTags.toLanguageTag(null); + } + + @Test + public void testToLanguageTag() throws Exception { + assertEquals("", LanguageTags.toLanguageTag(new Locale(""))); + assertEquals("en", LanguageTags.toLanguageTag(new Locale("en"))); + assertEquals("en-US", LanguageTags.toLanguageTag(new Locale("en", "US"))); + assertEquals("en-US", LanguageTags.toLanguageTag(new Locale("EN", "us"))); + } + + @Test(expected = NullPointerException.class) + public void toLocaleRejectsNull() { + LanguageTags.toLocale(null); + } + + @Test + public void testRFC3066ToLocale() throws Exception { + assertEquals(new Locale(""), LanguageTags.toLocale("")); + assertEquals(new Locale("en"), LanguageTags.toLocale("en")); + assertEquals(new Locale("en", "US"), LanguageTags.toLocale("en-US")); + assertEquals(new Locale("en", "US"), LanguageTags.toLocale("EN-us")); + } +} diff --git a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java index bc201bfae..26cfa4406 100644 --- a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java +++ b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java @@ -19,17 +19,21 @@ package org.apache.fop.util; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; -import junit.framework.TestCase; +import org.junit.Test; /** * Tests for XMLResourceBundle. */ -public class XMLResourceBundleTestCase extends TestCase { +public class XMLResourceBundleTestCase { + @Test public void testWithValidFile() throws Exception { ResourceBundle bundle = XMLResourceBundle.getXMLBundle( getClass().getName(), Locale.ENGLISH, getClass().getClassLoader()); @@ -47,6 +51,7 @@ public class XMLResourceBundleTestCase extends TestCase { assertEquals("Untranslatable", bundleDE.getString("untranslatable")); } + @Test public void testWithInvalidFile() throws Exception { try { ResourceBundle bundle = XMLResourceBundle.getXMLBundle( diff --git a/test/java/org/apache/fop/util/XMLUtilTestCase.java b/test/java/org/apache/fop/util/XMLUtilTestCase.java deleted file mode 100644 index 3e86b978e..000000000 --- a/test/java/org/apache/fop/util/XMLUtilTestCase.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.util.Locale; - -import junit.framework.TestCase; - -/** - * Tests {@link XMLUtil}. - */ -public class XMLUtilTestCase extends TestCase { - - public void testLocaleToRFC3066() throws Exception { - assertNull(XMLUtil.toRFC3066(null)); - assertEquals("en", XMLUtil.toRFC3066(new Locale("en"))); - assertEquals("en-US", XMLUtil.toRFC3066(new Locale("en", "US"))); - assertEquals("en-US", XMLUtil.toRFC3066(new Locale("EN", "us"))); - } - - public void testRFC3066ToLocale() throws Exception { - assertNull(XMLUtil.convertRFC3066ToLocale(null)); - assertNull(XMLUtil.convertRFC3066ToLocale("")); - assertEquals(new Locale("en"), XMLUtil.convertRFC3066ToLocale("en")); - assertEquals(new Locale("en", "US"), XMLUtil.convertRFC3066ToLocale("en-US")); - assertEquals(new Locale("en", "US"), XMLUtil.convertRFC3066ToLocale("EN-us")); - } -} diff --git a/test/java/org/apache/fop/visual/BatchDiffer.java b/test/java/org/apache/fop/visual/BatchDiffer.java index 08ac886a2..cbc9cd5e9 100644 --- a/test/java/org/apache/fop/visual/BatchDiffer.java +++ b/test/java/org/apache/fop/visual/BatchDiffer.java @@ -23,7 +23,6 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Collection; -import java.util.Iterator; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.stream.StreamSource; @@ -44,7 +43,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.image.writer.ImageWriterUtil; -import org.apache.fop.layoutengine.LayoutEngineTestSuite; +import org.apache.fop.layoutengine.LayoutEngineTestUtils; /** * This class is used to visually diff bitmap images created through various sources. @@ -150,8 +149,7 @@ public class BatchDiffer { throw new RuntimeException("source-directory does not exist: " + srcDir); } final File targetDir = new File(cfg.getChild("target-directory").getValue()); - targetDir.mkdirs(); - if (!targetDir.exists()) { + if (!targetDir.mkdirs() && !targetDir.exists()) { throw new RuntimeException("target-directory is invalid: " + targetDir); } context.setTargetDir(targetDir); @@ -164,7 +162,8 @@ public class BatchDiffer { IOFileFilter filter = new SuffixFileFilter(new String[] {".xml", ".fo"}); //Same filtering as in layout engine tests if (cfg.getChild("filter-disabled").getValueAsBoolean(true)) { - filter = LayoutEngineTestSuite.decorateWithDisabledList(filter); + String disabled = System.getProperty("fop.layoutengine.disabled"); + filter = LayoutEngineTestUtils.decorateWithDisabledList(filter, disabled); } String manualFilter = cfg.getChild("manual-filter").getValue(null); if (manualFilter != null) { @@ -176,10 +175,8 @@ public class BatchDiffer { } int maxfiles = cfg.getChild("max-files").getValueAsInteger(-1); - Collection files = FileUtils.listFiles(srcDir, filter, null); - Iterator i = files.iterator(); - while (i.hasNext()) { - final File f = (File)i.next(); + Collection<File> files = FileUtils.listFiles(srcDir, filter, null); + for (final File f : files) { try { log.info("---=== " + f + " ===---"); long[] times = new long[producers.length]; @@ -228,9 +225,6 @@ public class BatchDiffer { break; } } - } catch (IOException ioe) { - log.error("I/O problem while processing", ioe); - throw new RuntimeException("I/O problem: " + ioe.getMessage()); } catch (ConfigurationException e) { log.error("Error while configuring BatchDiffer", e); throw new RuntimeException("Error while configuring BatchDiffer: " + e.getMessage()); @@ -260,7 +254,7 @@ public class BatchDiffer { BitmapProducer[] producers = new BitmapProducer[children.length]; for (int i = 0; i < children.length; i++) { try { - Class clazz = Class.forName(children[i].getAttribute("classname")); + Class<?> clazz = Class.forName(children[i].getAttribute("classname")); producers[i] = (BitmapProducer)clazz.newInstance(); ContainerUtil.configure(producers[i], children[i]); } catch (Exception e) { diff --git a/test/java/org/apache/fop/visual/StreamRedirector.java b/test/java/org/apache/fop/visual/StreamRedirector.java index 918f5bf5c..543c539ff 100644 --- a/test/java/org/apache/fop/visual/StreamRedirector.java +++ b/test/java/org/apache/fop/visual/StreamRedirector.java @@ -79,4 +79,4 @@ public class StreamRedirector implements Runnable { this.exception = ioe; } } -}
\ No newline at end of file +} |