Add a GlobalColorSpaceCache to reduce unnecessary re-parsing
This complements the existing `LocalColorSpaceCache`, which is unique to each `getOperatorList`-invocation since it also caches by `Name`, which should help reduce unnecessary re-parsing especially for e.g. `ICCBased` ColorSpaces once we properly support those.
This commit is contained in:
parent
6e1cfa20d1
commit
4be79748c9
@ -83,14 +83,23 @@ class AnnotationFactory {
|
|||||||
// Only necessary to prevent the `Catalog.attachments`-getter, used
|
// Only necessary to prevent the `Catalog.attachments`-getter, used
|
||||||
// with "GoToE" actions, from throwing and thus breaking parsing:
|
// with "GoToE" actions, from throwing and thus breaking parsing:
|
||||||
pdfManager.ensureCatalog("attachments"),
|
pdfManager.ensureCatalog("attachments"),
|
||||||
|
pdfManager.ensureCatalog("globalColorSpaceCache"),
|
||||||
]).then(
|
]).then(
|
||||||
([acroForm, xfaDatasets, structTreeRoot, baseUrl, attachments]) => ({
|
([
|
||||||
|
acroForm,
|
||||||
|
xfaDatasets,
|
||||||
|
structTreeRoot,
|
||||||
|
baseUrl,
|
||||||
|
attachments,
|
||||||
|
globalColorSpaceCache,
|
||||||
|
]) => ({
|
||||||
pdfManager,
|
pdfManager,
|
||||||
acroForm: acroForm instanceof Dict ? acroForm : Dict.empty,
|
acroForm: acroForm instanceof Dict ? acroForm : Dict.empty,
|
||||||
xfaDatasets,
|
xfaDatasets,
|
||||||
structTreeRoot,
|
structTreeRoot,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
attachments,
|
attachments,
|
||||||
|
globalColorSpaceCache,
|
||||||
}),
|
}),
|
||||||
reason => {
|
reason => {
|
||||||
warn(`createGlobals: "${reason}".`);
|
warn(`createGlobals: "${reason}".`);
|
||||||
@ -3880,7 +3889,7 @@ class FreeTextAnnotation extends MarkupAnnotation {
|
|||||||
// We want to be able to add mouse listeners to the annotation.
|
// We want to be able to add mouse listeners to the annotation.
|
||||||
this.data.noHTML = false;
|
this.data.noHTML = false;
|
||||||
|
|
||||||
const { evaluatorOptions, xref } = params;
|
const { annotationGlobals, evaluatorOptions, xref } = params;
|
||||||
this.data.annotationType = AnnotationType.FREETEXT;
|
this.data.annotationType = AnnotationType.FREETEXT;
|
||||||
this.setDefaultAppearance(params);
|
this.setDefaultAppearance(params);
|
||||||
this._hasAppearance = !!this.appearance;
|
this._hasAppearance = !!this.appearance;
|
||||||
@ -3889,7 +3898,8 @@ class FreeTextAnnotation extends MarkupAnnotation {
|
|||||||
const { fontColor, fontSize } = parseAppearanceStream(
|
const { fontColor, fontSize } = parseAppearanceStream(
|
||||||
this.appearance,
|
this.appearance,
|
||||||
evaluatorOptions,
|
evaluatorOptions,
|
||||||
xref
|
xref,
|
||||||
|
annotationGlobals.globalColorSpaceCache
|
||||||
);
|
);
|
||||||
this.data.defaultAppearanceData.fontColor = fontColor;
|
this.data.defaultAppearanceData.fontColor = fontColor;
|
||||||
this.data.defaultAppearanceData.fontSize = fontSize || 10;
|
this.data.defaultAppearanceData.fontSize = fontSize || 10;
|
||||||
|
|||||||
@ -44,12 +44,12 @@ import {
|
|||||||
RefSet,
|
RefSet,
|
||||||
RefSetCache,
|
RefSetCache,
|
||||||
} from "./primitives.js";
|
} from "./primitives.js";
|
||||||
|
import { GlobalColorSpaceCache, GlobalImageCache } from "./image_utils.js";
|
||||||
import { NameTree, NumberTree } from "./name_number_tree.js";
|
import { NameTree, NumberTree } from "./name_number_tree.js";
|
||||||
import { BaseStream } from "./base_stream.js";
|
import { BaseStream } from "./base_stream.js";
|
||||||
import { clearGlobalCaches } from "./cleanup_helper.js";
|
import { clearGlobalCaches } from "./cleanup_helper.js";
|
||||||
import { ColorSpace } from "./colorspace.js";
|
import { ColorSpace } from "./colorspace.js";
|
||||||
import { FileSpec } from "./file_spec.js";
|
import { FileSpec } from "./file_spec.js";
|
||||||
import { GlobalImageCache } from "./image_utils.js";
|
|
||||||
import { MetadataParser } from "./metadata_parser.js";
|
import { MetadataParser } from "./metadata_parser.js";
|
||||||
import { StructTreeRoot } from "./struct_tree.js";
|
import { StructTreeRoot } from "./struct_tree.js";
|
||||||
|
|
||||||
@ -140,6 +140,7 @@ class Catalog {
|
|||||||
this.fontCache = new RefSetCache();
|
this.fontCache = new RefSetCache();
|
||||||
this.builtInCMapCache = new Map();
|
this.builtInCMapCache = new Map();
|
||||||
this.standardFontDataCache = new Map();
|
this.standardFontDataCache = new Map();
|
||||||
|
this.globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
this.globalImageCache = new GlobalImageCache();
|
this.globalImageCache = new GlobalImageCache();
|
||||||
this.pageKidsCountCache = new RefSetCache();
|
this.pageKidsCountCache = new RefSetCache();
|
||||||
this.pageIndexCache = new RefSetCache();
|
this.pageIndexCache = new RefSetCache();
|
||||||
@ -1171,6 +1172,7 @@ class Catalog {
|
|||||||
|
|
||||||
async cleanup(manuallyTriggered = false) {
|
async cleanup(manuallyTriggered = false) {
|
||||||
clearGlobalCaches();
|
clearGlobalCaches();
|
||||||
|
this.globalColorSpaceCache.clear();
|
||||||
this.globalImageCache.clear(/* onlyData = */ manuallyTriggered);
|
this.globalImageCache.clear(/* onlyData = */ manuallyTriggered);
|
||||||
this.pageKidsCountCache.clear();
|
this.pageKidsCountCache.clear();
|
||||||
this.pageIndexCache.clear();
|
this.pageIndexCache.clear();
|
||||||
|
|||||||
@ -306,19 +306,20 @@ class ColorSpace {
|
|||||||
return shadow(this, "usesZeroToOneRange", true);
|
return shadow(this, "usesZeroToOneRange", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static #cache(
|
||||||
* @private
|
cacheKey,
|
||||||
*/
|
xref,
|
||||||
static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {
|
globalColorSpaceCache,
|
||||||
if (!localColorSpaceCache) {
|
localColorSpaceCache,
|
||||||
|
parsedCS
|
||||||
|
) {
|
||||||
|
if (!globalColorSpaceCache || !localColorSpaceCache) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'ColorSpace._cache - expected "localColorSpaceCache" argument.'
|
'ColorSpace.#cache - expected "globalColorSpaceCache"/"localColorSpaceCache" argument.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!parsedColorSpace) {
|
if (!parsedCS) {
|
||||||
throw new Error(
|
throw new Error('ColorSpace.#cache - expected "parsedCS" argument.');
|
||||||
'ColorSpace._cache - expected "parsedColorSpace" argument.'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let csName, csRef;
|
let csName, csRef;
|
||||||
if (cacheKey instanceof Ref) {
|
if (cacheKey instanceof Ref) {
|
||||||
@ -331,20 +332,31 @@ class ColorSpace {
|
|||||||
csName = cacheKey.name;
|
csName = cacheKey.name;
|
||||||
}
|
}
|
||||||
if (csName || csRef) {
|
if (csName || csRef) {
|
||||||
localColorSpaceCache.set(csName, csRef, parsedColorSpace);
|
localColorSpaceCache.set(csName, csRef, parsedCS);
|
||||||
|
|
||||||
|
if (csRef) {
|
||||||
|
globalColorSpaceCache.set(/* name = */ null, csRef, parsedCS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCached(cacheKey, xref, localColorSpaceCache) {
|
static getCached(
|
||||||
if (!localColorSpaceCache) {
|
cacheKey,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache,
|
||||||
|
localColorSpaceCache
|
||||||
|
) {
|
||||||
|
if (!globalColorSpaceCache || !localColorSpaceCache) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'ColorSpace.getCached - expected "localColorSpaceCache" argument.'
|
'ColorSpace.getCached - expected "globalColorSpaceCache"/"localColorSpaceCache" argument.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (cacheKey instanceof Ref) {
|
if (cacheKey instanceof Ref) {
|
||||||
const localColorSpace = localColorSpaceCache.getByRef(cacheKey);
|
const cachedCS =
|
||||||
if (localColorSpace) {
|
globalColorSpaceCache.getByRef(cacheKey) ||
|
||||||
return localColorSpace;
|
localColorSpaceCache.getByRef(cacheKey);
|
||||||
|
if (cachedCS) {
|
||||||
|
return cachedCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -357,10 +369,7 @@ class ColorSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cacheKey instanceof Name) {
|
if (cacheKey instanceof Name) {
|
||||||
const localColorSpace = localColorSpaceCache.getByName(cacheKey.name);
|
return localColorSpaceCache.getByName(cacheKey.name) || null;
|
||||||
if (localColorSpace) {
|
|
||||||
return localColorSpace;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -370,26 +379,28 @@ class ColorSpace {
|
|||||||
xref,
|
xref,
|
||||||
resources = null,
|
resources = null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
}) {
|
}) {
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||||
assert(
|
assert(
|
||||||
!this.getCached(cs, xref, localColorSpaceCache),
|
!this.getCached(cs, xref, globalColorSpaceCache, localColorSpaceCache),
|
||||||
"Expected `ColorSpace.getCached` to have been manually checked " +
|
"Expected `ColorSpace.getCached` to have been manually checked " +
|
||||||
"before calling `ColorSpace.parseAsync`."
|
"before calling `ColorSpace.parseAsync`."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const parsedColorSpace = this._parse(
|
const parsedCS = this.#parse(cs, xref, resources, pdfFunctionFactory);
|
||||||
cs,
|
|
||||||
xref,
|
|
||||||
resources,
|
|
||||||
pdfFunctionFactory
|
|
||||||
);
|
|
||||||
|
|
||||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||||
this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
|
this.#cache(
|
||||||
|
cs,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache,
|
||||||
|
localColorSpaceCache,
|
||||||
|
parsedCS
|
||||||
|
);
|
||||||
|
|
||||||
return parsedColorSpace;
|
return parsedCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static parse({
|
static parse({
|
||||||
@ -397,29 +408,33 @@ class ColorSpace {
|
|||||||
xref,
|
xref,
|
||||||
resources = null,
|
resources = null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
}) {
|
}) {
|
||||||
const cachedColorSpace = this.getCached(cs, xref, localColorSpaceCache);
|
const cachedCS = this.getCached(
|
||||||
if (cachedColorSpace) {
|
|
||||||
return cachedColorSpace;
|
|
||||||
}
|
|
||||||
const parsedColorSpace = this._parse(
|
|
||||||
cs,
|
cs,
|
||||||
xref,
|
xref,
|
||||||
resources,
|
globalColorSpaceCache,
|
||||||
pdfFunctionFactory
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
|
if (cachedCS) {
|
||||||
|
return cachedCS;
|
||||||
|
}
|
||||||
|
const parsedCS = this.#parse(cs, xref, resources, pdfFunctionFactory);
|
||||||
|
|
||||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||||
this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
|
this.#cache(
|
||||||
|
cs,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache,
|
||||||
|
localColorSpaceCache,
|
||||||
|
parsedCS
|
||||||
|
);
|
||||||
|
|
||||||
return parsedColorSpace;
|
return parsedCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static #parse(cs, xref, resources = null, pdfFunctionFactory) {
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
static _parse(cs, xref, resources = null, pdfFunctionFactory) {
|
|
||||||
cs = xref.fetchIfRef(cs);
|
cs = xref.fetchIfRef(cs);
|
||||||
if (cs instanceof Name) {
|
if (cs instanceof Name) {
|
||||||
switch (cs.name) {
|
switch (cs.name) {
|
||||||
@ -443,7 +458,7 @@ class ColorSpace {
|
|||||||
const resourcesCS = colorSpaces.get(cs.name);
|
const resourcesCS = colorSpaces.get(cs.name);
|
||||||
if (resourcesCS) {
|
if (resourcesCS) {
|
||||||
if (resourcesCS instanceof Name) {
|
if (resourcesCS instanceof Name) {
|
||||||
return this._parse(
|
return this.#parse(
|
||||||
resourcesCS,
|
resourcesCS,
|
||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
@ -493,7 +508,7 @@ class ColorSpace {
|
|||||||
numComps = dict.get("N");
|
numComps = dict.get("N");
|
||||||
const alt = dict.get("Alternate");
|
const alt = dict.get("Alternate");
|
||||||
if (alt) {
|
if (alt) {
|
||||||
const altCS = this._parse(alt, xref, resources, pdfFunctionFactory);
|
const altCS = this.#parse(alt, xref, resources, pdfFunctionFactory);
|
||||||
// Ensure that the number of components are correct,
|
// Ensure that the number of components are correct,
|
||||||
// and also (indirectly) that it is not a PatternCS.
|
// and also (indirectly) that it is not a PatternCS.
|
||||||
if (altCS.numComps === numComps) {
|
if (altCS.numComps === numComps) {
|
||||||
@ -512,12 +527,12 @@ class ColorSpace {
|
|||||||
case "Pattern":
|
case "Pattern":
|
||||||
baseCS = cs[1] || null;
|
baseCS = cs[1] || null;
|
||||||
if (baseCS) {
|
if (baseCS) {
|
||||||
baseCS = this._parse(baseCS, xref, resources, pdfFunctionFactory);
|
baseCS = this.#parse(baseCS, xref, resources, pdfFunctionFactory);
|
||||||
}
|
}
|
||||||
return new PatternCS(baseCS);
|
return new PatternCS(baseCS);
|
||||||
case "I":
|
case "I":
|
||||||
case "Indexed":
|
case "Indexed":
|
||||||
baseCS = this._parse(cs[1], xref, resources, pdfFunctionFactory);
|
baseCS = this.#parse(cs[1], xref, resources, pdfFunctionFactory);
|
||||||
const hiVal = Math.max(0, Math.min(xref.fetchIfRef(cs[2]), 255));
|
const hiVal = Math.max(0, Math.min(xref.fetchIfRef(cs[2]), 255));
|
||||||
const lookup = xref.fetchIfRef(cs[3]);
|
const lookup = xref.fetchIfRef(cs[3]);
|
||||||
return new IndexedCS(baseCS, hiVal, lookup);
|
return new IndexedCS(baseCS, hiVal, lookup);
|
||||||
@ -525,7 +540,7 @@ class ColorSpace {
|
|||||||
case "DeviceN":
|
case "DeviceN":
|
||||||
const name = xref.fetchIfRef(cs[1]);
|
const name = xref.fetchIfRef(cs[1]);
|
||||||
numComps = Array.isArray(name) ? name.length : 1;
|
numComps = Array.isArray(name) ? name.length : 1;
|
||||||
baseCS = this._parse(cs[2], xref, resources, pdfFunctionFactory);
|
baseCS = this.#parse(cs[2], xref, resources, pdfFunctionFactory);
|
||||||
const tintFn = pdfFunctionFactory.create(cs[3]);
|
const tintFn = pdfFunctionFactory.create(cs[3]);
|
||||||
return new AlternateCS(numComps, baseCS, tintFn);
|
return new AlternateCS(numComps, baseCS, tintFn);
|
||||||
case "Lab":
|
case "Lab":
|
||||||
|
|||||||
@ -97,11 +97,12 @@ function parseDefaultAppearance(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
|
class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
|
||||||
constructor(stream, evaluatorOptions, xref) {
|
constructor(stream, evaluatorOptions, xref, globalColorSpaceCache) {
|
||||||
super(stream);
|
super(stream);
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.evaluatorOptions = evaluatorOptions;
|
this.evaluatorOptions = evaluatorOptions;
|
||||||
this.xref = xref;
|
this.xref = xref;
|
||||||
|
this.globalColorSpaceCache = globalColorSpaceCache;
|
||||||
|
|
||||||
this.resources = stream.dict?.get("Resources");
|
this.resources = stream.dict?.get("Resources");
|
||||||
}
|
}
|
||||||
@ -161,6 +162,7 @@ class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
|
|||||||
xref: this.xref,
|
xref: this.xref,
|
||||||
resources: this.resources,
|
resources: this.resources,
|
||||||
pdfFunctionFactory: this._pdfFunctionFactory,
|
pdfFunctionFactory: this._pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
localColorSpaceCache: this._localColorSpaceCache,
|
localColorSpaceCache: this._localColorSpaceCache,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -210,8 +212,18 @@ class AppearanceStreamEvaluator extends EvaluatorPreprocessor {
|
|||||||
|
|
||||||
// Parse appearance stream to extract font and color information.
|
// Parse appearance stream to extract font and color information.
|
||||||
// It returns the font properties used to render the first text object.
|
// It returns the font properties used to render the first text object.
|
||||||
function parseAppearanceStream(stream, evaluatorOptions, xref) {
|
function parseAppearanceStream(
|
||||||
return new AppearanceStreamEvaluator(stream, evaluatorOptions, xref).parse();
|
stream,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
) {
|
||||||
|
return new AppearanceStreamEvaluator(
|
||||||
|
stream,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPdfColor(color, isFill) {
|
function getPdfColor(color, isFill) {
|
||||||
|
|||||||
@ -87,6 +87,7 @@ class Page {
|
|||||||
fontCache,
|
fontCache,
|
||||||
builtInCMapCache,
|
builtInCMapCache,
|
||||||
standardFontDataCache,
|
standardFontDataCache,
|
||||||
|
globalColorSpaceCache,
|
||||||
globalImageCache,
|
globalImageCache,
|
||||||
systemFontCache,
|
systemFontCache,
|
||||||
nonBlendModesSet,
|
nonBlendModesSet,
|
||||||
@ -100,6 +101,7 @@ class Page {
|
|||||||
this.fontCache = fontCache;
|
this.fontCache = fontCache;
|
||||||
this.builtInCMapCache = builtInCMapCache;
|
this.builtInCMapCache = builtInCMapCache;
|
||||||
this.standardFontDataCache = standardFontDataCache;
|
this.standardFontDataCache = standardFontDataCache;
|
||||||
|
this.globalColorSpaceCache = globalColorSpaceCache;
|
||||||
this.globalImageCache = globalImageCache;
|
this.globalImageCache = globalImageCache;
|
||||||
this.systemFontCache = systemFontCache;
|
this.systemFontCache = systemFontCache;
|
||||||
this.nonBlendModesSet = nonBlendModesSet;
|
this.nonBlendModesSet = nonBlendModesSet;
|
||||||
@ -327,6 +329,7 @@ class Page {
|
|||||||
fontCache: this.fontCache,
|
fontCache: this.fontCache,
|
||||||
builtInCMapCache: this.builtInCMapCache,
|
builtInCMapCache: this.builtInCMapCache,
|
||||||
standardFontDataCache: this.standardFontDataCache,
|
standardFontDataCache: this.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: this.globalImageCache,
|
globalImageCache: this.globalImageCache,
|
||||||
systemFontCache: this.systemFontCache,
|
systemFontCache: this.systemFontCache,
|
||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
@ -381,6 +384,7 @@ class Page {
|
|||||||
fontCache: this.fontCache,
|
fontCache: this.fontCache,
|
||||||
builtInCMapCache: this.builtInCMapCache,
|
builtInCMapCache: this.builtInCMapCache,
|
||||||
standardFontDataCache: this.standardFontDataCache,
|
standardFontDataCache: this.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: this.globalImageCache,
|
globalImageCache: this.globalImageCache,
|
||||||
systemFontCache: this.systemFontCache,
|
systemFontCache: this.systemFontCache,
|
||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
@ -446,6 +450,7 @@ class Page {
|
|||||||
fontCache: this.fontCache,
|
fontCache: this.fontCache,
|
||||||
builtInCMapCache: this.builtInCMapCache,
|
builtInCMapCache: this.builtInCMapCache,
|
||||||
standardFontDataCache: this.standardFontDataCache,
|
standardFontDataCache: this.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: this.globalImageCache,
|
globalImageCache: this.globalImageCache,
|
||||||
systemFontCache: this.systemFontCache,
|
systemFontCache: this.systemFontCache,
|
||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
@ -670,6 +675,7 @@ class Page {
|
|||||||
fontCache: this.fontCache,
|
fontCache: this.fontCache,
|
||||||
builtInCMapCache: this.builtInCMapCache,
|
builtInCMapCache: this.builtInCMapCache,
|
||||||
standardFontDataCache: this.standardFontDataCache,
|
standardFontDataCache: this.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: this.globalImageCache,
|
globalImageCache: this.globalImageCache,
|
||||||
systemFontCache: this.systemFontCache,
|
systemFontCache: this.systemFontCache,
|
||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
@ -742,6 +748,7 @@ class Page {
|
|||||||
fontCache: this.fontCache,
|
fontCache: this.fontCache,
|
||||||
builtInCMapCache: this.builtInCMapCache,
|
builtInCMapCache: this.builtInCMapCache,
|
||||||
standardFontDataCache: this.standardFontDataCache,
|
standardFontDataCache: this.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: this.globalImageCache,
|
globalImageCache: this.globalImageCache,
|
||||||
systemFontCache: this.systemFontCache,
|
systemFontCache: this.systemFontCache,
|
||||||
options: this.evaluatorOptions,
|
options: this.evaluatorOptions,
|
||||||
@ -1632,6 +1639,7 @@ class PDFDocument {
|
|||||||
fontCache: catalog.fontCache,
|
fontCache: catalog.fontCache,
|
||||||
builtInCMapCache: catalog.builtInCMapCache,
|
builtInCMapCache: catalog.builtInCMapCache,
|
||||||
standardFontDataCache: catalog.standardFontDataCache,
|
standardFontDataCache: catalog.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: catalog.globalColorSpaceCache,
|
||||||
globalImageCache: catalog.globalImageCache,
|
globalImageCache: catalog.globalImageCache,
|
||||||
systemFontCache: catalog.systemFontCache,
|
systemFontCache: catalog.systemFontCache,
|
||||||
nonBlendModesSet: catalog.nonBlendModesSet,
|
nonBlendModesSet: catalog.nonBlendModesSet,
|
||||||
@ -1731,6 +1739,7 @@ class PDFDocument {
|
|||||||
fontCache: catalog.fontCache,
|
fontCache: catalog.fontCache,
|
||||||
builtInCMapCache: catalog.builtInCMapCache,
|
builtInCMapCache: catalog.builtInCMapCache,
|
||||||
standardFontDataCache: catalog.standardFontDataCache,
|
standardFontDataCache: catalog.standardFontDataCache,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
globalImageCache: catalog.globalImageCache,
|
globalImageCache: catalog.globalImageCache,
|
||||||
systemFontCache: catalog.systemFontCache,
|
systemFontCache: catalog.systemFontCache,
|
||||||
nonBlendModesSet: catalog.nonBlendModesSet,
|
nonBlendModesSet: catalog.nonBlendModesSet,
|
||||||
|
|||||||
@ -221,6 +221,7 @@ class PartialEvaluator {
|
|||||||
fontCache,
|
fontCache,
|
||||||
builtInCMapCache,
|
builtInCMapCache,
|
||||||
standardFontDataCache,
|
standardFontDataCache,
|
||||||
|
globalColorSpaceCache,
|
||||||
globalImageCache,
|
globalImageCache,
|
||||||
systemFontCache,
|
systemFontCache,
|
||||||
options = null,
|
options = null,
|
||||||
@ -232,6 +233,7 @@ class PartialEvaluator {
|
|||||||
this.fontCache = fontCache;
|
this.fontCache = fontCache;
|
||||||
this.builtInCMapCache = builtInCMapCache;
|
this.builtInCMapCache = builtInCMapCache;
|
||||||
this.standardFontDataCache = standardFontDataCache;
|
this.standardFontDataCache = standardFontDataCache;
|
||||||
|
this.globalColorSpaceCache = globalColorSpaceCache;
|
||||||
this.globalImageCache = globalImageCache;
|
this.globalImageCache = globalImageCache;
|
||||||
this.systemFontCache = systemFontCache;
|
this.systemFontCache = systemFontCache;
|
||||||
this.options = options || DefaultPartialEvaluatorOptions;
|
this.options = options || DefaultPartialEvaluatorOptions;
|
||||||
@ -492,6 +494,7 @@ class PartialEvaluator {
|
|||||||
const cachedColorSpace = ColorSpace.getCached(
|
const cachedColorSpace = ColorSpace.getCached(
|
||||||
cs,
|
cs,
|
||||||
this.xref,
|
this.xref,
|
||||||
|
this.globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
if (cachedColorSpace) {
|
if (cachedColorSpace) {
|
||||||
@ -737,6 +740,7 @@ class PartialEvaluator {
|
|||||||
image,
|
image,
|
||||||
isInline,
|
isInline,
|
||||||
pdfFunctionFactory: this._pdfFunctionFactory,
|
pdfFunctionFactory: this._pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
// We force the use of RGBA_32BPP images here, because we can't handle
|
// We force the use of RGBA_32BPP images here, because we can't handle
|
||||||
@ -839,6 +843,7 @@ class PartialEvaluator {
|
|||||||
image,
|
image,
|
||||||
isInline,
|
isInline,
|
||||||
pdfFunctionFactory: this._pdfFunctionFactory,
|
pdfFunctionFactory: this._pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
})
|
})
|
||||||
.then(async imageObj => {
|
.then(async imageObj => {
|
||||||
@ -1463,6 +1468,7 @@ class PartialEvaluator {
|
|||||||
xref: this.xref,
|
xref: this.xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory: this._pdfFunctionFactory,
|
pdfFunctionFactory: this._pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: this.globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
}).catch(reason => {
|
}).catch(reason => {
|
||||||
if (reason instanceof AbortException) {
|
if (reason instanceof AbortException) {
|
||||||
@ -1496,6 +1502,7 @@ class PartialEvaluator {
|
|||||||
this.xref,
|
this.xref,
|
||||||
resources,
|
resources,
|
||||||
this._pdfFunctionFactory,
|
this._pdfFunctionFactory,
|
||||||
|
this.globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
patternIR = shadingFill.getIR();
|
patternIR = shadingFill.getIR();
|
||||||
@ -1977,6 +1984,7 @@ class PartialEvaluator {
|
|||||||
const cachedColorSpace = ColorSpace.getCached(
|
const cachedColorSpace = ColorSpace.getCached(
|
||||||
args[0],
|
args[0],
|
||||||
xref,
|
xref,
|
||||||
|
self.globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
if (cachedColorSpace) {
|
if (cachedColorSpace) {
|
||||||
@ -2002,6 +2010,7 @@ class PartialEvaluator {
|
|||||||
const cachedColorSpace = ColorSpace.getCached(
|
const cachedColorSpace = ColorSpace.getCached(
|
||||||
args[0],
|
args[0],
|
||||||
xref,
|
xref,
|
||||||
|
self.globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
if (cachedColorSpace) {
|
if (cachedColorSpace) {
|
||||||
|
|||||||
@ -100,6 +100,7 @@ class PDFImage {
|
|||||||
mask = null,
|
mask = null,
|
||||||
isMask = false,
|
isMask = false,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
}) {
|
}) {
|
||||||
this.image = image;
|
this.image = image;
|
||||||
@ -214,6 +215,7 @@ class PDFImage {
|
|||||||
xref,
|
xref,
|
||||||
resources: isInline ? res : null,
|
resources: isInline ? res : null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
this.numComps = this.colorSpace.numComps;
|
this.numComps = this.colorSpace.numComps;
|
||||||
@ -261,6 +263,7 @@ class PDFImage {
|
|||||||
image: smask,
|
image: smask,
|
||||||
isInline,
|
isInline,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
} else if (mask) {
|
} else if (mask) {
|
||||||
@ -277,6 +280,7 @@ class PDFImage {
|
|||||||
isInline,
|
isInline,
|
||||||
isMask: true,
|
isMask: true,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -297,6 +301,7 @@ class PDFImage {
|
|||||||
image,
|
image,
|
||||||
isInline = false,
|
isInline = false,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
}) {
|
}) {
|
||||||
const imageData = image;
|
const imageData = image;
|
||||||
@ -328,6 +333,7 @@ class PDFImage {
|
|||||||
smask: smaskData,
|
smask: smaskData,
|
||||||
mask: maskData,
|
mask: maskData,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,6 +169,26 @@ class RegionalImageCache extends BaseLocalCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GlobalColorSpaceCache extends BaseLocalCache {
|
||||||
|
constructor(options) {
|
||||||
|
super({ onlyRefs: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
set(name = null, ref, data) {
|
||||||
|
if (!ref) {
|
||||||
|
throw new Error('GlobalColorSpaceCache.set - expected "ref" argument.');
|
||||||
|
}
|
||||||
|
if (this._imageCache.has(ref)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._imageCache.put(ref, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this._imageCache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GlobalImageCache {
|
class GlobalImageCache {
|
||||||
static NUM_PAGES_THRESHOLD = 2;
|
static NUM_PAGES_THRESHOLD = 2;
|
||||||
|
|
||||||
@ -290,6 +310,7 @@ class GlobalImageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
GlobalColorSpaceCache,
|
||||||
GlobalImageCache,
|
GlobalImageCache,
|
||||||
LocalColorSpaceCache,
|
LocalColorSpaceCache,
|
||||||
LocalFunctionCache,
|
LocalFunctionCache,
|
||||||
|
|||||||
@ -52,6 +52,7 @@ class Pattern {
|
|||||||
xref,
|
xref,
|
||||||
res,
|
res,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
) {
|
) {
|
||||||
const dict = shading instanceof BaseStream ? shading.dict : shading;
|
const dict = shading instanceof BaseStream ? shading.dict : shading;
|
||||||
@ -66,6 +67,7 @@ class Pattern {
|
|||||||
xref,
|
xref,
|
||||||
res,
|
res,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
case ShadingType.FREE_FORM_MESH:
|
case ShadingType.FREE_FORM_MESH:
|
||||||
@ -77,6 +79,7 @@ class Pattern {
|
|||||||
xref,
|
xref,
|
||||||
res,
|
res,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
@ -114,7 +117,14 @@ class BaseShading {
|
|||||||
// Radial and axial shading have very similar implementations
|
// Radial and axial shading have very similar implementations
|
||||||
// If needed, the implementations can be broken into two classes.
|
// If needed, the implementations can be broken into two classes.
|
||||||
class RadialAxialShading extends BaseShading {
|
class RadialAxialShading extends BaseShading {
|
||||||
constructor(dict, xref, resources, pdfFunctionFactory, localColorSpaceCache) {
|
constructor(
|
||||||
|
dict,
|
||||||
|
xref,
|
||||||
|
resources,
|
||||||
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
|
localColorSpaceCache
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.shadingType = dict.get("ShadingType");
|
this.shadingType = dict.get("ShadingType");
|
||||||
let coordsLen = 0;
|
let coordsLen = 0;
|
||||||
@ -132,6 +142,7 @@ class RadialAxialShading extends BaseShading {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
this.bbox = lookupNormalRect(dict.getArray("BBox"), null);
|
this.bbox = lookupNormalRect(dict.getArray("BBox"), null);
|
||||||
@ -452,6 +463,7 @@ class MeshShading extends BaseShading {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache
|
localColorSpaceCache
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
@ -466,6 +478,7 @@ class MeshShading extends BaseShading {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
this.background = dict.has("Background")
|
this.background = dict.has("Background")
|
||||||
|
|||||||
@ -14,9 +14,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Dict, Name, Ref } from "../../src/core/primitives.js";
|
import { Dict, Name, Ref } from "../../src/core/primitives.js";
|
||||||
|
import {
|
||||||
|
GlobalColorSpaceCache,
|
||||||
|
LocalColorSpaceCache,
|
||||||
|
} from "../../src/core/image_utils.js";
|
||||||
import { Stream, StringStream } from "../../src/core/stream.js";
|
import { Stream, StringStream } from "../../src/core/stream.js";
|
||||||
import { ColorSpace } from "../../src/core/colorspace.js";
|
import { ColorSpace } from "../../src/core/colorspace.js";
|
||||||
import { LocalColorSpaceCache } from "../../src/core/image_utils.js";
|
|
||||||
import { PDFFunctionFactory } from "../../src/core/function.js";
|
import { PDFFunctionFactory } from "../../src/core/function.js";
|
||||||
import { XRefMock } from "./test_utils.js";
|
import { XRefMock } from "./test_utils.js";
|
||||||
|
|
||||||
@ -50,13 +53,15 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("ColorSpace caching", function () {
|
describe("ColorSpace caching", function () {
|
||||||
let localColorSpaceCache = null;
|
let globalColorSpaceCache, localColorSpaceCache;
|
||||||
|
|
||||||
beforeAll(function () {
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
localColorSpaceCache = new LocalColorSpaceCache();
|
localColorSpaceCache = new LocalColorSpaceCache();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(function () {
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
localColorSpaceCache = null;
|
localColorSpaceCache = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -71,6 +76,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpace1.name).toEqual("Pattern");
|
expect(colorSpace1.name).toEqual("Pattern");
|
||||||
@ -80,6 +86,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpace2.name).toEqual("Pattern");
|
expect(colorSpace2.name).toEqual("Pattern");
|
||||||
@ -89,6 +96,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: new GlobalColorSpaceCache(),
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
expect(colorSpaceNonCached.name).toEqual("Pattern");
|
expect(colorSpaceNonCached.name).toEqual("Pattern");
|
||||||
@ -98,6 +106,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpaceOther.name).toEqual("DeviceRGB");
|
expect(colorSpaceOther.name).toEqual("DeviceRGB");
|
||||||
@ -140,6 +149,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpace1.name).toEqual("CalGray");
|
expect(colorSpace1.name).toEqual("CalGray");
|
||||||
@ -149,6 +159,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpace2.name).toEqual("CalGray");
|
expect(colorSpace2.name).toEqual("CalGray");
|
||||||
@ -158,6 +169,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache: new GlobalColorSpaceCache(),
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
expect(colorSpaceNonCached.name).toEqual("CalGray");
|
expect(colorSpaceNonCached.name).toEqual("CalGray");
|
||||||
@ -167,6 +179,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources: null,
|
resources: null,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
});
|
});
|
||||||
expect(colorSpaceOther.name).toEqual("CalRGB");
|
expect(colorSpaceOther.name).toEqual("CalRGB");
|
||||||
@ -180,6 +193,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("DeviceGrayCS", function () {
|
describe("DeviceGrayCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is a Name object", function () {
|
it("should handle the case when cs is a Name object", function () {
|
||||||
const cs = Name.get("DeviceGray");
|
const cs = Name.get("DeviceGray");
|
||||||
const xref = new XRefMock([
|
const xref = new XRefMock([
|
||||||
@ -198,6 +221,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -249,6 +273,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -278,6 +303,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("DeviceRgbCS", function () {
|
describe("DeviceRgbCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is a Name object", function () {
|
it("should handle the case when cs is a Name object", function () {
|
||||||
const cs = Name.get("DeviceRGB");
|
const cs = Name.get("DeviceRGB");
|
||||||
const xref = new XRefMock([
|
const xref = new XRefMock([
|
||||||
@ -296,6 +331,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -353,6 +389,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -388,6 +425,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("DeviceCmykCS", function () {
|
describe("DeviceCmykCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is a Name object", function () {
|
it("should handle the case when cs is a Name object", function () {
|
||||||
const cs = Name.get("DeviceCMYK");
|
const cs = Name.get("DeviceCMYK");
|
||||||
const xref = new XRefMock([
|
const xref = new XRefMock([
|
||||||
@ -406,6 +453,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -463,6 +511,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -498,6 +547,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("CalGrayCS", function () {
|
describe("CalGrayCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is an array", function () {
|
it("should handle the case when cs is an array", function () {
|
||||||
const params = new Dict();
|
const params = new Dict();
|
||||||
params.set("WhitePoint", [1, 1, 1]);
|
params.set("WhitePoint", [1, 1, 1]);
|
||||||
@ -521,6 +580,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -557,6 +617,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("CalRGBCS", function () {
|
describe("CalRGBCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is an array", function () {
|
it("should handle the case when cs is an array", function () {
|
||||||
const params = new Dict();
|
const params = new Dict();
|
||||||
params.set("WhitePoint", [1, 1, 1]);
|
params.set("WhitePoint", [1, 1, 1]);
|
||||||
@ -581,6 +651,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -616,6 +687,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("LabCS", function () {
|
describe("LabCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is an array", function () {
|
it("should handle the case when cs is an array", function () {
|
||||||
const params = new Dict();
|
const params = new Dict();
|
||||||
params.set("WhitePoint", [1, 1, 1]);
|
params.set("WhitePoint", [1, 1, 1]);
|
||||||
@ -639,6 +720,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -675,6 +757,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("IndexedCS", function () {
|
describe("IndexedCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is an array", function () {
|
it("should handle the case when cs is an array", function () {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const lookup = new Stream(
|
const lookup = new Stream(
|
||||||
@ -701,6 +793,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -730,6 +823,16 @@ describe("colorspace", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("AlternateCS", function () {
|
describe("AlternateCS", function () {
|
||||||
|
let globalColorSpaceCache;
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(function () {
|
||||||
|
globalColorSpaceCache = null;
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle the case when cs is an array", function () {
|
it("should handle the case when cs is an array", function () {
|
||||||
const fnDict = new Dict();
|
const fnDict = new Dict();
|
||||||
fnDict.set("FunctionType", 4);
|
fnDict.set("FunctionType", 4);
|
||||||
@ -769,6 +872,7 @@ describe("colorspace", function () {
|
|||||||
xref,
|
xref,
|
||||||
resources,
|
resources,
|
||||||
pdfFunctionFactory,
|
pdfFunctionFactory,
|
||||||
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache: new LocalColorSpaceCache(),
|
localColorSpaceCache: new LocalColorSpaceCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
} from "../../src/core/default_appearance.js";
|
} from "../../src/core/default_appearance.js";
|
||||||
import { Dict, Name } from "../../src/core/primitives.js";
|
import { Dict, Name } from "../../src/core/primitives.js";
|
||||||
import { NullStream, StringStream } from "../../src/core/stream.js";
|
import { NullStream, StringStream } from "../../src/core/stream.js";
|
||||||
|
import { GlobalColorSpaceCache } from "../../src/core/image_utils.js";
|
||||||
import { XRefMock } from "./test_utils.js";
|
import { XRefMock } from "./test_utils.js";
|
||||||
|
|
||||||
describe("Default appearance", function () {
|
describe("Default appearance", function () {
|
||||||
@ -56,7 +57,7 @@ describe("Default appearance", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("parseAppearanceStream", () => {
|
describe("parseAppearanceStream", () => {
|
||||||
let evaluatorOptions, xref;
|
let evaluatorOptions, xref, globalColorSpaceCache;
|
||||||
|
|
||||||
beforeAll(function () {
|
beforeAll(function () {
|
||||||
evaluatorOptions = {
|
evaluatorOptions = {
|
||||||
@ -64,11 +65,13 @@ describe("Default appearance", function () {
|
|||||||
isOffscreenCanvasSupported: false,
|
isOffscreenCanvasSupported: false,
|
||||||
};
|
};
|
||||||
xref = new XRefMock();
|
xref = new XRefMock();
|
||||||
|
globalColorSpaceCache = new GlobalColorSpaceCache();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(function () {
|
afterAll(function () {
|
||||||
evaluatorOptions = null;
|
evaluatorOptions = null;
|
||||||
xref = null;
|
xref = null;
|
||||||
|
globalColorSpaceCache = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should parse a FreeText (from Acrobat) appearance", () => {
|
it("should parse a FreeText (from Acrobat) appearance", () => {
|
||||||
@ -101,9 +104,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "Helv",
|
fontName: "Helv",
|
||||||
fontColor: new Uint8ClampedArray([107, 217, 41]),
|
fontColor: new Uint8ClampedArray([107, 217, 41]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -122,9 +130,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "Helv",
|
fontName: "Helv",
|
||||||
fontColor: new Uint8ClampedArray([237, 43, 112]),
|
fontColor: new Uint8ClampedArray([237, 43, 112]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,9 +172,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "TT1",
|
fontName: "TT1",
|
||||||
fontColor: new Uint8ClampedArray([135, 78, 254]),
|
fontColor: new Uint8ClampedArray([135, 78, 254]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -182,9 +200,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "Helv",
|
fontName: "Helv",
|
||||||
fontColor: new Uint8ClampedArray([16, 124, 16]),
|
fontColor: new Uint8ClampedArray([16, 124, 16]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -208,9 +231,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "FXF0",
|
fontName: "FXF0",
|
||||||
fontColor: new Uint8ClampedArray([149, 63, 60]),
|
fontColor: new Uint8ClampedArray([149, 63, 60]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -232,9 +260,14 @@ describe("Default appearance", function () {
|
|||||||
fontName: "Invalid_font",
|
fontName: "Invalid_font",
|
||||||
fontColor: new Uint8ClampedArray([0, 85, 127]),
|
fontColor: new Uint8ClampedArray([0, 85, 127]),
|
||||||
};
|
};
|
||||||
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
|
expect(
|
||||||
result
|
parseAppearanceStream(
|
||||||
);
|
appearance,
|
||||||
|
evaluatorOptions,
|
||||||
|
xref,
|
||||||
|
globalColorSpaceCache
|
||||||
|
)
|
||||||
|
).toEqual(result);
|
||||||
expect(appearance.pos).toEqual(0);
|
expect(appearance.pos).toEqual(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user