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.
This commit is contained in:
Danyal Ahmed 2026-05-24 18:36:26 +05:00
parent ea18e73de2
commit 4ee9c39fc8
3 changed files with 59 additions and 1 deletions

View File

@ -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", {

View File

@ -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

View File

@ -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;