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);
}
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() {
return offset;
}
- private class FDIndexReference {
+ private static class FDIndexReference {
private int newFDIndex;
private int oldFDIndex;
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;
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
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);
}
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();
+ }
}