diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2012-03-30 19:09:29 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2012-03-30 19:09:29 +0000 |
commit | 7c8f02c57302d672fe4d0a8fc5332af6d9f0e610 (patch) | |
tree | 9be4d0493b7aa44854254ae99dc842de739d9bea /test | |
parent | 7a51f3fdb1f7ae1f526ea75f804e8f016d653cb8 (diff) | |
download | xmlgraphics-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')
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. |