You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2015/11/29 15:03:20 UTC
svn commit: r1717066 -
/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
Author: lehmi
Date: Sun Nov 29 14:03:20 2015
New Revision: 1717066
URL: http://svn.apache.org/viewvc?rev=1717066&view=rev
Log:
PDFBOX-3131: reduce amount of intermediate data and objects
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java?rev=1717066&r1=1717065&r2=1717066&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java Sun Nov 29 14:03:20 2015
@@ -19,6 +19,7 @@ package org.apache.fontbox.cff;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -37,9 +38,9 @@ public class CFFParser
private CFFDataInput input = null;
@SuppressWarnings("unused")
private Header header = null;
- private List<byte[]> nameIndex = null;
+ private List<String> nameIndex = null;
private List<byte[]> topDictIndex = null;
- private List<byte[]> stringIndex = null;
+ private List<String> stringIndex = null;
// for debugging only
private String debugFontName;
@@ -104,9 +105,9 @@ public class CFFParser
}
header = readHeader(input);
- nameIndex = readIndexData(input);
+ nameIndex = readStringIndexData(input);
topDictIndex = readIndexData(input);
- stringIndex = readIndexData(input);
+ stringIndex = readStringIndexData(input);
List<byte[]> globalSubrIndex = readIndexData(input);
List<CFFFont> fonts = new ArrayList<CFFFont>();
@@ -141,13 +142,12 @@ public class CFFParser
return cffHeader;
}
- private static List<byte[]> readIndexData(CFFDataInput input) throws IOException
+ private static int[] readIndexDataOffsets(CFFDataInput input) throws IOException
{
- List<byte[]> indexDataValues = new ArrayList<byte[]>();
int count = input.readCard16();
if (count == 0)
{
- return indexDataValues;
+ return null;
}
int offSize = input.readOffSize();
int[] offsets = new int[count+1];
@@ -160,6 +160,18 @@ public class CFFParser
}
offsets[i] = offset;
}
+ return offsets;
+ }
+
+ private static List<byte[]> readIndexData(CFFDataInput input) throws IOException
+ {
+ int[] offsets = readIndexDataOffsets(input);
+ if (offsets == null)
+ {
+ return new ArrayList<byte[]>(0);
+ }
+ int count = offsets.length-1;
+ List<byte[]> indexDataValues = new ArrayList<byte[]>(count);
for (int i = 0; i < count; i++)
{
int length = offsets[i + 1] - offsets[i];
@@ -168,14 +180,29 @@ public class CFFParser
return indexDataValues;
}
+ private static List<String> readStringIndexData(CFFDataInput input) throws IOException
+ {
+ int[] offsets = readIndexDataOffsets(input);
+ if (offsets == null)
+ {
+ return new ArrayList<String>(0);
+ }
+ int count = offsets.length-1;
+ List<String> indexDataValues = new ArrayList<String>(count);
+ for (int i = 0; i < count; i++)
+ {
+ int length = offsets[i + 1] - offsets[i];
+ indexDataValues.add(new String(input.readBytes(length), "ISO-8859-1"));
+ }
+ return indexDataValues;
+ }
+
private static DictData readDictData(CFFDataInput input) throws IOException
{
DictData dict = new DictData();
- dict.entries = new ArrayList<DictData.Entry>();
while (input.hasRemaining())
{
- DictData.Entry entry = readEntry(input);
- dict.entries.add(entry);
+ dict.add(readEntry(input));
}
return dict;
}
@@ -183,12 +210,10 @@ public class CFFParser
private static DictData readDictData(CFFDataInput input, int dictSize) throws IOException
{
DictData dict = new DictData();
- dict.entries = new ArrayList<DictData.Entry>();
int endPosition = input.getPosition() + dictSize;
while (input.getPosition() < endPosition)
{
- DictData.Entry entry = readEntry(input);
- dict.entries.add(entry);
+ dict.add(readEntry(input));
}
return dict;
}
@@ -282,7 +307,7 @@ public class CFFParser
*/
private static Double readRealNumber(CFFDataInput input, int b0) throws IOException
{
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
boolean done = false;
boolean exponentMissing = false;
while (!done)
@@ -343,8 +368,7 @@ public class CFFParser
private CFFFont parseFont(int index) throws IOException
{
// name index
- DataInput nameInput = new DataInput(nameIndex.get(index));
- String name = nameInput.getString();
+ String name = nameIndex.get(index);
// top dict
CFFDataInput topDictInput = new CFFDataInput(topDictIndex.get(index));
@@ -384,20 +408,20 @@ public class CFFParser
font.addValueToTopDict("FullName", getString(topDict, "FullName"));
font.addValueToTopDict("FamilyName", getString(topDict, "FamilyName"));
font.addValueToTopDict("Weight", getString(topDict, "Weight"));
- font.addValueToTopDict("isFixedPitch", getBoolean(topDict, "isFixedPitch", false));
- font.addValueToTopDict("ItalicAngle", getNumber(topDict, "ItalicAngle", 0));
- font.addValueToTopDict("UnderlinePosition", getNumber(topDict, "UnderlinePosition", -100));
- font.addValueToTopDict("UnderlineThickness", getNumber(topDict, "UnderlineThickness", 50));
- font.addValueToTopDict("PaintType", getNumber(topDict, "PaintType", 0));
- font.addValueToTopDict("CharstringType", getNumber(topDict, "CharstringType", 2));
- font.addValueToTopDict("FontMatrix", getArray(topDict, "FontMatrix", Arrays.<Number>asList(
+ font.addValueToTopDict("isFixedPitch", topDict.getBoolean("isFixedPitch", false));
+ font.addValueToTopDict("ItalicAngle", topDict.getNumber("ItalicAngle", 0));
+ font.addValueToTopDict("UnderlinePosition", topDict.getNumber("UnderlinePosition", -100));
+ font.addValueToTopDict("UnderlineThickness", topDict.getNumber("UnderlineThickness", 50));
+ font.addValueToTopDict("PaintType", topDict.getNumber("PaintType", 0));
+ font.addValueToTopDict("CharstringType", topDict.getNumber("CharstringType", 2));
+ font.addValueToTopDict("FontMatrix", topDict.getArray("FontMatrix", Arrays.<Number>asList(
0.001, (double) 0, (double) 0, 0.001,
(double) 0, (double) 0)));
- font.addValueToTopDict("UniqueID", getNumber(topDict, "UniqueID", null));
- font.addValueToTopDict("FontBBox", getArray(topDict, "FontBBox",
+ font.addValueToTopDict("UniqueID", topDict.getNumber("UniqueID", null));
+ font.addValueToTopDict("FontBBox", topDict.getArray("FontBBox",
Arrays.<Number> asList(0, 0, 0, 0)));
- font.addValueToTopDict("StrokeWidth", getNumber(topDict, "StrokeWidth", 0));
- font.addValueToTopDict("XUID", getArray(topDict, "XUID", null));
+ font.addValueToTopDict("StrokeWidth", topDict.getNumber("StrokeWidth", 0));
+ font.addValueToTopDict("XUID", topDict.getArray("XUID", null));
// charstrings index
DictData.Entry charStringsEntry = topDict.getEntry("CharStrings");
@@ -463,7 +487,7 @@ public class CFFParser
else
{
// default
- font.addValueToTopDict("FontMatrix", getArray(topDict, "FontMatrix",
+ font.addValueToTopDict("FontMatrix", topDict.getArray("FontMatrix",
Arrays.<Number>asList(0.001, (double) 0, (double) 0, 0.001,
(double) 0, (double) 0)));
}
@@ -506,11 +530,11 @@ public class CFFParser
DictData fontDict = readDictData(fontDictInput);
// font dict
- Map<String, Object> fontDictMap = new LinkedHashMap<String, Object>();
+ Map<String, Object> fontDictMap = new LinkedHashMap<String, Object>(4);
fontDictMap.put("FontName", getString(fontDict, "FontName"));
- fontDictMap.put("FontType", getNumber(fontDict, "FontType", 0));
- fontDictMap.put("FontBBox", getDelta(fontDict, "FontBBox", null));
- fontDictMap.put("FontMatrix", getDelta(fontDict, "FontMatrix", null));
+ fontDictMap.put("FontType", fontDict.getNumber("FontType", 0));
+ fontDictMap.put("FontBBox", fontDict.getArray("FontBBox", null));
+ fontDictMap.put("FontMatrix", fontDict.getArray("FontMatrix", null));
// TODO OD-4 : Add here other keys
fontDictionaries.add(fontDictMap);
@@ -531,7 +555,7 @@ public class CFFParser
privateDictionaries.add(privDict);
// local subrs
- int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", 0);
+ int localSubrOffset = (Integer) privateDict.getNumber("Subrs", 0);
if (localSubrOffset == 0)
{
privDict.put("Subrs", new ArrayList<byte[]>());
@@ -560,24 +584,24 @@ public class CFFParser
private Map<String, Object> readPrivateDict(DictData privateDict)
{
- Map<String, Object> privDict = new LinkedHashMap<String, Object>();
- privDict.put("BlueValues", getDelta(privateDict, "BlueValues", null));
- privDict.put("OtherBlues", getDelta(privateDict, "OtherBlues", null));
- privDict.put("FamilyBlues", getDelta(privateDict, "FamilyBlues", null));
- privDict.put("FamilyOtherBlues", getDelta(privateDict, "FamilyOtherBlues", null));
- privDict.put("BlueScale", getNumber(privateDict, "BlueScale", 0.039625));
- privDict.put("BlueShift", getNumber(privateDict, "BlueShift", 7));
- privDict.put("BlueFuzz", getNumber(privateDict, "BlueFuzz", 1));
- privDict.put("StdHW", getNumber(privateDict, "StdHW", null));
- privDict.put("StdVW", getNumber(privateDict, "StdVW", null));
- privDict.put("StemSnapH", getDelta(privateDict, "StemSnapH", null));
- privDict.put("StemSnapV", getDelta(privateDict, "StemSnapV", null));
- privDict.put("ForceBold", getBoolean(privateDict, "ForceBold", false));
- privDict.put("LanguageGroup", getNumber(privateDict, "LanguageGroup", 0));
- privDict.put("ExpansionFactor", getNumber(privateDict, "ExpansionFactor", 0.06));
- privDict.put("initialRandomSeed", getNumber(privateDict, "initialRandomSeed", 0));
- privDict.put("defaultWidthX", getNumber(privateDict, "defaultWidthX", 0));
- privDict.put("nominalWidthX", getNumber(privateDict, "nominalWidthX", 0));
+ Map<String, Object> privDict = new LinkedHashMap<String, Object>(17);
+ privDict.put("BlueValues", privateDict.getArray("BlueValues", null));
+ privDict.put("OtherBlues", privateDict.getArray("OtherBlues", null));
+ privDict.put("FamilyBlues", privateDict.getArray("FamilyBlues", null));
+ privDict.put("FamilyOtherBlues", privateDict.getArray("FamilyOtherBlues", null));
+ privDict.put("BlueScale", privateDict.getNumber("BlueScale", 0.039625));
+ privDict.put("BlueShift", privateDict.getNumber("BlueShift", 7));
+ privDict.put("BlueFuzz", privateDict.getNumber("BlueFuzz", 1));
+ privDict.put("StdHW", privateDict.getNumber("StdHW", null));
+ privDict.put("StdVW", privateDict.getNumber("StdVW", null));
+ privDict.put("StemSnapH", privateDict.getArray("StemSnapH", null));
+ privDict.put("StemSnapV", privateDict.getArray("StemSnapV", null));
+ privDict.put("ForceBold", privateDict.getBoolean("ForceBold", false));
+ privDict.put("LanguageGroup", privateDict.getNumber("LanguageGroup", 0));
+ privDict.put("ExpansionFactor", privateDict.getNumber("ExpansionFactor", 0.06));
+ privDict.put("initialRandomSeed", privateDict.getNumber("initialRandomSeed", 0));
+ privDict.put("defaultWidthX", privateDict.getNumber("defaultWidthX", 0));
+ privDict.put("nominalWidthX", privateDict.getNumber("nominalWidthX", 0));
return privDict;
}
@@ -625,7 +649,7 @@ public class CFFParser
}
// local subrs
- int localSubrOffset = (Integer) getNumber(privateDict, "Subrs", 0);
+ int localSubrOffset = (Integer) privateDict.getNumber("Subrs", 0);
if (localSubrOffset == 0)
{
font.addToPrivateDict("Subrs", new ArrayList<byte[]>());
@@ -645,8 +669,7 @@ public class CFFParser
}
if (index - 391 < stringIndex.size())
{
- DataInput dataInput = new DataInput(stringIndex.get(index - 391));
- return dataInput.getString();
+ return stringIndex.get(index - 391);
}
else
{
@@ -661,32 +684,6 @@ public class CFFParser
return entry != null ? readString(entry.getNumber(0).intValue()) : null;
}
- private static Boolean getBoolean(DictData dict, String name, boolean defaultValue)
- {
- DictData.Entry entry = dict.getEntry(name);
- return entry != null ? entry.getBoolean(0) : defaultValue;
- }
-
- private static Number getNumber(DictData dict, String name, Number defaultValue)
- {
- DictData.Entry entry = dict.getEntry(name);
- return entry != null ? entry.getNumber(0) : defaultValue;
- }
-
- // TODO Where is the difference to getDelta??
- private static List<Number> getArray(DictData dict, String name, List<Number> defaultValue)
- {
- DictData.Entry entry = dict.getEntry(name);
- return entry != null ? entry.getArray() : defaultValue;
- }
-
- // TODO Where is the difference to getArray??
- private static List<Number> getDelta(DictData dict, String name, List<Number> defaultValue)
- {
- DictData.Entry entry = dict.getEntry(name);
- return entry != null ? entry.getArray() : defaultValue;
- }
-
private CFFEncoding readEncoding(CFFDataInput dataInput, CFFCharset charset) throws IOException
{
int format = dataInput.readCard8();
@@ -1094,28 +1091,44 @@ public class CFFParser
*/
private static class DictData
{
+ private Map<String, Entry> entries = new HashMap<String, Entry>();
- private List<Entry> entries = null;
-
- public Entry getEntry(CFFOperator.Key key)
+ public void add(Entry entry)
{
- return getEntry(CFFOperator.getOperator(key));
+ if (entry.operator != null)
+ {
+ entries.put(entry.operator.getName(), entry);
+ }
}
-
+
public Entry getEntry(String name)
{
return getEntry(CFFOperator.getOperator(name));
}
+ public Boolean getBoolean(String name, boolean defaultValue)
+ {
+ Entry entry = getEntry(name);
+ return entry != null ? entry.getBoolean(0) : defaultValue;
+ }
+
+ public List<Number> getArray(String name, List<Number> defaultValue)
+ {
+ Entry entry = getEntry(name);
+ return entry != null ? entry.getArray() : defaultValue;
+ }
+
+ public Number getNumber(String name, Number defaultValue)
+ {
+ Entry entry = getEntry(name);
+ return entry != null ? entry.getNumber(0) : defaultValue;
+ }
+
private Entry getEntry(CFFOperator operator)
{
- for (Entry entry : entries)
+ if (operator != null && entries.containsKey(operator.getName()))
{
- // Check for null entry before comparing the Font
- if (entry != null && entry.operator != null && entry.operator.equals(operator))
- {
- return entry;
- }
+ return entries.get(operator.getName());
}
return null;
}
@@ -1160,7 +1173,6 @@ public class CFFParser
throw new IllegalArgumentException();
}
- // TODO Where is the difference to getDelta??
public List<Number> getArray()
{
return operands;