Use Path2D
, if available, when rendering Type3-fonts (bug 810214)
Note that in order to avoid unnecessary allocations we build the `Path2D`-object *inline* during parsing, rather than iterating through the complete `outlines`-Array at the end. This patch was tested using the PDF file from bug 810214, i.e. https://bug810214.bmoattachments.org/attachment.cgi?id=9254990, with the following manifest file: ``` [ { "id": "bug810214", "file": "../web/pdfs/bug810214.pdf", "md5": "2b7243178f5dd5fd3edc7b6649e4bdf3", "rounds": 100, "lastPage": 25, "type": "eq" } ] ``` which gave the following results when comparing this patch against the `master` branch: - Overall ``` -- Grouped By browser, stat -- browser | stat | Count | Baseline(ms) | Current(ms) | +/- | % | Result(P<.05) ------- | ------------ | ----- | ------------ | ----------- | --- | ------ | ------------- firefox | Overall | 2500 | 123 | 78 | -44 | -36.25 | faster firefox | Page Request | 2500 | 2 | 2 | 0 | 9.11 | slower firefox | Rendering | 2500 | 121 | 76 | -45 | -36.93 | faster ``` - Page-specific ``` -- Grouped By browser, page, stat -- browser | page | stat | Count | Baseline(ms) | Current(ms) | +/- | % | Result(P<.05) ------- | ---- | ------------ | ----- | ------------ | ----------- | --- | ------ | ------------- firefox | 0 | Overall | 100 | 36 | 35 | -1 | -2.89 | firefox | 0 | Page Request | 100 | 2 | 2 | 0 | 7.33 | firefox | 0 | Rendering | 100 | 34 | 33 | -1 | -3.47 | firefox | 1 | Overall | 100 | 123 | 81 | -42 | -33.92 | faster firefox | 1 | Page Request | 100 | 2 | 2 | 0 | -3.31 | firefox | 1 | Rendering | 100 | 121 | 79 | -42 | -34.44 | faster firefox | 2 | Overall | 100 | 129 | 82 | -47 | -36.61 | faster firefox | 2 | Page Request | 100 | 2 | 2 | 0 | 24.84 | slower firefox | 2 | Rendering | 100 | 127 | 80 | -47 | -37.33 | faster firefox | 3 | Overall | 100 | 114 | 68 | -46 | -40.18 | faster firefox | 3 | Page Request | 100 | 2 | 2 | 0 | 15.63 | slower firefox | 3 | Rendering | 100 | 112 | 66 | -46 | -41.07 | faster firefox | 4 | Overall | 100 | 102 | 75 | -27 | -26.09 | faster firefox | 4 | Page Request | 100 | 2 | 2 | 0 | 9.62 | firefox | 4 | Rendering | 100 | 100 | 73 | -27 | -26.71 | faster firefox | 5 | Overall | 100 | 103 | 77 | -26 | -25.15 | faster firefox | 5 | Page Request | 100 | 2 | 2 | 0 | -6.86 | firefox | 5 | Rendering | 100 | 100 | 75 | -26 | -25.53 | faster firefox | 6 | Overall | 100 | 48 | 37 | -11 | -22.56 | faster firefox | 6 | Page Request | 100 | 2 | 2 | 0 | -10.14 | firefox | 6 | Rendering | 100 | 46 | 35 | -11 | -23.16 | faster firefox | 7 | Overall | 100 | 109 | 70 | -39 | -35.59 | faster firefox | 7 | Page Request | 100 | 2 | 2 | 0 | 5.29 | firefox | 7 | Rendering | 100 | 107 | 68 | -39 | -36.23 | faster firefox | 8 | Overall | 100 | 39 | 31 | -9 | -22.14 | faster firefox | 8 | Page Request | 100 | 2 | 2 | 0 | 1.72 | firefox | 8 | Rendering | 100 | 38 | 29 | -9 | -23.38 | faster firefox | 9 | Overall | 100 | 156 | 96 | -60 | -38.49 | faster firefox | 9 | Page Request | 100 | 1 | 2 | 0 | 13.61 | firefox | 9 | Rendering | 100 | 155 | 94 | -60 | -38.98 | faster firefox | 10 | Overall | 100 | 173 | 105 | -68 | -39.20 | faster firefox | 10 | Page Request | 100 | 2 | 2 | 0 | -8.81 | firefox | 10 | Rendering | 100 | 171 | 103 | -68 | -39.60 | faster firefox | 11 | Overall | 100 | 152 | 89 | -64 | -41.88 | faster firefox | 11 | Page Request | 100 | 2 | 2 | 0 | 6.04 | firefox | 11 | Rendering | 100 | 150 | 87 | -64 | -42.47 | faster firefox | 12 | Overall | 100 | 141 | 90 | -51 | -35.91 | faster firefox | 12 | Page Request | 100 | 2 | 2 | 0 | 17.37 | firefox | 12 | Rendering | 100 | 139 | 88 | -51 | -36.60 | faster firefox | 13 | Overall | 100 | 97 | 61 | -36 | -36.79 | faster firefox | 13 | Page Request | 100 | 2 | 2 | 0 | 25.44 | slower firefox | 13 | Rendering | 100 | 95 | 59 | -36 | -37.87 | faster firefox | 14 | Overall | 100 | 118 | 82 | -36 | -30.33 | faster firefox | 14 | Page Request | 100 | 2 | 2 | 0 | 9.20 | firefox | 14 | Rendering | 100 | 117 | 80 | -36 | -30.95 | faster firefox | 15 | Overall | 100 | 111 | 73 | -37 | -33.85 | faster firefox | 15 | Page Request | 100 | 2 | 2 | 0 | 13.25 | firefox | 15 | Rendering | 100 | 109 | 71 | -38 | -34.61 | faster firefox | 16 | Overall | 100 | 145 | 88 | -57 | -39.19 | faster firefox | 16 | Page Request | 100 | 2 | 2 | 1 | 33.75 | slower firefox | 16 | Rendering | 100 | 143 | 86 | -57 | -40.03 | faster firefox | 17 | Overall | 100 | 171 | 126 | -45 | -26.27 | faster firefox | 17 | Page Request | 100 | 2 | 2 | 0 | 17.92 | slower firefox | 17 | Rendering | 100 | 169 | 124 | -45 | -26.69 | faster firefox | 18 | Overall | 100 | 126 | 78 | -47 | -37.71 | faster firefox | 18 | Page Request | 100 | 2 | 2 | 0 | 2.43 | firefox | 18 | Rendering | 100 | 124 | 76 | -48 | -38.43 | faster firefox | 19 | Overall | 100 | 92 | 58 | -34 | -37.19 | faster firefox | 19 | Page Request | 100 | 2 | 2 | 0 | 12.74 | firefox | 19 | Rendering | 100 | 90 | 56 | -35 | -38.13 | faster firefox | 20 | Overall | 100 | 178 | 96 | -82 | -46.18 | faster firefox | 20 | Page Request | 100 | 2 | 2 | 0 | -2.23 | firefox | 20 | Rendering | 100 | 176 | 94 | -82 | -46.67 | faster firefox | 21 | Overall | 100 | 181 | 102 | -79 | -43.77 | faster firefox | 21 | Page Request | 100 | 2 | 2 | 0 | 12.36 | slower firefox | 21 | Rendering | 100 | 179 | 99 | -79 | -44.34 | faster firefox | 22 | Overall | 100 | 140 | 84 | -55 | -39.59 | faster firefox | 22 | Page Request | 100 | 2 | 2 | 0 | 12.50 | firefox | 22 | Rendering | 100 | 138 | 82 | -55 | -40.25 | faster firefox | 23 | Overall | 100 | 119 | 73 | -46 | -38.48 | faster firefox | 23 | Page Request | 100 | 2 | 2 | 1 | 35.71 | slower firefox | 23 | Rendering | 100 | 117 | 71 | -46 | -39.48 | faster firefox | 24 | Overall | 100 | 165 | 96 | -68 | -41.51 | faster firefox | 24 | Page Request | 100 | 2 | 2 | 0 | 2.81 | firefox | 24 | Rendering | 100 | 163 | 94 | -68 | -42.00 | faster ```
This commit is contained in:
parent
4bd5d98d59
commit
c2488c7864
@ -32,6 +32,7 @@ import {
|
||||
TilingPattern,
|
||||
} from "./pattern_helper.js";
|
||||
import { applyMaskImageData } from "../shared/image_utils.js";
|
||||
import { isNodeJS } from "../shared/is_node.js";
|
||||
import { PixelsPerInch } from "./display_utils.js";
|
||||
|
||||
// <canvas> contexts store most of the state we need natively.
|
||||
@ -556,7 +557,13 @@ function compileType3Glyph(imgData) {
|
||||
|
||||
// building outlines
|
||||
const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);
|
||||
const outlines = [];
|
||||
let path, outlines, coords;
|
||||
if (!isNodeJS) {
|
||||
path = new Path2D();
|
||||
} else {
|
||||
outlines = [];
|
||||
}
|
||||
|
||||
for (i = 0; count && i <= height; i++) {
|
||||
let p = i * width1;
|
||||
const end = p + width;
|
||||
@ -566,7 +573,12 @@ function compileType3Glyph(imgData) {
|
||||
if (p === end) {
|
||||
continue;
|
||||
}
|
||||
const coords = [p % width1, i];
|
||||
|
||||
if (path) {
|
||||
path.moveTo(p % width1, i);
|
||||
} else {
|
||||
coords = [p % width1, i];
|
||||
}
|
||||
|
||||
const p0 = p;
|
||||
let type = points[p];
|
||||
@ -590,13 +602,20 @@ function compileType3Glyph(imgData) {
|
||||
points[p] &= (type >> 2) | (type << 2);
|
||||
}
|
||||
|
||||
coords.push(p % width1, (p / width1) | 0);
|
||||
if (path) {
|
||||
path.lineTo(p % width1, (p / width1) | 0);
|
||||
} else {
|
||||
coords.push(p % width1, (p / width1) | 0);
|
||||
}
|
||||
|
||||
if (!points[p]) {
|
||||
--count;
|
||||
}
|
||||
} while (p0 !== p);
|
||||
outlines.push(coords);
|
||||
|
||||
if (!path) {
|
||||
outlines.push(coords);
|
||||
}
|
||||
--i;
|
||||
}
|
||||
|
||||
@ -605,15 +624,18 @@ 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);
|
||||
c.beginPath();
|
||||
for (let k = 0, kk = outlines.length; k < kk; k++) {
|
||||
const o = outlines[k];
|
||||
c.moveTo(o[0], o[1]);
|
||||
for (let l = 2, ll = o.length; l < ll; l += 2) {
|
||||
c.lineTo(o[l], o[l + 1]);
|
||||
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();
|
||||
c.beginPath();
|
||||
c.restore();
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { isNodeJS } from "../shared/is_node.js";
|
||||
|
||||
const PathType = {
|
||||
FILL: "Fill",
|
||||
@ -29,7 +30,7 @@ const PathType = {
|
||||
};
|
||||
|
||||
function applyBoundingBox(ctx, bbox) {
|
||||
if (!bbox || typeof Path2D === "undefined") {
|
||||
if (!bbox || isNodeJS) {
|
||||
return;
|
||||
}
|
||||
const width = bbox[2] - bbox[0];
|
||||
|
@ -19,6 +19,7 @@
|
||||
// https://www.electronjs.org/docs/api/process#processversionselectron-readonly
|
||||
// https://www.electronjs.org/docs/api/process#processtype-readonly
|
||||
const isNodeJS =
|
||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
|
||||
typeof process === "object" &&
|
||||
process + "" === "[object process]" &&
|
||||
!process.versions.nw &&
|
||||
|
Loading…
Reference in New Issue
Block a user