1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

Merge pull request #18283 from nicolo-ribaudo/ignore-browser-min-font-size

Override the minimum font size when rendering the text layer
This commit is contained in:
Tim van der Meij 2024-06-25 15:57:15 +02:00 committed by GitHub
commit 11cb3a8e11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 79 additions and 3 deletions

View file

@ -83,6 +83,8 @@ class TextLayer {
static #canvasContexts = new Map();
static #minFontSize = null;
static #pendingTextLayers = new Set();
/**
@ -120,6 +122,8 @@ class TextLayer {
this.#pageWidth = pageWidth;
this.#pageHeight = pageHeight;
TextLayer.#ensureMinFontSizeComputed();
setLayerDimensions(container, viewport);
// Always clean-up the temporary canvas once rendering is no longer pending.
@ -242,7 +246,7 @@ class TextLayer {
if (this.#disableProcessItems) {
return;
}
this.#layoutTextParams.ctx ||= TextLayer.#getCtx(this.#lang);
this.#layoutTextParams.ctx ??= TextLayer.#getCtx(this.#lang);
const textDivs = this.#textDivs,
textContentItemsStr = this.#textContentItemsStr;
@ -326,7 +330,11 @@ class TextLayer {
divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`;
divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`;
}
divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`;
// We multiply the font size by #minFontSize, and then #layout will
// scale the element by 1/#minFontSize. This allows us to effectively
// ignore the minimum font size enforced by the browser, so that the text
// layer <span>s can always match the size of the text in the canvas.
divStyle.fontSize = `${scaleFactorStr}${(TextLayer.#minFontSize * fontHeight).toFixed(2)}px)`;
divStyle.fontFamily = fontFamily;
textDivProperties.fontSize = fontHeight;
@ -388,7 +396,12 @@ class TextLayer {
#layout(params) {
const { div, properties, ctx, prevFontSize, prevFontFamily } = params;
const { style } = div;
let transform = "";
if (TextLayer.#minFontSize > 1) {
transform = `scale(${1 / TextLayer.#minFontSize})`;
}
if (properties.canvasWidth !== 0 && properties.hasText) {
const { fontFamily } = style;
const { canvasWidth, fontSize } = properties;
@ -403,7 +416,7 @@ class TextLayer {
const { width } = ctx.measureText(div.textContent);
if (width > 0) {
transform = `scaleX(${(canvasWidth * this.#scale) / width})`;
transform = `scaleX(${(canvasWidth * this.#scale) / width}) ${transform}`;
}
}
if (properties.angle !== 0) {
@ -456,6 +469,26 @@ class TextLayer {
return canvasContext;
}
/**
* Compute the minimum font size enforced by the browser.
*/
static #ensureMinFontSizeComputed() {
if (this.#minFontSize !== null) {
return;
}
const div = document.createElement("div");
div.style.opacity = 0;
div.style.lineHeight = 1;
div.style.fontSize = "1px";
div.textContent = "X";
document.body.append(div);
// In `display:block` elements contain a single line of text,
// the height matches the line height (which, when set to 1,
// matches the actual font size).
this.#minFontSize = div.getBoundingClientRect().height;
div.remove();
}
static #getAscent(fontFamily, lang) {
const cachedAscent = this.#ascentCache.get(fontFamily);
if (cachedAscent) {