From 4ee9c39fc89fc9607ce188521a236cd4a2b8dbf3 Mon Sep 17 00:00:00 2001 From: Danyal Ahmed <58849388+danyalahmed1995@users.noreply.github.com> Date: Sun, 24 May 2026 18:36:26 +0500 Subject: [PATCH 1/2] Prevent inherited spacing from affecting text layer Fixes #21259. Reset letter-spacing and word-spacing on the text layer and hidden measurement canvas so inherited page styles do not affect text layer alignment. Add an integration regression test for inherited spacing. --- src/display/text_layer.js | 3 +- test/integration/text_layer_spec.mjs | 55 ++++++++++++++++++++++++++++ web/text_layer_builder.css | 2 + 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/display/text_layer.js b/src/display/text_layer.js index c5487bd07770d..257c2ced0a58a 100644 --- a/src/display/text_layer.js +++ b/src/display/text_layer.js @@ -473,7 +473,8 @@ class TextLayer { // OffscreenCanvas. const canvas = document.createElement("canvas"); canvas.style.cssText = - "position:absolute;top:0;left:0;width:0;height:0;display:none"; + "position:absolute;top:0;left:0;width:0;height:0;display:none;" + + "letter-spacing:normal;word-spacing:normal"; canvas.lang = lang; document.body.append(canvas); ctx = canvas.getContext("2d", { diff --git a/test/integration/text_layer_spec.mjs b/test/integration/text_layer_spec.mjs index 102438691f3da..8c1a02a60a6dd 100644 --- a/test/integration/text_layer_spec.mjs +++ b/test/integration/text_layer_spec.mjs @@ -49,6 +49,61 @@ import { startBrowser } from "../test.mjs"; */ describe("Text layer", () => { + describe("Text layout", () => { + let pages; + + beforeEach(async () => { + pages = await loadAndWait( + "tracemonkey.pdf", + ".textLayer .endOfContent", + 100, + { + postPageSetup: async page => { + await page.evaluate(() => { + const style = document.createElement("style"); + style.textContent = ` + body, + #mainContainer { + letter-spacing: 5px; + word-spacing: 5px; + } + `; + document.documentElement.append(style); + }); + }, + } + ); + }); + + afterEach(async () => { + await closePages(pages); + }); + + it("must ignore inherited text spacing styles", async () => { + await Promise.all( + pages.map(async ([_, page]) => { + const spacing = await page.evaluate(() => { + const textLayer = document.querySelector(".textLayer"); + const span = textLayer.querySelector("span"); + const textLayerStyle = getComputedStyle(textLayer); + const spanStyle = getComputedStyle(span); + return { + textLayerLetterSpacing: textLayerStyle.letterSpacing, + textLayerWordSpacing: textLayerStyle.wordSpacing, + spanLetterSpacing: spanStyle.letterSpacing, + spanWordSpacing: spanStyle.wordSpacing, + }; + }); + + expect(spacing.textLayerLetterSpacing).toEqual("normal"); + expect(spacing.spanLetterSpacing).toEqual("normal"); + expect(["0px", "normal"]).toContain(spacing.textLayerWordSpacing); + expect(["0px", "normal"]).toContain(spacing.spanWordSpacing); + }) + ); + }); + }); + describe("Text selection", () => { // page.mouse.move(x, y, { steps: ... }) doesn't work in Firefox, because // puppeteer will send fractional intermediate positions and Firefox doesn't diff --git a/web/text_layer_builder.css b/web/text_layer_builder.css index cadaba76744a3..a78b199847628 100644 --- a/web/text_layer_builder.css +++ b/web/text_layer_builder.css @@ -22,6 +22,8 @@ overflow: clip; opacity: 1; line-height: 1; + letter-spacing: normal; + word-spacing: normal; text-size-adjust: none; forced-color-adjust: none; transform-origin: 0 0; From f7af3ea9acc36f565a2445e923f8d7efe8c6483d Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Mon, 25 May 2026 09:08:42 +0200 Subject: [PATCH 2/2] Force the text selection color to be in light mode Most of the pdfs have a white background, so it makes sense to use the colors for light mode. --- src/display/filter_factory.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/display/filter_factory.js b/src/display/filter_factory.js index f39edfaded81a..430cb697ef757 100644 --- a/src/display/filter_factory.js +++ b/src/display/filter_factory.js @@ -132,6 +132,9 @@ class DOMFilterFactory extends BaseFilterFactory { if (!this.#_defs) { const div = this.#document.createElement("div"); const { style } = div; + // The pdf colors are mostly in light mode (white background with a black + // foreground), so the filters are created in light mode. + style.colorScheme = "only light"; style.visibility = "hidden"; style.contain = "strict"; style.width = style.height = 0;