aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-03-30 19:09:29 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-03-30 19:09:29 +0000
commit7c8f02c57302d672fe4d0a8fc5332af6d9f0e610 (patch)
tree9be4d0493b7aa44854254ae99dc842de739d9bea /test
parent7a51f3fdb1f7ae1f526ea75f804e8f016d653cb8 (diff)
downloadxmlgraphics-fop-7c8f02c57302d672fe4d0a8fc5332af6d9f0e610.tar.gz
xmlgraphics-fop-7c8f02c57302d672fe4d0a8fc5332af6d9f0e610.zip
Bugzilla #50483: Improved support for TrueType fonts in PostScript
Refactored code and added unit tests Patch by Mehdi Houshmand git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1307574 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
-rw-r--r--test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java4
-rw-r--r--test/java/org/apache/fop/fonts/EncodingModeTest.java23
-rw-r--r--test/java/org/apache/fop/fonts/FOPFontsTestSuite.java54
-rw-r--r--test/java/org/apache/fop/fonts/truetype/FontFileReaderTest.java283
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFileTest.java399
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTest.java69
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFTableNameTest.java145
-rw-r--r--test/java/org/apache/fop/render/ps/RenderPSTestSuite.java55
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTest.java111
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTest.java105
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTest.java82
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTest.java86
-rw-r--r--test/resources/fonts/DroidSansMono.LICENSE18
13 files changed, 1429 insertions, 5 deletions
diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java
index fb0c3a795..17d614829 100644
--- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java
+++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTest.java
@@ -33,13 +33,13 @@ public class DejaVuLGCSerifTest extends TestCase {
/**
* sets up the testcase by loading the DejaVu Font.
- *
+ *
* @throws Exception
* if the test fails.
*/
public void setUp() throws Exception {
File file = new File("test/resources/fonts/DejaVuLGCSerif.ttf");
- font = FontLoader.loadFont(file, "", true, EncodingMode.AUTO,
+ font = FontLoader.loadFont(file, "", true, EmbeddingMode.AUTO, EncodingMode.AUTO,
fontResolver);
}
diff --git a/test/java/org/apache/fop/fonts/EncodingModeTest.java b/test/java/org/apache/fop/fonts/EncodingModeTest.java
index 4e81c46d6..e240aea30 100644
--- a/test/java/org/apache/fop/fonts/EncodingModeTest.java
+++ b/test/java/org/apache/fop/fonts/EncodingModeTest.java
@@ -21,16 +21,33 @@ package org.apache.fop.fonts;
import junit.framework.TestCase;
+/**
+ * Tests the enum org.apache.fop.fonts.EncodingMode.
+ */
public class EncodingModeTest extends TestCase {
+ /**
+ * Test getName() - tests the getName() method returns the expected String.
+ */
public void testGetName() {
assertEquals("auto", EncodingMode.AUTO.getName());
assertEquals("single-byte", EncodingMode.SINGLE_BYTE.getName());
assertEquals("cid", EncodingMode.CID.getName());
}
+ /**
+ * Test getValue() - test that getValue() method returns the expected enum value when given
+ * an appropriate String.
+ */
public void testGetValue() {
- assertEquals(EncodingMode.AUTO, EncodingMode.getEncodingMode("auto"));
- assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getEncodingMode("single-byte"));
- assertEquals(EncodingMode.CID, EncodingMode.getEncodingMode("cid"));
+ assertEquals(EncodingMode.AUTO, EncodingMode.getValue("auto"));
+ assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getValue("single-byte"));
+ assertEquals(EncodingMode.CID, EncodingMode.getValue("cid"));
+ try {
+ // We expect this to fail
+ assertEquals(EncodingMode.AUTO, EncodingMode.getValue("fail"));
+ fail("Encoding mode fails to throw an appropriate exception");
+ } catch (IllegalArgumentException e) {
+ // PASS
+ }
}
}
diff --git a/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java b/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java
new file mode 100644
index 000000000..618bdde22
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/FOPFontsTestSuite.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.fonts;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.fop.fonts.truetype.FontFileReaderTest;
+import org.apache.fop.fonts.truetype.TTFFileTest;
+import org.apache.fop.fonts.truetype.TTFSubSetFileTest;
+import org.apache.fop.fonts.truetype.TTFTableNameTest;
+
+/**
+ * A test suite designed for org.apache.fop.fonts.*
+ */
+public final class FOPFontsTestSuite {
+ /**
+ * Constructor
+ */
+ private FOPFontsTestSuite() {
+ }
+ /**
+ * Testing org.apache.fop.fonts.*
+ * @return test
+ */
+ public static Test suite() {
+ TestSuite testSuite = new TestSuite("Test suite for FOPs fonts classes");
+ //$JUnit-BEGIN$
+ testSuite.addTest(new TestSuite(EncodingModeTest.class));
+ testSuite.addTest(new TestSuite(FontFileReaderTest.class));
+ testSuite.addTest(new TestSuite(TTFFileTest.class));
+ testSuite.addTest(new TestSuite(TTFSubSetFileTest.class));
+ testSuite.addTest(new TestSuite(TTFTableNameTest.class));
+ //$JUnit-END$
+ return testSuite;
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/FontFileReaderTest.java b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTest.java
new file mode 100644
index 000000000..25d5be735
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTest.java
@@ -0,0 +1,283 @@
+/*
+ * 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.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * A test class for org.apache.fop.truetype.FontFileReader
+ */
+public class FontFileReaderTest extends TestCase {
+ private FontFileReader fontReader;
+ private final InputStream in;
+ private final byte[] byteArray;
+
+ /**
+ * Constructor - initialises an array that only needs to be created once. It creates a byte[]
+ * of form { 0x00, 0x01, 0x02, 0x03..., 0xff};
+ */
+ public FontFileReaderTest() {
+ byteArray = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ byteArray[i] = (byte) i;
+ }
+ in = new ByteArrayInputStream(byteArray);
+ }
+
+ /**
+ * sets up the test subject object for testing.
+ */
+ public void setUp() {
+ try {
+ fontReader = new FontFileReader(in);
+ } catch (Exception e) {
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * the "destructor" method.
+ *
+ */
+ public void tearDown() {
+ fontReader = null;
+ }
+
+ /**
+ * Test readTTFByte()
+ * @throws IOException exception
+ */
+ public void testReadTTFByte() throws IOException {
+ for (int i = 0; i < 256; i++) {
+ assertEquals((byte) i, fontReader.readTTFByte());
+ }
+ }
+
+ /**
+ * Test seekSet() - check that it moves to the correct position and enforce a failure case.
+ * @throws IOException exception
+ */
+ public void testSeekSet() throws IOException {
+ fontReader.seekSet(10);
+ assertEquals(10, fontReader.readTTFByte());
+ try {
+ fontReader.seekSet(257);
+ fail("FileFontReaderTest Failed testSeekSet");
+ } catch (IOException e) {
+ // Passed
+ }
+ }
+
+ /**
+ * Test skip() - check that it moves to the correct position and enforce a failure case.
+ * @throws IOException exception
+ */
+ public void testSkip() throws IOException {
+ fontReader.skip(100);
+ assertEquals(100, fontReader.readTTFByte());
+ try {
+ // 100 (seekAdd) + 1 (read() = 1 byte) + 156 = 257
+ fontReader.skip(156);
+ fail("FileFontReaderTest Failed testSkip");
+ } catch (IOException e) {
+ // Passed
+ }
+ }
+
+ /**
+ * Test getCurrentPos() - 3 checks:
+ * 1) test with seekSet(int)
+ * 2) test with skip(int)
+ * 3) test with a readTTFByte() (this moves the position by the size of the data being read)
+ * @throws IOException exception
+ */
+ public void testGetCurrentPos() throws IOException {
+ fontReader.seekSet(10);
+ fontReader.skip(100);
+ assertEquals(110, fontReader.getCurrentPos());
+ fontReader.readTTFByte();
+ assertEquals(111, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test getFileSize()
+ */
+ public void testGetFileSize() {
+ assertEquals(256, fontReader.getFileSize());
+ }
+
+ /**
+ * Test readTTFUByte()
+ * @throws IOException exception
+ */
+ public void testReadTTFUByte() throws IOException {
+ for (int i = 0; i < 256; i++) {
+ assertEquals(i, fontReader.readTTFUByte());
+ }
+ }
+
+ /**
+ * Test readTTFShort() - Test positive and negative numbers (two's compliment).
+ * @throws IOException exception
+ */
+ public void testReadTTFShort() throws IOException {
+ // 0x0001 = 1
+ assertEquals("Should have been 1 (0x0001)", 1, fontReader.readTTFShort());
+ // 0x0203 = 515
+ assertEquals(515, fontReader.readTTFShort());
+ // now test negative numbers
+ fontReader.seekSet(250);
+ // 0xfafb
+ assertEquals(-1285, fontReader.readTTFShort());
+ }
+
+ /**
+ * Test readTTFUShort() - Test positive and potentially negative numbers (two's compliment).
+ * @throws IOException exception
+ */
+ public void testReadTTFUShort() throws IOException {
+ // 0x0001
+ assertEquals(1, fontReader.readTTFUShort());
+ // 0x0203
+ assertEquals(515, fontReader.readTTFUShort());
+ // test potential negatives
+ fontReader.seekSet(250);
+ // 0xfafb
+ assertEquals((250 << 8) + 251, fontReader.readTTFUShort());
+ }
+
+ /**
+ * Test readTTFShort(int) - test reading ahead of current position and behind current position
+ * and in both cases ensure that our current position isn't changed.
+ * @throws IOException exception
+ */
+ public void testReadTTFShortWithArg() throws IOException {
+ // 0x6465
+ assertEquals(25701, fontReader.readTTFShort(100));
+ assertEquals(0, fontReader.getCurrentPos());
+ // read behind current position (and negative)
+ fontReader.seekSet(255);
+ // 0xfafb
+ assertEquals(-1285, fontReader.readTTFShort(250));
+ assertEquals(255, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test readTTFUShort(int arg) - test reading ahead of current position and behind current
+ * position and in both cases ensure that our current position isn't changed.
+ * @throws IOException exception
+ */
+ public void testReadTTFUShortWithArg() throws IOException {
+ // 0x6465
+ assertEquals(25701, fontReader.readTTFUShort(100));
+ assertEquals(0, fontReader.getCurrentPos());
+ // read behind current position (and potential negative)
+ fontReader.seekSet(255);
+ // 0xfafb
+ assertEquals(64251, fontReader.readTTFUShort(250));
+ assertEquals(255, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test readTTFLong()
+ * @throws IOException exception
+ */
+ public void testReadTTFLong() throws IOException {
+ // 0x00010203
+ assertEquals(66051, fontReader.readTTFLong());
+ // test negative numbers
+ fontReader.seekSet(250);
+ // 0xf0f1f2f3
+ assertEquals(-84148995, fontReader.readTTFLong());
+ }
+
+ /**
+ * Test readTTFULong()
+ * @throws IOException exception
+ */
+ public void testReadTTFULong() throws IOException {
+ // 0x00010203
+ assertEquals(66051, fontReader.readTTFULong());
+ // test negative numbers
+ fontReader.seekSet(250);
+ // 0xfafbfcfd
+ assertEquals(4210818301L, fontReader.readTTFULong());
+ }
+
+ /**
+ * Test readTTFString() - there are two paths to test here:
+ * 1) A null terminated string
+ * 2) A string not terminated with a null (we expect this to throw an EOFException)
+ * @throws IOException exception
+ */
+ public void testReadTTFString() throws IOException {
+ byte[] strByte = {(byte)'t', (byte)'e', (byte)'s', (byte)'t', 0x00};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString());
+ try {
+ // not NUL terminated
+ byte[] strByteNoNull = {(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByteNoNull));
+ assertEquals("test", fontReader.readTTFString());
+ fail("FontFileReaderTest testReadTTFString Fails.");
+ } catch (EOFException e) {
+ // Pass
+ }
+ }
+
+ /**
+ * Test readTTFString(int arg)
+ * @throws IOException exception
+ */
+ public void testReadTTFStringIntArg() throws IOException {
+ byte[] strByte = {(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString(4));
+ try {
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString(5));
+ fail("FontFileReaderTest testReadTTFStringIntArg Fails.");
+ } catch (EOFException e) {
+ // Pass
+ }
+ }
+
+ /**
+ * Test readTTFString(int arg1, int arg2)
+ */
+ public void testReadTTFString2IntArgs() {
+ // currently the same as above
+ }
+
+ /**
+ * Test getBytes()
+ * @throws IOException exception
+ */
+ public void testGetBytes() throws IOException {
+ byte[] retrievedBytes = fontReader.getBytes(0, 256);
+ assertTrue(Arrays.equals(byteArray, retrievedBytes));
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFileTest.java b/test/java/org/apache/fop/fonts/truetype/TTFFileTest.java
new file mode 100644
index 000000000..ccc12d991
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFFileTest.java
@@ -0,0 +1,399 @@
+/*
+ * 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.IOException;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
+
+/**
+ * Class for testing org.apache.fop.fonts.truetype.TTFFile
+ */
+public class TTFFileTest extends TestCase {
+ // We only want to initialize the FontFileReader once (for performance reasons)
+ /** The truetype font file (DejaVuLGCSerif) */
+ protected final TTFFile dejavuTTFFile;
+ /** The FontFileReader for ttfFile (DejaVuLGCSerif) */
+ protected final FontFileReader dejavuReader;
+ /** The truetype font file (DroidSansMono) */
+ protected final TTFFile droidmonoTTFFile;
+ /** The FontFileReader for ttfFile (DroidSansMono) */
+ protected final FontFileReader droidmonoReader;
+
+
+ /**
+ * Constructor initialises FileFontReader to
+ * @throws IOException exception
+ */
+ public TTFFileTest() throws IOException {
+ dejavuTTFFile = new TTFFile();
+ dejavuReader = new FontFileReader("test/resources/fonts/DejaVuLGCSerif.ttf");
+ dejavuTTFFile.readFont(dejavuReader);
+ droidmonoTTFFile = new TTFFile();
+ droidmonoReader = new FontFileReader("test/resources/fonts/DroidSansMono.ttf");
+ droidmonoTTFFile.readFont(droidmonoReader);
+ }
+
+ /**
+ * Test convertTTFUnit2PDFUnit() - The units per em retrieved reading the HEAD table from
+ * the font file. (DroidSansMono has the same units per em as DejaVu so no point testing it)
+ */
+ public void testConvertTTFUnit2PDFUnit() {
+ // DejaVu has 2048 units per em (PDF works in millipts, thus the 1000)
+ // test rational number
+ assertEquals(1000, dejavuTTFFile.convertTTFUnit2PDFUnit(2048));
+ // test smallest case, this should = 0.488 (round down to 0)
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(1));
+ // this should round up, but since it's millipts...
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(2));
+ // ensure behaviour is the same for negative numbers
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-0));
+ assertEquals(-1000, dejavuTTFFile.convertTTFUnit2PDFUnit(-2048));
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-1));
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-2));
+ }
+
+ /**
+ * Test checkTTC()
+ * @throws IOException exception
+ */
+ public void testCheckTTC() throws IOException {
+ // DejaVu is not a TTC, thus this returns true
+ assertTrue(dejavuTTFFile.checkTTC(""));
+ assertTrue(droidmonoTTFFile.checkTTC(""));
+ /*
+ * Cannot reasonably test the rest of this method without an actual truetype collection
+ * because all methods in FontFileReader are "final" and thus mocking isn't possible.
+ */
+ }
+
+ /**
+ * Test getAnsiKerning() - Tests values retrieved from the kern table in the font file.
+ */
+ public void testGetAnsiKerning() {
+ Map<Integer, Map<Integer, Integer>> ansiKerning = dejavuTTFFile.getKerning();
+ if (ansiKerning.isEmpty()) {
+ fail();
+ }
+ Integer k1 = ansiKerning.get(Integer.valueOf('A')).get(
+ Integer.valueOf('T'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-112), k1.intValue());
+ Integer k2 = ansiKerning.get(Integer.valueOf('Y')).get(Integer.valueOf('u'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-178), k2.intValue());
+
+ // DroidSansMono doens't have kerning (it's mono-spaced)
+ ansiKerning = droidmonoTTFFile.getAnsiKerning();
+ if (!ansiKerning.isEmpty()) {
+ fail("DroidSansMono shouldn't have any kerning data.");
+ }
+ }
+
+ /**
+ * Test getCapHeight - there are several paths to test:
+ * 1) The PCLT table (if present)
+ * 2) The yMax (3rd) value, for the bounding box, for 'H' in the glyf table.
+ * if not the above:
+ * 3) The caps height in the OS/2 table
+ * Tests values retrieved from analysing the font file.
+ */
+ public void testGetCapHeight() {
+ // DejaVu doesn't have the PCLT table and so these have to be guessed
+ // The height is approximated to be the height of the "H" which for
+ // Deja = 1493 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1493), dejavuTTFFile.getCapHeight());
+ // DroidSansMono doesn't have a PCLT table either
+ // height of "H" = 1462
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1462),
+ droidmonoTTFFile.getCapHeight());
+ }
+
+ /**
+ * Test getCharSetName() - check that it returns "WinAnsiEncoding".
+ */
+ public void testGetCharSetName() {
+ assertTrue("WinAnsiEncoding".equals(dejavuTTFFile.getCharSetName()));
+ assertTrue("WinAnsiEncoding".equals(droidmonoTTFFile.getCharSetName()));
+ }
+
+ /**
+ * Test getCharWidth() - Test values retrieved from the metrics in the glyf table in
+ * the font file.
+ */
+ public void testGetCharWidth() {
+ // Arbitrarily test a few values:
+ // The width of "H" (Unicode index 0x0048) is 1786
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1786), dejavuTTFFile.getCharWidth(0x48));
+ // The width of "i" (unicode index 0x0069) is 655 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(655), dejavuTTFFile.getCharWidth(0x69));
+ // final check, "!" (unicode index 0x0021) is 823 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(823), dejavuTTFFile.getCharWidth(0x21));
+
+ // All the glyphs should be the same width in DroidSansMono (mono-spaced)
+ int charWidth = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229);
+ for (int i = 0; i < 255; i++) {
+ assertEquals(charWidth, droidmonoTTFFile.getCharWidth(i));
+ }
+ }
+
+ /**
+ * TODO: add implementation to this test
+ */
+ public void testGetCMaps() {
+ }
+
+ /**
+ * Test getFamilyNames() - Test value retrieved from the name table in the font file.
+ */
+ public void testGetFamilyNames() {
+ assertEquals(1, dejavuTTFFile.getFamilyNames().size());
+ for (String name : dejavuTTFFile.getFamilyNames()) {
+ assertEquals("DejaVu LGC Serif", name);
+ }
+ assertEquals(1, droidmonoTTFFile.getFamilyNames().size());
+ for (String name : droidmonoTTFFile.getFamilyNames()) {
+ assertEquals("Droid Sans Mono", name);
+ }
+ }
+
+ /**
+ * Test getFirstChar() - TODO: implement a more intelligent test here.
+ */
+ public void testGetFirstChar() {
+ // Not really sure how to test this intelligently
+ assertEquals(0, dejavuTTFFile.getFirstChar());
+ assertEquals(0, droidmonoTTFFile.getFirstChar());
+ }
+
+ /**
+ * Test getFlags() - Test values retrieved from the POST table in the font file.
+ */
+ public void testGetFlags() {
+ /* DejaVu flags are:
+ * italic angle = 0
+ * fixed pitch = 0
+ * has serifs = true (default value; this font doesn't have a PCLT table)
+ */
+ int flags = dejavuTTFFile.getFlags();
+ assertEquals(0, flags & 64); // Italics angle = 0
+ assertEquals(32, flags & 32); // Adobe standard charset
+ assertEquals(0, flags & 2); // fixed pitch = 0
+ assertEquals(1, flags & 1); // has serifs = 1 (true)
+ /*
+ * Droid flags are:
+ * italic angle = 0
+ * fixed pitch = 1
+ * has serifs = true (default value; this font doesn't have a PCLT table)
+ */
+ flags = droidmonoTTFFile.getFlags();
+ assertEquals(0, flags & 64);
+ assertEquals(32, flags & 32);
+ assertEquals(2, flags & 2);
+ assertEquals(1, flags & 1);
+ }
+
+ /**
+ * Test getFontBBox() - Test values retrieved from values in the HEAD table in the font file.
+ */
+ public void testGetFontBBox() {
+ int[] bBox = dejavuTTFFile.getFontBBox();
+ /*
+ * The head table has the following values(DejaVu):
+ * xmin = -1576, ymin = -710, xmax = 3439, ymax = 2544
+ */
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-1576), bBox[0]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-710), bBox[1]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(3439), bBox[2]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(2544), bBox[3]);
+ /*
+ * The head table has the following values (DroidSansMono):
+ * xmin = -312, ymin= -555, xmax = 1315, ymax = 2163
+ */
+ bBox = droidmonoTTFFile.getFontBBox();
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(-312), bBox[0]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(-555), bBox[1]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1315), bBox[2]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(2163), bBox[3]);
+ }
+
+ /**
+ * Test getFullName() - Test value retrieved from the name table in the font file.
+ */
+ public void testGetFullName() {
+ assertEquals("DejaVu LGC Serif", dejavuTTFFile.getFullName());
+ assertEquals("Droid Sans Mono", droidmonoTTFFile.getFullName());
+ }
+
+ /**
+ * Test getGlyphName - Test value retrieved from the POST table in the font file.
+ */
+ public void testGetGlyphName() {
+ assertEquals("H", dejavuTTFFile.getGlyphName(43));
+ assertEquals("H", droidmonoTTFFile.getGlyphName(43));
+ }
+
+ /**
+ * Test getItalicAngle() - Test value retrieved from the POST table in the font file.
+ */
+ public void testGetItalicAngle() {
+ assertEquals("0", dejavuTTFFile.getItalicAngle());
+ assertEquals("0", droidmonoTTFFile.getItalicAngle());
+ }
+
+ /**
+ * Test getKerning() - Test values retrieved from the kern table in the font file.
+ */
+ public void testGetKerning() {
+ Map<Integer, Map<Integer, Integer>> kerning = dejavuTTFFile.getKerning();
+ if (kerning.isEmpty()) {
+ fail();
+ }
+ Integer k1 = kerning.get(Integer.valueOf('A')).get(Integer.valueOf('T'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-112), k1.intValue());
+ Integer k2 = kerning.get(Integer.valueOf('K')).get(Integer.valueOf('u'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-45), k2.intValue());
+
+ // DroidSansMono has no kerning data (mono-spaced)
+ kerning = droidmonoTTFFile.getKerning();
+ if (!kerning.isEmpty()) {
+ fail("DroidSansMono shouldn't have any kerning data");
+ }
+ }
+
+ /**
+ * Test lastChar() - TODO: implement a more intelligent test
+ */
+ public void testLastChar() {
+ assertEquals(0xff, dejavuTTFFile.getLastChar());
+ assertEquals(0xff, droidmonoTTFFile.getLastChar());
+ }
+
+ /**
+ * Test getLowerCaseAscent() - There are several paths to test:
+ * 1) The values in the HHEA table (see code)
+ * 2) Fall back to values from the OS/2 table
+ * Test values retrieved from the font file.
+ */
+ public void testGetLowerCaseAscent() {
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1556),
+ dejavuTTFFile.getLowerCaseAscent());
+ // Curiously the same value
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1556),
+ droidmonoTTFFile.getLowerCaseAscent());
+ }
+
+ /**
+ * Test getPostScriptName() - Test values retrieved from the post table in the font file.
+ */
+ public void testGetPostScriptName() {
+ assertEquals(PostScriptVersion.V2, dejavuTTFFile.getPostScriptVersion());
+ assertEquals(PostScriptVersion.V2, droidmonoTTFFile.getPostScriptVersion());
+ }
+
+ /**
+ * Test getStemV() - Undefined.
+ */
+ public void testGetStemV() {
+ // Undefined
+ assertEquals("0", dejavuTTFFile.getStemV());
+ assertEquals("0", droidmonoTTFFile.getStemV());
+ }
+
+ /**
+ * Test getSubFamilyName() - Test values retrieved from the name table in the font file.
+ */
+ public void testGetSubFamilyName() {
+ assertEquals("Book", dejavuTTFFile.getSubFamilyName());
+ assertEquals("Regular", droidmonoTTFFile.getSubFamilyName());
+ }
+
+ /**
+ * Test getTTCnames() - TODO: add implementation with TTC font.
+ */
+ public void testGetTTCnames() {
+ // Can't test with with DejaVu since it's not a TrueType Collection
+ }
+
+ /**
+ * Test getWeightClass() - Test value retrieved from the OS/2 table in the font file.
+ */
+ public void testGetWeightClass() {
+ // Retrieved from OS/2 table
+ assertEquals(400, dejavuTTFFile.getWeightClass());
+ assertEquals(400, droidmonoTTFFile.getWeightClass());
+ }
+
+ /**
+ * Test getWidths() - Test values retrieved from the hmtx table in the font file.
+ */
+ public void testGetWidths() {
+ int[] widths = dejavuTTFFile.getWidths();
+ // using the width of 'A' index = 36
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1479), widths[36]);
+ // using the width of '|' index = 95
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(690), widths[95]);
+ widths = droidmonoTTFFile.getWidths();
+ // DroidSansMono should have all widths the same size (mono-spaced)
+ int width = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229);
+ for (int i = 0; i < 255; i++) {
+ assertEquals(width, widths[i]);
+ }
+ }
+
+ /**
+ * Test getXHeight() - There are several paths to test:
+ * 1) The PCLT table (if available)
+ * 2) The yMax for the bounding box for 'x' in the glyf table.
+ * Fall back:
+ * 3) The xheight in the OS/2 table.
+ */
+ public void testGetXHeight() {
+ // Since there's no PCLT table, the height of 'x' is used for both DejaVu and DroidSansMono
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1064), dejavuTTFFile.getXHeight());
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1098), droidmonoTTFFile.getXHeight());
+ }
+
+ /**
+ * Test isCFF() - TODO: add test for a CFF font.
+ */
+ public void testIsCFF() {
+ // Neither DejaVu nor DroidSansMono are a compact format font
+ assertEquals(false, dejavuTTFFile.isCFF());
+ assertEquals(false, droidmonoTTFFile.isCFF());
+ }
+
+ /**
+ * Test isEmbeddable() - Test value retrieved from the OS/2 table in the font file.
+ */
+ public void testIsEmbeddable() {
+ // Dejavu and DroidSansMono are both embeddable
+ assertEquals(true, dejavuTTFFile.isEmbeddable());
+ assertEquals(true, droidmonoTTFFile.isEmbeddable());
+ }
+
+ /**
+ * Test readFont() - Add implementation if necessary.
+ */
+ public void testReadFont() {
+ // I'm pretty sure we've tested this with all the other tests
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTest.java b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTest.java
new file mode 100644
index 000000000..b0ced70e8
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class tests TTFSubSetFile
+ * TODO: Test with more than just a single font
+ */
+public class TTFSubSetFileTest extends TTFFileTest {
+ private TTFSubSetFile ttfSubset;
+ private byte[] subset;
+ /**
+ * Constructor
+ * @throws IOException exception
+ */
+ public TTFSubSetFileTest() throws IOException {
+ super();
+ }
+
+ /**
+ * setUp()
+ * @exception IOException file read error
+ */
+ public void setUp() throws IOException {
+ ttfSubset = new TTFSubSetFile();
+ Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>();
+ for (int i = 0; i < 255; i++) {
+ glyphs.put(i, i);
+ }
+ ttfSubset.readFont(dejavuReader, "DejaVu", glyphs);
+ subset = ttfSubset.getFontSubset();
+ }
+ /**
+ * Test readFont(FontFileReader, String, Map) - Reads the font and tests the output by injecting
+ * it into a TTFFile object to check the validity of the file as a font. This currently doesn't
+ * create a cmap table, and so the font doesn't contain ALL of the mandatory tables.
+ * @throws IOException exception
+ */
+ public void testReadFont3Args() throws IOException {
+
+ ByteArrayInputStream byteArray = new ByteArrayInputStream(subset);
+ dejavuTTFFile.readFont(new FontFileReader(byteArray));
+ // Test a couple arbitrary values
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-1576), dejavuTTFFile.getFontBBox()[0]);
+ assertEquals(dejavuTTFFile.getFullName(), "DejaVu LGC Serif");
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFTableNameTest.java b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTest.java
new file mode 100644
index 000000000..224dad8a3
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * This class tests the enum org.apache.fop.fonts.truetype.TTFTableName
+ *
+ */
+public class TTFTableNameTest extends TestCase {
+ /**
+ * Test getName() - tests that the getName() method returns the expected String as expected in
+ * the Directory Table.
+ * @exception IllegalAccessException error
+ */
+ public void testGetName() throws IllegalAccessException {
+ assertEquals("dirTable", TTFTableName.DIRECTORY_TABLE.getName());
+ assertEquals("EBDT", TTFTableName.EBDT.getName());
+ assertEquals("EBLC", TTFTableName.EBLC.getName());
+ assertEquals("EBSC", TTFTableName.EBSC.getName());
+ assertEquals("FFTM", TTFTableName.FFTM.getName());
+ assertEquals("GDEF", TTFTableName.GDEF.getName());
+ assertEquals("GPOS", TTFTableName.GPOS.getName());
+ assertEquals("GSUB", TTFTableName.GSUB.getName());
+ assertEquals("LTSH", TTFTableName.LTSH.getName());
+ assertEquals("OS/2", TTFTableName.OS2.getName());
+ assertEquals("PCLT", TTFTableName.PCLT.getName());
+ assertEquals("VDMX", TTFTableName.VDMX.getName());
+ assertEquals("cmap", TTFTableName.CMAP.getName());
+ assertEquals("cvt ", TTFTableName.CVT.getName());
+ assertEquals("fpgm", TTFTableName.FPGM.getName());
+ assertEquals("gasp", TTFTableName.GASP.getName());
+ assertEquals("glyf", TTFTableName.GLYF.getName());
+ assertEquals("hdmx", TTFTableName.HDMX.getName());
+ assertEquals("head", TTFTableName.HEAD.getName());
+ assertEquals("hhea", TTFTableName.HHEA.getName());
+ assertEquals("hmtx", TTFTableName.HMTX.getName());
+ assertEquals("kern", TTFTableName.KERN.getName());
+ assertEquals("loca", TTFTableName.LOCA.getName());
+ assertEquals("maxp", TTFTableName.MAXP.getName());
+ assertEquals("name", TTFTableName.NAME.getName());
+ assertEquals("post", TTFTableName.POST.getName());
+ assertEquals("prep", TTFTableName.PREP.getName());
+ assertEquals("vhea", TTFTableName.VHEA.getName());
+ assertEquals("vmtx", TTFTableName.VMTX.getName());
+ // make sure it works with other table names
+ TTFTableName test = TTFTableName.getValue("test");
+ assertEquals("test", test.getName());
+ }
+
+ /**
+ * Test getValue(String) - tests that the getValue(String) method returns the expected
+ * TTFTableNames value when it is given a String (name of a table).
+ * @exception IllegalAccessException error
+ */
+ public void testGetValue() throws IllegalAccessException {
+ assertEquals(TTFTableName.EBDT, TTFTableName.getValue("EBDT"));
+ assertEquals(TTFTableName.EBLC, TTFTableName.getValue("EBLC"));
+ assertEquals(TTFTableName.EBSC, TTFTableName.getValue("EBSC"));
+ assertEquals(TTFTableName.FFTM, TTFTableName.getValue("FFTM"));
+ assertEquals(TTFTableName.LTSH, TTFTableName.getValue("LTSH"));
+ assertEquals(TTFTableName.OS2, TTFTableName.getValue("OS/2"));
+ assertEquals(TTFTableName.PCLT, TTFTableName.getValue("PCLT"));
+ assertEquals(TTFTableName.VDMX, TTFTableName.getValue("VDMX"));
+ assertEquals(TTFTableName.CMAP, TTFTableName.getValue("cmap"));
+ assertEquals(TTFTableName.CVT, TTFTableName.getValue("cvt "));
+ assertEquals(TTFTableName.FPGM, TTFTableName.getValue("fpgm"));
+ assertEquals(TTFTableName.GASP, TTFTableName.getValue("gasp"));
+ assertEquals(TTFTableName.GLYF, TTFTableName.getValue("glyf"));
+ assertEquals(TTFTableName.HDMX, TTFTableName.getValue("hdmx"));
+ assertEquals(TTFTableName.HEAD, TTFTableName.getValue("head"));
+ assertEquals(TTFTableName.HHEA, TTFTableName.getValue("hhea"));
+ assertEquals(TTFTableName.HMTX, TTFTableName.getValue("hmtx"));
+ assertEquals(TTFTableName.KERN, TTFTableName.getValue("kern"));
+ assertEquals(TTFTableName.LOCA, TTFTableName.getValue("loca"));
+ assertEquals(TTFTableName.MAXP, TTFTableName.getValue("maxp"));
+ assertEquals(TTFTableName.NAME, TTFTableName.getValue("name"));
+ assertEquals(TTFTableName.POST, TTFTableName.getValue("post"));
+ assertEquals(TTFTableName.PREP, TTFTableName.getValue("prep"));
+ assertEquals(TTFTableName.VHEA, TTFTableName.getValue("vhea"));
+ assertEquals(TTFTableName.VMTX, TTFTableName.getValue("vmtx"));
+ // Test that we can store a random table name and it will not fail or throw an error.
+ TTFTableName test = TTFTableName.getValue("random");
+ assertTrue(test instanceof TTFTableName);
+ }
+
+ /**
+ * This class overrides hashCode() - we need to ensure it works properly by instantiating two
+ * objects and comparing their hash-codes.
+ * @exception IllegalAccessException error
+ */
+ public void testHashCode() throws IllegalAccessException {
+ TTFTableName a = TTFTableName.getValue("testObject");
+ TTFTableName b = TTFTableName.getValue("testObject");
+ assertTrue(a.hashCode() == b.hashCode());
+ TTFTableName c = TTFTableName.getValue("fail");
+ assertFalse(a.hashCode() == c.hashCode());
+ }
+
+ /**
+ * This class overrides equals(object) - we need to test:
+ * 1) Reflexivity
+ * 2) Symmetry
+ * 3) Transitivity
+ * 4) Consistency
+ * 5) check it fails if you put in a null value
+ * @throws IllegalAccessException error
+ */
+ public void testEquals() throws IllegalAccessException {
+ // Reflexivity
+ TTFTableName a = TTFTableName.getValue("test");
+ assertTrue(a.equals(a));
+ // Symmetry
+ TTFTableName b = TTFTableName.getValue("test");
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ // Transitivity (tested with symmetry)
+ // Consistency (test that a == b is true and that a == c fails)
+ TTFTableName c = TTFTableName.getValue("fail");
+ for (int i = 0; i < 100; i++) {
+ assertTrue(a.equals(b));
+ assertFalse(a.equals(c));
+ }
+ // check with null value
+ assertFalse(a.equals(null));
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java b/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java
new file mode 100644
index 000000000..6052faeb5
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java
@@ -0,0 +1,55 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.fop.render.ps.fonts.PSTTFGeneratorTest;
+import org.apache.fop.render.ps.fonts.PSTTFGlyphOutputStreamTest;
+import org.apache.fop.render.ps.fonts.PSTTFOutputStreamTest;
+import org.apache.fop.render.ps.fonts.PSTTFTableOutputStreamTest;
+
+
+/**
+ * A test Suite for org.apache.fop.render.ps.*
+ */
+public final class RenderPSTestSuite {
+ /**
+ * Constructor.
+ */
+ private RenderPSTestSuite() {
+ }
+
+ /**
+ * Testing org.apache.fop.render.ps.*
+ * @return test
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ //$JUnit-BEGIN$
+ suite.addTest(new TestSuite(PSTTFGeneratorTest.class));
+ suite.addTest(new TestSuite(PSTTFOutputStreamTest.class));
+ suite.addTest(new TestSuite(PSTTFGlyphOutputStreamTest.class));
+ suite.addTest(new TestSuite(PSTTFTableOutputStreamTest.class));
+ //$JUnit-END$
+ return suite;
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTest.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTest.java
new file mode 100644
index 000000000..fd3d98c98
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.fonts;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+/**
+ * The test class for org.apache.fop.render.ps.fonts.PSGenerator
+ */
+public class PSTTFGeneratorTest extends TestCase {
+ private PSTTFGenerator ttfGen;
+ private ByteArrayOutputStream out = new ByteArrayOutputStream();
+ private PSGenerator gen = new PSGenerator(out);
+ private byte[] byteArray;
+
+ /**
+ * Constructor
+ */
+ public PSTTFGeneratorTest() {
+ byteArray = new byte[65536];
+ for (int i = 0; i < 65536; i++) {
+ byteArray[i] = (byte) i;
+ }
+ }
+
+ @Override
+ public void setUp() {
+ ttfGen = new PSTTFGenerator(gen);
+ }
+
+ /**
+ * Tests startString() - starts the string in an appropriate way for a PostScript file.
+ * @exception IOException write error
+ */
+ public void testStartString() throws IOException {
+ ttfGen.startString();
+ assertEquals("<\n", out.toString());
+ }
+
+ /**
+ * Test streamBytes() - tests that strings are written to file in the proper format.
+ * @throws IOException write error.
+ */
+ public void testStreamBytes() throws IOException {
+ ttfGen.streamBytes(byteArray, 0, 16);
+ assertEquals("000102030405060708090A0B0C0D0E0F", out.toString());
+ /*
+ * 65520 is the closes multiple of 80 to 65535 (max string size in PS document) and since
+ * one byte takes up two characters, 65520 / 2 - 16 (16 bytes already written)= 32744.
+ */
+ ttfGen.streamBytes(byteArray, 0, 32744);
+ // Using a regex to ensure that the format is correct
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n){819}"));
+ try {
+ ttfGen.streamBytes(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ fail("Shouldn't be able to write more than MAX_BUFFER_SIZE to a PS document");
+ } catch (UnsupportedOperationException e) {
+ // PASS
+ }
+ }
+
+ /**
+ * Test reset() - reset should reset the line counter such that when reset() is invoked the
+ * following string streamed to the PS document should be 80 chars long.
+ * @throws IOException file write error.
+ */
+ public void testReset() throws IOException {
+ ttfGen.streamBytes(byteArray, 0, 40);
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n)"));
+ ttfGen.streamBytes(byteArray, 0, 40);
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n){2}"));
+
+ }
+
+ /**
+ * Test endString() - ensures strings are ended in the PostScript document in the correct
+ * format, a "00" needs to be appended to the end of a string.
+ * @throws IOException file write error
+ */
+ public void testEndString() throws IOException {
+ ttfGen.endString();
+ assertEquals("00\n> ", out.toString());
+ out.reset();
+ // we need to check that this doesn't write more than 80 chars per line
+ ttfGen.streamBytes(byteArray, 0, 40);
+ ttfGen.endString();
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n)00\n> "));
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTest.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTest.java
new file mode 100644
index 000000000..3bd93b1ba
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.fonts;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.mockito.InOrder;
+
+/**
+ * Test class for PSTTFGlyphOutputStream
+ */
+public class PSTTFGlyphOutputStreamTest extends TestCase {
+ private PSTTFGenerator mockGen;
+ private PSTTFGlyphOutputStream glyphOut;
+
+ @Override
+ public void setUp() {
+ mockGen = mock(PSTTFGenerator.class);
+ glyphOut = new PSTTFGlyphOutputStream(mockGen);
+ }
+
+ /**
+ * Test startGlyphStream() - test that startGlyphStream() invokes reset() and startString() in
+ * PSTTFGenerator.
+ * @exception IOException file write error
+ */
+ public void testStartGlyphStream() throws IOException {
+ glyphOut.startGlyphStream();
+ verify(mockGen).startString();
+ }
+
+ /**
+ * Test streamGlyph(byte[],int,int) - tests several paths:
+ * 1) strings are properly appended
+ * 2) when total strings size > PSTTFGenerator.MAX_BUFFER_SIZE, the strings is closed and a new
+ * strings is started.
+ * 3) if a glyph of size > PSTTFGenerator.MAX_BUFFER_SIZE is attempted, an exception is thrown.
+ * @throws IOException file write error.
+ */
+ public void testStreamGlyph() throws IOException {
+ int byteArraySize = 10;
+ byte[] byteArray = new byte[byteArraySize];
+ int runs = 100;
+ for (int i = 0; i < runs; i++) {
+ glyphOut.streamGlyph(byteArray, 0, byteArraySize);
+ }
+ verify(mockGen, times(runs)).streamBytes(byteArray, 0, byteArraySize);
+
+ /*
+ * We want to run this for MAX_BUFFER_SIZE / byteArraySize so that go over the string
+ * boundary and enforce the ending and starting of a new string. Using mockito to ensure
+ * that this behaviour is performed in order (since this is an integral behavioural aspect)
+ */
+ int stringLimit = PSTTFGenerator.MAX_BUFFER_SIZE / byteArraySize;
+ for (int i = 0; i < stringLimit; i++) {
+ glyphOut.streamGlyph(byteArray, 0, byteArraySize);
+ }
+ InOrder inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen, times(stringLimit)).streamBytes(byteArray, 0, byteArraySize);
+ inOrder.verify(mockGen).endString();
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen, times(runs)).streamBytes(byteArray, 0, byteArraySize);
+
+ try {
+ glyphOut.streamGlyph(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ fail("Shouldn't allow a length > PSTTFGenerator.MAX_BUFFER_SIZE");
+ } catch (UnsupportedOperationException e) {
+ // PASS
+ }
+ }
+
+ /**
+ * Test endGlyphStream() - tests that PSTTFGenerator.endString() is invoked when this method
+ * is called.
+ * @throws IOException file write exception
+ */
+ public void testEndGlyphStream() throws IOException {
+ glyphOut.endGlyphStream();
+ verify(mockGen).endString();
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTest.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTest.java
new file mode 100644
index 000000000..f9b623f69
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.fonts;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.fop.fonts.truetype.TTFGlyphOutputStream;
+import org.apache.fop.fonts.truetype.TTFTableOutputStream;
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+/**
+ * Tests PSTTFOuputStream
+ */
+public class PSTTFOutputStreamTest extends TestCase {
+ private PSGenerator gen;
+ private PSTTFOutputStream out;
+
+ /**
+ * Assigns an OutputStream to the PSGenerator.
+ */
+ public void setUp() {
+ gen = mock(PSGenerator.class);
+ out = new PSTTFOutputStream(gen);
+ }
+
+ /**
+ * Test startFontStream() - Just tests that the font is properly initiated in the PostScript
+ * document (in this case with "/sfnts[")
+ * @throws IOException write exception.
+ */
+ public void testStartFontStream() throws IOException {
+ out.startFontStream();
+ verify(gen).write("/sfnts[");
+ }
+
+ /**
+ * Test getTableOutputStream() - we need to test that the inheritance model is properly obeyed.
+ */
+ public void testGetTableOutputStream() {
+ TTFTableOutputStream tableOut = out.getTableOutputStream();
+ assertTrue(tableOut instanceof PSTTFTableOutputStream);
+ }
+
+ /**
+ * Test getGlyphOutputStream() - we need to test that the inheritance model is properly obeyed.
+ */
+ public void testGetGlyphOutputStream() {
+ TTFGlyphOutputStream glyphOut = out.getGlyphOutputStream();
+ assertTrue(glyphOut instanceof PSTTFGlyphOutputStream);
+ }
+
+ /**
+ * Test endFontStream()
+ * @exception IOException write error.
+ */
+ public void testEndFontStream() throws IOException {
+ out.endFontStream();
+ verify(gen).writeln("] def");
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTest.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTest.java
new file mode 100644
index 000000000..41605ceb0
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.fonts;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.mockito.InOrder;
+
+/**
+ * Test class for unit testing PSTTFTableOutputStream
+ */
+public class PSTTFTableOutputStreamTest extends TestCase {
+ private PSTTFGenerator mockGen;
+ private PSTTFTableOutputStream tableOut;
+
+ @Override
+ public void setUp() {
+ mockGen = mock(PSTTFGenerator.class);
+ tableOut = new PSTTFTableOutputStream(mockGen);
+ }
+
+ /**
+ * Test streamTable() - several paths to test (2. and 3. test corner cases):
+ * 1) that a table of length < PSTTFGenerator.MAX_BUFFER_SIZE invokes the correct methods in
+ * PSTTFGenerator.
+ * 2) that a table of length > PSTTFGenerator.MAX_BUFFER_SIZE and
+ * length == n * PSTTFGenerator.MAX_BUFFER_SIZE is split up and the methods in PSTTFGenerator
+ * are invoked.
+ * 3) that a table of length > PSTTFGenerator.MAX_BUFFER_SIZE but
+ * length != n * PSTTFGenerator.MAX_BUFFER_SIZE is split up and the methods in PSTTFGenerator
+ * are invoked.
+ * @throws IOException file write error.
+ */
+ public void testStreamTable() throws IOException {
+ byte[] byteArray = new byte[PSTTFGenerator.MAX_BUFFER_SIZE * 3];
+ tableOut.streamTable(byteArray, 0, 10);
+ InOrder inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, 0, 10);
+ inOrder.verify(mockGen).endString();
+
+ setUp(); // reset all all the method calls
+ /* We're going to run this 3 times to ensure the proper method calls are invoked and all
+ * the bytes are streamed */
+ tableOut.streamTable(byteArray, 0, byteArray.length);
+ inOrder = inOrder(mockGen);
+ for (int i = 0; i < 3; i++) {
+ int offset = PSTTFGenerator.MAX_BUFFER_SIZE * i;
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, offset, PSTTFGenerator.MAX_BUFFER_SIZE);
+ inOrder.verify(mockGen).endString();
+ }
+
+ setUp(); // reset all the method calls
+ tableOut.streamTable(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE);
+ inOrder.verify(mockGen).endString();
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, PSTTFGenerator.MAX_BUFFER_SIZE, 1);
+ inOrder.verify(mockGen).endString();
+ }
+}
diff --git a/test/resources/fonts/DroidSansMono.LICENSE b/test/resources/fonts/DroidSansMono.LICENSE
new file mode 100644
index 000000000..1a96dfde6
--- /dev/null
+++ b/test/resources/fonts/DroidSansMono.LICENSE
@@ -0,0 +1,18 @@
+Copyright (C) 2008 The Android Open Source Project
+
+Licensed 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.
+
+##########
+
+This directory contains the fonts for the platform. They are licensed
+under the Apache 2 license.