aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorRobert Meyer <rmeyer@apache.org>2015-08-10 14:15:48 +0000
committerRobert Meyer <rmeyer@apache.org>2015-08-10 14:15:48 +0000
commit399828422a499e8125d31192918134095ec1c64e (patch)
tree7d75f50155d38a4d2a8347aa4b467b0fe83f9adc /test
parenteb8f9e82d215f6daae9a0702063b0ab86ef859b3 (diff)
parent1e7790e82370eaf36efe6751667b2c369ec59ca1 (diff)
downloadxmlgraphics-fop-399828422a499e8125d31192918134095ec1c64e.tar.gz
xmlgraphics-fop-399828422a499e8125d31192918134095ec1c64e.zip
FOP-2486: Soft font support for TrueType fonts in PCL
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1695082 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
-rw-r--r--test/java/org/apache/fop/render/pcl/fonts/MockPCLTTFFontReader.java51
-rw-r--r--test/java/org/apache/fop/render/pcl/fonts/PCLByteWriterUtilTestCase.java74
-rw-r--r--test/java/org/apache/fop/render/pcl/fonts/PCLFontReaderFactoryTestCase.java52
-rw-r--r--test/java/org/apache/fop/render/pcl/fonts/PCLTTFFontReaderTestCase.java198
-rw-r--r--test/java/org/apache/fop/render/pcl/fonts/truetype/PCLTTFCharacterWriterTestCase.java76
5 files changed, 451 insertions, 0 deletions
diff --git a/test/java/org/apache/fop/render/pcl/fonts/MockPCLTTFFontReader.java b/test/java/org/apache/fop/render/pcl/fonts/MockPCLTTFFontReader.java
new file mode 100644
index 000000000..a155dd43d
--- /dev/null
+++ b/test/java/org/apache/fop/render/pcl/fonts/MockPCLTTFFontReader.java
@@ -0,0 +1,51 @@
+/*
+ * 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.pcl.fonts;
+
+import java.io.IOException;
+
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.fonts.truetype.FontFileReader;
+import org.apache.fop.fonts.truetype.TTFFile;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
+import org.apache.fop.render.pcl.fonts.truetype.PCLTTFFontReader;
+
+public class MockPCLTTFFontReader extends PCLTTFFontReader {
+
+ public MockPCLTTFFontReader(Typeface font, PCLByteWriterUtil pclByteWriter) throws IOException {
+ super(font, pclByteWriter);
+ }
+
+ @Override
+ protected void loadFont() throws IOException {
+ if (typeface instanceof CustomFontMetricsMapper) {
+ CustomFontMetricsMapper fontMetrics = (CustomFontMetricsMapper) typeface;
+ CustomFont customFont = (CustomFont) fontMetrics.getRealFont();
+ fontStream = customFont.getInputStream();
+ reader = new FontFileReader(fontStream);
+
+ ttfFont = new TTFFile();
+ ttfFont.readFont(reader, customFont.getFullName());
+ readFontTables();
+ } else {
+ // TODO - Handle when typeface is not in the expected format for a PCL TrueType object
+ }
+ }
+}
diff --git a/test/java/org/apache/fop/render/pcl/fonts/PCLByteWriterUtilTestCase.java b/test/java/org/apache/fop/render/pcl/fonts/PCLByteWriterUtilTestCase.java
new file mode 100644
index 000000000..a21f204bf
--- /dev/null
+++ b/test/java/org/apache/fop/render/pcl/fonts/PCLByteWriterUtilTestCase.java
@@ -0,0 +1,74 @@
+/*
+ * 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.pcl.fonts;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class PCLByteWriterUtilTestCase {
+ private PCLByteWriterUtil byteWriter;
+
+ @Before
+ public void setUp() {
+ byteWriter = new PCLByteWriterUtil();
+ }
+
+ @Test
+ public void testWriteMethods() throws IOException {
+ byte[] output = byteWriter.writeCommand("(s4X");
+ // 27 = PCL escape character with rest in ASCII format
+ byte[] command = {27, 40, 115, 52, 88};
+ assertArrayEquals(command, output);
+
+ byte[] resultB = byteWriter.unsignedLongInt(102494);
+ byte[] compareB = {0, 1, -112, 94};
+ assertArrayEquals(compareB, resultB);
+
+ byte[] resultC = byteWriter.unsignedInt(1024);
+ byte[] compareC = {4, 0};
+ assertArrayEquals(compareC, resultC);
+ }
+
+ @Test
+ public void testUtilMethods() throws IOException {
+ byte[] anArray = {1, 2, 3, 4, 5, 9, 10};
+ byte[] insertArray = {6, 7, 8};
+ byte[] result = byteWriter.insertIntoArray(5, anArray, insertArray);
+ byte[] compareA = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ assertArrayEquals(compareA, result);
+
+ byte[] reverse = {10, 9, 8, 7, 6};
+ byteWriter.updateDataAtLocation(compareA, reverse, 5);
+ byte[] compareB = {1, 2, 3, 4, 5, 10, 9, 8, 7, 6};
+ assertArrayEquals(compareB, compareA);
+
+ byte[] anArrayC = {1, 2, 3, 4, 5};
+ byte[] resultC = byteWriter.padBytes(anArrayC, 10);
+ byte[] compareC = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0};
+ assertArrayEquals(compareC, resultC);
+
+ byte[] resultD = byteWriter.padBytes(anArrayC, 10, 1);
+ byte[] compareD = {1, 2, 3, 4, 5, 1, 1, 1, 1, 1};
+ assertArrayEquals(compareD, resultD);
+ }
+}
diff --git a/test/java/org/apache/fop/render/pcl/fonts/PCLFontReaderFactoryTestCase.java b/test/java/org/apache/fop/render/pcl/fonts/PCLFontReaderFactoryTestCase.java
new file mode 100644
index 000000000..2860afbdf
--- /dev/null
+++ b/test/java/org/apache/fop/render/pcl/fonts/PCLFontReaderFactoryTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * 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.pcl.fonts;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.net.URI;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
+import org.apache.fop.render.pcl.fonts.truetype.PCLTTFFontReader;
+
+public class PCLFontReaderFactoryTestCase {
+ private static final String TEST_FONT_TTF = "./test/resources/fonts/ttf/DejaVuLGCSerif.ttf";
+
+ @Test
+ public void verifyTypeIdentification() throws Exception {
+ CustomFont sbFont = mock(CustomFont.class);
+ when(sbFont.getInputStream()).thenReturn(new FileInputStream(new File(TEST_FONT_TTF)));
+ when(sbFont.getEmbedFileURI()).thenReturn(new URI(TEST_FONT_TTF));
+ CustomFontMetricsMapper customFont = new CustomFontMetricsMapper(sbFont);
+ when(customFont.getFontType()).thenReturn(FontType.TRUETYPE);
+ // Have to mock the input stream twice otherwise get a Stream is closed exception
+ when(((CustomFont) customFont.getRealFont()).getInputStream()).thenReturn(
+ new FileInputStream(new File(TEST_FONT_TTF)));
+ PCLFontReaderFactory fontReaderFactory = PCLFontReaderFactory.getInstance(null);
+ assertTrue(fontReaderFactory.createInstance(customFont) instanceof PCLTTFFontReader);
+ }
+}
diff --git a/test/java/org/apache/fop/render/pcl/fonts/PCLTTFFontReaderTestCase.java b/test/java/org/apache/fop/render/pcl/fonts/PCLTTFFontReaderTestCase.java
new file mode 100644
index 000000000..5673efbb4
--- /dev/null
+++ b/test/java/org/apache/fop/render/pcl/fonts/PCLTTFFontReaderTestCase.java
@@ -0,0 +1,198 @@
+/*
+ * 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.pcl.fonts;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.SingleByteFont;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
+import org.apache.fop.render.pcl.fonts.PCLFontSegment.SegmentID;
+import org.apache.fop.render.pcl.fonts.truetype.PCLTTFFontReader;
+
+public class PCLTTFFontReaderTestCase {
+
+ private CustomFontMetricsMapper customFont = mock(CustomFontMetricsMapper.class);
+ private PCLByteWriterUtil byteWriter;
+ private static final String TEST_FONT_A = "./test/resources/fonts/ttf/DejaVuLGCSerif.ttf";
+
+ @Before
+ public void setUp() {
+ byteWriter = new PCLByteWriterUtil();
+ }
+
+ @Test
+ public void verifyFontAData() throws Exception {
+ CustomFont sbFont = mock(CustomFont.class);
+ when(sbFont.getInputStream()).thenReturn(new FileInputStream(new File(TEST_FONT_A)));
+ when(customFont.getRealFont()).thenReturn(sbFont);
+ SingleByteFont font = mock(SingleByteFont.class);
+ when(font.getGIDFromChar('h')).thenReturn(104);
+ when(font.getGIDFromChar('e')).thenReturn(101);
+ when(font.getGIDFromChar('l')).thenReturn(108);
+ when(font.getGIDFromChar('o')).thenReturn(111);
+ PCLTTFFontReader reader = new MockPCLTTFFontReader(customFont, byteWriter);
+ reader.setFont(font);
+ verifyFontData(reader);
+ validateOffsets(reader);
+ validateFontSegments(reader);
+ }
+
+ /**
+ * Compares the input font data against a sample of the data read and calculated by the reader. The assertions are
+ * made against data taken from the TrueType Font Analyzer tool.
+ * @param reader The reader
+ */
+ private void verifyFontData(PCLTTFFontReader reader) {
+ assertEquals(reader.getCellWidth(), 5015); // Bounding box X2 - X1
+ assertEquals(reader.getCellHeight(), 3254); // Bounding box Y2 - Y1
+ assertEquals(reader.getCapHeight(), 0); // OS2Table.capHeight
+ assertEquals(reader.getFontName(), "DejaVu LGC Serif"); // Full name read by TTFFont object
+ assertEquals(reader.getFirstCode(), 32); // Always 32 for bound font
+ assertEquals(reader.getLastCode(), 255); // Always 255 for bound font
+
+ // Values that require conversion tables (See PCLTTFFontReader.java)
+ assertEquals(reader.getStrokeWeight(), 0); // Weight Class 400 (regular) should be equivalent 0
+ assertEquals(reader.getSerifStyle(), 128); // Serif Style 0 should equal 0
+ assertEquals(reader.getWidthType(), 0); // Width Class 5 (regular) should be equivalent 0
+ }
+
+ private void validateOffsets(PCLTTFFontReader reader) throws IOException {
+ // Offsets are stored with their character ID with the array [offset, length]
+ Map<Integer, int[]> offsets = reader.getCharacterOffsets();
+
+ // Test data
+ int[] charC = {27644, 144}; // Char index = 99
+ int[] charDollar = {16044, 264}; // Char index = 36
+ int[] charOne = {17808, 176}; // Char index = 49
+ int[] charUpperD = {21236, 148}; // Char index = 68
+ int[] charUpperJ = {22140, 176}; // Char index = 74
+
+ assertArrayEquals(offsets.get(99), charC);
+ assertArrayEquals(offsets.get(36), charDollar);
+ assertArrayEquals(offsets.get(49), charOne);
+ assertArrayEquals(offsets.get(68), charUpperD);
+ assertArrayEquals(offsets.get(74), charUpperJ);
+ }
+
+ /**
+ * Verifies the font segment data copied originally from the TrueType font. Data was verified using TrueType Font
+ * Analyzer and PCLParaphernalia tool.
+ * @param reader The reader
+ * @throws IOException
+ */
+ private void validateFontSegments(PCLTTFFontReader reader) throws IOException {
+ HashMap<Character, Integer> mappedChars = new HashMap<Character, Integer>();
+ mappedChars.put('H', 1);
+ mappedChars.put('e', 1);
+ mappedChars.put('l', 1);
+ mappedChars.put('o', 1);
+
+ List<PCLFontSegment> segments = reader.getFontSegments(mappedChars);
+ assertEquals(segments.size(), 5);
+ for (PCLFontSegment segment : segments) {
+ if (segment.getIdentifier() == SegmentID.PA) {
+ // Panose
+ assertEquals(segment.getData().length, 10);
+ byte[] panose = {2, 6, 6, 3, 5, 6, 5, 2, 2, 4};
+ assertArrayEquals(segment.getData(), panose);
+ } else if (segment.getIdentifier() == SegmentID.GT) {
+ verifyGlobalTrueTypeData(segment, mappedChars.size());
+ } else if (segment.getIdentifier() == SegmentID.NULL) {
+ // Terminating segment
+ assertEquals(segment.getData().length, 0);
+ }
+ }
+ }
+
+ private void verifyGlobalTrueTypeData(PCLFontSegment segment, int mappedCharsSize)
+ throws IOException {
+ byte[] ttfData = segment.getData();
+ int currentPos = 0;
+ //Version
+ assertEquals(readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]}), 1);
+ assertEquals(readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]}), 0);
+ //Number of tables
+ int numTables = readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]});
+ assertEquals(numTables, 8);
+ //Search range
+ assertEquals(readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]}), 128);
+ //Entry Selector
+ assertEquals(readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]}), 3);
+ //Range shift
+ assertEquals(readInt(new byte[]{ttfData[currentPos++], ttfData[currentPos++]}), 0);
+ String[] validTags = {"head", "hhea", "hmtx", "maxp", "gdir"};
+ int matches = 0;
+ for (int i = 0; i < numTables; i++) {
+ String tag = readTag(new byte[]{ttfData[currentPos++], ttfData[currentPos++],
+ ttfData[currentPos++], ttfData[currentPos++]});
+ if (Arrays.asList(validTags).contains(tag)) {
+ matches++;
+ }
+ if (tag.equals("hmtx")) {
+ currentPos += 4;
+ int offset = readLong(new byte[]{ttfData[currentPos++], ttfData[currentPos++],
+ ttfData[currentPos++], ttfData[currentPos++]});
+ int length = readLong(new byte[]{ttfData[currentPos++], ttfData[currentPos++],
+ ttfData[currentPos++], ttfData[currentPos++]});
+ verifyHmtx(ttfData, offset, length, mappedCharsSize);
+ } else {
+ currentPos += 12;
+ }
+ }
+ assertEquals(matches, 5);
+ }
+
+ private void verifyHmtx(byte[] ttfData, int offset, int length, int mappedCharsSize)
+ throws IOException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(ttfData);
+ byte[] subsetHmtx = new byte[length];
+ bais.skip(offset);
+ bais.read(subsetHmtx);
+ assertEquals(subsetHmtx.length, (mappedCharsSize + 32) * 4);
+ }
+
+ private int readInt(byte[] bytes) {
+ return ((0xFF & bytes[0]) << 8) | (0xFF & bytes[1]);
+ }
+
+ private int readLong(byte[] bytes) {
+ return ((0xFF & bytes[0]) << 24) | ((0xFF & bytes[1]) << 16) | ((0xFF & bytes[2]) << 8)
+ | (0xFF & bytes[3]);
+ }
+
+ private String readTag(byte[] tag) {
+ return new String(tag);
+ }
+}
diff --git a/test/java/org/apache/fop/render/pcl/fonts/truetype/PCLTTFCharacterWriterTestCase.java b/test/java/org/apache/fop/render/pcl/fonts/truetype/PCLTTFCharacterWriterTestCase.java
new file mode 100644
index 000000000..04849db87
--- /dev/null
+++ b/test/java/org/apache/fop/render/pcl/fonts/truetype/PCLTTFCharacterWriterTestCase.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.render.pcl.fonts.truetype;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.truetype.FontFileReader;
+import org.apache.fop.fonts.truetype.OFFontLoader;
+import org.apache.fop.fonts.truetype.TTFFile;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
+import org.apache.fop.render.pcl.fonts.PCLByteWriterUtil;
+import org.apache.fop.render.pcl.fonts.PCLSoftFont;
+
+public class PCLTTFCharacterWriterTestCase {
+
+ private PCLTTFCharacterWriter characterWriter;
+ private PCLSoftFont softFont;
+ private CustomFontMetricsMapper customFont = mock(CustomFontMetricsMapper.class);
+ private static final String TEST_FONT_A = "./test/resources/fonts/ttf/DejaVuLGCSerif.ttf";
+
+ @Test
+ public void verifyCharacterDefinition() throws Exception {
+ CustomFont sbFont = mock(CustomFont.class);
+ when(customFont.getRealFont()).thenReturn(sbFont);
+ softFont = new PCLSoftFont(1, customFont, false);
+ TTFFile openFont = new TTFFile();
+ FontFileReader reader = new FontFileReader(new FileInputStream(new File(TEST_FONT_A)));
+ String header = OFFontLoader.readHeader(reader);
+ openFont.readFont(reader, header);
+ softFont.setOpenFont(openFont);
+ softFont.setReader(reader);
+
+ characterWriter = new PCLTTFCharacterWriter(softFont);
+ byte[] charDefinition = characterWriter.writeCharacterDefinitions("f");
+ PCLByteWriterUtil pclByteWriter = new PCLByteWriterUtil();
+ // Character command
+ byte[] command = pclByteWriter.writeCommand(String.format("*c%dE", 32));
+ assertArrayEquals(getBytes(charDefinition, 0, 6), command);
+ // Character definition command
+ byte[] charDefCommand = pclByteWriter.writeCommand(String.format("(s%dW", 210));
+ assertArrayEquals(getBytes(charDefinition, 6, 7), charDefCommand);
+ }
+
+ private byte[] getBytes(byte[] byteArray, int offset, int length) {
+ byte[] result = new byte[length];
+ int count = 0;
+ for (int i = offset; i < offset + length; i++) {
+ result[count++] = byteArray[i];
+ }
+ return result;
+ }
+}