Skip to content

Commit

Permalink
Only compile Type3 glyphs when Path2D is supported
Browse files Browse the repository at this point in the history
According to MDN `Path2D` is available in all browsers that we currently support, see https://developer.mozilla.org/en-US/docs/Web/API/Path2D#browser_compatibility
Hence only Node.js is currently lagging behind here, and requires that we keep the old code as a fallback in the `compileType3Glyph` function. However, there's an open PR in the `node-canvas` repository for adding `Path2D` support.

As far as I'm concerned, there's two possible solutions here:
 - We land this patch now, since it removes unnecessary code in e.g. the Firefox PDF Viewer, which means that compilation of Type3 glyphs will be disabled in Node.js until that PR is landed.[1]
   If users report bugs about Type3 glyphs looking "inconsistent" in Node.js and/or being slow to render, we could perhaps encourage them to upvote and otherwise help out getting that PR landed?

 - We wait for the mentioned PR to land *first*, before moving forward with this patch. Given that there's been no updates on that PR for almost two months, this alternative may possibly take a while.

---
[1] Note that Type3 fonts are first of all not very common in PDF documents, and secondly that compilation only applies specifically to Type3 glyphs that contain /ImageMask-data (i.e. not all Type3 fonts are affected).
  • Loading branch information
Snuffleupagus authored and pull[bot] committed Apr 10, 2024
1 parent be67431 commit 1883609
Showing 1 changed file with 13 additions and 41 deletions.
54 changes: 13 additions & 41 deletions src/display/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,14 @@ const EXECUTION_TIME = 15; // ms
// Defines the number of steps before checking the execution time.
const EXECUTION_STEPS = 10;

const COMPILE_TYPE3_GLYPHS = true;
const MAX_SIZE_TO_COMPILE = 1000;
// To disable Type3 compilation, set the value to `-1`.
const MAX_SIZE_TO_COMPILE =
typeof PDFJSDev !== "undefined" &&
PDFJSDev.test("GENERIC") &&
isNodeJS &&
typeof Path2D === "undefined"
? -1
: 1000;

const FULL_CHUNK_HEIGHT = 16;

Expand Down Expand Up @@ -294,11 +300,7 @@ function drawImageAtIntegerCoords(

function compileType3Glyph(imgData) {
const { width, height } = imgData;
if (
!COMPILE_TYPE3_GLYPHS ||
width > MAX_SIZE_TO_COMPILE ||
height > MAX_SIZE_TO_COMPILE
) {
if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {
return null;
}

Expand Down Expand Up @@ -404,12 +406,7 @@ function compileType3Glyph(imgData) {

// building outlines
const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);
let path, outlines, coords;
if (!isNodeJS) {
path = new Path2D();
} else {
outlines = [];
}
const path = new Path2D();

for (i = 0; count && i <= height; i++) {
let p = i * width1;
Expand All @@ -420,12 +417,7 @@ function compileType3Glyph(imgData) {
if (p === end) {
continue;
}

if (path) {
path.moveTo(p % width1, i);
} else {
coords = [p % width1, i];
}
path.moveTo(p % width1, i);

const p0 = p;
let type = points[p];
Expand All @@ -448,21 +440,12 @@ function compileType3Glyph(imgData) {
// set new type for "future hit"
points[p] &= (type >> 2) | (type << 2);
}

if (path) {
path.lineTo(p % width1, (p / width1) | 0);
} else {
coords.push(p % width1, (p / width1) | 0);
}
path.lineTo(p % width1, (p / width1) | 0);

if (!points[p]) {
--count;
}
} while (p0 !== p);

if (!path) {
outlines.push(coords);
}
--i;
}

Expand All @@ -475,18 +458,7 @@ function compileType3Glyph(imgData) {
// the path shall be painted in [0..1]x[0..1] space
c.scale(1 / width, -1 / height);
c.translate(0, -height);
if (path) {
c.fill(path);
} else {
c.beginPath();
for (const o of outlines) {
c.moveTo(o[0], o[1]);
for (let l = 2, ll = o.length; l < ll; l += 2) {
c.lineTo(o[l], o[l + 1]);
}
}
c.fill();
}
c.fill(path);
c.beginPath();
c.restore();
};
Expand Down

0 comments on commit 1883609

Please sign in to comment.