From b0eefade3a3ed215b03939436710cf42c15fd937 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Tue, 12 Sep 2017 12:14:48 +0000 Subject: [PATCH] FOP-2735: Use correct offset size for FDArray git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1808111 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/fonts/truetype/OTFSubSetFile.java | 15 +--- .../fonts/truetype/OTFSubSetFileTestCase.java | 89 ++++++++++++++++--- 2 files changed, 81 insertions(+), 23 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java index 889b9512d..70ac3cb62 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java @@ -523,17 +523,7 @@ public class OTFSubSetFile extends OTFSubSetWriter { throws IOException { int offset = currentPos; List fdFonts = cffReader.getFDFonts(); - - writeCard16(uniqueNewRefs.size()); - writeByte(1); //Offset size - writeByte(1); //First offset - - int count = 1; - for (Integer uniqueNewRef : uniqueNewRefs) { - FontDict fdFont = fdFonts.get(uniqueNewRef); - count += fdFont.getByteData().length; - writeByte(count); - } + List index = new ArrayList(); for (int i = 0; i < uniqueNewRefs.size(); i++) { FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i)); @@ -548,8 +538,9 @@ public class OTFSubSetFile extends OTFSubSetWriter { + fdFontDict.get("Private").getOperandLengths().get(0), fdFontDict.get("Private").getOperandLengths().get(1), privateDictOffsets.get(i)); - writeBytes(fdFontByteData); + index.add(fdFontByteData); } + writeIndex(index); return offset; } diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java index 2b6d8adb5..8804dd1bc 100644 --- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java @@ -20,8 +20,10 @@ package org.apache.fop.fonts.truetype; import java.io.ByteArrayInputStream; +import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -34,6 +36,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -46,9 +49,6 @@ import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry; import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber; public class OTFSubSetFileTestCase extends OTFFileTestCase { - - private CFFDataReader cffReaderSourceSans; - private OTFSubSetFile sourceSansSubset; private Map glyphs = new HashMap(); /** @@ -62,11 +62,17 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { for (int i = 0; i < 256; i++) { glyphs.put(i, i); } + } + + private CFFDataReader getCFFReaderSourceSans() throws IOException { + byte[] sourceSansData = getSourceSansSubset().getFontSubset(); + return new CFFDataReader(sourceSansData); + } - sourceSansSubset = new OTFSubSetFile(); + private OTFSubSetFile getSourceSansSubset() throws IOException { + OTFSubSetFile sourceSansSubset = new OTFSubSetFile(); sourceSansSubset.readFont(sourceSansReader, "SourceSansProBold", null, glyphs); - byte[] sourceSansData = sourceSansSubset.getFontSubset(); - cffReaderSourceSans = new CFFDataReader(sourceSansData); + return sourceSansSubset; } /** @@ -75,9 +81,10 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { */ @Test public void testCharStringIndex() throws IOException { + CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans(); assertEquals(256, cffReaderSourceSans.getCharStringIndex().getNumObjects()); assertTrue(checkCorrectOffsets(cffReaderSourceSans.getCharStringIndex())); - validateCharStrings(cffReaderSourceSans, sourceSansSubset.getCFFReader()); + validateCharStrings(cffReaderSourceSans, getSourceSansSubset().getCFFReader()); } /** @@ -113,7 +120,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { List origOperands = getFullCharString(new Context(), origCharData, origCFF); List subsetOperands = getFullCharString(new Context(), charData, subsetCFF); for (int j = 0; j < origOperands.size(); j++) { - assertTrue(origOperands.get(j).equals(subsetOperands.get(j))); + assertTrue(origOperands.get(j).equals(subsetOperands.get(j))); } } } @@ -308,6 +315,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { super(number, numBytes); this.opName = opName; } + public String toString() { return String.format("[%s]", opName); } @@ -406,7 +414,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { case 37: return "flex1"; case 38: return "Reserved"; default: return "Unknown"; - } + } } /** @@ -415,6 +423,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { */ @Test public void testStringIndex() throws IOException { + CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans(); assertEquals(164, cffReaderSourceSans.getStringIndex().getNumObjects()); assertTrue(checkCorrectOffsets(cffReaderSourceSans.getStringIndex())); assertEquals("Amacron", new String(cffReaderSourceSans.getStringIndex().getValue(5))); @@ -428,6 +437,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { */ @Test public void testTopDictData() throws IOException { + CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans(); Map topDictEntries = cffReaderSourceSans.parseDictData( cffReaderSourceSans.getTopDictIndex().getData()); assertEquals(10, topDictEntries.size()); @@ -435,8 +445,8 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { @Test public void testFDSelect() throws IOException { - Assert.assertEquals(getSubset(1).length, 43); - Assert.assertEquals(getSubset(2).length, 50); + Assert.assertEquals(getSubset(1).length, 42); + Assert.assertEquals(getSubset(2).length, 49); } private byte[] getSubset(final int opLen) throws IOException { @@ -516,4 +526,61 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { assertEquals(cffReader.getTopDictEntries().get("CharStrings").getOperandLength(), 5); assertEquals(cffReader.getTopDictEntries().get("CharStrings").getByteData().length, 6); } + + @Test + public void testFDArraySize() throws IOException { + OTFSubSetFileFDArraySize otfSubSetFileFDArraySize = new OTFSubSetFileFDArraySize(); + otfSubSetFileFDArraySize.readFont(sourceSansReader, "StandardOpenType", null, glyphs); + byte[] fontSubset = otfSubSetFileFDArraySize.getFontSubset(); + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(fontSubset)); + dis.skipBytes(otfSubSetFileFDArraySize.offset); + Assert.assertEquals(dis.readUnsignedShort(), otfSubSetFileFDArraySize.fdFontCount); + Assert.assertEquals(dis.readByte(), 2); + } + + static class OTFSubSetFileFDArraySize extends OTFSubSetFile { + int offset; + int fdFontCount = 128; + + public OTFSubSetFileFDArraySize() throws IOException { + super(); + } + + protected void createCFF() throws IOException { + super.createCFF(); + writeFDArray(new ArrayList(), new ArrayList(), new ArrayList()); + } + + protected int writeFDArray(List uniqueNewRefs, List privateDictOffsets, + List fontNameSIDs) throws IOException { + List fdFonts = cffReader.getFDFonts(); + CFFDataReader.FontDict fdFont = cffReader.new FontDict() { + public byte[] getByteData() throws IOException { + return new byte[128]; + } + }; + cffReader = mock(CFFDataReader.class); + LinkedHashMap map = new LinkedHashMap(); + DICTEntry e = new DICTEntry(); + e.setOffset(1); + e.setOperandLengths(Arrays.asList(0, 0)); + map.put("FontName", e); + map.put("Private", e); + when(cffReader.parseDictData(any(byte[].class))).thenReturn(map); + when(cffReader.getFDFonts()).thenReturn(fdFonts); + + fdFonts.clear(); + uniqueNewRefs.clear(); + privateDictOffsets.clear(); + fontNameSIDs.clear(); + for (int i = 0; i < fdFontCount; i++) { + fdFonts.add(fdFont); + uniqueNewRefs.add(i); + privateDictOffsets.add(i); + fontNameSIDs.add(i); + } + offset = super.writeFDArray(uniqueNewRefs, privateDictOffsets, fontNameSIDs); + return offset; + } + } } -- 2.39.5