diff options
Diffstat (limited to 'test/java/org/apache/fop')
17 files changed, 1553 insertions, 17 deletions
diff --git a/test/java/org/apache/fop/UtilityCodeTestSuite.java b/test/java/org/apache/fop/UtilityCodeTestSuite.java index cf6b8875d..762b86b14 100644 --- a/test/java/org/apache/fop/UtilityCodeTestSuite.java +++ b/test/java/org/apache/fop/UtilityCodeTestSuite.java @@ -28,10 +28,13 @@ import org.apache.fop.pdf.FileIDGeneratorTestCase; import org.apache.fop.pdf.PDFDocumentGraphics2DTestCase; import org.apache.fop.pdf.PDFEncryptionJCETestCase; import org.apache.fop.pdf.PDFFactoryTestCase; +import org.apache.fop.pdf.PDFNumberTestCase; +import org.apache.fop.pdf.PDFObjectTestCase; import org.apache.fop.traits.BorderPropsTestCase; import org.apache.fop.util.BitmapImageUtilTestCase; import org.apache.fop.util.ColorUtilTestCase; import org.apache.fop.util.ElementListUtilsTestCase; +import org.apache.fop.util.HexEncoderTestCase; import org.apache.fop.util.XMLResourceBundleTestCase; /** @@ -49,7 +52,10 @@ import org.apache.fop.util.XMLResourceBundleTestCase; PDFFactoryTestCase.class, PDFEncryptionJCETestCase.class, BitmapImageUtilTestCase.class, - PDFDocumentGraphics2DTestCase.class + PDFDocumentGraphics2DTestCase.class, + PDFNumberTestCase.class, + PDFObjectTestCase.class, + HexEncoderTestCase.class }) public class UtilityCodeTestSuite { } diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java index 35748743f..20212b002 100644 --- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java +++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java @@ -47,8 +47,8 @@ public class DejaVuLGCSerifTestCase { @Before public void setUp() throws Exception { File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); - font = FontLoader.loadFont(file.toURI(), "", true, EncodingMode.AUTO, false, false, - resolver); + font = FontLoader.loadFont(file.toURI(), "", true, EmbeddingMode.AUTO, EncodingMode.AUTO, + false, false, resolver); } /** diff --git a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java index 2deec5a73..d156b908c 100644 --- a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java +++ b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java @@ -43,6 +43,7 @@ public class EmbedFontInfoTestCase { private final boolean useAdvanced = false; private final String subFontName = "Gladiator Bold"; private final EncodingMode encMode = EncodingMode.CID; + private final EmbeddingMode embedMode = EmbeddingMode.AUTO; private final FontTriplet triplet = new FontTriplet(subFontName, "bold", Font.WEIGHT_BOLD); @Before @@ -50,7 +51,7 @@ public class EmbedFontInfoTestCase { List<FontTriplet> triplets = new ArrayList<FontTriplet>(); triplets.add(triplet); sut = new EmbedFontInfo(metricsURI, kerning, useAdvanced, triplets, embedURI, subFontName, - encMode); + encMode, embedMode); } @Test @@ -80,7 +81,7 @@ public class EmbedFontInfoTestCase { @Test public void testQuirkyBoundaryCasesIsEmbedded() { sut = new EmbedFontInfo(metricsURI, kerning, useAdvanced, sut.getFontTriplets(), null, - subFontName, encMode); + subFontName, encMode, embedMode); sut.setEmbedded(true); assertFalse(sut.isEmbedded()); diff --git a/test/java/org/apache/fop/fonts/EncodingModeTestCase.java b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java index 1ec22e1ef..8cab9eb8b 100644 --- a/test/java/org/apache/fop/fonts/EncodingModeTestCase.java +++ b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java @@ -19,10 +19,13 @@ package org.apache.fop.fonts; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + +/** + * Tests {@link EncodingMode}. + */ public class EncodingModeTestCase { @Test @@ -34,8 +37,13 @@ public class EncodingModeTestCase { @Test 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")); + } + + @Test(expected = IllegalArgumentException.class) + public void getValueMustCheckForIllegalArguments() { + EncodingMode.getValue("fail"); } } 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..8e1a0040d --- /dev/null +++ b/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java @@ -0,0 +1,42 @@ +/* + * 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 org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.fonts.truetype.FontFileReaderTestCase; +import org.apache.fop.fonts.truetype.TTFFileTestCase; +import org.apache.fop.fonts.truetype.TTFSubSetFileTestCase; +import org.apache.fop.fonts.truetype.TTFTableNameTestCase; + +/** + * A test suite designed for org.apache.fop.fonts.* + */ +@RunWith(Suite.class) +@SuiteClasses({ + EncodingModeTestCase.class, + FontFileReaderTestCase.class, + TTFFileTestCase.class, + TTFSubSetFileTestCase.class, + TTFTableNameTestCase.class }) +public final class FOPFontsTestSuite { +} diff --git a/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java new file mode 100644 index 000000000..5c1fec175 --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java @@ -0,0 +1,304 @@ +/* + * 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 org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * A test class for org.apache.fop.truetype.FontFileReader + */ +public class FontFileReaderTestCase { + 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 FontFileReaderTestCase() { + 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. + */ + @Before + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + public void testGetCurrentPos() throws IOException { + fontReader.seekSet(10); + fontReader.skip(100); + assertEquals(110, fontReader.getCurrentPos()); + fontReader.readTTFByte(); + assertEquals(111, fontReader.getCurrentPos()); + } + + /** + * Test getFileSize() + */ + @Test + public void testGetFileSize() { + assertEquals(256, fontReader.getFileSize()); + } + + /** + * Test readTTFUByte() + * @throws IOException exception + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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/GlyfTableTestCase.java b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java index 3f4d859e7..204803a32 100644 --- a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java @@ -148,10 +148,10 @@ public class GlyfTableTestCase { private void setupSubsetReader(Map<Integer, Integer> glyphs) throws IOException { TTFSubSetFile fontFile = new TTFSubSetFile(); - byte[] subsetFont = fontFile.readFont(originalFontReader, "Deja", glyphs); - InputStream inputStream = new ByteArrayInputStream(subsetFont); - subsetReader = new FontFileReader(inputStream); - inputStream.close(); + fontFile.readFont(originalFontReader, "Deja", glyphs); + byte[] subsetFont = fontFile.getFontSubset(); + InputStream intputStream = new ByteArrayInputStream(subsetFont); + subsetReader = new FontFileReader(intputStream); } private void readLoca() throws IOException { diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java new file mode 100644 index 000000000..e04347032 --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java @@ -0,0 +1,435 @@ +/* + * 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.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import org.junit.Test; + +import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Class for testing org.apache.fop.fonts.truetype.TTFFile + */ +public class TTFFileTestCase { + // 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 TTFFileTestCase() throws IOException { + dejavuTTFFile = new TTFFile(); + InputStream dejaStream = new FileInputStream("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); + dejavuReader = new FontFileReader(dejaStream); + dejavuTTFFile.readFont(dejavuReader); + dejaStream.close(); + + InputStream droidStream = new FileInputStream("test/resources/fonts/ttf/DroidSansMono.ttf"); + + droidmonoTTFFile = new TTFFile(); + droidmonoReader = new FontFileReader(droidStream); + droidmonoTTFFile.readFont(droidmonoReader); + droidStream.close(); + } + + /** + * 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) + */ + @Test + 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 + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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". + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + public void testGetItalicAngle() { + assertEquals("0", dejavuTTFFile.getItalicAngle()); + assertEquals("0", droidmonoTTFFile.getItalicAngle()); + } + + /** + * Test getKerning() - Test values retrieved from the kern table in the font file. + */ + @Test + 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 + */ + @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. + */ + @Test + 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. + */ + @Test + public void testGetPostScriptName() { + assertEquals(PostScriptVersion.V2, dejavuTTFFile.getPostScriptVersion()); + assertEquals(PostScriptVersion.V2, droidmonoTTFFile.getPostScriptVersion()); + } + + /** + * Test getStemV() - Undefined. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java index b1dc571f9..063d8c781 100644 --- a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java +++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; +import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.EncodingMode; import static org.junit.Assert.assertFalse; @@ -49,12 +50,12 @@ public class TTFFontLoaderTestCase { boolean useKerning = true; TTFFontLoader fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, - EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver); + EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver); assertTrue(fontLoader.getFont().hasKerningInfo()); useKerning = false; - fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, EncodingMode.AUTO, - useKerning, useComplexScriptFeatures, resourceResolver); + fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, EmbeddingMode.AUTO, + EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resourceResolver); assertFalse(fontLoader.getFont().hasKerningInfo()); } } diff --git a/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java new file mode 100644 index 000000000..16bedad8d --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java @@ -0,0 +1,76 @@ +/* + * 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; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * This class tests TTFSubSetFile + * TODO: Test with more than just a single font + */ +public class TTFSubSetFileTestCase extends TTFFileTestCase { + private TTFSubSetFile ttfSubset; + private byte[] subset; + /** + * Constructor + * @throws IOException exception + */ + public TTFSubSetFileTestCase() throws IOException { + super(); + } + + /** + * setUp() + * @exception IOException file read error + */ + @Before + 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 + */ + @Test + 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/TTFTableNameTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.java new file mode 100644 index 000000000..b9066dc2d --- /dev/null +++ b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.java @@ -0,0 +1,153 @@ +/* + * 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 org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * This class tests the enum org.apache.fop.fonts.truetype.TTFTableName + * + */ +public class TTFTableNameTestCase { + /** + * Test getName() - tests that the getName() method returns the expected String as expected in + * the Directory Table. + * @exception IllegalAccessException error + */ + @Test + public void testGetName() throws IllegalAccessException { + assertEquals("tableDirectory", TTFTableName.TABLE_DIRECTORY.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 + */ + @Test + 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 + */ + @Test + 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 + */ + @Test + 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..2e15bf91f --- /dev/null +++ b/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java @@ -0,0 +1,43 @@ +/* + * 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 org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import org.apache.fop.render.ps.fonts.PSTTFGeneratorTestCase; +import org.apache.fop.render.ps.fonts.PSTTFGlyphOutputStreamTestCase; +import org.apache.fop.render.ps.fonts.PSTTFOutputStreamTestCase; +import org.apache.fop.render.ps.fonts.PSTTFTableOutputStreamTestCase; + + +/** + * A test Suite for org.apache.fop.render.ps.* + */ +@RunWith(Suite.class) +@SuiteClasses({ + PSTTFGeneratorTestCase.class, + PSTTFOutputStreamTestCase.class, + PSTTFGlyphOutputStreamTestCase.class, + PSTTFTableOutputStreamTestCase.class +}) +public final class RenderPSTestSuite { +} diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java new file mode 100644 index 000000000..f7f311ff8 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java @@ -0,0 +1,120 @@ +/* + * 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 org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.xmlgraphics.ps.PSGenerator; + +/** + * The test class for org.apache.fop.render.ps.fonts.PSGenerator + */ +public class PSTTFGeneratorTestCase { + private PSTTFGenerator ttfGen; + private ByteArrayOutputStream out = new ByteArrayOutputStream(); + private PSGenerator gen = new PSGenerator(out); + private byte[] byteArray; + + /** + * Constructor + */ + public PSTTFGeneratorTestCase() { + byteArray = new byte[65536]; + for (int i = 0; i < 65536; i++) { + byteArray[i] = (byte) i; + } + } + + @Before + public void setUp() { + ttfGen = new PSTTFGenerator(gen); + } + + /** + * Tests startString() - starts the string in an appropriate way for a PostScript file. + * @exception IOException write error + */ + @Test + 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. + */ + @Test + 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. + */ + @Test + 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 + */ + @Test + 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/PSTTFGlyphOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java new file mode 100644 index 000000000..82b4364c3 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java @@ -0,0 +1,109 @@ +/* + * 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.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Test class for PSTTFGlyphOutputStream + */ +public class PSTTFGlyphOutputStreamTestCase { + private PSTTFGenerator mockGen; + private PSTTFGlyphOutputStream glyphOut; + + @Before + 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 + */ + @Test + 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. + */ + @Test + 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 + */ + @Test + public void testEndGlyphStream() throws IOException { + glyphOut.endGlyphStream(); + verify(mockGen).endString(); + } +} diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java new file mode 100644 index 000000000..744f17f64 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java @@ -0,0 +1,90 @@ +/* + * 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.IOException; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.apache.xmlgraphics.ps.PSGenerator; + +import org.apache.fop.fonts.truetype.TTFGlyphOutputStream; +import org.apache.fop.fonts.truetype.TTFTableOutputStream; + +/** + * Tests PSTTFOuputStream + */ +public class PSTTFOutputStreamTestCase { + private PSGenerator gen; + private PSTTFOutputStream out; + + /** + * Assigns an OutputStream to the PSGenerator. + */ + @Before + 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. + */ + @Test + public void testStartFontStream() throws IOException { + out.startFontStream(); + verify(gen).write("/sfnts["); + } + + /** + * Test getTableOutputStream() - we need to test that the inheritance model is properly obeyed. + */ + @Test + public void testGetTableOutputStream() { + TTFTableOutputStream tableOut = out.getTableOutputStream(); + assertTrue(tableOut instanceof PSTTFTableOutputStream); + } + + /** + * Test getGlyphOutputStream() - we need to test that the inheritance model is properly obeyed. + */ + @Test + public void testGetGlyphOutputStream() { + TTFGlyphOutputStream glyphOut = out.getGlyphOutputStream(); + assertTrue(glyphOut instanceof PSTTFGlyphOutputStream); + } + + /** + * Test endFontStream() + * @exception IOException write error. + */ + @Test + public void testEndFontStream() throws IOException { + out.endFontStream(); + verify(gen).writeln("] def"); + } +} diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java new file mode 100644 index 000000000..c20c3d8b1 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java @@ -0,0 +1,87 @@ +/* + * 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.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; + +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; + +/** + * Test class for unit testing PSTTFTableOutputStream + */ +public class PSTTFTableOutputStreamTestCase { + private PSTTFGenerator mockGen; + private PSTTFTableOutputStream tableOut; + + @Before + 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. + */ + @Test + 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/java/org/apache/fop/util/HexEncoderTestCase.java b/test/java/org/apache/fop/util/HexEncoderTestCase.java new file mode 100644 index 000000000..cb366abdf --- /dev/null +++ b/test/java/org/apache/fop/util/HexEncoderTestCase.java @@ -0,0 +1,61 @@ +/* + * 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.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Test case for the conversion of characters into hex-encoded strings. + */ +public class HexEncoderTestCase { + + /** + * Tests that characters are properly encoded into hex strings. + */ + @Test + public void testEncodeChar() { + char[] digits = new char[] {'0', '0', '0', '0'}; + for (int c = 0; c <= 0xFFFF; c++) { + assertEquals(new String(digits), HexEncoder.encode((char) c)); + increment(digits); + } + } + + private static void increment(char[] digits) { + int d = 4; + do { + d--; + digits[d] = successor(digits[d]); + } while (digits[d] == '0' && d > 0); + } + + private static char successor(char d) { + if (d == '9') { + return 'A'; + } else if (d == 'F') { + return '0'; + } else { + return (char) (d + 1); + } + } + +} |