/*
* 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.fonts.cff;
import java.io.IOException;
import java.util.Map;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.apache.fontbox.cff.CFFDataInput;
import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData;
import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry;
import org.apache.fop.fonts.truetype.OTFSubSetFile;
public class CFFDataReaderTestCase {
private CFFDataReader cffReader;
/**
* Initializes the CFFDataReader for testing purposes
*/
@Before
public void setUp() {
cffReader = new CFFDataReader();
}
/**
* Parses a test dictionary to verify whether the stored data is read correctly.
* @throws IOException
*/
@Test
public void parseDictData() throws IOException {
byte[] testDictData = prepareDictData();
Map<String, DICTEntry> testTopDict = cffReader.parseDictData(testDictData);
validateDictData(testTopDict);
}
private byte[] prepareDictData() {
byte[] testDictData = new byte[0];
//Version
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
392, new int[] { 0 }, -1, true));
//Notice
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
393, new int[] { 1 }, -1, true));
//Copyright
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
394, new int[] { 12, 0 }, -1, true));
//FullName
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
395, new int[] { 2 }, -1, true));
//FamilyName
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
396, new int[] { 3 }, -1, true));
//Weight
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
397, new int[] { 4 }, -1, true));
//isFixedPitch (boolean = false)
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
0, new int[] { 12, 1 }, -1, true));
//FontBBox
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
-50, new int[0], -1, true));
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
-40, new int[0], -1, true));
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
100, new int[0], -1, true));
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
120, new int[] { 5 }, -1, true));
//charset
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
1234, new int[] { 15 }, -1, true));
//CharStrings
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
3654, new int[] { 17 }, -1, true));
//Private
testDictData = OTFSubSetFile.concatArray(testDictData, OTFSubSetFile.createNewRef(
11454, new int[] { 18 }, -1, true));
return testDictData;
}
private void validateDictData(Map<String, DICTEntry> dictMap) {
//SID Values (numbers)
assertEquals(dictMap.get("version").getOperands().get(0).intValue(), 392);
assertEquals(dictMap.get("Notice").getOperands().get(0).intValue(), 393);
assertEquals(dictMap.get("Copyright").getOperands().get(0).intValue(), 394);
assertEquals(dictMap.get("FullName").getOperands().get(0).intValue(), 395);
assertEquals(dictMap.get("FamilyName").getOperands().get(0).intValue(), 396);
assertEquals(dictMap.get("Weight").getOperands().get(0).intValue(), 397);
//Boolean comparison
assertEquals(dictMap.get("isFixedPitch").getOperands().get(0).intValue(), 0);
//Array comparison
int[] fontBBox = { -50, -40, 100, 120 };
DICTEntry fontBBoxEntry = dictMap.get("FontBBox");
for (int i = 0; i < fontBBoxEntry.getOperands().size(); i++) {
assertEquals(fontBBoxEntry.getOperands().get(i).intValue(), fontBBox[i]);
}
//Multi-byte offset (number)
assertEquals(dictMap.get("charset").getOperands().get(0).intValue(), 1234);
assertEquals(dictMap.get("CharStrings").getOperands().get(0).intValue(), 3654);
//Larger offset
assertEquals(dictMap.get("Private").getOperands().get(0).intValue(), 11454);
}
/**
* Tests the parsing of an example byte data index structure
* @throws IOException
*/
@Test
public void testIndexParsing() throws IOException {
byte[] testIndex = {
0, 5, //Number of objects
1, //Offset size
1, //Offsets...
5,
12,
24,
27,
32
};
Random randGen = new Random();
byte[] data = new byte[31];
for (int i = 0; i < data.length; i++) {
data[i] = (byte)randGen.nextInt(255);
}
testIndex = OTFSubSetFile.concatArray(testIndex, data);
CFFIndexData indexData = cffReader.readIndex(new CFFDataInput(testIndex));
assertEquals(indexData.getNumObjects(), 5);
assertEquals(indexData.getOffSize(), 1);
assertEquals(indexData.getOffsets().length, 6);
assertEquals(indexData.getOffsets()[5], 32);
}
}