diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js index dfcc9fd68a309..d33454251edab 100644 --- a/src/core/xfa/template.js +++ b/src/core/xfa/template.js @@ -102,13 +102,12 @@ import { getStringOption, HTMLResult, } from "./utils.js"; -import { Util, warn } from "../../shared/util.js"; +import { SVG_NS, Util, warn } from "../../shared/util.js"; import { getMetrics } from "./fonts.js"; import { recoverJsURL } from "../core_utils.js"; import { searchNode } from "./som.js"; const TEMPLATE_NS_ID = NamespaceIds.template.id; -const SVG_NS = "http://www.w3.org/2000/svg"; // In case of lr-tb (and rl-tb) layouts, we try: // - to put the container at the end of a line diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 80af717fdfc23..4e0c840aafac5 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -38,6 +38,7 @@ import { LINE_FACTOR, makeArr, shadow, + SVG_NS, unreachable, Util, warn, @@ -666,8 +667,7 @@ class AnnotationElement { style.borderWidth = 0; svgBuffer = [ "url('data:image/svg+xml;utf8,", - ``, + ``, ``, ]; this.container.classList.add("hasBorder"); diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 3c44cc9e169aa..b64ccce103ce1 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -25,8 +25,6 @@ import { MathClamp } from "../shared/math_clamp.js"; import { PageViewport } from "./page_viewport.js"; import { XfaLayer } from "./xfa_layer.js"; -const SVG_NS = "http://www.w3.org/2000/svg"; - class PixelsPerInch { static CSS = 96.0; @@ -844,5 +842,4 @@ export { StatTimer, stopEvent, SupportedImageMimeTypes, - SVG_NS, }; diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index 331d9ab43b440..52ffdc83233f2 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -24,6 +24,7 @@ import { FeatureTest, getUuid, shadow, + SVG_NS, Util, warn, } from "../../shared/util.js"; @@ -170,7 +171,7 @@ class ImageManager { // The "workaround" is to append "svgView(preserveAspectRatio(none))" to the // url, but according to comment #15, it seems that it leads to unexpected // behavior in Safari. - const svg = `data:image/svg+xml;charset=UTF-8,`; + const svg = `data:image/svg+xml;charset=UTF-8,`; const canvas = new OffscreenCanvas(1, 3); const ctx = canvas.getContext("2d", { willReadFrequently: true }); const image = new Image(); diff --git a/src/display/filter_factory.js b/src/display/filter_factory.js index 32f69e4ec5848..3473d543dc878 100644 --- a/src/display/filter_factory.js +++ b/src/display/filter_factory.js @@ -13,8 +13,14 @@ * limitations under the License. */ -import { getRGB, isDataScheme, SVG_NS } from "./display_utils.js"; -import { unreachable, updateUrlHash, Util, warn } from "../shared/util.js"; +import { getRGB, isDataScheme } from "./display_utils.js"; +import { + SVG_NS, + unreachable, + updateUrlHash, + Util, + warn, +} from "../shared/util.js"; class BaseFilterFactory { constructor() { diff --git a/src/display/svg_factory.js b/src/display/svg_factory.js index f9591a818499f..67c6a88973a31 100644 --- a/src/display/svg_factory.js +++ b/src/display/svg_factory.js @@ -13,8 +13,7 @@ * limitations under the License. */ -import { SVG_NS } from "./display_utils.js"; -import { unreachable } from "../shared/util.js"; +import { SVG_NS, unreachable } from "../shared/util.js"; class BaseSVGFactory { constructor() { diff --git a/src/shared/util.js b/src/shared/util.js index f73f6fc816b96..88fda0439ffa8 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -36,6 +36,8 @@ const LINE_FACTOR = 1.35; const LINE_DESCENT_FACTOR = 0.35; const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR; +const SVG_NS = "http://www.w3.org/2000/svg"; + /** * Refer to the `WorkerTransport.getRenderingIntent`-method in the API, to see * how these flags are being used: @@ -1237,6 +1239,7 @@ export { stringToBytes, stringToUTF8String, stripPath, + SVG_NS, TextRenderingMode, UnknownErrorException, unreachable, diff --git a/test/unit/clitests.json b/test/unit/clitests.json index ce261c24957b2..2033ddd7a2328 100644 --- a/test/unit/clitests.json +++ b/test/unit/clitests.json @@ -48,6 +48,7 @@ "pdf_viewer_spec.js", "postscript_spec.js", "primitives_spec.js", + "scripting_utils_spec.js", "stream_spec.js", "string_utils_spec.js", "struct_tree_spec.js", diff --git a/test/unit/jasmine-boot.js b/test/unit/jasmine-boot.js index fbbc7730ecff3..ea6404f9ab673 100644 --- a/test/unit/jasmine-boot.js +++ b/test/unit/jasmine-boot.js @@ -95,6 +95,7 @@ async function initializePDFJS(callback) { "pdfjs-test/unit/postscript_spec.js", "pdfjs-test/unit/primitives_spec.js", "pdfjs-test/unit/scripting_spec.js", + "pdfjs-test/unit/scripting_utils_spec.js", "pdfjs-test/unit/stream_spec.js", "pdfjs-test/unit/string_utils_spec.js", "pdfjs-test/unit/struct_tree_spec.js", diff --git a/test/unit/scripting_utils_spec.js b/test/unit/scripting_utils_spec.js new file mode 100644 index 0000000000000..efc3cc0ba6fd6 --- /dev/null +++ b/test/unit/scripting_utils_spec.js @@ -0,0 +1,70 @@ +/* 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. + */ + +import { ColorConverters } from "../../src/shared/scripting_utils.js"; + +describe("scripting_utils", function () { + describe("ColorConverters", function () { + it("should check G conversion", function () { + const color = [0.5]; + + expect(ColorConverters.G_CMYK(color)).toEqual(["CMYK", 0, 0, 0, 0.5]); + + expect(ColorConverters.G_RGB(color)).toEqual(["RGB", 0.5, 0.5, 0.5]); + + expect(ColorConverters.G_rgb(color)).toEqual([127.5, 127.5, 127.5]); + + expect(ColorConverters.G_HTML(color)).toEqual("#7f7f7f"); + }); + + it("should check RGB conversion", function () { + const color = [0.4, 0.5, 0.6]; + + expect(ColorConverters.RGB_CMYK(color)).toEqual([ + "CMYK", + 0.6, + 0.5, + 0.4, + 0.4, + ]); + + expect(ColorConverters.RGB_G(color)).toEqual(["G", 0.481]); + + expect(ColorConverters.RGB_rgb(color)).toEqual([102, 127.5, 153]); + + expect(ColorConverters.RGB_HTML(color)).toEqual("#667f99"); + }); + + it("should check CMYK conversion", function () { + const color = [0.4, 0.5, 0.6, 0]; + + expect(ColorConverters.CMYK_RGB(color)).toEqual(["RGB", 0.6, 0.4, 0.5]); + + expect(ColorConverters.CMYK_G(color)).toEqual(["G", 0.471]); + + expect(ColorConverters.CMYK_rgb(color)).toEqual([153, 102, 127.5]); + + expect(ColorConverters.CMYK_HTML(color)).toEqual("#99667f"); + }); + + it("should check T conversion", function () { + const color = [0.4, 0.5, 0.6]; + + expect(ColorConverters.T_rgb(color)).toEqual([null]); + + expect(ColorConverters.T_HTML(color)).toEqual("#00000000"); + }); + }); +});