/*
* 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.FilenameFilter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.IntBuffer;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
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;
// CSOFF: LineLength
/**
* Tests for functionality related to the arabic script.
*/
public class ArabicWordFormsTestCase implements ArabicWordFormsConstants {
@Test
public void testArabicWordForms() {
for (String sfn : SRC_FILES) {
try {
processWordForms(new File(DAT_FILES_DIR));
} 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, SRC_FILES) && 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) { /* NOP */ }
}
}
}
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(TTX_FONTS_DIR + 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;
}
}