Skip to content

Commit

Permalink
PDFBOX-5819: remove private member fields to make Type2CharStringPars…
Browse files Browse the repository at this point in the history
…er thread-safe again

git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1917601 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
lehmi committed May 9, 2024
1 parent 7883188 commit 5c7937d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 32 deletions.
3 changes: 1 addition & 2 deletions fontbox/src/main/java/org/apache/fontbox/cff/CFFCIDFont.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.fontbox.type1.Type1CharStringReader;
Expand Down Expand Up @@ -236,7 +235,7 @@ public CIDKeyedType2CharString getType2CharString(int cid) throws IOException
bytes = charStrings[0]; // .notdef
}
List<Object> type2seq = getParser().parse(bytes, globalSubrIndex,
getLocalSubrIndex(gid), String.format(Locale.US, "%04x", cid));
getLocalSubrIndex(gid));
type2 = new CIDKeyedType2CharString(reader, getName(), cid, gid, type2seq,
getDefaultWidthX(gid), getNominalWidthX(gid));
charStringCache.put(cid, type2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ private Type2CharString getType2CharString(int gid, String name) throws IOExcept
// .notdef
bytes = charStrings[0];
}
List<Object> type2seq = getParser().parse(bytes, globalSubrIndex, getLocalSubrIndex(),
name);
List<Object> type2seq = getParser().parse(bytes, globalSubrIndex, getLocalSubrIndex());
type2 = new Type2CharString(reader, getName(), name, gid, type2seq, getDefaultWidthX(),
getNominalWidthX());
charStringCache.put(gid, type2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ public class Type2CharStringParser
private static final int CALLSUBR = 10;
private static final int CALLGSUBR = 29;

private int hstemCount;
private int vstemCount;
private List<Object> sequence;
private final String fontName;
private String currentGlyph;

/**
* Constructs a new Type1CharStringParser object for a Type 1-equivalent font.
Expand All @@ -54,25 +50,19 @@ public Type2CharStringParser(String fontName)
* @param bytes the given mapping as byte array
* @param globalSubrIndex array containing all global subroutines
* @param localSubrIndex array containing all local subroutines
* @param glyphName the name of the current glyph
*
* @return the Type2 sequence
* @throws IOException if an error occurs during reading
*/
public List<Object> parse(byte[] bytes, byte[][] globalSubrIndex, byte[][] localSubrIndex,
String glyphName) throws IOException
public List<Object> parse(byte[] bytes, byte[][] globalSubrIndex, byte[][] localSubrIndex)
throws IOException
{
// reset values if the parser is used multiple times
hstemCount = 0;
vstemCount = 0;
// create a new list as it is used as return value
sequence = new ArrayList<>();
currentGlyph = glyphName;
return parseSequence(bytes, globalSubrIndex, localSubrIndex);
return parseSequence(bytes, globalSubrIndex, localSubrIndex, new ArrayList<>(), 0, 0);
}

private List<Object> parseSequence(byte[] bytes, byte[][] globalSubrIndex,
byte[][] localSubrIndex) throws IOException
byte[][] localSubrIndex, List<Object> sequence, int hstemCount, int vstemCount)
throws IOException
{
DataInput input = new DataInputByteArray(bytes);
boolean localSubroutineIndexProvided = localSubrIndex != null && localSubrIndex.length > 0;
Expand All @@ -83,15 +73,16 @@ private List<Object> parseSequence(byte[] bytes, byte[][] globalSubrIndex,
int b0 = input.readUnsignedByte();
if (b0 == CALLSUBR && localSubroutineIndexProvided)
{
processCallSubr(globalSubrIndex, localSubrIndex, localSubrIndex);
processCallSubr(globalSubrIndex, localSubrIndex, localSubrIndex, sequence);
}
else if (b0 == CALLGSUBR && globalSubroutineIndexProvided)
{
processCallSubr(globalSubrIndex, localSubrIndex, globalSubrIndex);
processCallSubr(globalSubrIndex, localSubrIndex, globalSubrIndex, sequence);
}
else if ( (b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31))
{
sequence.add(readCommand(b0, input));
sequence.add(
readCommand(b0, input, countNumbers(sequence), hstemCount, vstemCount));
}
else if (b0 == 28 || (b0 >= 32 && b0 <= 255))
{
Expand All @@ -105,15 +96,16 @@ else if (b0 == 28 || (b0 >= 32 && b0 <= 255))
return sequence;
}

private void processCallSubr(byte[][] globalSubrIndex, byte[][] localSubrIndex, byte[][] subrIndex)
private void processCallSubr(byte[][] globalSubrIndex, byte[][] localSubrIndex,
byte[][] subrIndex, List<Object> sequence)
throws IOException
{
int subrNumber = calculateSubrNumber((Integer) sequence.remove(sequence.size() - 1),
subrIndex.length);
if (subrNumber < subrIndex.length)
{
byte[] subrBytes = subrIndex[subrNumber];
parseSequence(subrBytes, globalSubrIndex, localSubrIndex);
parseSequence(subrBytes, globalSubrIndex, localSubrIndex, sequence, 0, 0);
Object lastItem = sequence.get(sequence.size() - 1);
if (lastItem instanceof CharStringCommand
&& Type2KeyWord.RET == ((CharStringCommand) lastItem).getType2KeyWord())
Expand All @@ -137,24 +129,26 @@ private int calculateSubrNumber(int operand, int subrIndexlength)
return 32768 + operand;
}

private CharStringCommand readCommand(int b0, DataInput input) throws IOException
private CharStringCommand readCommand(int b0, DataInput input, int numberCount, int hstemCount,
int vstemCount)
throws IOException
{
switch (b0)
{
case 1:
case 18:
hstemCount += countNumbers() / 2;
hstemCount += numberCount / 2;
return CharStringCommand.getInstance(b0);
case 3:
case 23:
vstemCount += countNumbers() / 2;
vstemCount += numberCount / 2;
return CharStringCommand.getInstance(b0);
case 12:
return CharStringCommand.getInstance(b0, input.readUnsignedByte());
case 19:
case 20:
vstemCount += countNumbers() / 2;
int[] value = new int[1 + getMaskLength()];
vstemCount += numberCount / 2;
int[] value = new int[1 + getMaskLength(hstemCount, vstemCount)];
value[0] = b0;

for (int i = 1; i < value.length; i++)
Expand Down Expand Up @@ -203,7 +197,7 @@ else if (b0 == 255)
}
}

private int getMaskLength()
private int getMaskLength(int hstemCount, int vstemCount)
{
int hintCount = hstemCount + vstemCount;
int length = hintCount / 8;
Expand All @@ -214,7 +208,7 @@ private int getMaskLength()
return length;
}

private int countNumbers()
private int countNumbers(List<Object> sequence)
{
int count = 0;
for (int i = sequence.size() - 1; i > -1; i--)
Expand All @@ -231,6 +225,6 @@ private int countNumbers()
@Override
public String toString()
{
return fontName + ", current glpyh " + currentGlyph;
return fontName;
}
}

0 comments on commit 5c7937d

Please sign in to comment.