/* * 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.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.util.TTXFile; import org.apache.fop.fonts.GlyphPositioningTable; import org.apache.fop.fonts.GlyphSequence; import org.apache.fop.fonts.GlyphSubstitutionTable; 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 data = (List) 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 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; } }