Author: tilman
Date: Tue Apr 15 15:15:09 2025
New Revision: 1925096
URL: http://svn.apache.org/viewvc?rev=1925096&view=rev
Log:
PDFBOX-5987: preprocess DIV commands
Modified:
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
Modified:
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
URL:
http://svn.apache.org/viewvc/pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java?rev=1925096&r1=1925095&r2=1925096&view=diff
==============================================================================
---
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
(original)
+++
pdfbox/branches/2.0/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
Tue Apr 15 15:15:09 2025
@@ -82,6 +82,43 @@ public class Type2CharString extends Typ
{
type1Sequence = new ArrayList<Object>();
pathCount = 0;
+
+ // PDFBOX-5987: the sequence contains several "num denom DIV"
sequences whose results are used
+ // for further operations. However the converter only handles direct
arguments properly,
+ // not arguments that are created at runtime on the stack. It's not
possible to fix this
+ // by just copying the command codes because addAlternatingCurve /
addCurve require
+ // switching the sequence of arguments.
+ // The solution below just replaces all "num denom DIV" sequences with
its result.
+ // If more files with even more complex sequences appear we will have
to get rid of the
+ // converter and implement a complete renderer like with type1
charstrings.
+ List<Object> newSequence = new ArrayList<Object>(sequence.size());
+ for (int i = 0; i < sequence.size(); ++i)
+ {
+ Object obj = sequence.get(i);
+ if (obj instanceof CharStringCommand &&
+
"div".equals(CharStringCommand.TYPE2_VOCABULARY.get(((CharStringCommand)
obj).getKey())) &&
+ i >= 2)
+ {
+ Object num = sequence.get(i - 2);
+ Object den = sequence.get(i - 1);
+ if (num instanceof Number && den instanceof Number)
+ {
+ float f = ((Number) num).floatValue() / ((Number)
den).floatValue();
+ newSequence.remove(newSequence.size() - 1);
+ newSequence.remove(newSequence.size() - 1);
+ newSequence.add(f);
+ }
+ else
+ {
+ newSequence.add(sequence.get(i)); // GIGO
+ }
+ }
+ else
+ {
+ newSequence.add(sequence.get(i));
+ }
+ }
+
CharStringHandler handler = new CharStringHandler() {
@Override
public List<Number> handleCommand(List<Number> numbers,
CharStringCommand command)
@@ -89,7 +126,7 @@ public class Type2CharString extends Typ
return Type2CharString.this.handleCommand(numbers, command);
}
};
- handler.handleSequence(sequence);
+ handler.handleSequence(newSequence);
}
@SuppressWarnings(value = { "unchecked" })