aboutsummaryrefslogtreecommitdiffstats
path: root/test/java/org/apache/fop
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-04-05 16:19:19 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-04-05 16:19:19 +0000
commit502152b4779d4b970148a074e741754828fcc89a (patch)
tree809eb271a8251dcb69dda9679eaeb09398d232d0 /test/java/org/apache/fop
parent7c8f02c57302d672fe4d0a8fc5332af6d9f0e610 (diff)
parent73c7b4470f8793bcbf5f1ae795a72fdb7d4455b3 (diff)
downloadxmlgraphics-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')
-rw-r--r--test/java/org/apache/fop/AbstractBasicTranscoderTest.java (renamed from test/java/org/apache/fop/AbstractBasicTranscoderTestCase.java)13
-rw-r--r--test/java/org/apache/fop/AbstractFOPTest.java (renamed from test/java/org/apache/fop/AbstractFOPTestCase.java)20
-rw-r--r--test/java/org/apache/fop/BasicDriverTestCase.java16
-rw-r--r--test/java/org/apache/fop/BasicDriverTestSuite.java20
-rw-r--r--test/java/org/apache/fop/BasicPDFTranscoderTestCase.java13
-rw-r--r--test/java/org/apache/fop/BasicPSTranscoderTestCase.java13
-rw-r--r--test/java/org/apache/fop/BasicTranscoderTestSuite.java24
-rw-r--r--test/java/org/apache/fop/DigestFilterTestCase.java15
-rw-r--r--test/java/org/apache/fop/GenericFOPTestCase.java144
-rw-r--r--test/java/org/apache/fop/KnuthAlgorithmTestCase.java14
-rw-r--r--test/java/org/apache/fop/StandardTestSuite.java80
-rw-r--r--test/java/org/apache/fop/URIResolutionTestCase.java22
-rw-r--r--test/java/org/apache/fop/UtilityCodeTestSuite.java50
-rw-r--r--test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java54
-rw-r--r--test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java223
-rw-r--r--test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl135
-rw-r--r--test/java/org/apache/fop/accessibility/fo/table-footers.fo195
-rw-r--r--test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl66
-rw-r--r--test/java/org/apache/fop/afp/AFPEventProcessingTestCase.java79
-rw-r--r--test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java76
-rw-r--r--test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java61
-rw-r--r--test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java89
-rw-r--r--test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java102
-rw-r--r--test/java/org/apache/fop/afp/AFPTestSuite.java39
-rw-r--r--test/java/org/apache/fop/afp/expected_named_resource.afpbin0 -> 21494 bytes
-rw-r--r--test/java/org/apache/fop/afp/expected_resource.afpbin0 -> 21511 bytes
-rw-r--r--test/java/org/apache/fop/afp/fonts/CharactersetEncoderTestCase.java116
-rw-r--r--test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java72
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java251
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java64
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java63
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java160
-rw-r--r--test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java134
-rw-r--r--test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java245
-rw-r--r--test/java/org/apache/fop/afp/simple.fo14
-rw-r--r--test/java/org/apache/fop/area/BlockViewportTestCase.java47
-rw-r--r--test/java/org/apache/fop/area/RegionViewportTestCase.java54
-rw-r--r--test/java/org/apache/fop/area/ViewportTest.java43
-rw-r--r--test/java/org/apache/fop/area/ViewportTestSuite.java37
-rw-r--r--test/java/org/apache/fop/area/inline/InlineViewportTestCase.java49
-rw-r--r--test/java/org/apache/fop/check/Check.java27
-rw-r--r--test/java/org/apache/fop/check/ChecksFactory.java97
-rw-r--r--test/java/org/apache/fop/check/package-info.java25
-rw-r--r--test/java/org/apache/fop/complexscripts/ComplexScriptsTestSuite.java42
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java265
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java58
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD0.serbin0 -> 87 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.serbin0 -> 119 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.serbin0 -> 359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.serbin0 -> 11343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.serbin0 -> 5103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.serbin0 -> 1263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.serbin0 -> 16943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.serbin0 -> 22043 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.serbin0 -> 10463 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.serbin0 -> 12883 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.serbin0 -> 12143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.serbin0 -> 9343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.serbin0 -> 6143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.serbin0 -> 275 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.serbin0 -> 1903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.serbin0 -> 13015 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.serbin0 -> 2647 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.serbin0 -> 1351 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.serbin0 -> 58383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.serbin0 -> 2359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.serbin0 -> 919 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.serbin0 -> 631 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.serbin0 -> 13023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.serbin0 -> 95 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.serbin0 -> 1351 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.serbin0 -> 6543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.serbin0 -> 28143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.serbin0 -> 22743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.serbin0 -> 23823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.serbin0 -> 2223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.serbin0 -> 29583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.serbin0 -> 3511 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.serbin0 -> 12123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.serbin0 -> 18423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.serbin0 -> 14103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.serbin0 -> 9243 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.serbin0 -> 2103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.serbin0 -> 151 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.serbin0 -> 10143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.serbin0 -> 1127 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.serbin0 -> 823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.serbin0 -> 13015 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.serbin0 -> 3799 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.serbin0 -> 58383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.serbin0 -> 551 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.serbin0 -> 3687 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.serbin0 -> 1943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.serbin0 -> 18783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.serbin0 -> 5343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.serbin0 -> 32223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.serbin0 -> 25383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.serbin0 -> 20583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.serbin0 -> 4383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.serbin0 -> 5983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.serbin0 -> 31623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.serbin0 -> 15123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.serbin0 -> 17963 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.serbin0 -> 15863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.serbin0 -> 7623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.serbin0 -> 1863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.serbin0 -> 155 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.serbin0 -> 1335 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.serbin0 -> 151 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.serbin0 -> 5823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.serbin0 -> 311 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.serbin0 -> 3735 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.serbin0 -> 935 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.serbin0 -> 16623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.serbin0 -> 1975 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.serbin0 -> 5239 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.serbin0 -> 1303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.serbin0 -> 10143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.serbin0 -> 10503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.serbin0 -> 9903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.serbin0 -> 6903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.serbin0 -> 3183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.serbin0 -> 10283 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.serbin0 -> 6223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.serbin0 -> 239 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.serbin0 -> 6283 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.serbin0 -> 5383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.serbin0 -> 2583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.serbin0 -> 21423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.serbin0 -> 6423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.serbin0 -> 4623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.serbin0 -> 14943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.serbin0 -> 1127 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.serbin0 -> 8163 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.serbin0 -> 9183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.serbin0 -> 2263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.serbin0 -> 1403 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.serbin0 -> 7503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.serbin0 -> 41343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.serbin0 -> 11103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.serbin0 -> 2343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.serbin0 -> 119 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.serbin0 -> 359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.serbin0 -> 10323 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.serbin0 -> 20803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.serbin0 -> 16803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.serbin0 -> 15183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.serbin0 -> 4583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.serbin0 -> 903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.serbin0 -> 6783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.serbin0 -> 11703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.serbin0 -> 5239 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.serbin0 -> 25023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.serbin0 -> 1983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.serbin0 -> 11423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.serbin0 -> 13183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.serbin0 -> 9603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.serbin0 -> 10263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.serbin0 -> 8543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.serbin0 -> 823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.serbin0 -> 443 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.serbin0 -> 155 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.serbin0 -> 4623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.serbin0 -> 1263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.serbin0 -> 20703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.serbin0 -> 1063 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.serbin0 -> 9803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.serbin0 -> 1563 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.serbin0 -> 4183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.serbin0 -> 7863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.serbin0 -> 359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.serbin0 -> 7363 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.serbin0 -> 1623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.serbin0 -> 2343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.serbin0 -> 1983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.serbin0 -> 563 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.serbin0 -> 2043 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.serbin0 -> 443 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.serbin0 -> 215 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.serbin0 -> 1803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.serbin0 -> 1243 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.serbin0 -> 323 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.serbin0 -> 17823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.serbin0 -> 3963 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.serbin0 -> 3383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.serbin0 -> 1623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.serbin0 -> 1083 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.serbin0 -> 1783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.serbin0 -> 5683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.serbin0 -> 27783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.serbin0 -> 6623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.serbin0 -> 1883 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.serbin0 -> 1783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.serbin0 -> 903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.serbin0 -> 7143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.serbin0 -> 8303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.serbin0 -> 2551 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.serbin0 -> 19743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.serbin0 -> 1663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.serbin0 -> 863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.serbin0 -> 4743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.serbin0 -> 5523 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.serbin0 -> 1063 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.serbin0 -> 23903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.serbin0 -> 3683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.serbin0 -> 3123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.serbin0 -> 5223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.serbin0 -> 4183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.serbin0 -> 2643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.serbin0 -> 15503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.serbin0 -> 1343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.serbin0 -> 703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.serbin0 -> 2583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.serbin0 -> 863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.serbin0 -> 7183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.serbin0 -> 1303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.serbin0 -> 2551 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.serbin0 -> 903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.serbin0 -> 87543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.serbin0 -> 19503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.serbin0 -> 9783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.serbin0 -> 51903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.serbin0 -> 34083 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.serbin0 -> 1879 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.serbin0 -> 35703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.serbin0 -> 1683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.serbin0 -> 15183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.serbin0 -> 6543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.serbin0 -> 4383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.serbin0 -> 10143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.serbin0 -> 8343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.serbin0 -> 8703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.serbin0 -> 63 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.serbin0 -> 439 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.serbin0 -> 8703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.serbin0 -> 2223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.serbin0 -> 2223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.serbin0 -> 5463 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.serbin0 -> 3843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.serbin0 -> 4383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.serbin0 -> 243 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.serbin0 -> 36783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.serbin0 -> 2679 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.serbin0 -> 9603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.serbin0 -> 6903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.serbin0 -> 243 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.serbin0 -> 15003 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.serbin0 -> 32103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.serbin0 -> 5643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.serbin0 -> 14103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.serbin0 -> 3843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.serbin0 -> 33183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.serbin0 -> 3495 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.serbin0 -> 1863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.serbin0 -> 603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.serbin0 -> 1943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.serbin0 -> 13743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.serbin0 -> 7903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.serbin0 -> 1743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.serbin0 -> 5303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.serbin0 -> 623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.serbin0 -> 5103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.serbin0 -> 87543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.serbin0 -> 2119 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.serbin0 -> 28143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.serbin0 -> 4063 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.serbin0 -> 57343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.serbin0 -> 37923 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.serbin0 -> 30843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.serbin0 -> 6543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.serbin0 -> 24183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.serbin0 -> 14223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.serbin0 -> 2263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.serbin0 -> 1559 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.serbin0 -> 16743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.serbin0 -> 13863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.serbin0 -> 9943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.serbin0 -> 2143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.serbin0 -> 6143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.serbin0 -> 1063 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.serbin0 -> 1103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.serbin0 -> 4023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.serbin0 -> 727 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.serbin0 -> 43423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.serbin0 -> 13403 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.serbin0 -> 3483 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.serbin0 -> 3703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.serbin0 -> 19003 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.serbin0 -> 35223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.serbin0 -> 215 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.serbin0 -> 10323 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.serbin0 -> 1863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.serbin0 -> 31023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.serbin0 -> 4923 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.serbin0 -> 2223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.serbin0 -> 3483 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.serbin0 -> 8703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.serbin0 -> 25983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.serbin0 -> 4863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.serbin0 -> 1323 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.serbin0 -> 3083 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.serbin0 -> 223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.serbin0 -> 1743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.serbin0 -> 24903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.serbin0 -> 6663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.serbin0 -> 7831 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.serbin0 -> 16843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.serbin0 -> 8803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.serbin0 -> 8603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.serbin0 -> 1803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.serbin0 -> 1983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.serbin0 -> 12783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.serbin0 -> 9423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.serbin0 -> 1263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.serbin0 -> 9223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.serbin0 -> 479 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.serbin0 -> 1783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.serbin0 -> 9763 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.serbin0 -> 5583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.serbin0 -> 1283 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.serbin0 -> 3743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.serbin0 -> 643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.serbin0 -> 583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.serbin0 -> 83 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.serbin0 -> 1723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.serbin0 -> 14023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.serbin0 -> 919 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.serbin0 -> 3743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.serbin0 -> 1203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.serbin0 -> 1983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.serbin0 -> 8263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.serbin0 -> 13423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.serbin0 -> 3483 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.serbin0 -> 4663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.serbin0 -> 10383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.serbin0 -> 1683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.serbin0 -> 123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.serbin0 -> 1203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.serbin0 -> 33423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.serbin0 -> 7223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.serbin0 -> 3079 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.serbin0 -> 4103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.serbin0 -> 6843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.serbin0 -> 5543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.serbin0 -> 1963 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.serbin0 -> 4503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.serbin0 -> 1123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.serbin0 -> 4383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.serbin0 -> 3223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.serbin0 -> 223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.serbin0 -> 123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.serbin0 -> 7223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.serbin0 -> 3363 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.serbin0 -> 723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.serbin0 -> 11943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.serbin0 -> 66583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.serbin0 -> 13783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.serbin0 -> 823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.serbin0 -> 223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.serbin0 -> 2683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.serbin0 -> 12803 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.serbin0 -> 10183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.serbin0 -> 199 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.serbin0 -> 223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.serbin0 -> 1203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.serbin0 -> 3503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.serbin0 -> 603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.serbin0 -> 443 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.serbin0 -> 38943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.serbin0 -> 5663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.serbin0 -> 723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.serbin0 -> 3343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.serbin0 -> 203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.serbin0 -> 1723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.serbin0 -> 14103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.serbin0 -> 6163 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.serbin0 -> 343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.serbin0 -> 203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.serbin0 -> 1399 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.serbin0 -> 11583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.serbin0 -> 16383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.serbin0 -> 37903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.serbin0 -> 2623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.serbin0 -> 1343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.serbin0 -> 1663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.serbin0 -> 703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.serbin0 -> 7831 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.serbin0 -> 2343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.serbin0 -> 695 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.serbin0 -> 2551 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.serbin0 -> 3123 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.serbin0 -> 563 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.serbin0 -> 1543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.serbin0 -> 10383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.serbin0 -> 951 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.serbin0 -> 33983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.serbin0 -> 4363 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.serbin0 -> 1683 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.serbin0 -> 443 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.serbin0 -> 2863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.serbin0 -> 2423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.serbin0 -> 203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.serbin0 -> 5207 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.serbin0 -> 83 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.serbin0 -> 543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.serbin0 -> 203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.serbin0 -> 523 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.serbin0 -> 1043 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.serbin0 -> 143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.serbin0 -> 3431 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.serbin0 -> 1203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.serbin0 -> 3183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.serbin0 -> 1703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.serbin0 -> 2791 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.serbin0 -> 1723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.serbin0 -> 145863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.serbin0 -> 29223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.serbin0 -> 14643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.serbin0 -> 25983 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.serbin0 -> 9783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.serbin0 -> 6543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.serbin0 -> 14643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.serbin0 -> 631 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.serbin0 -> 23103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.serbin0 -> 8703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.serbin0 -> 6903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.serbin0 -> 5643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.serbin0 -> 5643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.serbin0 -> 2583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.serbin0 -> 14463 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.serbin0 -> 38943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.serbin0 -> 1143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.serbin0 -> 603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.serbin0 -> 1503 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.serbin0 -> 3303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.serbin0 -> 783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.serbin0 -> 963 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.serbin0 -> 21183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.serbin0 -> 1423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.serbin0 -> 823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.serbin0 -> 823 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.serbin0 -> 1343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.serbin0 -> 843 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.serbin0 -> 1043 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.serbin0 -> 7743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.serbin0 -> 863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.serbin0 -> 743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.serbin0 -> 2263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.serbin0 -> 6143 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.serbin0 -> 145863 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.serbin0 -> 42323 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.serbin0 -> 4883 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.serbin0 -> 41063 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.serbin0 -> 21023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.serbin0 -> 5003 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.serbin0 -> 1343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.serbin0 -> 1399 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.serbin0 -> 40263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.serbin0 -> 9643 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.serbin0 -> 2203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.serbin0 -> 20403 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.serbin0 -> 13163 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.serbin0 -> 14463 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.serbin0 -> 1343 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.serbin0 -> 703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.serbin0 -> 1023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.serbin0 -> 695 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.serbin0 -> 535 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.serbin0 -> 423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.serbin0 -> 603 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.serbin0 -> 2623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.serbin0 -> 383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.serbin0 -> 2623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.serbin0 -> 41463 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.serbin0 -> 10583 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.serbin0 -> 1735 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.serbin0 -> 1403 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.serbin0 -> 9723 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.serbin0 -> 5203 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.serbin0 -> 3263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.serbin0 -> 303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.serbin0 -> 703 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.serbin0 -> 21263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.serbin0 -> 5303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.serbin0 -> 963 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.serbin0 -> 1367 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.serbin0 -> 13383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.serbin0 -> 9623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.serbin0 -> 967 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.serbin0 -> 247 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.serbin0 -> 13023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.serbin0 -> 3319 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.serbin0 -> 903 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.serbin0 -> 663 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.serbin0 -> 87 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.serbin0 -> 263 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.serbin0 -> 71 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.serbin0 -> 18783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.serbin0 -> 1383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.serbin0 -> 5975 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.serbin0 -> 1527 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.serbin0 -> 359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.serbin0 -> 119 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.serbin0 -> 31023 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.serbin0 -> 1303 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.serbin0 -> 1975 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.serbin0 -> 431 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.serbin0 -> 3383 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.serbin0 -> 311 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.serbin0 -> 183 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.serbin0 -> 18783 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.serbin0 -> 151 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.serbin0 -> 967 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.serbin0 -> 215 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.serbin0 -> 2807 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.serbin0 -> 487 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.serbin0 -> 13743 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.serbin0 -> 635 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.serbin0 -> 247 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.serbin0 -> 151 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.serbin0 -> 359 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.serbin0 -> 311 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.serbin0 -> 2943 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.serbin0 -> 15423 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.serbin0 -> 21543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.serbin0 -> 14223 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.serbin0 -> 15543 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.serbin0 -> 4191 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.serbin0 -> 39 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.serbin0 -> 199 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.serbin0 -> 79 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.serbin0 -> 135 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.serbin0 -> 1623 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.serbin0 -> 127 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.serbin0 -> 71 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.serbin0 -> 55 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.serbin0 -> 95 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.serbin0 -> 1495 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.serbin0 -> 39 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.serbin0 -> 407 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.serbin0 -> 199 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.serbin0 -> 39 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.serbin0 -> 39 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.serbin0 -> 39 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.serbin0 -> 119 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.serbin0 -> 103 bytes
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java74
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestSuite.java35
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java39
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java3177
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java473
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java2266
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java3450
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFileTestCase.java52
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java36
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java195
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java49
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java179
-rw-r--r--test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java1564
-rw-r--r--test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java34
-rw-r--r--test/java/org/apache/fop/config/BaseConstructiveUserConfigTest.java (renamed from test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java)15
-rw-r--r--test/java/org/apache/fop/config/BaseDestructiveUserConfigTest.java (renamed from test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java)17
-rw-r--r--test/java/org/apache/fop/config/BaseUserConfigTest.java (renamed from test/java/org/apache/fop/config/BaseUserConfigTestCase.java)23
-rw-r--r--test/java/org/apache/fop/config/FOURIResolverTestCase.java8
-rw-r--r--test/java/org/apache/fop/config/FontAttributesMissingTestCase.java12
-rw-r--r--test/java/org/apache/fop/config/FontBaseBadTestCase.java10
-rw-r--r--test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java10
-rw-r--r--test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java10
-rw-r--r--test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java15
-rw-r--r--test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java12
-rw-r--r--test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java12
-rw-r--r--test/java/org/apache/fop/config/FontsAutoDetectTestCase.java10
-rw-r--r--test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java10
-rw-r--r--test/java/org/apache/fop/config/FontsSubstitutionTestCase.java21
-rw-r--r--test/java/org/apache/fop/config/UserConfigTestSuite.java42
-rw-r--r--test/java/org/apache/fop/datatypes/URISpecificationTestCase.java8
-rw-r--r--test/java/org/apache/fop/events/BasicEventTestCase.java11
-rw-r--r--test/java/org/apache/fop/events/EventChecker.java10
-rw-r--r--test/java/org/apache/fop/events/EventProcessingTestCase.java80
-rw-r--r--test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java531
-rw-r--r--test/java/org/apache/fop/fo/FODocumentParser.java161
-rw-r--r--test/java/org/apache/fop/fo/FONodeMocks.java88
-rw-r--r--test/java/org/apache/fop/fo/LoadingException.java (renamed from test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java)24
-rw-r--r--test/java/org/apache/fop/fo/complete_document.fo176
-rw-r--r--test/java/org/apache/fop/fo/extract-events.xsl62
-rw-r--r--test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java (renamed from test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java)28
-rw-r--r--test/java/org/apache/fop/fo/flow/table/AllTests.java37
-rw-r--r--test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java12
-rw-r--r--test/java/org/apache/fop/fo/flow/table/ErrorCheckTest.java (renamed from test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java)15
-rw-r--r--test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java12
-rw-r--r--test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java21
-rw-r--r--test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java12
-rw-r--r--test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java13
-rw-r--r--test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java38
-rw-r--r--test/java/org/apache/fop/fo/pagination/AllTests.java33
-rw-r--r--test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java161
-rw-r--r--test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java169
-rw-r--r--test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java77
-rw-r--r--test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java128
-rw-r--r--test/java/org/apache/fop/fo/properties/PropertyListMocks.java94
-rw-r--r--test/java/org/apache/fop/fo/properties/PropertyMocks.java80
-rw-r--r--test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java (renamed from test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java)13
-rw-r--r--test/java/org/apache/fop/fonts/EncodingModeTestCase.java41
-rw-r--r--test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java70
-rw-r--r--test/java/org/apache/fop/fonts/substituted-font.fo14
-rw-r--r--test/java/org/apache/fop/fonts/svg-fonts.fo37
-rw-r--r--test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java198
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java59
-rw-r--r--test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java131
-rw-r--r--test/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.txt213
-rw-r--r--test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java84
-rw-r--r--test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java85
-rw-r--r--test/java/org/apache/fop/fonts/type1/adobe-charset_adobe-encoding.afm158
-rw-r--r--test/java/org/apache/fop/fonts/type1/adobe-charset_unknown-encoding.afm158
-rw-r--r--test/java/org/apache/fop/fonts/type1/notadobe-charset_adobe-encoding.afm158
-rw-r--r--test/java/org/apache/fop/fonts/type1/notadobe-charset_unknown-encoding.afm158
-rw-r--r--test/java/org/apache/fop/fotreetest/FOTreeTestCase.java171
-rw-r--r--test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java129
-rw-r--r--test/java/org/apache/fop/fotreetest/FOTreeTester.java126
-rw-r--r--test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java99
-rw-r--r--test/java/org/apache/fop/fotreetest/ResultCollector.java5
-rw-r--r--test/java/org/apache/fop/fotreetest/ext/AssertElement.java2
-rw-r--r--test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java2
-rw-r--r--test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java19
-rw-r--r--test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java31
-rw-r--r--test/java/org/apache/fop/intermediate/AbstractIFTest.java153
-rw-r--r--test/java/org/apache/fop/intermediate/AbstractIntermediateTest.java (renamed from test/java/org/apache/fop/intermediate/AbstractIntermediateTestCase.java)55
-rw-r--r--test/java/org/apache/fop/intermediate/AreaTreeParserTestCase.java49
-rw-r--r--test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java49
-rw-r--r--test/java/org/apache/fop/intermediate/IFCheck.java4
-rw-r--r--test/java/org/apache/fop/intermediate/IFChecksFactory.java49
-rw-r--r--test/java/org/apache/fop/intermediate/IFMimickingTestCase.java15
-rw-r--r--test/java/org/apache/fop/intermediate/IFParserTestCase.java151
-rw-r--r--test/java/org/apache/fop/intermediate/IFTestCase.java116
-rw-r--r--test/java/org/apache/fop/intermediate/IFTester.java153
-rw-r--r--test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java53
-rw-r--r--test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java32
-rw-r--r--test/java/org/apache/fop/intermediate/TestAssistant.java (renamed from test/java/org/apache/fop/layoutengine/TestEnvironment.java)27
-rw-r--r--test/java/org/apache/fop/layoutengine/ElementListCollector.java2
-rw-r--r--test/java/org/apache/fop/layoutengine/EvalCheck.java10
-rw-r--r--test/java/org/apache/fop/layoutengine/HyphenationLayoutTestCase.java53
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java4
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineChecksFactory.java62
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java260
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java200
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java203
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTester.java226
-rw-r--r--test/java/org/apache/fop/layoutengine/ResultCheck.java19
-rw-r--r--test/java/org/apache/fop/layoutengine/TestFilesConfiguration.java205
-rw-r--r--test/java/org/apache/fop/layoutengine/TrueCheck.java8
-rw-r--r--test/java/org/apache/fop/layoutmgr/PageSequenceLayoutManagerTestCase.java118
-rw-r--r--test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java92
-rw-r--r--test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java126
-rw-r--r--test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java113
-rw-r--r--test/java/org/apache/fop/pdf/ObjectStreamTestCase.java131
-rw-r--r--test/java/org/apache/fop/pdf/PDFArrayTestCase.java237
-rw-r--r--test/java/org/apache/fop/pdf/PDFDestsTestCase.java64
-rw-r--r--test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java135
-rw-r--r--test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java93
-rw-r--r--test/java/org/apache/fop/pdf/PDFDocumentTestCase.java62
-rw-r--r--test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java503
-rw-r--r--test/java/org/apache/fop/pdf/PDFFactoryTestCase.java60
-rw-r--r--test/java/org/apache/fop/pdf/PDFFilterListTestCase.java33
-rw-r--r--test/java/org/apache/fop/pdf/PDFLibraryTestSuite.java48
-rw-r--r--test/java/org/apache/fop/pdf/PDFNameTestCase.java169
-rw-r--r--test/java/org/apache/fop/pdf/PDFNullTestCase.java49
-rw-r--r--test/java/org/apache/fop/pdf/PDFNumberTestCase.java (renamed from test/java/org/apache/fop/util/PDFNumberTestCase.java)56
-rw-r--r--test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java54
-rw-r--r--test/java/org/apache/fop/pdf/PDFObjectTestCase.java168
-rw-r--r--test/java/org/apache/fop/pdf/PDFRectangleTestCase.java52
-rw-r--r--test/java/org/apache/fop/pdf/PDFReferenceTestCase.java64
-rw-r--r--test/java/org/apache/fop/pdf/PDFStreamTestCase.java126
-rw-r--r--test/java/org/apache/fop/pdf/VersionControllerTestCase.java143
-rw-r--r--test/java/org/apache/fop/pdf/VersionTestCase.java89
-rw-r--r--test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java50
-rw-r--r--test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java106
-rw-r--r--test/java/org/apache/fop/pdf/xref/CrossReferenceStreamTestCase.java142
-rw-r--r--test/java/org/apache/fop/pdf/xref/CrossReferenceTableTestCase.java80
-rw-r--r--test/java/org/apache/fop/pdf/xref/ObjectReferenceTest.java62
-rw-r--r--test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java90
-rw-r--r--test/java/org/apache/fop/render/AbstractRenderingTest.java103
-rw-r--r--test/java/org/apache/fop/render/RendererFactoryTestCase.java (renamed from test/java/org/apache/fop/render/RendererFactoryTest.java)11
-rw-r--r--test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java92
-rw-r--r--test/java/org/apache/fop/render/afp/AFPTestSuite.java34
-rw-r--r--test/java/org/apache/fop/render/afp/AbstractAFPTest.java47
-rw-r--r--test/java/org/apache/fop/render/afp/NoOperationTestCase.java125
-rw-r--r--test/java/org/apache/fop/render/afp/nops.fo41
-rw-r--r--test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java (renamed from test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTest.java)31
-rw-r--r--test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java (renamed from test/java/org/apache/fop/render/extensions/prepress/PageScaleTest.java)28
-rw-r--r--test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java169
-rw-r--r--test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java131
-rw-r--r--test/java/org/apache/fop/render/pdf/BasePDFTest.java (renamed from test/java/org/apache/fop/render/pdf/BasePDFTestCase.java)12
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java16
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java19
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFRendererConfiguratorTestCase.java153
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java14
-rw-r--r--test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java33
-rw-r--r--test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java (renamed from test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java)56
-rw-r--r--test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java12
-rw-r--r--test/java/org/apache/fop/render/ps/PSTestSuite.java35
-rw-r--r--test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java12
-rw-r--r--test/java/org/apache/fop/render/rtf/Bug39607TestCase.java6
-rw-r--r--test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java20
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java2
-rw-r--r--test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java (renamed from test/java/org/apache/fop/text/linebreak/LineBreakStatusTest.java)36
-rw-r--r--test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java (renamed from test/java/org/apache/fop/text/linebreak/LineBreakUtilsTest.java)18
-rw-r--r--test/java/org/apache/fop/threading/AvalonAdapter.java2
-rw-r--r--test/java/org/apache/fop/threading/FOPTestbed.java2
-rw-r--r--test/java/org/apache/fop/threading/FOProcessorImpl.java2
-rw-r--r--test/java/org/apache/fop/threading/IFProcessorImpl.java2
-rw-r--r--test/java/org/apache/fop/threading/Main.java2
-rw-r--r--test/java/org/apache/fop/threading/Processor.java2
-rw-r--r--test/java/org/apache/fop/traits/BorderPropsTestCase.java18
-rw-r--r--test/java/org/apache/fop/traits/MinOptMaxTestCase.java (renamed from test/java/org/apache/fop/traits/MinOptMaxTest.java)31
-rw-r--r--test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java15
-rw-r--r--test/java/org/apache/fop/util/BitmapImageUtilTestCase.java166
-rw-r--r--test/java/org/apache/fop/util/ColorUtilTestCase.java193
-rw-r--r--test/java/org/apache/fop/util/ConsoleEventListenerForTests.java2
-rw-r--r--test/java/org/apache/fop/util/ElementListUtilsTestCase.java16
-rw-r--r--test/java/org/apache/fop/util/LanguageTagsTestCase.java58
-rw-r--r--test/java/org/apache/fop/util/XMLResourceBundleTestCase.java9
-rw-r--r--test/java/org/apache/fop/util/XMLUtilTestCase.java45
-rw-r--r--test/java/org/apache/fop/visual/BatchDiffer.java20
-rw-r--r--test/java/org/apache/fop/visual/StreamRedirector.java2
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
new file mode 100644
index 000000000..9fe45c388
--- /dev/null
+++ b/test/java/org/apache/fop/afp/expected_named_resource.afp
Binary files differ
diff --git a/test/java/org/apache/fop/afp/expected_resource.afp b/test/java/org/apache/fop/afp/expected_resource.afp
new file mode 100644
index 000000000..a98ac0e5e
--- /dev/null
+++ b/test/java/org/apache/fop/afp/expected_resource.afp
Binary files differ
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
new file mode 100644
index 000000000..6eccb4b6f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD0.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser
new file mode 100644
index 000000000..8a7a802d2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD1.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser
new file mode 100644
index 000000000..74a52f212
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD10.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser
new file mode 100644
index 000000000..4058da121
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD100.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser
new file mode 100644
index 000000000..321ed2682
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD101.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser
new file mode 100644
index 000000000..f5e3973dd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD102.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser
new file mode 100644
index 000000000..0235952c9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD103.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser
new file mode 100644
index 000000000..00d9ff6b4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD104.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser
new file mode 100644
index 000000000..b924c8d19
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD105.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser
new file mode 100644
index 000000000..2cdabbf17
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD106.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser
new file mode 100644
index 000000000..24e41ceab
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD107.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser
new file mode 100644
index 000000000..8c9d014f2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD108.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser
new file mode 100644
index 000000000..fc2fc255e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD109.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser
new file mode 100644
index 000000000..2a40fe758
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD11.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser
new file mode 100644
index 000000000..89ef3a341
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD110.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser
new file mode 100644
index 000000000..0691f5f96
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD111.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser
new file mode 100644
index 000000000..c3bd6103e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD112.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser
new file mode 100644
index 000000000..54d27e213
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD113.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser
new file mode 100644
index 000000000..0ba52993a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD114.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser
new file mode 100644
index 000000000..0b95e6283
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD115.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser
new file mode 100644
index 000000000..ca1111447
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD116.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser
new file mode 100644
index 000000000..fbce0f949
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD117.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser
new file mode 100644
index 000000000..c7bee5162
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD118.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser
new file mode 100644
index 000000000..83ad166ef
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD119.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser
new file mode 100644
index 000000000..81ff5dcbd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD12.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser
new file mode 100644
index 000000000..2a84369ef
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD120.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser
new file mode 100644
index 000000000..3c3f08edf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD121.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser
new file mode 100644
index 000000000..81a342bc0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD122.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser
new file mode 100644
index 000000000..f2fdba316
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD123.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser
new file mode 100644
index 000000000..5bebb054f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD124.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser
new file mode 100644
index 000000000..1292a8a01
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD125.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser
new file mode 100644
index 000000000..f7c910fb0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD126.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser
new file mode 100644
index 000000000..bb2d2353a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD127.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser
new file mode 100644
index 000000000..4ef886527
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD128.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser
new file mode 100644
index 000000000..7538307f8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD129.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser
new file mode 100644
index 000000000..5a81f8f76
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD13.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser
new file mode 100644
index 000000000..dfa56bb42
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD130.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser
new file mode 100644
index 000000000..04c0e6b02
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD131.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser
new file mode 100644
index 000000000..5389ec53c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD132.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser
new file mode 100644
index 000000000..6ec49f1c7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD133.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser
new file mode 100644
index 000000000..381b6b741
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD134.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser
new file mode 100644
index 000000000..e991a278f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD135.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser
new file mode 100644
index 000000000..84eb27fa3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD136.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser
new file mode 100644
index 000000000..3e3ceb4f0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD137.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser
new file mode 100644
index 000000000..52f01ebbf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD138.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser
new file mode 100644
index 000000000..54a66ac43
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD139.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser
new file mode 100644
index 000000000..5bad9fe23
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD14.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser
new file mode 100644
index 000000000..7e58aea97
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD140.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser
new file mode 100644
index 000000000..60811580c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD141.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser
new file mode 100644
index 000000000..bfa39bf75
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD142.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser
new file mode 100644
index 000000000..5df598aa7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD143.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser
new file mode 100644
index 000000000..f46f6a289
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD144.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser
new file mode 100644
index 000000000..825930ea8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD145.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser
new file mode 100644
index 000000000..3d2efe600
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD146.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser
new file mode 100644
index 000000000..5e3667df8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD147.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser
new file mode 100644
index 000000000..4a04343a5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD148.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser
new file mode 100644
index 000000000..85260e0f8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD149.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser
new file mode 100644
index 000000000..c1cb2878d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD15.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser
new file mode 100644
index 000000000..ab5dd0c00
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD150.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser
new file mode 100644
index 000000000..df304a84b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD151.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser
new file mode 100644
index 000000000..887699163
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD152.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser
new file mode 100644
index 000000000..fa70ead76
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD153.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser
new file mode 100644
index 000000000..73402d898
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD154.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser
new file mode 100644
index 000000000..c611d952e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD155.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser
new file mode 100644
index 000000000..a5a70cf81
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD156.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser
new file mode 100644
index 000000000..736576c15
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD157.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser
new file mode 100644
index 000000000..4667a5a4a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD158.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser
new file mode 100644
index 000000000..9a07236c3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD159.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser
new file mode 100644
index 000000000..6a8e667fb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD16.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser
new file mode 100644
index 000000000..abfeac3ec
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD160.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser
new file mode 100644
index 000000000..1b225c825
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD161.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser
new file mode 100644
index 000000000..36aab1fd1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD162.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser
new file mode 100644
index 000000000..77a744263
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD163.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser
new file mode 100644
index 000000000..6f340e971
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD164.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser
new file mode 100644
index 000000000..92ab48e50
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD165.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser
new file mode 100644
index 000000000..412885433
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD166.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser
new file mode 100644
index 000000000..3b4b83607
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD167.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser
new file mode 100644
index 000000000..3e04f60f7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD168.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser
new file mode 100644
index 000000000..5e58d00f8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD169.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser
new file mode 100644
index 000000000..290d0e5b4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD17.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser
new file mode 100644
index 000000000..fb1f6b7ae
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD170.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser
new file mode 100644
index 000000000..7ba80984d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD171.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser
new file mode 100644
index 000000000..594645bdc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD172.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser
new file mode 100644
index 000000000..5d995d076
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD173.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser
new file mode 100644
index 000000000..e57c46d8e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD174.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser
new file mode 100644
index 000000000..ad4317529
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD175.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser
new file mode 100644
index 000000000..52cdcd567
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD176.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser
new file mode 100644
index 000000000..e786ab17e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD177.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser
new file mode 100644
index 000000000..2f9e41f08
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD178.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser
new file mode 100644
index 000000000..94f739223
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD179.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser
new file mode 100644
index 000000000..53073211e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD18.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser
new file mode 100644
index 000000000..172498f80
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD180.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser
new file mode 100644
index 000000000..c5a9b434d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD181.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser
new file mode 100644
index 000000000..1c98e34a4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD182.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser
new file mode 100644
index 000000000..4e8c8e30c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD183.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser
new file mode 100644
index 000000000..824fad23d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD184.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser
new file mode 100644
index 000000000..969e34a37
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD185.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser
new file mode 100644
index 000000000..0867d2e55
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD186.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser
new file mode 100644
index 000000000..dd052d7a1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD187.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser
new file mode 100644
index 000000000..d52c97d1d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD188.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser
new file mode 100644
index 000000000..2bdb9dab4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD189.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser
new file mode 100644
index 000000000..21128bf86
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD19.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser
new file mode 100644
index 000000000..d153d3442
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD190.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser
new file mode 100644
index 000000000..5019d6fea
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD191.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser
new file mode 100644
index 000000000..e726e2651
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD192.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser
new file mode 100644
index 000000000..c37e1cdd0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD193.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser
new file mode 100644
index 000000000..1ba7b2877
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD194.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser
new file mode 100644
index 000000000..62215ed07
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD195.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser
new file mode 100644
index 000000000..709279994
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD196.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser
new file mode 100644
index 000000000..788ac372f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD197.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser
new file mode 100644
index 000000000..9d4a14249
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD198.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser
new file mode 100644
index 000000000..6cbb79535
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD199.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser
new file mode 100644
index 000000000..05cf07859
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD2.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser
new file mode 100644
index 000000000..9c10e367c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD20.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser
new file mode 100644
index 000000000..583084f0b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD200.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser
new file mode 100644
index 000000000..d8ed032c6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD201.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser
new file mode 100644
index 000000000..21e97fff0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD202.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser
new file mode 100644
index 000000000..5e3e01293
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD203.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser
new file mode 100644
index 000000000..eba9874c5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD204.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser
new file mode 100644
index 000000000..182c5fc35
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD205.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser
new file mode 100644
index 000000000..47ed04ba6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD206.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser
new file mode 100644
index 000000000..b56f3ee7c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD207.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser
new file mode 100644
index 000000000..302b20c39
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD208.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser
new file mode 100644
index 000000000..c97cbbe12
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD209.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser
new file mode 100644
index 000000000..e7eb886be
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD21.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser
new file mode 100644
index 000000000..4da33f6c0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD210.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser
new file mode 100644
index 000000000..46f29b71a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD211.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser
new file mode 100644
index 000000000..b84d2efaa
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD212.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser
new file mode 100644
index 000000000..2d0995a6f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD213.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser
new file mode 100644
index 000000000..66a505aae
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD214.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser
new file mode 100644
index 000000000..cbd99924e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD215.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser
new file mode 100644
index 000000000..46b5315a0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD216.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser
new file mode 100644
index 000000000..4afc67dbc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD217.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser
new file mode 100644
index 000000000..992177ded
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD218.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser
new file mode 100644
index 000000000..e75b1d344
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD219.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser
new file mode 100644
index 000000000..ca7478b6c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD22.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser
new file mode 100644
index 000000000..3f754847c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD220.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser
new file mode 100644
index 000000000..02efa8786
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD221.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser
new file mode 100644
index 000000000..1897b09f8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD222.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser
new file mode 100644
index 000000000..cd24d1101
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD223.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser
new file mode 100644
index 000000000..aba011dba
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD224.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser
new file mode 100644
index 000000000..dad463960
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD225.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser
new file mode 100644
index 000000000..6430967e4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD226.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser
new file mode 100644
index 000000000..4f2bde014
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD227.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser
new file mode 100644
index 000000000..7be09ec92
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD228.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser
new file mode 100644
index 000000000..6ffa285db
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD229.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser
new file mode 100644
index 000000000..d6c532596
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD23.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser
new file mode 100644
index 000000000..3519adb5e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD230.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser
new file mode 100644
index 000000000..7540663aa
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD231.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser
new file mode 100644
index 000000000..788e4c7e1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD232.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser
new file mode 100644
index 000000000..c36265614
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD233.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser
new file mode 100644
index 000000000..772b72aef
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD234.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser
new file mode 100644
index 000000000..e5fa50b85
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD235.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser
new file mode 100644
index 000000000..13fdb364c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD236.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser
new file mode 100644
index 000000000..c600524d6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD237.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser
new file mode 100644
index 000000000..6043e0155
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD238.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser
new file mode 100644
index 000000000..14250a315
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD239.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser
new file mode 100644
index 000000000..209e8179e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD24.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser
new file mode 100644
index 000000000..bdbc02f69
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD240.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser
new file mode 100644
index 000000000..d3f40a8de
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD241.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser
new file mode 100644
index 000000000..03b94bc76
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD242.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser
new file mode 100644
index 000000000..cb0321933
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD243.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser
new file mode 100644
index 000000000..3cdc87c9c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD244.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser
new file mode 100644
index 000000000..7c50f1284
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD245.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser
new file mode 100644
index 000000000..b04164e4c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD246.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser
new file mode 100644
index 000000000..bdce40f9c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD247.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser
new file mode 100644
index 000000000..e50ed7988
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD248.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser
new file mode 100644
index 000000000..14ac62043
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD249.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser
new file mode 100644
index 000000000..c1b31fcce
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD25.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser
new file mode 100644
index 000000000..d96343972
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD250.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser
new file mode 100644
index 000000000..7b3168b23
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD251.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser
new file mode 100644
index 000000000..7f9b9056d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD252.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser
new file mode 100644
index 000000000..d5849ec9d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD253.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser
new file mode 100644
index 000000000..00a2b4a0e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD254.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser
new file mode 100644
index 000000000..5cc330f12
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD255.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser
new file mode 100644
index 000000000..23e032ac9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD256.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser
new file mode 100644
index 000000000..7ba16c21a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD257.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser
new file mode 100644
index 000000000..334737ecd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD258.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser
new file mode 100644
index 000000000..26defabff
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD259.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser
new file mode 100644
index 000000000..09dc4ca08
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD26.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser
new file mode 100644
index 000000000..03cb82426
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD260.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser
new file mode 100644
index 000000000..6d00960cf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD261.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser
new file mode 100644
index 000000000..920e4c5b1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD262.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser
new file mode 100644
index 000000000..dbbee5d7f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD263.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser
new file mode 100644
index 000000000..716661a75
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD264.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser
new file mode 100644
index 000000000..b418d9b9f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD265.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser
new file mode 100644
index 000000000..bc16ddcff
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD266.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser
new file mode 100644
index 000000000..a105347f0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD267.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser
new file mode 100644
index 000000000..f75552dc3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD268.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser
new file mode 100644
index 000000000..a3f6eab8f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD269.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser
new file mode 100644
index 000000000..604170dcc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD27.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser
new file mode 100644
index 000000000..755d6cd60
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD270.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser
new file mode 100644
index 000000000..9b29a7d1e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD271.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser
new file mode 100644
index 000000000..5685e40b8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD272.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser
new file mode 100644
index 000000000..49a7c0739
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD273.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser
new file mode 100644
index 000000000..1697a421b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD274.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser
new file mode 100644
index 000000000..ea0d9adf1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD275.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser
new file mode 100644
index 000000000..067dca228
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD276.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser
new file mode 100644
index 000000000..9f9078678
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD277.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser
new file mode 100644
index 000000000..9cd498c3c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD278.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser
new file mode 100644
index 000000000..c5c4c6ab0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD279.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser
new file mode 100644
index 000000000..890ce30bb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD28.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser
new file mode 100644
index 000000000..fac475452
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD280.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser
new file mode 100644
index 000000000..4711e4586
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD281.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser
new file mode 100644
index 000000000..1fcea5dbf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD282.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser
new file mode 100644
index 000000000..bf2a0bcc5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD283.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser
new file mode 100644
index 000000000..29a3c23d4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD284.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser
new file mode 100644
index 000000000..fea28c7d2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD285.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser
new file mode 100644
index 000000000..48663053e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD286.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser
new file mode 100644
index 000000000..43f440cf7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD287.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser
new file mode 100644
index 000000000..385ac7184
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD288.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser
new file mode 100644
index 000000000..8a032f261
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD289.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser
new file mode 100644
index 000000000..fdc27290b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD29.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser
new file mode 100644
index 000000000..264c28e08
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD290.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser
new file mode 100644
index 000000000..daf236abf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD291.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser
new file mode 100644
index 000000000..8f972bf5a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD292.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser
new file mode 100644
index 000000000..647424ee0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD293.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser
new file mode 100644
index 000000000..9e8b99773
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD294.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser
new file mode 100644
index 000000000..486bcf475
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD295.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser
new file mode 100644
index 000000000..856d72fd1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD296.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser
new file mode 100644
index 000000000..ce0b5bf4c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD297.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser
new file mode 100644
index 000000000..cad0d5049
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD298.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser
new file mode 100644
index 000000000..b14aa4597
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD299.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser
new file mode 100644
index 000000000..6657a3593
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD3.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser
new file mode 100644
index 000000000..b30faf809
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD30.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser
new file mode 100644
index 000000000..4baca2704
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD300.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser
new file mode 100644
index 000000000..630a13467
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD301.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser
new file mode 100644
index 000000000..0f8e3d7d8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD302.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser
new file mode 100644
index 000000000..42a05ced7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD303.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser
new file mode 100644
index 000000000..13ba94a7e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD304.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser
new file mode 100644
index 000000000..e5a3a925e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD305.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser
new file mode 100644
index 000000000..1ada57413
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD306.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser
new file mode 100644
index 000000000..a14a0bebf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD307.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser
new file mode 100644
index 000000000..c66ae933f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD308.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser
new file mode 100644
index 000000000..fd1e62ca8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD309.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser
new file mode 100644
index 000000000..4914c3b65
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD31.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser
new file mode 100644
index 000000000..e8aad8cad
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD310.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser
new file mode 100644
index 000000000..0d8f4cf1e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD311.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser
new file mode 100644
index 000000000..54d856156
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD312.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser
new file mode 100644
index 000000000..5bd0e8286
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD313.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser
new file mode 100644
index 000000000..37a4d8c68
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD314.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser
new file mode 100644
index 000000000..a16a7b8f9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD315.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser
new file mode 100644
index 000000000..6e5747ed9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD316.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser
new file mode 100644
index 000000000..3ee6650ed
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD317.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser
new file mode 100644
index 000000000..8c6f200a2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD318.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser
new file mode 100644
index 000000000..4774611b5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD319.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser
new file mode 100644
index 000000000..09332a05e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD32.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser
new file mode 100644
index 000000000..88327e077
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD320.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser
new file mode 100644
index 000000000..600eb2ac3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD321.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser
new file mode 100644
index 000000000..eed01d875
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD322.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser
new file mode 100644
index 000000000..cc2db9896
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD323.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser
new file mode 100644
index 000000000..d0ae70999
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD324.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser
new file mode 100644
index 000000000..eb2a30d19
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD325.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser
new file mode 100644
index 000000000..5825c9571
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD326.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser
new file mode 100644
index 000000000..c1b927a19
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD327.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser
new file mode 100644
index 000000000..5d7eb7f7e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD328.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser
new file mode 100644
index 000000000..a78094615
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD329.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser
new file mode 100644
index 000000000..efb28b562
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD33.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser
new file mode 100644
index 000000000..686c66e20
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD330.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser
new file mode 100644
index 000000000..b210f7896
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD331.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser
new file mode 100644
index 000000000..da93f81fc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD332.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser
new file mode 100644
index 000000000..8a0f567f1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD333.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser
new file mode 100644
index 000000000..622bdd1e1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD334.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser
new file mode 100644
index 000000000..4baa13941
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD335.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser
new file mode 100644
index 000000000..1d40b0818
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD336.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser
new file mode 100644
index 000000000..ef0b76e42
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD337.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser
new file mode 100644
index 000000000..bd0a0456f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD338.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser
new file mode 100644
index 000000000..73ee20cbe
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD339.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser
new file mode 100644
index 000000000..9e33d39e9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD34.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser
new file mode 100644
index 000000000..6afa6bf7c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD340.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser
new file mode 100644
index 000000000..84782b980
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD341.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser
new file mode 100644
index 000000000..fdde6d7a5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD342.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser
new file mode 100644
index 000000000..2654a884a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD343.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser
new file mode 100644
index 000000000..b24a2a444
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD344.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser
new file mode 100644
index 000000000..613d80bee
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD345.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser
new file mode 100644
index 000000000..df1df5fbf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD346.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser
new file mode 100644
index 000000000..3f68bd344
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD347.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser
new file mode 100644
index 000000000..361734a3c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD348.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser
new file mode 100644
index 000000000..009e2419c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD349.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser
new file mode 100644
index 000000000..7c142c3e3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD35.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser
new file mode 100644
index 000000000..6e14a51a4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD350.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser
new file mode 100644
index 000000000..ed8f2450d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD351.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser
new file mode 100644
index 000000000..80489aa41
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD352.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser
new file mode 100644
index 000000000..ede61bef1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD353.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser
new file mode 100644
index 000000000..e837ec5a6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD354.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser
new file mode 100644
index 000000000..0dbeb4a18
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD355.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser
new file mode 100644
index 000000000..fdbc6a8f2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD356.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser
new file mode 100644
index 000000000..47665da0c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD357.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser
new file mode 100644
index 000000000..aae718782
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD358.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser
new file mode 100644
index 000000000..5bc6e4083
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD359.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser
new file mode 100644
index 000000000..07d3b8d15
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD36.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser
new file mode 100644
index 000000000..81af1c964
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD360.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser
new file mode 100644
index 000000000..4abfa7c14
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD361.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser
new file mode 100644
index 000000000..aec3af860
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD362.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser
new file mode 100644
index 000000000..ac1eecb96
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD363.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser
new file mode 100644
index 000000000..1f1367be6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD364.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser
new file mode 100644
index 000000000..3cf337cda
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD365.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser
new file mode 100644
index 000000000..19f7fd9e9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD366.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser
new file mode 100644
index 000000000..8c92df043
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD367.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser
new file mode 100644
index 000000000..dad7f014b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD368.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser
new file mode 100644
index 000000000..b0022c672
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD369.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser
new file mode 100644
index 000000000..bfbb586fb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD37.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser
new file mode 100644
index 000000000..b435feea0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD370.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser
new file mode 100644
index 000000000..dafe64d04
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD371.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser
new file mode 100644
index 000000000..973fcdc92
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD372.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser
new file mode 100644
index 000000000..a49d73cfe
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD373.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser
new file mode 100644
index 000000000..892a50d1b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD374.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser
new file mode 100644
index 000000000..0fa29c84b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD375.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser
new file mode 100644
index 000000000..a29b52179
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD376.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser
new file mode 100644
index 000000000..e7c2a5a36
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD377.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser
new file mode 100644
index 000000000..0ec361014
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD378.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser
new file mode 100644
index 000000000..bca795879
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD379.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser
new file mode 100644
index 000000000..49ca3d106
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD38.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser
new file mode 100644
index 000000000..0a340e65e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD380.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser
new file mode 100644
index 000000000..2e73aff87
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD381.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser
new file mode 100644
index 000000000..d3a437077
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD382.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser
new file mode 100644
index 000000000..963e0a877
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD383.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser
new file mode 100644
index 000000000..092300f46
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD384.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser
new file mode 100644
index 000000000..0c4c00312
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD385.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser
new file mode 100644
index 000000000..9abf70ed9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD386.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser
new file mode 100644
index 000000000..7e518db09
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD387.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser
new file mode 100644
index 000000000..797d08f9c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD388.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser
new file mode 100644
index 000000000..672e36e4a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD389.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser
new file mode 100644
index 000000000..de9d5aadb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD39.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser
new file mode 100644
index 000000000..44c076196
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD390.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser
new file mode 100644
index 000000000..2706725f7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD391.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser
new file mode 100644
index 000000000..1cc61a4ed
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD392.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser
new file mode 100644
index 000000000..33305fe62
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD393.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser
new file mode 100644
index 000000000..278fb38d7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD394.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser
new file mode 100644
index 000000000..3d2ff817c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD395.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser
new file mode 100644
index 000000000..45833bacc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD396.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser
new file mode 100644
index 000000000..54e88ffc0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD397.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser
new file mode 100644
index 000000000..751b118a7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD398.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser
new file mode 100644
index 000000000..4acd804ca
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD399.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser
new file mode 100644
index 000000000..c65761df1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD4.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser
new file mode 100644
index 000000000..d6759145b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD40.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser
new file mode 100644
index 000000000..4c9b21368
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD400.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser
new file mode 100644
index 000000000..e3e6c6ec2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD401.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser
new file mode 100644
index 000000000..92e5a6187
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD402.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser
new file mode 100644
index 000000000..873595ead
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD403.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser
new file mode 100644
index 000000000..1709012da
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD404.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser
new file mode 100644
index 000000000..5ad6315e3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD405.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser
new file mode 100644
index 000000000..aa04c95e2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD406.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser
new file mode 100644
index 000000000..12edd65ab
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD407.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser
new file mode 100644
index 000000000..40290ec4c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD408.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser
new file mode 100644
index 000000000..b59671610
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD409.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser
new file mode 100644
index 000000000..5d664e82c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD41.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser
new file mode 100644
index 000000000..9c5866504
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD410.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser
new file mode 100644
index 000000000..01fe69955
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD411.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser
new file mode 100644
index 000000000..b71d6c546
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD412.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser
new file mode 100644
index 000000000..5ad3f0613
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD413.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser
new file mode 100644
index 000000000..b89491a41
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD414.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser
new file mode 100644
index 000000000..289f9b48d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD415.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser
new file mode 100644
index 000000000..24d1e1cbe
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD416.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser
new file mode 100644
index 000000000..927349572
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD417.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser
new file mode 100644
index 000000000..8208a5005
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD418.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser
new file mode 100644
index 000000000..346fb131d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD419.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser
new file mode 100644
index 000000000..28c0e15e1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD42.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser
new file mode 100644
index 000000000..53d6b158d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD420.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser
new file mode 100644
index 000000000..c324000e4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD421.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser
new file mode 100644
index 000000000..d99423cbb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD422.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser
new file mode 100644
index 000000000..d78b800db
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD423.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser
new file mode 100644
index 000000000..eabb33cc3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD424.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser
new file mode 100644
index 000000000..571728da3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD425.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser
new file mode 100644
index 000000000..25d9cb0aa
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD426.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser
new file mode 100644
index 000000000..d493f3859
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD427.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser
new file mode 100644
index 000000000..06b90d501
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD428.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser
new file mode 100644
index 000000000..5b97f90ca
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD429.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser
new file mode 100644
index 000000000..22b1b8d9b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD43.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser
new file mode 100644
index 000000000..db3749949
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD430.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser
new file mode 100644
index 000000000..272364c6f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD431.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser
new file mode 100644
index 000000000..078a31f84
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD432.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser
new file mode 100644
index 000000000..b4aaf015b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD433.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser
new file mode 100644
index 000000000..52c01f7e9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD434.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser
new file mode 100644
index 000000000..626e52df0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD435.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser
new file mode 100644
index 000000000..2de03dae5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD436.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser
new file mode 100644
index 000000000..041c1a4cf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD437.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser
new file mode 100644
index 000000000..c8da3b083
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD438.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser
new file mode 100644
index 000000000..74f71d784
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD439.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser
new file mode 100644
index 000000000..d1321181b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD44.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser
new file mode 100644
index 000000000..bcf11b73c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD440.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser
new file mode 100644
index 000000000..a9ba2dea1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD441.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser
new file mode 100644
index 000000000..fe728d89c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD442.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser
new file mode 100644
index 000000000..23d7eb22b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD443.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser
new file mode 100644
index 000000000..58f06cbce
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD444.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser
new file mode 100644
index 000000000..bd56f8524
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD445.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser
new file mode 100644
index 000000000..54d14da06
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD446.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser
new file mode 100644
index 000000000..ee6f83422
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD447.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser
new file mode 100644
index 000000000..f94d24f69
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD448.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser
new file mode 100644
index 000000000..feef36694
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD449.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser
new file mode 100644
index 000000000..93720aeac
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD45.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser
new file mode 100644
index 000000000..d1a58aaa5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD450.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser
new file mode 100644
index 000000000..11f0d14b3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD451.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser
new file mode 100644
index 000000000..2aef6789e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD452.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser
new file mode 100644
index 000000000..e60e00a75
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD453.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser
new file mode 100644
index 000000000..e7ed6f17e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD454.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser
new file mode 100644
index 000000000..49062bd27
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD455.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser
new file mode 100644
index 000000000..5b4049240
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD456.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser
new file mode 100644
index 000000000..c051bb336
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD457.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser
new file mode 100644
index 000000000..bb781c485
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD458.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser
new file mode 100644
index 000000000..289e7e587
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD459.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser
new file mode 100644
index 000000000..c4b5db34b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD46.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser
new file mode 100644
index 000000000..bacc29cf6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD460.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser
new file mode 100644
index 000000000..d791c7d59
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD461.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser
new file mode 100644
index 000000000..eac181fa5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD462.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser
new file mode 100644
index 000000000..4d4c36621
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD463.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser
new file mode 100644
index 000000000..ab10d3c9d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD464.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser
new file mode 100644
index 000000000..ada0cfb53
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD465.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser
new file mode 100644
index 000000000..b2f924cb4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD466.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser
new file mode 100644
index 000000000..4965ccab3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD467.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser
new file mode 100644
index 000000000..f04ae6182
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD468.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser
new file mode 100644
index 000000000..27fc5e31f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD469.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser
new file mode 100644
index 000000000..dd2f2f73d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD47.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser
new file mode 100644
index 000000000..868c0718f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD470.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser
new file mode 100644
index 000000000..95ba064e9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD471.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser
new file mode 100644
index 000000000..ec1bcb735
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD472.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser
new file mode 100644
index 000000000..d4bfab753
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD473.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser
new file mode 100644
index 000000000..bf4de5393
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD474.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser
new file mode 100644
index 000000000..b01e493df
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD475.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser
new file mode 100644
index 000000000..247977216
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD476.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser
new file mode 100644
index 000000000..0a4655675
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD477.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser
new file mode 100644
index 000000000..7847c8b34
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD478.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser
new file mode 100644
index 000000000..6ac093714
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD479.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser
new file mode 100644
index 000000000..1fb8a568a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD48.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser
new file mode 100644
index 000000000..4f5ce8e37
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD480.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser
new file mode 100644
index 000000000..b9cf2310e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD481.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser
new file mode 100644
index 000000000..d8cc78a39
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD482.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser
new file mode 100644
index 000000000..44438e065
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD483.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser
new file mode 100644
index 000000000..a6227255a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD484.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser
new file mode 100644
index 000000000..415f6c049
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD485.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser
new file mode 100644
index 000000000..8ea2f93ad
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD486.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser
new file mode 100644
index 000000000..ca7f77129
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD487.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser
new file mode 100644
index 000000000..5aaf07824
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD488.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser
new file mode 100644
index 000000000..655516191
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD489.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser
new file mode 100644
index 000000000..3cc2d4a75
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD49.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser
new file mode 100644
index 000000000..94f1d83fd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD490.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser
new file mode 100644
index 000000000..14b49f0a4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD491.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser
new file mode 100644
index 000000000..adb3d3737
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD492.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser
new file mode 100644
index 000000000..b2c4902eb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD493.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser
new file mode 100644
index 000000000..8b28deac8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD494.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser
new file mode 100644
index 000000000..5d238271b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD495.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser
new file mode 100644
index 000000000..ab8f4d6d1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD496.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser
new file mode 100644
index 000000000..901e4173d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD497.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser
new file mode 100644
index 000000000..d6fd495bb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD498.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser
new file mode 100644
index 000000000..52400b507
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD499.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser
new file mode 100644
index 000000000..4d03b7211
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD5.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser
new file mode 100644
index 000000000..975618522
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD50.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser
new file mode 100644
index 000000000..33e7b0c7d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD500.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser
new file mode 100644
index 000000000..8e101db57
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD501.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser
new file mode 100644
index 000000000..f8246c2d2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD502.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser
new file mode 100644
index 000000000..c8707cd48
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD503.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser
new file mode 100644
index 000000000..41e6c694a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD504.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser
new file mode 100644
index 000000000..595e24ff2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD505.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser
new file mode 100644
index 000000000..731b47fd2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD506.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser
new file mode 100644
index 000000000..8bf1d99fa
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD507.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser
new file mode 100644
index 000000000..bc63d7e97
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD508.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser
new file mode 100644
index 000000000..d7415c13a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD509.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser
new file mode 100644
index 000000000..e8d28148e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD51.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser
new file mode 100644
index 000000000..b94811af6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD510.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser
new file mode 100644
index 000000000..91a3bd4ea
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD511.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser
new file mode 100644
index 000000000..2e31b49d8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD512.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser
new file mode 100644
index 000000000..2cef55911
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD513.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser
new file mode 100644
index 000000000..84c1bdeb8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD514.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser
new file mode 100644
index 000000000..431fe2dd8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD515.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser
new file mode 100644
index 000000000..37c17f168
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD516.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser
new file mode 100644
index 000000000..087847d57
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD517.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser
new file mode 100644
index 000000000..8bd76318d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD518.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser
new file mode 100644
index 000000000..318fc84a7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD519.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser
new file mode 100644
index 000000000..5e853ec29
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD52.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser
new file mode 100644
index 000000000..e72f8d30e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD520.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser
new file mode 100644
index 000000000..cbd161b83
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD521.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser
new file mode 100644
index 000000000..a2c4ccff7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD522.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser
new file mode 100644
index 000000000..cbd7fa3b8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD523.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser
new file mode 100644
index 000000000..b876b1b27
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD524.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser
new file mode 100644
index 000000000..64e50de82
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD525.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser
new file mode 100644
index 000000000..e5f094eeb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD526.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser
new file mode 100644
index 000000000..537459e7f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD527.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser
new file mode 100644
index 000000000..577b66158
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD528.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser
new file mode 100644
index 000000000..4679568f4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD529.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser
new file mode 100644
index 000000000..389261a05
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD53.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser
new file mode 100644
index 000000000..635151fa9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD530.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser
new file mode 100644
index 000000000..69e85f02b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD531.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser
new file mode 100644
index 000000000..c28ba450a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD532.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser
new file mode 100644
index 000000000..fe26705e5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD533.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser
new file mode 100644
index 000000000..19595d9e3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD534.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser
new file mode 100644
index 000000000..95e9836b4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD535.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser
new file mode 100644
index 000000000..d179f7c8c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD536.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser
new file mode 100644
index 000000000..1b91641ad
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD537.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser
new file mode 100644
index 000000000..fc83f4562
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD538.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser
new file mode 100644
index 000000000..ea2af6364
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD539.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser
new file mode 100644
index 000000000..0f76396bb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD54.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser
new file mode 100644
index 000000000..143d5894a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD540.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser
new file mode 100644
index 000000000..671cf26d1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD541.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser
new file mode 100644
index 000000000..1a7fda27b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD542.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser
new file mode 100644
index 000000000..5aee466d8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD543.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser
new file mode 100644
index 000000000..37f124113
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD544.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser
new file mode 100644
index 000000000..8bc00e144
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD545.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser
new file mode 100644
index 000000000..9d9b9c119
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD546.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser
new file mode 100644
index 000000000..88411a216
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD547.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser
new file mode 100644
index 000000000..f8324788b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD548.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser
new file mode 100644
index 000000000..2d3118a56
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD549.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser
new file mode 100644
index 000000000..51a8b7095
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD55.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser
new file mode 100644
index 000000000..e939d4754
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD550.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser
new file mode 100644
index 000000000..61e5e3f3c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD551.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser
new file mode 100644
index 000000000..496e6912a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD552.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser
new file mode 100644
index 000000000..0fc2f1a23
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD553.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser
new file mode 100644
index 000000000..dc5183342
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD554.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser
new file mode 100644
index 000000000..de477db15
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD555.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser
new file mode 100644
index 000000000..6a4e51c29
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD556.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser
new file mode 100644
index 000000000..fccb593ae
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD557.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser
new file mode 100644
index 000000000..828b3a72e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD558.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser
new file mode 100644
index 000000000..3b14d4a8f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD559.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser
new file mode 100644
index 000000000..373392279
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD56.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser
new file mode 100644
index 000000000..a91b8512a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD560.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser
new file mode 100644
index 000000000..639a7be49
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD561.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser
new file mode 100644
index 000000000..68dd4089b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD562.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser
new file mode 100644
index 000000000..2908e3f63
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD563.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser
new file mode 100644
index 000000000..391e3e14a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD564.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser
new file mode 100644
index 000000000..5bd9c1e71
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD565.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser
new file mode 100644
index 000000000..d4ecb3a88
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD566.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser
new file mode 100644
index 000000000..d68ca24ac
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD567.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser
new file mode 100644
index 000000000..73cd97bf6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD568.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser
new file mode 100644
index 000000000..a6d766289
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD569.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser
new file mode 100644
index 000000000..d0af60722
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD57.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser
new file mode 100644
index 000000000..231290df6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD570.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser
new file mode 100644
index 000000000..21e85e747
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD571.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser
new file mode 100644
index 000000000..e99365766
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD572.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser
new file mode 100644
index 000000000..4f844be2e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD573.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser
new file mode 100644
index 000000000..ccb6d70f1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD574.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser
new file mode 100644
index 000000000..aa3909601
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD575.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser
new file mode 100644
index 000000000..5d1bb4981
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD576.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser
new file mode 100644
index 000000000..64823ec47
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD577.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser
new file mode 100644
index 000000000..09d6843e8
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD578.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser
new file mode 100644
index 000000000..59f2572ad
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD579.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser
new file mode 100644
index 000000000..cb600cfca
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD58.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser
new file mode 100644
index 000000000..b1faa848b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD580.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser
new file mode 100644
index 000000000..1e057fdf4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD581.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser
new file mode 100644
index 000000000..cdd3cbec1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD582.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser
new file mode 100644
index 000000000..84eed41fe
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD583.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser
new file mode 100644
index 000000000..7b91077fc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD584.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser
new file mode 100644
index 000000000..259194e4e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD585.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser
new file mode 100644
index 000000000..0616c3c12
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD586.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser
new file mode 100644
index 000000000..22430bd97
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD587.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser
new file mode 100644
index 000000000..b583a1a1b
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD588.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser
new file mode 100644
index 000000000..841747bdf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD589.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser
new file mode 100644
index 000000000..23521f3cd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD59.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser
new file mode 100644
index 000000000..168552d3c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD590.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser
new file mode 100644
index 000000000..c0da95a76
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD591.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser
new file mode 100644
index 000000000..276e0ffed
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD592.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser
new file mode 100644
index 000000000..363f4f695
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD593.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser
new file mode 100644
index 000000000..a0f6639ba
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD594.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser
new file mode 100644
index 000000000..cdc9eb94a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD595.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser
new file mode 100644
index 000000000..c6223a7ce
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD596.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser
new file mode 100644
index 000000000..74f023e83
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD597.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser
new file mode 100644
index 000000000..9755e4a3c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD598.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser
new file mode 100644
index 000000000..986a332f3
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD599.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser
new file mode 100644
index 000000000..edc35abdc
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD6.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser
new file mode 100644
index 000000000..6ed639c5e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD60.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser
new file mode 100644
index 000000000..d2c52eba1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD600.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser
new file mode 100644
index 000000000..f34830970
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD601.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser
new file mode 100644
index 000000000..7cea4a6c6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD602.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser
new file mode 100644
index 000000000..e2c08df91
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD603.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser
new file mode 100644
index 000000000..7a37cd019
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD604.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser
new file mode 100644
index 000000000..85f679da2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD605.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser
new file mode 100644
index 000000000..8f1d6966d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD606.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser
new file mode 100644
index 000000000..f82e37287
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD607.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser
new file mode 100644
index 000000000..f22902dd5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD608.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser
new file mode 100644
index 000000000..bb7f98e41
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD609.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser
new file mode 100644
index 000000000..d25cb04c7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD61.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser
new file mode 100644
index 000000000..8ddaeb744
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD610.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser
new file mode 100644
index 000000000..b11de6c32
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD611.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser
new file mode 100644
index 000000000..2b1ea8898
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD612.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser
new file mode 100644
index 000000000..1d2ea017c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD613.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser
new file mode 100644
index 000000000..ae74ca063
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD614.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser
new file mode 100644
index 000000000..fed68df6e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD615.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser
new file mode 100644
index 000000000..94b09c1e1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD616.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser
new file mode 100644
index 000000000..0af062be1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD617.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser
new file mode 100644
index 000000000..bd93b288c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD618.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser
new file mode 100644
index 000000000..ea7a544bf
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD619.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser
new file mode 100644
index 000000000..c3510ec9e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD62.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser
new file mode 100644
index 000000000..c02164344
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD620.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser
new file mode 100644
index 000000000..16cf973f2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD621.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser
new file mode 100644
index 000000000..f827db274
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD63.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser
new file mode 100644
index 000000000..c079752d6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD64.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser
new file mode 100644
index 000000000..18d091c4a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD65.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser
new file mode 100644
index 000000000..2628ac645
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD66.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser
new file mode 100644
index 000000000..e0a656874
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD67.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser
new file mode 100644
index 000000000..cd908264a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD68.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser
new file mode 100644
index 000000000..da9a56794
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD69.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser
new file mode 100644
index 000000000..1eec94eeb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD7.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser
new file mode 100644
index 000000000..1458485b6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD70.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser
new file mode 100644
index 000000000..0bb894af9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD71.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser
new file mode 100644
index 000000000..596af011c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD72.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser
new file mode 100644
index 000000000..adac3305c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD73.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser
new file mode 100644
index 000000000..1440bb78a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD74.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser
new file mode 100644
index 000000000..2a1091e9c
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD75.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser
new file mode 100644
index 000000000..a519dc078
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD76.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser
new file mode 100644
index 000000000..533579a8f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD77.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser
new file mode 100644
index 000000000..cd8bea1c7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD78.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser
new file mode 100644
index 000000000..16635b605
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD79.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser
new file mode 100644
index 000000000..05616a937
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD8.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser
new file mode 100644
index 000000000..44ce6375e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD80.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser
new file mode 100644
index 000000000..cfd698d7d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD81.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser
new file mode 100644
index 000000000..415f1bf8e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD82.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser
new file mode 100644
index 000000000..2fc94de93
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD83.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser
new file mode 100644
index 000000000..a7e226ec1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD84.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser
new file mode 100644
index 000000000..573c8ce87
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD85.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser
new file mode 100644
index 000000000..e8df233a5
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD86.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser
new file mode 100644
index 000000000..abcad78d0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD87.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser
new file mode 100644
index 000000000..e702881e7
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD88.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser
new file mode 100644
index 000000000..1b76a8499
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD89.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser
new file mode 100644
index 000000000..13edb5406
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD9.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser
new file mode 100644
index 000000000..da2ee39ec
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD90.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser
new file mode 100644
index 000000000..7f9f0a3fd
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD91.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser
new file mode 100644
index 000000000..6cbe89840
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD92.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser
new file mode 100644
index 000000000..423f92310
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD93.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser
new file mode 100644
index 000000000..331ba261f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD94.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser
new file mode 100644
index 000000000..0c4e54135
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD95.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser
new file mode 100644
index 000000000..20afc295a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD96.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser
new file mode 100644
index 000000000..e801916f4
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD97.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser
new file mode 100644
index 000000000..7fc398de9
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD98.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser
new file mode 100644
index 000000000..5c7a0de21
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$LD99.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser
new file mode 100644
index 000000000..f7b1fbed1
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD0.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser
new file mode 100644
index 000000000..dc3634dec
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD1.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser
new file mode 100644
index 000000000..a3108b43e
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD10.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser
new file mode 100644
index 000000000..f561c2d2f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD11.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser
new file mode 100644
index 000000000..1dc99e434
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD12.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser
new file mode 100644
index 000000000..e1b97d053
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD13.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser
new file mode 100644
index 000000000..5600cbfa2
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD14.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser
new file mode 100644
index 000000000..fe4068c42
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD15.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser
new file mode 100644
index 000000000..59ad5e462
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD16.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser
new file mode 100644
index 000000000..b11600cd0
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD17.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser
new file mode 100644
index 000000000..5abc2b1b6
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD18.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser
new file mode 100644
index 000000000..37814223f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD2.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser
new file mode 100644
index 000000000..58bb75a7f
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD3.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser
new file mode 100644
index 000000000..f905fc364
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD4.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser
new file mode 100644
index 000000000..0c1e74beb
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD5.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser
new file mode 100644
index 000000000..1032043be
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD6.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser
new file mode 100644
index 000000000..d0e34603a
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD7.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser
new file mode 100644
index 000000000..4d47ada2d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD8.ser
Binary files differ
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser
new file mode 100644
index 000000000..eb522634d
--- /dev/null
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData$TD9.ser
Binary files differ
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
+}