diff options
author | Simon Steiner <ssteiner@apache.org> | 2017-01-17 15:00:19 +0000 |
---|---|---|
committer | Simon Steiner <ssteiner@apache.org> | 2017-01-17 15:00:19 +0000 |
commit | a9223cdc46a0d61e8f4ce9c4d7da267f6c4f933f (patch) | |
tree | 561730b34c2fd051882462d2a8f336b96d20f2b2 /fop-core | |
parent | d78aa6ee137f6095d50fba09edd66b5762bf17c6 (diff) | |
download | xmlgraphics-fop-a9223cdc46a0d61e8f4ce9c4d7da267f6c4f933f.tar.gz xmlgraphics-fop-a9223cdc46a0d61e8f4ce9c4d7da267f6c4f933f.zip |
FOP-2680: OTF font needs format 3 FDSelect due to offset size
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1779202 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'fop-core')
3 files changed, 79 insertions, 10 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/fonts/cff/CFFDataReader.java b/fop-core/src/main/java/org/apache/fop/fonts/cff/CFFDataReader.java index 3ce63a2a4..83ebd6053 100644 --- a/fop-core/src/main/java/org/apache/fop/fonts/cff/CFFDataReader.java +++ b/fop-core/src/main/java/org/apache/fop/fonts/cff/CFFDataReader.java @@ -814,7 +814,7 @@ public class CFFDataReader { } } - public class FDSelect { + public abstract class FDSelect { private int format; public void setFormat(int format) { 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 c28bca5fe..5ee54eaa8 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 @@ -415,11 +415,10 @@ public class OTFSubSetFile extends OTFFile { int gid = subsetGlyph.getKey(); int group = subsetGroups.get(gid); localIndexSubr = cffReader.getFDFonts().get(group).getLocalSubrData(); - localUniques = foundLocalUniques.get(uniqueGroups.indexOf(subsetGroups.get(gid))); + localUniques = foundLocalUniques.get(uniqueGroups.indexOf(group)); type2Parser = new Type2Parser(); - FDIndexReference newFDReference = new FDIndexReference( - uniqueGroups.indexOf(subsetGroups.get(gid)), subsetGroups.get(gid)); + FDIndexReference newFDReference = new FDIndexReference(uniqueGroups.indexOf(group), group); subsetFDSelect.put(subsetGlyph.getValue(), newFDReference); byte[] data = charStringsIndex.getValue(gid); preScanForSubsetIndexSize(data); @@ -460,10 +459,40 @@ public class OTFSubSetFile extends OTFFile { } protected void writeFDSelect() { - writeByte(0); //Format + if (cffReader.getTopDictEntries().get("CharStrings").getOperandLength() == 2) { + Map<Integer, Integer> indexs = getFormat3Index(); + writeByte(3); //Format + writeCard16(indexs.size()); + int count = 0; + for (Entry<Integer, Integer> x : indexs.entrySet()) { + writeCard16(count); + writeByte(x.getKey()); + count += x.getValue(); + } + writeCard16(subsetFDSelect.size()); + } else { + writeByte(0); //Format + for (FDIndexReference e : subsetFDSelect.values()) { + writeByte(e.getNewFDIndex()); + } + } + } + + private Map<Integer, Integer> getFormat3Index() { + Map<Integer, Integer> indexs = new LinkedHashMap<Integer, Integer>(); + int last = -1; + int count = 0; for (FDIndexReference e : subsetFDSelect.values()) { - writeByte(e.getNewFDIndex()); + int i = e.getNewFDIndex(); + count++; + if (i != last) { + indexs.put(i, count); + count = 1; + } + last = i; } + indexs.put(last, count); + return indexs; } protected List<Integer> getUsedFDFonts() { @@ -534,7 +563,7 @@ public class OTFSubSetFile extends OTFFile { return offset; } - private class FDIndexReference { + private static class FDIndexReference { private int newFDIndex; private int oldFDIndex; 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 cce22531c..d87d19be5 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 @@ -21,15 +21,20 @@ package org.apache.fop.fonts.truetype; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import org.apache.fontbox.cff.CFFFont; @@ -40,9 +45,8 @@ import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber; public class OTFSubSetFileTestCase extends OTFFileTestCase { - CFFDataReader cffReaderSourceSans; + private CFFDataReader cffReaderSourceSans; private OTFSubSetFile sourceSansSubset; - private byte[] sourceSansData; /** * Initialises the test by creating the font subset. A CFFDataReader is @@ -61,7 +65,7 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { sourceSansSubset = new OTFSubSetFile(); String sourceSansHeader = OFFontLoader.readHeader(sourceSansReader); sourceSansSubset.readFont(sourceSansReader, "SourceSansProBold", sourceSansHeader, glyphs); - sourceSansData = sourceSansSubset.getFontSubset(); + byte[] sourceSansData = sourceSansSubset.getFontSubset(); cffReaderSourceSans = new CFFDataReader(sourceSansData); } @@ -428,4 +432,40 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase { cffReaderSourceSans.getTopDictIndex().getData()); assertEquals(10, topDictEntries.size()); } + + @Test + public void testFDSelect() throws IOException { + Assert.assertEquals(getSubset(1).length, 39); + Assert.assertEquals(getSubset(2).length, 46); + } + + private byte[] getSubset(final int opLen) throws IOException { + FontFileReader reader = sourceSansReader; + String header = OFFontLoader.readHeader(reader); + + OTFSubSetFile otfSubSetFile = new OTFSubSetFile() { + protected void createCFF() throws IOException { + cffReader = mock(CFFDataReader.class); + when(cffReader.getHeader()).thenReturn(new byte[0]); + when(cffReader.getTopDictIndex()).thenReturn(new CFFDataReader().new CFFIndexData() { + public byte[] getByteData() throws IOException { + return new byte[3]; + } + }); + + LinkedHashMap<String, DICTEntry> map = new LinkedHashMap<String, DICTEntry>(); + DICTEntry dict = new DICTEntry(); + dict.setOperands(Collections.<Number>singletonList(1)); + map.put("charset", dict); + map.put("CharStrings", dict); + when((cffReader.getTopDictEntries())).thenReturn(map); + when(cffReader.getFDSelect()).thenReturn(new CFFDataReader().new Format3FDSelect()); + cffReader.getTopDictEntries().get("CharStrings").setOperandLength(opLen); + super.createCFF(); + } + }; + + otfSubSetFile.readFont(reader, "StandardOpenType", header, new HashMap<Integer, Integer>()); + return otfSubSetFile.getFontSubset(); + } } |