Improve argument/name handling when parsing TilingPatterns (PR 12458 follow-up)

- Handle the arguments correctly in `PartialEvaluator.handleColorN`.
   For TilingPatterns with a base-ColorSpace, we're currently using the `args` when computing the color. However, as can be seen we're passing the Array as-is to the `ColorSpace.getRgb` method, which means that the `Name` is included as well.[1]
   Thankfully this hasn't, as far as I know, caused any actual bugs, but that may be more luck than anything else given how the `ColorSpace` code is implemented. This can be easily fixed though, simply by popping the `Name`-object off of the `args` Array.

 - Cache TilingPatterns using the `Name`-string, rather than the object directly.
   This is not only consistent with other caches in `PartialEvaluator`, but importantly it also ensures that the cache lookup always works correctly. Note that since `Name`-objects, similar to other primitives, uses a cache themselves a *manually* triggered `cleanup`-call could thus (theoretically) cause the `LocalTilingPatternCache` to not find an existing entry. While the likelihood of this happening is *extremely* small, it's still something that we should fix.

---
[1] The `args` Array can e.g. look like this: `[0.043, 0.09, 0.188, 0.004, /P1]`, which means that we're passing in the `Name`-object to the `ColorSpace` method.
This commit is contained in:
Jonas Jenwald 2020-10-24 13:29:48 +02:00
parent 1eaf9c961b
commit b478d3e7b9

View File

@ -1224,10 +1224,12 @@ class PartialEvaluator {
localTilingPatternCache
) {
// compile tiling patterns
const patternName = args[args.length - 1];
const patternName = args.pop();
// SCN/scn applies patterns along with normal colors
if (patternName instanceof Name) {
const localTilingPattern = localTilingPatternCache.getByName(patternName);
const name = patternName.name;
const localTilingPattern = localTilingPatternCache.getByName(name);
if (localTilingPattern) {
try {
const color = cs.base ? cs.base.getRgb(args, 0) : null;
@ -1249,7 +1251,7 @@ class PartialEvaluator {
// if and only if there are PDF documents where doing so would
// significantly improve performance.
let pattern = patterns.get(patternName.name);
let pattern = patterns.get(name);
if (pattern) {
var dict = isStream(pattern) ? pattern.dict : pattern;
var typeNum = dict.get("PatternType");
@ -1264,7 +1266,7 @@ class PartialEvaluator {
dict,
operatorList,
task,
patternName,
/* cacheKey = */ name,
localTilingPatternCache
);
} else if (typeNum === PatternType.SHADING) {