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 #19399 from Snuffleupagus/TextLayer-#getAscent-simplify

[api-minor] Simplify the `TextLayer.#getAscent` fallback (PR 12896 follow-up)
This commit is contained in:
Jonas Jenwald 2025-02-08 00:01:40 +01:00 committed by GitHub
commit 72339dc561
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -46,7 +46,6 @@ import { setLayerDimensions } from "./display_utils.js";
const MAX_TEXT_DIVS_TO_RENDER = 100000;
const DEFAULT_FONT_SIZE = 30;
const DEFAULT_FONT_ASCENT = 0.8;
class TextLayer {
#capability = Promise.withResolvers();
@ -332,7 +331,7 @@ class TextLayer {
fontFamily = TextLayer.fontFamilyMap.get(fontFamily) || fontFamily;
const fontHeight = Math.hypot(tx[2], tx[3]);
const fontAscent =
fontHeight * TextLayer.#getAscent(fontFamily, this.#lang);
fontHeight * TextLayer.#getAscent(fontFamily, style, this.#lang);
let left, top;
if (angle === 0) {
@ -523,7 +522,7 @@ class TextLayer {
div.remove();
}
static #getAscent(fontFamily, lang) {
static #getAscent(fontFamily, style, lang) {
const cachedAscent = this.#ascentCache.get(fontFamily);
if (cachedAscent) {
return cachedAscent;
@ -534,55 +533,31 @@ class TextLayer {
this.#ensureCtxFont(ctx, DEFAULT_FONT_SIZE, fontFamily);
const metrics = ctx.measureText("");
// Both properties aren't available by default in Firefox.
let ascent = metrics.fontBoundingBoxAscent;
let descent = Math.abs(metrics.fontBoundingBoxDescent);
if (ascent) {
const ratio = ascent / (ascent + descent);
this.#ascentCache.set(fontFamily, ratio);
ctx.canvas.width = ctx.canvas.height = 0;
return ratio;
}
// Try basic heuristic to guess ascent/descent.
// Draw a g with baseline at 0,0 and then get the line
// number where a pixel has non-null red component (starting
// from bottom).
ctx.strokeStyle = "red";
ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
ctx.strokeText("g", 0, 0);
let pixels = ctx.getImageData(
0,
0,
DEFAULT_FONT_SIZE,
DEFAULT_FONT_SIZE
).data;
descent = 0;
for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) {
if (pixels[i] > 0) {
descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE);
break;
}
}
// Draw an A with baseline at 0,DEFAULT_FONT_SIZE and then get the line
// number where a pixel has non-null red component (starting
// from top).
ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
ctx.strokeText("A", 0, DEFAULT_FONT_SIZE);
pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data;
ascent = 0;
for (let i = 0, ii = pixels.length; i < ii; i += 4) {
if (pixels[i] > 0) {
ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE);
break;
}
}
const ascent = metrics.fontBoundingBoxAscent;
const descent = Math.abs(metrics.fontBoundingBoxDescent);
ctx.canvas.width = ctx.canvas.height = 0;
let ratio = 0.8; // DEFAULT_FONT_ASCENT
if (ascent) {
ratio = ascent / (ascent + descent);
} else {
if (
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
FeatureTest.platform.isFirefox
) {
warn(
"Enable the `dom.textMetrics.fontBoundingBox.enabled` preference " +
"in `about:config` to improve TextLayer rendering."
);
}
if (style.ascent) {
ratio = style.ascent;
} else if (style.descent) {
ratio = 1 + style.descent;
}
}
const ratio = ascent ? ascent / (ascent + descent) : DEFAULT_FONT_ASCENT;
this.#ascentCache.set(fontFamily, ratio);
return ratio;
}