ソースを参照

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
tags/fop-2_3
Simon Steiner 6年前
コミット
b0eefade3a

+ 3
- 12
fop-core/src/main/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java ファイルの表示

throws IOException { throws IOException {
int offset = currentPos; int offset = currentPos;
List<FontDict> fdFonts = cffReader.getFDFonts(); List<FontDict> 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<byte[]> index = new ArrayList<byte[]>();


for (int i = 0; i < uniqueNewRefs.size(); i++) { for (int i = 0; i < uniqueNewRefs.size(); i++) {
FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i)); FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i));
+ fdFontDict.get("Private").getOperandLengths().get(0), + fdFontDict.get("Private").getOperandLengths().get(0),
fdFontDict.get("Private").getOperandLengths().get(1), fdFontDict.get("Private").getOperandLengths().get(1),
privateDictOffsets.get(i)); privateDictOffsets.get(i));
writeBytes(fdFontByteData);
index.add(fdFontByteData);
} }
writeIndex(index);
return offset; return offset;
} }



+ 78
- 11
fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java ファイルの表示

package org.apache.fop.fonts.truetype; package org.apache.fop.fonts.truetype;


import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;


import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;


import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber; import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber;


public class OTFSubSetFileTestCase extends OTFFileTestCase { public class OTFSubSetFileTestCase extends OTFFileTestCase {

private CFFDataReader cffReaderSourceSans;
private OTFSubSetFile sourceSansSubset;
private Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>(); private Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>();


/** /**
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
glyphs.put(i, 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); sourceSansSubset.readFont(sourceSansReader, "SourceSansProBold", null, glyphs);
byte[] sourceSansData = sourceSansSubset.getFontSubset();
cffReaderSourceSans = new CFFDataReader(sourceSansData);
return sourceSansSubset;
} }


/** /**
*/ */
@Test @Test
public void testCharStringIndex() throws IOException { public void testCharStringIndex() throws IOException {
CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans();
assertEquals(256, cffReaderSourceSans.getCharStringIndex().getNumObjects()); assertEquals(256, cffReaderSourceSans.getCharStringIndex().getNumObjects());
assertTrue(checkCorrectOffsets(cffReaderSourceSans.getCharStringIndex())); assertTrue(checkCorrectOffsets(cffReaderSourceSans.getCharStringIndex()));
validateCharStrings(cffReaderSourceSans, sourceSansSubset.getCFFReader());
validateCharStrings(cffReaderSourceSans, getSourceSansSubset().getCFFReader());
} }


/** /**
List<BytesNumber> origOperands = getFullCharString(new Context(), origCharData, origCFF); List<BytesNumber> origOperands = getFullCharString(new Context(), origCharData, origCFF);
List<BytesNumber> subsetOperands = getFullCharString(new Context(), charData, subsetCFF); List<BytesNumber> subsetOperands = getFullCharString(new Context(), charData, subsetCFF);
for (int j = 0; j < origOperands.size(); j++) { for (int j = 0; j < origOperands.size(); j++) {
assertTrue(origOperands.get(j).equals(subsetOperands.get(j)));
assertTrue(origOperands.get(j).equals(subsetOperands.get(j)));
} }
} }
} }
super(number, numBytes); super(number, numBytes);
this.opName = opName; this.opName = opName;
} }

public String toString() { public String toString() {
return String.format("[%s]", opName); return String.format("[%s]", opName);
} }
case 37: return "flex1"; case 37: return "flex1";
case 38: return "Reserved"; case 38: return "Reserved";
default: return "Unknown"; default: return "Unknown";
}
}
} }


/** /**
*/ */
@Test @Test
public void testStringIndex() throws IOException { public void testStringIndex() throws IOException {
CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans();
assertEquals(164, cffReaderSourceSans.getStringIndex().getNumObjects()); assertEquals(164, cffReaderSourceSans.getStringIndex().getNumObjects());
assertTrue(checkCorrectOffsets(cffReaderSourceSans.getStringIndex())); assertTrue(checkCorrectOffsets(cffReaderSourceSans.getStringIndex()));
assertEquals("Amacron", new String(cffReaderSourceSans.getStringIndex().getValue(5))); assertEquals("Amacron", new String(cffReaderSourceSans.getStringIndex().getValue(5)));
*/ */
@Test @Test
public void testTopDictData() throws IOException { public void testTopDictData() throws IOException {
CFFDataReader cffReaderSourceSans = getCFFReaderSourceSans();
Map<String, DICTEntry> topDictEntries = cffReaderSourceSans.parseDictData( Map<String, DICTEntry> topDictEntries = cffReaderSourceSans.parseDictData(
cffReaderSourceSans.getTopDictIndex().getData()); cffReaderSourceSans.getTopDictIndex().getData());
assertEquals(10, topDictEntries.size()); assertEquals(10, topDictEntries.size());


@Test @Test
public void testFDSelect() throws IOException { 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 { private byte[] getSubset(final int opLen) throws IOException {
assertEquals(cffReader.getTopDictEntries().get("CharStrings").getOperandLength(), 5); assertEquals(cffReader.getTopDictEntries().get("CharStrings").getOperandLength(), 5);
assertEquals(cffReader.getTopDictEntries().get("CharStrings").getByteData().length, 6); 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<Integer>(), new ArrayList<Integer>(), new ArrayList<Integer>());
}

protected int writeFDArray(List<Integer> uniqueNewRefs, List<Integer> privateDictOffsets,
List<Integer> fontNameSIDs) throws IOException {
List<CFFDataReader.FontDict> fdFonts = cffReader.getFDFonts();
CFFDataReader.FontDict fdFont = cffReader.new FontDict() {
public byte[] getByteData() throws IOException {
return new byte[128];
}
};
cffReader = mock(CFFDataReader.class);
LinkedHashMap<String, DICTEntry> map = new LinkedHashMap<String, DICTEntry>();
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;
}
}
} }

読み込み中…
キャンセル
保存