You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by sp...@apache.org on 2011/10/18 10:33:40 UTC
svn commit: r1185530 [6/14] - in
/xmlgraphics/fop/branches/Temp_ComplexScripts: ./
src/documentation/content/xdocs/trunk/ src/foschema/
src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/
src/java/org/apache/fop/cli/ src/java/org/apache/fop/fo/...
Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gdef/GDEFTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gdef/GDEFTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id
Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java?rev=1185530&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java Tue Oct 18 08:33:32 2011
@@ -0,0 +1,475 @@
+/*
+ * 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.gpos;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fop.complexscripts.util.TTXFile;
+import org.apache.fop.fonts.GlyphContextTester;
+import org.apache.fop.fonts.GlyphSequence;
+import org.apache.fop.fonts.GlyphSubtable;
+import org.apache.fop.fonts.GlyphPositioningSubtable;
+import org.apache.fop.fonts.GlyphPositioningTable;
+import org.apache.fop.fonts.GlyphTable.LookupSpec;
+import org.apache.fop.fonts.GlyphTable.LookupTable;
+import org.apache.fop.fonts.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;
+ }
+
+ @Override
+ public GlyphContextTester getTester ( String feature ) {
+ return this;
+ }
+
+ @Override
+ public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
+ 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 );
+ }
+ }
+ }
+}
Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/gpos/GPOSTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org