diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index 367ac75c1..8ec06ad0f 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -14,7 +14,8 @@ */ import { arrayBuffersToBytes, MissingDataException } from "./core_utils.js"; -import { assert, MathClamp } from "../shared/util.js"; +import { assert } from "../shared/util.js"; +import { MathClamp } from "../shared/math_clamp.js"; import { Stream } from "./stream.js"; class ChunkedStream extends Stream { diff --git a/src/core/colorspace.js b/src/core/colorspace.js index f81e4c9f8..3db3e6ca6 100644 --- a/src/core/colorspace.js +++ b/src/core/colorspace.js @@ -18,13 +18,13 @@ import { FeatureTest, FormatError, info, - MathClamp, shadow, unreachable, Util, warn, } from "../shared/util.js"; import { BaseStream } from "./base_stream.js"; +import { MathClamp } from "../shared/math_clamp.js"; /** * Resizes an RGB image with 3 components. diff --git a/src/core/colorspace_utils.js b/src/core/colorspace_utils.js index 04fa44dd8..0113f537b 100644 --- a/src/core/colorspace_utils.js +++ b/src/core/colorspace_utils.js @@ -27,7 +27,8 @@ import { } from "./colorspace.js"; import { CmykICCBasedCS, IccColorSpace } from "./icc_colorspace.js"; import { Dict, Name, Ref } from "./primitives.js"; -import { MathClamp, shadow, unreachable, warn } from "../shared/util.js"; +import { shadow, unreachable, warn } from "../shared/util.js"; +import { MathClamp } from "../shared/math_clamp.js"; import { MissingDataException } from "./core_utils.js"; class ColorSpaceUtils { diff --git a/src/core/function.js b/src/core/function.js index 2bfa150d6..84e41638c 100644 --- a/src/core/function.js +++ b/src/core/function.js @@ -18,7 +18,6 @@ import { FeatureTest, FormatError, info, - MathClamp, shadow, unreachable, warn, @@ -29,6 +28,7 @@ import { buildPostScriptJsFunction } from "./postscript/js_evaluator.js"; import { buildPostScriptWasmFunction } from "./postscript/wasm_compiler.js"; import { isNumberArray } from "./core_utils.js"; import { LocalFunctionCache } from "./image_utils.js"; +import { MathClamp } from "../shared/math_clamp.js"; class PDFFunctionFactory { static #useWasm = true; diff --git a/src/core/image.js b/src/core/image.js index c3f849222..8aa2ae280 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -18,7 +18,6 @@ import { FeatureTest, FormatError, ImageKind, - MathClamp, warn, } from "../shared/util.js"; import { @@ -32,6 +31,7 @@ import { DecodeStream } from "./decode_stream.js"; import { ImageResizer } from "./image_resizer.js"; import { JpegStream } from "./jpeg_stream.js"; import { JpxImage } from "./jpx.js"; +import { MathClamp } from "../shared/math_clamp.js"; import { Name } from "./primitives.js"; /** diff --git a/src/core/pattern.js b/src/core/pattern.js index e2a71f182..cb7fff730 100644 --- a/src/core/pattern.js +++ b/src/core/pattern.js @@ -17,7 +17,6 @@ import { assert, FormatError, info, - MathClamp, MeshFigureType, unreachable, Util, @@ -34,6 +33,7 @@ import { } from "./core_utils.js"; import { BaseStream } from "./base_stream.js"; import { ColorSpaceUtils } from "./colorspace_utils.js"; +import { MathClamp } from "../shared/math_clamp.js"; const ShadingType = { FUNCTION_BASED: 1, diff --git a/src/core/postscript/js_evaluator.js b/src/core/postscript/js_evaluator.js index c4ef13cbe..5c931589e 100644 --- a/src/core/postscript/js_evaluator.js +++ b/src/core/postscript/js_evaluator.js @@ -19,7 +19,7 @@ import { PS_VALUE_TYPE, PSStackToTree, } from "./ast.js"; -import { MathClamp } from "../../shared/util.js"; +import { MathClamp } from "../../shared/math_clamp.js"; import { TOKEN } from "./lexer.js"; // Consecutive integers for a dense jump table in _execute. diff --git a/src/core/xfa/layout.js b/src/core/xfa/layout.js index ce5142e6f..e87831cb5 100644 --- a/src/core/xfa/layout.js +++ b/src/core/xfa/layout.js @@ -21,7 +21,7 @@ import { $isSplittable, $isThereMoreWidth, } from "./symbol_utils.js"; -import { MathClamp } from "../../shared/util.js"; +import { MathClamp } from "../../shared/math_clamp.js"; import { measureToString } from "./html_utils.js"; // Subform and ExclGroup have a layout so they share these functions. diff --git a/src/core/xfa/utils.js b/src/core/xfa/utils.js index 2dbe8da21..2a9f8f550 100644 --- a/src/core/xfa/utils.js +++ b/src/core/xfa/utils.js @@ -13,7 +13,8 @@ * limitations under the License. */ -import { MathClamp, shadow } from "../../shared/util.js"; +import { MathClamp } from "../../shared/math_clamp.js"; +import { shadow } from "../../shared/util.js"; const dimConverters = { pt: x => x, diff --git a/src/display/api.js b/src/display/api.js index 314206ac8..8f6c40f03 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -26,7 +26,6 @@ import { info, isNodeJS, makeObj, - MathClamp, RenderingIntentFlag, setVerbosityLevel, shadow, @@ -77,6 +76,7 @@ import { DOMFilterFactory } from "./filter_factory.js"; import { getNetworkStream } from "display-network_stream"; import { GlobalWorkerOptions } from "./worker_options.js"; import { initWebGPUMesh } from "./webgpu_mesh.js"; +import { MathClamp } from "../shared/math_clamp.js"; import { Metadata } from "./metadata.js"; import { OptionalContentConfig } from "./optional_content_config.js"; import { PagesMapper } from "./pages_mapper.js"; diff --git a/src/display/canvas_dependency_tracker.js b/src/display/canvas_dependency_tracker.js index b18e6ca26..936f10666 100644 --- a/src/display/canvas_dependency_tracker.js +++ b/src/display/canvas_dependency_tracker.js @@ -13,7 +13,8 @@ * limitations under the License. */ -import { FeatureTest, MathClamp, Util } from "../shared/util.js"; +import { FeatureTest, Util } from "../shared/util.js"; +import { MathClamp } from "../shared/math_clamp.js"; const FORCED_DEPENDENCY_LABEL = "__forcedDependency"; diff --git a/src/display/display_utils.js b/src/display/display_utils.js index d7e7a4134..be5bcd486 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -17,12 +17,12 @@ import { BaseException, DrawOPS, FeatureTest, - MathClamp, shadow, stripPath, Util, warn, } from "../shared/util.js"; +import { MathClamp } from "../shared/math_clamp.js"; import { XfaLayer } from "./xfa_layer.js"; const SVG_NS = "http://www.w3.org/2000/svg"; diff --git a/src/display/editor/drawers/inkdraw.js b/src/display/editor/drawers/inkdraw.js index fa4df96e3..3ecf3af8a 100644 --- a/src/display/editor/drawers/inkdraw.js +++ b/src/display/editor/drawers/inkdraw.js @@ -13,8 +13,9 @@ * limitations under the License. */ -import { MathClamp, Util } from "../../../shared/util.js"; +import { MathClamp } from "../../../shared/math_clamp.js"; import { Outline } from "./outline.js"; +import { Util } from "../../../shared/util.js"; class InkDrawOutliner { // The last 3 points of the line. diff --git a/src/display/editor/editor.js b/src/display/editor/editor.js index a175690d7..202970c64 100644 --- a/src/display/editor/editor.js +++ b/src/display/editor/editor.js @@ -22,16 +22,12 @@ import { ColorManager, KeyboardManager, } from "./tools.js"; -import { - FeatureTest, - MathClamp, - shadow, - unreachable, -} from "../../shared/util.js"; +import { FeatureTest, shadow, unreachable } from "../../shared/util.js"; import { noContextMenu, stopEvent } from "../display_utils.js"; import { AltText } from "./alt_text.js"; import { Comment } from "./comment.js"; import { EditorToolbar } from "./toolbar.js"; +import { MathClamp } from "../../shared/math_clamp.js"; import { TouchManager } from "../touch_manager.js"; /** diff --git a/src/display/pages_mapper.js b/src/display/pages_mapper.js index 1a4654fd8..3dca542c2 100644 --- a/src/display/pages_mapper.js +++ b/src/display/pages_mapper.js @@ -13,7 +13,8 @@ * limitations under the License. */ -import { makeArr, MathClamp } from "../shared/util.js"; +import { makeArr } from "../shared/util.js"; +import { MathClamp } from "../shared/math_clamp.js"; /** * Maps between page IDs and page numbers, allowing bidirectional conversion diff --git a/src/pdf.js b/src/pdf.js index 3f4b17446..7cce4c0af 100644 --- a/src/pdf.js +++ b/src/pdf.js @@ -36,7 +36,6 @@ import { makeArr, makeMap, makeObj, - MathClamp, normalizeUnicode, OPS, PasswordResponses, @@ -84,6 +83,7 @@ import { DrawLayer } from "./display/draw_layer.js"; import { GlobalWorkerOptions } from "./display/worker_options.js"; import { HighlightOutliner } from "./display/editor/drawers/highlight.js"; import { isValidExplicitDest } from "./display/api_utils.js"; +import { MathClamp } from "./shared/math_clamp.js"; import { SignatureExtractor } from "./display/editor/drawers/signaturedraw.js"; import { TextLayer } from "./display/text_layer.js"; import { TextLayerImages } from "./display/text_layer_images.js"; diff --git a/src/scripting_api/aform.js b/src/scripting_api/aform.js index 81639bdd2..d39004445 100644 --- a/src/scripting_api/aform.js +++ b/src/scripting_api/aform.js @@ -15,6 +15,7 @@ import { DateFormats, TimeFormats } from "../shared/scripting_utils.js"; import { GlobalConstants } from "./constants.js"; +import { MathClamp } from "../shared/math_clamp.js"; class AForm { constructor(document, app, util, color) { @@ -139,7 +140,7 @@ class AForm { } // sepStyle is an integer in [0;4] - sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4); + sepStyle = MathClamp(Math.floor(sepStyle), 0, 4); buf.push("%,", sepStyle, ".", nDec.toString(), "f"); @@ -226,7 +227,7 @@ class AForm { nDec = Math.floor(nDec); // sepStyle is an integer in [0;4] - sepStyle = Math.min(Math.max(0, Math.floor(sepStyle)), 4); + sepStyle = MathClamp(Math.floor(sepStyle), 0, 4); let value = this.AFMakeNumber(event.value); if (value === null) { diff --git a/src/shared/math_clamp.js b/src/shared/math_clamp.js new file mode 100644 index 000000000..bd8a8f061 --- /dev/null +++ b/src/shared/math_clamp.js @@ -0,0 +1,22 @@ +/* Copyright 2026 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO: Replace all occurrences of this function, and remove the file, once +// https://github.com/tc39/proposal-math-clamp/ is generally available. +function MathClamp(v, min, max) { + return Math.min(Math.max(v, min), max); +} + +export { MathClamp }; diff --git a/src/shared/scripting_utils.js b/src/shared/scripting_utils.js index f5405e031..e508534f4 100644 --- a/src/shared/scripting_utils.js +++ b/src/shared/scripting_utils.js @@ -20,14 +20,16 @@ * unexpected/unnecessary size increase of the *built* files. */ +import { MathClamp } from "../shared/math_clamp.js"; + function makeColorComp(n) { - return Math.floor(Math.max(0, Math.min(1, n)) * 255) + return Math.floor(MathClamp(n, 0, 1) * 255) .toString(16) .padStart(2, "0"); } function scaleAndClamp(x) { - return Math.max(0, Math.min(255, 255 * x)); + return MathClamp(x, 0, 1) * 255; } // PDF specifications section 10.3 diff --git a/src/shared/util.js b/src/shared/util.js index 92bc091d0..4e433fda6 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -1240,12 +1240,6 @@ const makeArr = () => []; const makeMap = () => new Map(); const makeObj = () => Object.create(null); -// TODO: Replace all occurrences of this function with `Math.clamp` once -// https://github.com/tc39/proposal-math-clamp/ is generally available. -function MathClamp(v, min, max) { - return Math.min(Math.max(v, min), max); -} - // TODO: Remove this once `Math.sumPrecise` is generally available. if ( (typeof PDFJSDev === "undefined" || @@ -1351,7 +1345,6 @@ export { makeArr, makeMap, makeObj, - MathClamp, MeshFigureType, normalizeUnicode, objectSize, diff --git a/test/unit/pdf_spec.js b/test/unit/pdf_spec.js index f3ed3ba6c..2a03df8b1 100644 --- a/test/unit/pdf_spec.js +++ b/test/unit/pdf_spec.js @@ -27,7 +27,6 @@ import { makeArr, makeMap, makeObj, - MathClamp, normalizeUnicode, OPS, PasswordResponses, @@ -74,6 +73,7 @@ import { DOMSVGFactory } from "../../src/display/svg_factory.js"; import { DrawLayer } from "../../src/display/draw_layer.js"; import { GlobalWorkerOptions } from "../../src/display/worker_options.js"; import { isValidExplicitDest } from "../../src/display/api_utils.js"; +import { MathClamp } from "../../src/shared/math_clamp.js"; import { SignatureExtractor } from "../../src/display/editor/drawers/signaturedraw.js"; import { TextLayer } from "../../src/display/text_layer.js"; import { TextLayerImages } from "../../src/display/text_layer_images.js";