Introduce a function type enumeration

This improves readability by removing "magic" numbers, and matches what
we already have for e.g. annotation and shading types.

Note that function type 1 does not exist in the specification, but that
also applies to everything higher than 4, so we can also remove the
specific handling of function type 1 and instead just let it fall
through to throwing an exception for unknown function types, in which we
now also log the provided function type to aid debugging.
This commit is contained in:
Tim van der Meij 2026-04-04 14:41:23 +02:00
parent e10f11bd3a
commit 68da778329
No known key found for this signature in database
GPG Key ID: 8C3FD2925A5F2762
3 changed files with 17 additions and 12 deletions

View File

@ -60,6 +60,7 @@ import {
RefSet,
RefSetCache,
} from "./primitives.js";
import { FunctionType, PDFFunctionFactory } from "./function.js";
import { getXfaFontDict, getXfaFontName } from "./xfa_fonts.js";
import { NullStream, Stream } from "./stream.js";
import { BaseStream } from "./base_stream.js";
@ -73,7 +74,6 @@ import { LocalColorSpaceCache } from "./image_utils.js";
import { ObjectLoader } from "./object_loader.js";
import { OperatorList } from "./operator_list.js";
import { PartialEvaluator } from "./evaluator.js";
import { PDFFunctionFactory } from "./function.js";
import { PDFImage } from "./image.js";
import { StreamsSequenceStream } from "./decode_stream.js";
import { StructTreePage } from "./struct_tree.js";
@ -2131,7 +2131,7 @@ class PDFDocument {
return obj;
}
if (dict.get("FunctionType") === 4) {
if (dict.get("FunctionType") === FunctionType.POSTSCRIPT_CALCULATOR) {
const source = value.getString();
value.reset();
const domain = dict.get("Domain") ?? [];

View File

@ -22,6 +22,13 @@ import { isNumberArray } from "./core_utils.js";
import { LocalFunctionCache } from "./image_utils.js";
import { MathClamp } from "../shared/math_clamp.js";
const FunctionType = {
SAMPLED: 0,
EXPONENTIAL_INTERPOLATION: 2,
STITCHING: 3,
POSTSCRIPT_CALCULATOR: 4,
};
class PDFFunctionFactory {
static #useWasm = true;
@ -126,18 +133,16 @@ class PDFFunction {
const typeNum = dict.get("FunctionType");
switch (typeNum) {
case 0:
case FunctionType.SAMPLED:
return this.constructSampled(factory, fn, dict);
case 1:
break;
case 2:
case FunctionType.EXPONENTIAL_INTERPOLATION:
return this.constructInterpolated(factory, dict);
case 3:
case FunctionType.STITCHING:
return this.constructStiched(factory, dict);
case 4:
case FunctionType.POSTSCRIPT_CALCULATOR:
return this.constructPostScript(factory, fn, dict);
}
throw new FormatError("Unknown type of function");
throw new FormatError(`Unknown function type: ${typeNum}`);
}
static parseArray(factory, fnObj) {
@ -391,4 +396,4 @@ function isPDFFunction(v) {
return fnDict.has("FunctionType");
}
export { isPDFFunction, PDFFunctionFactory };
export { FunctionType, isPDFFunction, PDFFunctionFactory };

View File

@ -14,6 +14,7 @@
*/
import { Dict, Name, Ref } from "../../src/core/primitives.js";
import { FunctionType, PDFFunctionFactory } from "../../src/core/function.js";
import {
GlobalColorSpaceCache,
LocalColorSpaceCache,
@ -21,7 +22,6 @@ import {
import { Stream, StringStream } from "../../src/core/stream.js";
import { ColorSpace } from "../../src/core/colorspace.js";
import { ColorSpaceUtils } from "../../src/core/colorspace_utils.js";
import { PDFFunctionFactory } from "../../src/core/function.js";
import { XRefMock } from "./test_utils.js";
describe("colorspace", function () {
@ -836,7 +836,7 @@ describe("colorspace", function () {
it("should handle the case when cs is an array", function () {
const fnDict = new Dict();
fnDict.set("FunctionType", 4);
fnDict.set("FunctionType", FunctionType.POSTSCRIPT_CALCULATOR);
fnDict.set("Domain", [0.0, 1.0]);
fnDict.set("Range", [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]);
fnDict.set("Length", 58);