From b478d3e7b9cce8659f94d4299ab32f59b497e0b7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Oct 2020 13:29:48 +0200 Subject: [PATCH] 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. --- src/core/evaluator.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 2dd89eaa7abf2..d63b98757b1dd 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -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) {