1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-19 22:58:07 +02:00

Merge pull request #19623 from Snuffleupagus/PDFFunctionFactory-rm-createFromArray

Remove the `PDFFunctionFactory.createFromArray` method
This commit is contained in:
Tim van der Meij 2025-03-09 12:58:55 +01:00 committed by GitHub
commit 621258f85c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 84 deletions

View file

@ -33,78 +33,41 @@ class PDFFunctionFactory {
this.isEvalSupported = isEvalSupported !== false;
}
create(fn) {
const cachedFunction = this.getCached(fn);
if (cachedFunction) {
return cachedFunction;
}
const parsedFunction = PDFFunction.parse({
xref: this.xref,
isEvalSupported: this.isEvalSupported,
fn: fn instanceof Ref ? this.xref.fetch(fn) : fn,
});
create(fn, parseArray = false) {
let fnRef, parsedFn;
// Attempt to cache the parsed Function, by reference.
this._cache(fn, parsedFunction);
return parsedFunction;
}
createFromArray(fnObj) {
const cachedFunction = this.getCached(fnObj);
if (cachedFunction) {
return cachedFunction;
}
const parsedFunction = PDFFunction.parseArray({
xref: this.xref,
isEvalSupported: this.isEvalSupported,
fnObj: fnObj instanceof Ref ? this.xref.fetch(fnObj) : fnObj,
});
// Attempt to cache the parsed Function, by reference.
this._cache(fnObj, parsedFunction);
return parsedFunction;
}
getCached(cacheKey) {
let fnRef;
if (cacheKey instanceof Ref) {
fnRef = cacheKey;
} else if (cacheKey instanceof Dict) {
fnRef = cacheKey.objId;
} else if (cacheKey instanceof BaseStream) {
fnRef = cacheKey.dict?.objId;
// Check if the Function is cached first, to avoid re-parsing it.
if (fn instanceof Ref) {
fnRef = fn;
} else if (fn instanceof Dict) {
fnRef = fn.objId;
} else if (fn instanceof BaseStream) {
fnRef = fn.dict?.objId;
}
if (fnRef) {
const localFunction = this._localFunctionCache.getByRef(fnRef);
if (localFunction) {
return localFunction;
const cachedFn = this._localFunctionCache.getByRef(fnRef);
if (cachedFn) {
return cachedFn;
}
}
return null;
}
/**
* @private
*/
_cache(cacheKey, parsedFunction) {
if (!parsedFunction) {
throw new Error(
'PDFFunctionFactory._cache - expected "parsedFunction" argument.'
);
}
let fnRef;
if (cacheKey instanceof Ref) {
fnRef = cacheKey;
} else if (cacheKey instanceof Dict) {
fnRef = cacheKey.objId;
} else if (cacheKey instanceof BaseStream) {
fnRef = cacheKey.dict?.objId;
const fnObj = this.xref.fetchIfRef(fn);
if (Array.isArray(fnObj)) {
if (!parseArray) {
throw new Error(
'PDFFunctionFactory.create - expected "parseArray" argument.'
);
}
parsedFn = PDFFunction.parseArray(this, fnObj);
} else {
parsedFn = PDFFunction.parse(this, fnObj);
}
// Attempt to cache the parsed Function, by reference.
if (fnRef) {
this._localFunctionCache.set(/* name = */ null, fnRef, parsedFunction);
this._localFunctionCache.set(/* name = */ null, fnRef, parsedFn);
}
return parsedFn;
}
/**
@ -156,36 +119,31 @@ class PDFFunction {
return array;
}
static parse({ xref, isEvalSupported, fn }) {
static parse(factory, fn) {
const dict = fn.dict || fn;
const typeNum = dict.get("FunctionType");
switch (typeNum) {
case 0:
return this.constructSampled({ xref, isEvalSupported, fn, dict });
return this.constructSampled(factory, fn, dict);
case 1:
break;
case 2:
return this.constructInterpolated({ xref, isEvalSupported, dict });
return this.constructInterpolated(factory, dict);
case 3:
return this.constructStiched({ xref, isEvalSupported, dict });
return this.constructStiched(factory, dict);
case 4:
return this.constructPostScript({ xref, isEvalSupported, fn, dict });
return this.constructPostScript(factory, fn, dict);
}
throw new FormatError("Unknown type of function");
}
static parseArray({ xref, isEvalSupported, fnObj }) {
if (!Array.isArray(fnObj)) {
// not an array -- parsing as regular function
return this.parse({ xref, isEvalSupported, fn: fnObj });
}
static parseArray(factory, fnObj) {
const { xref } = factory;
const fnArray = [];
for (const fn of fnObj) {
fnArray.push(
this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fn) })
);
fnArray.push(this.parse(factory, xref.fetchIfRef(fn)));
}
return function (src, srcOffset, dest, destOffset) {
for (let i = 0, ii = fnArray.length; i < ii; i++) {
@ -194,7 +152,7 @@ class PDFFunction {
};
}
static constructSampled({ xref, isEvalSupported, fn, dict }) {
static constructSampled(factory, fn, dict) {
function toMultiArray(arr) {
const inputLength = arr.length;
const out = [];
@ -317,7 +275,7 @@ class PDFFunction {
};
}
static constructInterpolated({ xref, isEvalSupported, dict }) {
static constructInterpolated(factory, dict) {
const c0 = toNumberArray(dict.getArray("C0")) || [0];
const c1 = toNumberArray(dict.getArray("C1")) || [1];
const n = dict.get("N");
@ -337,7 +295,7 @@ class PDFFunction {
};
}
static constructStiched({ xref, isEvalSupported, dict }) {
static constructStiched(factory, dict) {
const domain = toNumberArray(dict.getArray("Domain"));
if (!domain) {
@ -348,10 +306,11 @@ class PDFFunction {
if (inputSize !== 1) {
throw new FormatError("Bad domain for stiched function");
}
const { xref } = factory;
const fns = [];
for (const fn of dict.get("Functions")) {
fns.push(this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fn) }));
fns.push(this.parse(factory, xref.fetchIfRef(fn)));
}
const bounds = toNumberArray(dict.getArray("Bounds"));
@ -395,7 +354,7 @@ class PDFFunction {
};
}
static constructPostScript({ xref, isEvalSupported, fn, dict }) {
static constructPostScript(factory, fn, dict) {
const domain = toNumberArray(dict.getArray("Domain"));
const range = toNumberArray(dict.getArray("Range"));
@ -411,7 +370,7 @@ class PDFFunction {
const parser = new PostScriptParser(lexer);
const code = parser.parse();
if (isEvalSupported && FeatureTest.isEvalSupported) {
if (factory.isEvalSupported && FeatureTest.isEvalSupported) {
const compiled = new PostScriptCompiler().compile(code, domain, range);
if (compiled) {
// Compiled function consists of simple expressions such as addition,

View file

@ -179,7 +179,7 @@ class RadialAxialShading extends BaseShading {
this.extendEnd = extendEnd;
const fnObj = dict.getRaw("Function");
const fn = pdfFunctionFactory.createFromArray(fnObj);
const fn = pdfFunctionFactory.create(fnObj, /* parseArray = */ true);
// Use lcm(1,2,3,4,5,6,7,8,10) = 840 (including 9 increases this to 2520)
// to catch evenly spaced stops. oeis.org/A003418
@ -487,7 +487,9 @@ class MeshShading extends BaseShading {
: null;
const fnObj = dict.getRaw("Function");
const fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;
const fn = fnObj
? pdfFunctionFactory.create(fnObj, /* parseArray = */ true)
: null;
this.coords = [];
this.colors = [];