2015-11-10 10:24:15 +09:00
|
|
|
/* Copyright 2015 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-04-02 21:25:33 +09:00
|
|
|
import {
|
2022-01-03 21:36:49 +09:00
|
|
|
BaseCanvasFactory,
|
|
|
|
BaseCMapReaderFactory,
|
[api-minor] Extend general transfer function support to browsers without `OffscreenCanvas`
This patch extends PR 16115 to work in all browsers, regardless of their `OffscreenCanvas` support, such that transfer functions will be applied to general rendering (and not just image data).
In order to do this we introduce the `BaseFilterFactory` that is then extended in browsers/Node.js environments, similar to all the other factories used in the API, such that we always have the necessary factory available in `src/display/canvas.js`.
These changes help simplify the existing `putBinaryImageData` function, and the new method can easily be stubbed-out in the Firefox PDF Viewer.
*Please note:* This patch removes the old *partial* transfer function support, which only applied to image data, from Node.js environments since the `node-canvas` package currently doesn't support filters. However, this should hopefully be fine given that:
- Transfer functions are not very commonly used in PDF documents.
- Browsers in general, and Firefox in particular, are the *primary* development target for the PDF.js library.
- The FAQ only lists Node.js as *mostly* supported, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2023-03-12 23:47:01 +09:00
|
|
|
BaseFilterFactory,
|
2022-01-03 21:36:49 +09:00
|
|
|
BaseStandardFontDataFactory,
|
|
|
|
BaseSVGFactory,
|
|
|
|
} from "./base_factory.js";
|
2022-12-08 20:37:18 +09:00
|
|
|
import {
|
|
|
|
BaseException,
|
|
|
|
shadow,
|
|
|
|
stringToBytes,
|
|
|
|
Util,
|
|
|
|
warn,
|
|
|
|
} from "../shared/util.js";
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
|
|
|
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
2017-01-24 01:34:27 +09:00
|
|
|
|
2022-07-29 00:59:03 +09:00
|
|
|
const AnnotationPrefix = "pdfjs_internal_id_";
|
|
|
|
|
2022-02-19 17:05:40 +09:00
|
|
|
class PixelsPerInch {
|
|
|
|
static CSS = 96.0;
|
2021-09-20 17:10:57 +09:00
|
|
|
|
2022-02-19 17:05:40 +09:00
|
|
|
static PDF = 72.0;
|
|
|
|
|
|
|
|
static PDF_TO_CSS_UNITS = this.CSS / this.PDF;
|
|
|
|
}
|
2021-09-09 09:31:10 +09:00
|
|
|
|
2023-02-16 01:14:04 +09:00
|
|
|
/**
|
|
|
|
* FilterFactory aims to create some SVG filters we can use when drawing an
|
|
|
|
* image (or whatever) on a canvas.
|
|
|
|
* Filters aren't applied with ctx.putImageData because it just overwrites the
|
|
|
|
* underlying pixels.
|
|
|
|
* With these filters, it's possible for example to apply some transfer maps on
|
|
|
|
* an image without the need to apply them on the pixel arrays: the renderer
|
|
|
|
* does the magic for us.
|
|
|
|
*/
|
[api-minor] Extend general transfer function support to browsers without `OffscreenCanvas`
This patch extends PR 16115 to work in all browsers, regardless of their `OffscreenCanvas` support, such that transfer functions will be applied to general rendering (and not just image data).
In order to do this we introduce the `BaseFilterFactory` that is then extended in browsers/Node.js environments, similar to all the other factories used in the API, such that we always have the necessary factory available in `src/display/canvas.js`.
These changes help simplify the existing `putBinaryImageData` function, and the new method can easily be stubbed-out in the Firefox PDF Viewer.
*Please note:* This patch removes the old *partial* transfer function support, which only applied to image data, from Node.js environments since the `node-canvas` package currently doesn't support filters. However, this should hopefully be fine given that:
- Transfer functions are not very commonly used in PDF documents.
- Browsers in general, and Firefox in particular, are the *primary* development target for the PDF.js library.
- The FAQ only lists Node.js as *mostly* supported, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2023-03-12 23:47:01 +09:00
|
|
|
class DOMFilterFactory extends BaseFilterFactory {
|
2023-02-16 01:14:04 +09:00
|
|
|
#_cache;
|
|
|
|
|
|
|
|
#_defs;
|
|
|
|
|
2023-03-09 23:27:57 +09:00
|
|
|
#docId;
|
|
|
|
|
2023-02-16 01:14:04 +09:00
|
|
|
#document;
|
|
|
|
|
2023-03-07 03:09:56 +09:00
|
|
|
#hcmFilter;
|
|
|
|
|
|
|
|
#hcmKey;
|
|
|
|
|
|
|
|
#hcmUrl;
|
|
|
|
|
2023-06-23 22:47:59 +09:00
|
|
|
#hcmHighlightFilter;
|
|
|
|
|
|
|
|
#hcmHighlightKey;
|
|
|
|
|
|
|
|
#hcmHighlightUrl;
|
|
|
|
|
2023-02-16 01:14:04 +09:00
|
|
|
#id = 0;
|
|
|
|
|
2023-03-09 23:27:57 +09:00
|
|
|
constructor({ docId, ownerDocument = globalThis.document } = {}) {
|
[api-minor] Extend general transfer function support to browsers without `OffscreenCanvas`
This patch extends PR 16115 to work in all browsers, regardless of their `OffscreenCanvas` support, such that transfer functions will be applied to general rendering (and not just image data).
In order to do this we introduce the `BaseFilterFactory` that is then extended in browsers/Node.js environments, similar to all the other factories used in the API, such that we always have the necessary factory available in `src/display/canvas.js`.
These changes help simplify the existing `putBinaryImageData` function, and the new method can easily be stubbed-out in the Firefox PDF Viewer.
*Please note:* This patch removes the old *partial* transfer function support, which only applied to image data, from Node.js environments since the `node-canvas` package currently doesn't support filters. However, this should hopefully be fine given that:
- Transfer functions are not very commonly used in PDF documents.
- Browsers in general, and Firefox in particular, are the *primary* development target for the PDF.js library.
- The FAQ only lists Node.js as *mostly* supported, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2023-03-12 23:47:01 +09:00
|
|
|
super();
|
2023-03-09 23:27:57 +09:00
|
|
|
this.#docId = docId;
|
2023-02-16 01:14:04 +09:00
|
|
|
this.#document = ownerDocument;
|
|
|
|
}
|
|
|
|
|
|
|
|
get #cache() {
|
|
|
|
return (this.#_cache ||= new Map());
|
|
|
|
}
|
|
|
|
|
|
|
|
get #defs() {
|
|
|
|
if (!this.#_defs) {
|
2023-03-10 00:10:31 +09:00
|
|
|
const div = this.#document.createElement("div");
|
|
|
|
const { style } = div;
|
|
|
|
style.visibility = "hidden";
|
|
|
|
style.contain = "strict";
|
|
|
|
style.width = style.height = 0;
|
|
|
|
style.position = "absolute";
|
|
|
|
style.top = style.left = 0;
|
|
|
|
style.zIndex = -1;
|
|
|
|
|
2023-02-16 01:14:04 +09:00
|
|
|
const svg = this.#document.createElementNS(SVG_NS, "svg");
|
|
|
|
svg.setAttribute("width", 0);
|
|
|
|
svg.setAttribute("height", 0);
|
|
|
|
this.#_defs = this.#document.createElementNS(SVG_NS, "defs");
|
2023-03-10 00:10:31 +09:00
|
|
|
div.append(svg);
|
2023-02-16 01:14:04 +09:00
|
|
|
svg.append(this.#_defs);
|
2023-03-10 00:10:31 +09:00
|
|
|
this.#document.body.append(div);
|
2023-02-16 01:14:04 +09:00
|
|
|
}
|
|
|
|
return this.#_defs;
|
|
|
|
}
|
|
|
|
|
|
|
|
addFilter(maps) {
|
|
|
|
if (!maps) {
|
2023-03-06 18:57:05 +09:00
|
|
|
return "none";
|
2023-02-16 01:14:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// When a page is zoomed the page is re-drawn but the maps are likely
|
|
|
|
// the same.
|
|
|
|
let value = this.#cache.get(maps);
|
|
|
|
if (value) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
let tableR, tableG, tableB, key;
|
|
|
|
if (maps.length === 1) {
|
|
|
|
const mapR = maps[0];
|
|
|
|
const buffer = new Array(256);
|
|
|
|
for (let i = 0; i < 256; i++) {
|
|
|
|
buffer[i] = mapR[i] / 255;
|
|
|
|
}
|
|
|
|
key = tableR = tableG = tableB = buffer.join(",");
|
|
|
|
} else {
|
|
|
|
const [mapR, mapG, mapB] = maps;
|
|
|
|
const bufferR = new Array(256);
|
|
|
|
const bufferG = new Array(256);
|
|
|
|
const bufferB = new Array(256);
|
|
|
|
for (let i = 0; i < 256; i++) {
|
|
|
|
bufferR[i] = mapR[i] / 255;
|
|
|
|
bufferG[i] = mapG[i] / 255;
|
|
|
|
bufferB[i] = mapB[i] / 255;
|
|
|
|
}
|
|
|
|
tableR = bufferR.join(",");
|
|
|
|
tableG = bufferG.join(",");
|
|
|
|
tableB = bufferB.join(",");
|
|
|
|
key = `${tableR}${tableG}${tableB}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = this.#cache.get(key);
|
|
|
|
if (value) {
|
|
|
|
this.#cache.set(maps, value);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We create a SVG filter: feComponentTransferElement
|
|
|
|
// https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement
|
|
|
|
|
2023-03-09 23:27:57 +09:00
|
|
|
const id = `g_${this.#docId}_transfer_map_${this.#id++}`;
|
2023-02-16 01:14:04 +09:00
|
|
|
const url = `url(#${id})`;
|
|
|
|
this.#cache.set(maps, url);
|
|
|
|
this.#cache.set(key, url);
|
|
|
|
|
2023-06-23 22:47:59 +09:00
|
|
|
const filter = this.#createFilter(id);
|
|
|
|
this.#addTransferMapConversion(tableR, tableG, tableB, filter);
|
2023-02-16 01:14:04 +09:00
|
|
|
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2023-03-07 03:09:56 +09:00
|
|
|
addHCMFilter(fgColor, bgColor) {
|
|
|
|
const key = `${fgColor}-${bgColor}`;
|
|
|
|
if (this.#hcmKey === key) {
|
|
|
|
return this.#hcmUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.#hcmKey = key;
|
|
|
|
this.#hcmUrl = "none";
|
|
|
|
this.#hcmFilter?.remove();
|
|
|
|
|
|
|
|
if (!fgColor || !bgColor) {
|
|
|
|
return this.#hcmUrl;
|
|
|
|
}
|
|
|
|
|
2023-06-23 22:47:59 +09:00
|
|
|
const fgRGB = this.#getRGB(fgColor);
|
2023-03-07 03:09:56 +09:00
|
|
|
fgColor = Util.makeHexColor(...fgRGB);
|
2023-06-23 22:47:59 +09:00
|
|
|
const bgRGB = this.#getRGB(bgColor);
|
2023-03-07 03:09:56 +09:00
|
|
|
bgColor = Util.makeHexColor(...bgRGB);
|
|
|
|
this.#defs.style.color = "";
|
|
|
|
|
|
|
|
if (
|
|
|
|
(fgColor === "#000000" && bgColor === "#ffffff") ||
|
|
|
|
fgColor === bgColor
|
|
|
|
) {
|
|
|
|
return this.#hcmUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_Colors_and_Luminance
|
|
|
|
//
|
|
|
|
// Relative luminance:
|
|
|
|
// https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
|
|
|
//
|
|
|
|
// We compute the rounded luminance of the default background color.
|
|
|
|
// Then for every color in the pdf, if its rounded luminance is the
|
|
|
|
// same as the background one then it's replaced by the new
|
|
|
|
// background color else by the foreground one.
|
|
|
|
const map = new Array(256);
|
|
|
|
for (let i = 0; i <= 255; i++) {
|
|
|
|
const x = i / 255;
|
|
|
|
map[i] = x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;
|
|
|
|
}
|
|
|
|
const table = map.join(",");
|
|
|
|
|
|
|
|
const id = `g_${this.#docId}_hcm_filter`;
|
2023-06-23 22:47:59 +09:00
|
|
|
const filter = (this.#hcmHighlightFilter = this.#createFilter(id));
|
|
|
|
this.#addTransferMapConversion(table, table, table, filter);
|
|
|
|
this.#addGrayConversion(filter);
|
2023-03-07 03:09:56 +09:00
|
|
|
|
|
|
|
const getSteps = (c, n) => {
|
|
|
|
const start = fgRGB[c] / 255;
|
|
|
|
const end = bgRGB[c] / 255;
|
|
|
|
const arr = new Array(n + 1);
|
|
|
|
for (let i = 0; i <= n; i++) {
|
|
|
|
arr[i] = start + (i / n) * (end - start);
|
|
|
|
}
|
|
|
|
return arr.join(",");
|
|
|
|
};
|
2023-06-23 22:47:59 +09:00
|
|
|
this.#addTransferMapConversion(
|
|
|
|
getSteps(0, 5),
|
|
|
|
getSteps(1, 5),
|
|
|
|
getSteps(2, 5),
|
|
|
|
filter
|
|
|
|
);
|
2023-03-07 03:09:56 +09:00
|
|
|
|
|
|
|
this.#hcmUrl = `url(#${id})`;
|
|
|
|
return this.#hcmUrl;
|
|
|
|
}
|
|
|
|
|
2023-06-23 22:47:59 +09:00
|
|
|
addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) {
|
|
|
|
const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`;
|
|
|
|
if (this.#hcmHighlightKey === key) {
|
|
|
|
return this.#hcmHighlightUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.#hcmHighlightKey = key;
|
|
|
|
this.#hcmHighlightUrl = "none";
|
|
|
|
this.#hcmHighlightFilter?.remove();
|
|
|
|
|
|
|
|
if (!fgColor || !bgColor) {
|
|
|
|
return this.#hcmHighlightUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this));
|
|
|
|
let fgGray = Math.round(
|
|
|
|
0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]
|
|
|
|
);
|
|
|
|
let bgGray = Math.round(
|
|
|
|
0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]
|
|
|
|
);
|
|
|
|
let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(
|
|
|
|
this.#getRGB.bind(this)
|
|
|
|
);
|
|
|
|
if (bgGray < fgGray) {
|
|
|
|
[fgGray, bgGray, newFgRGB, newBgRGB] = [
|
|
|
|
bgGray,
|
|
|
|
fgGray,
|
|
|
|
newBgRGB,
|
|
|
|
newFgRGB,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
this.#defs.style.color = "";
|
|
|
|
|
|
|
|
// Now we can create the filters to highlight some canvas parts.
|
|
|
|
// The colors in the pdf will almost be Canvas and CanvasText, hence we
|
|
|
|
// want to filter them to finally get Highlight and HighlightText.
|
|
|
|
// Since we're in HCM the background color and the foreground color should
|
|
|
|
// be really different when converted to grayscale (if they're not then it
|
|
|
|
// means that we've a poor contrast). Once the canvas colors are converted
|
|
|
|
// to grayscale we can easily map them on their new colors.
|
|
|
|
// The grayscale step is important because if we've something like:
|
|
|
|
// fgColor = #FF....
|
|
|
|
// bgColor = #FF....
|
|
|
|
// then we are enable to map the red component on the new red components
|
|
|
|
// which can be different.
|
|
|
|
|
|
|
|
const getSteps = (fg, bg, n) => {
|
|
|
|
const arr = new Array(256);
|
|
|
|
const step = (bgGray - fgGray) / n;
|
|
|
|
const newStart = fg / 255;
|
|
|
|
const newStep = (bg - fg) / (255 * n);
|
|
|
|
let prev = 0;
|
|
|
|
for (let i = 0; i <= n; i++) {
|
|
|
|
const k = Math.round(fgGray + i * step);
|
|
|
|
const value = newStart + i * newStep;
|
|
|
|
for (let j = prev; j <= k; j++) {
|
|
|
|
arr[j] = value;
|
|
|
|
}
|
|
|
|
prev = k + 1;
|
|
|
|
}
|
|
|
|
for (let i = prev; i < 256; i++) {
|
|
|
|
arr[i] = arr[prev - 1];
|
|
|
|
}
|
|
|
|
return arr.join(",");
|
|
|
|
};
|
|
|
|
|
|
|
|
const id = `g_${this.#docId}_hcm_highlight_filter`;
|
|
|
|
const filter = (this.#hcmHighlightFilter = this.#createFilter(id));
|
|
|
|
|
|
|
|
this.#addGrayConversion(filter);
|
|
|
|
this.#addTransferMapConversion(
|
|
|
|
getSteps(newFgRGB[0], newBgRGB[0], 5),
|
|
|
|
getSteps(newFgRGB[1], newBgRGB[1], 5),
|
|
|
|
getSteps(newFgRGB[2], newBgRGB[2], 5),
|
|
|
|
filter
|
|
|
|
);
|
|
|
|
|
|
|
|
this.#hcmHighlightUrl = `url(#${id})`;
|
|
|
|
return this.#hcmHighlightUrl;
|
|
|
|
}
|
|
|
|
|
2023-03-07 03:09:56 +09:00
|
|
|
destroy(keepHCM = false) {
|
2023-06-23 22:47:59 +09:00
|
|
|
if (keepHCM && (this.#hcmUrl || this.#hcmHighlightUrl)) {
|
2023-03-07 03:09:56 +09:00
|
|
|
return;
|
|
|
|
}
|
2023-02-16 01:14:04 +09:00
|
|
|
if (this.#_defs) {
|
2023-03-10 00:10:31 +09:00
|
|
|
this.#_defs.parentNode.parentNode.remove();
|
2023-02-16 01:14:04 +09:00
|
|
|
this.#_defs = null;
|
|
|
|
}
|
|
|
|
if (this.#_cache) {
|
|
|
|
this.#_cache.clear();
|
|
|
|
this.#_cache = null;
|
|
|
|
}
|
|
|
|
this.#id = 0;
|
|
|
|
}
|
2023-06-23 22:47:59 +09:00
|
|
|
|
|
|
|
#addGrayConversion(filter) {
|
|
|
|
const feColorMatrix = this.#document.createElementNS(
|
|
|
|
SVG_NS,
|
|
|
|
"feColorMatrix"
|
|
|
|
);
|
|
|
|
feColorMatrix.setAttribute("type", "matrix");
|
|
|
|
feColorMatrix.setAttribute(
|
|
|
|
"values",
|
|
|
|
"0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"
|
|
|
|
);
|
|
|
|
filter.append(feColorMatrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
#createFilter(id) {
|
|
|
|
const filter = this.#document.createElementNS(SVG_NS, "filter");
|
|
|
|
filter.setAttribute("color-interpolation-filters", "sRGB");
|
|
|
|
filter.setAttribute("id", id);
|
|
|
|
this.#defs.append(filter);
|
|
|
|
|
|
|
|
return filter;
|
|
|
|
}
|
|
|
|
|
|
|
|
#appendFeFunc(feComponentTransfer, func, table) {
|
|
|
|
const feFunc = this.#document.createElementNS(SVG_NS, func);
|
|
|
|
feFunc.setAttribute("type", "discrete");
|
|
|
|
feFunc.setAttribute("tableValues", table);
|
|
|
|
feComponentTransfer.append(feFunc);
|
|
|
|
}
|
|
|
|
|
|
|
|
#addTransferMapConversion(rTable, gTable, bTable, filter) {
|
|
|
|
const feComponentTransfer = this.#document.createElementNS(
|
|
|
|
SVG_NS,
|
|
|
|
"feComponentTransfer"
|
|
|
|
);
|
|
|
|
filter.append(feComponentTransfer);
|
|
|
|
this.#appendFeFunc(feComponentTransfer, "feFuncR", rTable);
|
|
|
|
this.#appendFeFunc(feComponentTransfer, "feFuncG", gTable);
|
|
|
|
this.#appendFeFunc(feComponentTransfer, "feFuncB", bTable);
|
|
|
|
}
|
|
|
|
|
|
|
|
#getRGB(color) {
|
|
|
|
this.#defs.style.color = color;
|
|
|
|
return getRGB(getComputedStyle(this.#defs).getPropertyValue("color"));
|
|
|
|
}
|
2023-02-16 01:14:04 +09:00
|
|
|
}
|
|
|
|
|
2020-06-29 20:18:51 +09:00
|
|
|
class DOMCanvasFactory extends BaseCanvasFactory {
|
2020-07-28 02:22:45 +09:00
|
|
|
constructor({ ownerDocument = globalThis.document } = {}) {
|
|
|
|
super();
|
|
|
|
this._document = ownerDocument;
|
|
|
|
}
|
|
|
|
|
2022-03-07 19:55:17 +09:00
|
|
|
/**
|
|
|
|
* @ignore
|
|
|
|
*/
|
2021-06-11 23:35:42 +09:00
|
|
|
_createCanvas(width, height) {
|
2020-07-28 02:22:45 +09:00
|
|
|
const canvas = this._document.createElement("canvas");
|
2020-06-29 20:18:51 +09:00
|
|
|
canvas.width = width;
|
|
|
|
canvas.height = height;
|
2021-06-11 23:35:42 +09:00
|
|
|
return canvas;
|
2020-06-29 20:18:51 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-12 00:12:55 +09:00
|
|
|
async function fetchData(url, asTypedArray = false) {
|
2020-12-11 10:32:18 +09:00
|
|
|
if (
|
|
|
|
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
2021-06-12 05:53:09 +09:00
|
|
|
isValidFetchUrl(url, document.baseURI)
|
2020-12-11 10:32:18 +09:00
|
|
|
) {
|
2021-06-12 00:12:55 +09:00
|
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(response.statusText);
|
|
|
|
}
|
|
|
|
return asTypedArray
|
|
|
|
? new Uint8Array(await response.arrayBuffer())
|
|
|
|
: stringToBytes(await response.text());
|
2020-12-11 10:32:18 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// The Fetch API is not supported.
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const request = new XMLHttpRequest();
|
|
|
|
request.open("GET", url, /* asTypedArray = */ true);
|
|
|
|
|
|
|
|
if (asTypedArray) {
|
|
|
|
request.responseType = "arraybuffer";
|
|
|
|
}
|
|
|
|
request.onreadystatechange = () => {
|
|
|
|
if (request.readyState !== XMLHttpRequest.DONE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (request.status === 200 || request.status === 0) {
|
|
|
|
let data;
|
|
|
|
if (asTypedArray && request.response) {
|
|
|
|
data = new Uint8Array(request.response);
|
|
|
|
} else if (!asTypedArray && request.responseText) {
|
|
|
|
data = stringToBytes(request.responseText);
|
|
|
|
}
|
|
|
|
if (data) {
|
|
|
|
resolve(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reject(new Error(request.statusText));
|
|
|
|
};
|
|
|
|
|
|
|
|
request.send(null);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-29 20:18:51 +09:00
|
|
|
class DOMCMapReaderFactory extends BaseCMapReaderFactory {
|
2022-03-07 19:55:17 +09:00
|
|
|
/**
|
|
|
|
* @ignore
|
|
|
|
*/
|
2020-06-29 20:18:51 +09:00
|
|
|
_fetchData(url, compressionType) {
|
2020-12-11 10:32:18 +09:00
|
|
|
return fetchData(url, /* asTypedArray = */ this.isCompressed).then(data => {
|
|
|
|
return { cMapData: data, compressionType };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2017-02-12 23:54:41 +09:00
|
|
|
|
2020-12-11 10:32:18 +09:00
|
|
|
class DOMStandardFontDataFactory extends BaseStandardFontDataFactory {
|
2022-03-07 19:55:17 +09:00
|
|
|
/**
|
|
|
|
* @ignore
|
|
|
|
*/
|
2020-12-11 10:32:18 +09:00
|
|
|
_fetchData(url) {
|
|
|
|
return fetchData(url, /* asTypedArray = */ true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-11 23:50:57 +09:00
|
|
|
class DOMSVGFactory extends BaseSVGFactory {
|
2022-03-07 19:55:17 +09:00
|
|
|
/**
|
|
|
|
* @ignore
|
|
|
|
*/
|
2021-06-11 23:50:57 +09:00
|
|
|
_createSVG(type) {
|
2017-07-24 07:09:18 +09:00
|
|
|
return document.createElementNS(SVG_NS, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-04 19:37:00 +09:00
|
|
|
/**
|
|
|
|
* @typedef {Object} PageViewportParameters
|
2020-08-02 17:46:24 +09:00
|
|
|
* @property {Array<number>} viewBox - The xMin, yMin, xMax and
|
|
|
|
* yMax coordinates.
|
2018-06-04 19:37:00 +09:00
|
|
|
* @property {number} scale - The scale of the viewport.
|
|
|
|
* @property {number} rotation - The rotation, in degrees, of the viewport.
|
2019-10-12 23:30:32 +09:00
|
|
|
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The
|
|
|
|
* default value is `0`.
|
|
|
|
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset. The
|
|
|
|
* default value is `0`.
|
|
|
|
* @property {boolean} [dontFlip] - If true, the y-axis will not be flipped.
|
|
|
|
* The default value is `false`.
|
2018-06-04 19:37:00 +09:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef {Object} PageViewportCloneParameters
|
2019-10-12 23:30:32 +09:00
|
|
|
* @property {number} [scale] - The scale, overriding the one in the cloned
|
|
|
|
* viewport. The default value is `this.scale`.
|
|
|
|
* @property {number} [rotation] - The rotation, in degrees, overriding the one
|
|
|
|
* in the cloned viewport. The default value is `this.rotation`.
|
2019-10-24 03:35:49 +09:00
|
|
|
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset.
|
|
|
|
* The default value is `this.offsetX`.
|
|
|
|
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset.
|
|
|
|
* The default value is `this.offsetY`.
|
2019-10-12 23:30:32 +09:00
|
|
|
* @property {boolean} [dontFlip] - If true, the x-axis will not be flipped.
|
|
|
|
* The default value is `false`.
|
2018-06-04 19:37:00 +09:00
|
|
|
*/
|
|
|
|
|
2018-06-04 19:36:26 +09:00
|
|
|
/**
|
|
|
|
* PDF page viewport created based on scale, rotation and offset.
|
|
|
|
*/
|
2018-06-04 19:36:53 +09:00
|
|
|
class PageViewport {
|
2018-06-04 19:36:26 +09:00
|
|
|
/**
|
2018-06-04 19:37:00 +09:00
|
|
|
* @param {PageViewportParameters}
|
2018-06-04 19:36:26 +09:00
|
|
|
*/
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
constructor({
|
|
|
|
viewBox,
|
|
|
|
scale,
|
|
|
|
rotation,
|
|
|
|
offsetX = 0,
|
|
|
|
offsetY = 0,
|
|
|
|
dontFlip = false,
|
|
|
|
}) {
|
2018-06-04 19:36:26 +09:00
|
|
|
this.viewBox = viewBox;
|
|
|
|
this.scale = scale;
|
|
|
|
this.rotation = rotation;
|
|
|
|
this.offsetX = offsetX;
|
|
|
|
this.offsetY = offsetY;
|
|
|
|
|
|
|
|
// creating transform to convert pdf coordinate system to the normal
|
|
|
|
// canvas like coordinates taking in account scale and rotation
|
2019-03-02 06:28:19 +09:00
|
|
|
const centerX = (viewBox[2] + viewBox[0]) / 2;
|
|
|
|
const centerY = (viewBox[3] + viewBox[1]) / 2;
|
2018-06-04 19:36:53 +09:00
|
|
|
let rotateA, rotateB, rotateC, rotateD;
|
2021-03-28 21:12:13 +09:00
|
|
|
// Normalize the rotation, by clamping it to the [0, 360) range.
|
|
|
|
rotation %= 360;
|
|
|
|
if (rotation < 0) {
|
|
|
|
rotation += 360;
|
|
|
|
}
|
2018-06-04 19:36:26 +09:00
|
|
|
switch (rotation) {
|
|
|
|
case 180:
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
rotateA = -1;
|
|
|
|
rotateB = 0;
|
|
|
|
rotateC = 0;
|
|
|
|
rotateD = 1;
|
2018-06-04 19:36:26 +09:00
|
|
|
break;
|
|
|
|
case 90:
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
rotateA = 0;
|
|
|
|
rotateB = 1;
|
|
|
|
rotateC = 1;
|
|
|
|
rotateD = 0;
|
2018-06-04 19:36:26 +09:00
|
|
|
break;
|
|
|
|
case 270:
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
rotateA = 0;
|
|
|
|
rotateB = -1;
|
|
|
|
rotateC = -1;
|
|
|
|
rotateD = 0;
|
2018-06-04 19:36:26 +09:00
|
|
|
break;
|
2020-04-22 22:18:27 +09:00
|
|
|
case 0:
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
rotateA = 1;
|
|
|
|
rotateB = 0;
|
|
|
|
rotateC = 0;
|
|
|
|
rotateD = -1;
|
2018-06-04 19:36:26 +09:00
|
|
|
break;
|
2020-04-22 22:18:27 +09:00
|
|
|
default:
|
|
|
|
throw new Error(
|
|
|
|
"PageViewport: Invalid rotation, must be a multiple of 90 degrees."
|
|
|
|
);
|
2018-06-04 19:36:26 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dontFlip) {
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
rotateC = -rotateC;
|
|
|
|
rotateD = -rotateD;
|
2018-06-04 19:36:26 +09:00
|
|
|
}
|
|
|
|
|
2018-06-04 19:36:53 +09:00
|
|
|
let offsetCanvasX, offsetCanvasY;
|
|
|
|
let width, height;
|
2018-06-04 19:36:26 +09:00
|
|
|
if (rotateA === 0) {
|
|
|
|
offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
|
|
|
|
offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
|
2022-12-02 18:09:35 +09:00
|
|
|
width = (viewBox[3] - viewBox[1]) * scale;
|
|
|
|
height = (viewBox[2] - viewBox[0]) * scale;
|
2018-06-04 19:36:26 +09:00
|
|
|
} else {
|
|
|
|
offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
|
|
|
|
offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
|
2022-12-02 18:09:35 +09:00
|
|
|
width = (viewBox[2] - viewBox[0]) * scale;
|
|
|
|
height = (viewBox[3] - viewBox[1]) * scale;
|
2018-06-04 19:36:26 +09:00
|
|
|
}
|
|
|
|
// creating transform for the following operations:
|
|
|
|
// translate(-centerX, -centerY), rotate and flip vertically,
|
|
|
|
// scale, and translate(offsetCanvasX, offsetCanvasY)
|
|
|
|
this.transform = [
|
|
|
|
rotateA * scale,
|
|
|
|
rotateB * scale,
|
|
|
|
rotateC * scale,
|
|
|
|
rotateD * scale,
|
|
|
|
offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY,
|
2018-06-04 19:36:26 +09:00
|
|
|
];
|
|
|
|
|
|
|
|
this.width = width;
|
|
|
|
this.height = height;
|
|
|
|
}
|
2018-06-04 19:36:53 +09:00
|
|
|
|
2022-12-08 20:37:18 +09:00
|
|
|
/**
|
|
|
|
* The original, un-scaled, viewport dimensions.
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
get rawDims() {
|
|
|
|
const { viewBox } = this;
|
|
|
|
return shadow(this, "rawDims", {
|
|
|
|
pageWidth: viewBox[2] - viewBox[0],
|
|
|
|
pageHeight: viewBox[3] - viewBox[1],
|
|
|
|
pageX: viewBox[0],
|
|
|
|
pageY: viewBox[1],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-06-04 19:36:53 +09:00
|
|
|
/**
|
2018-06-04 19:37:00 +09:00
|
|
|
* Clones viewport, with optional additional properties.
|
2019-10-12 23:30:32 +09:00
|
|
|
* @param {PageViewportCloneParameters} [params]
|
2019-10-13 01:14:29 +09:00
|
|
|
* @returns {PageViewport} Cloned viewport.
|
2018-06-04 19:36:53 +09:00
|
|
|
*/
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
clone({
|
|
|
|
scale = this.scale,
|
|
|
|
rotation = this.rotation,
|
|
|
|
offsetX = this.offsetX,
|
|
|
|
offsetY = this.offsetY,
|
|
|
|
dontFlip = false,
|
|
|
|
} = {}) {
|
2018-06-04 19:37:00 +09:00
|
|
|
return new PageViewport({
|
|
|
|
viewBox: this.viewBox.slice(),
|
|
|
|
scale,
|
|
|
|
rotation,
|
2019-10-24 03:35:49 +09:00
|
|
|
offsetX,
|
|
|
|
offsetY,
|
2018-06-04 19:37:00 +09:00
|
|
|
dontFlip,
|
|
|
|
});
|
2018-06-04 19:36:53 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts PDF point to the viewport coordinates. For examples, useful for
|
|
|
|
* converting PDF location into canvas pixel coordinates.
|
2018-06-04 19:37:00 +09:00
|
|
|
* @param {number} x - The x-coordinate.
|
|
|
|
* @param {number} y - The y-coordinate.
|
2023-03-09 23:51:55 +09:00
|
|
|
* @returns {Array} Array containing `x`- and `y`-coordinates of the
|
2018-06-04 19:37:00 +09:00
|
|
|
* point in the viewport coordinate space.
|
2018-06-04 19:36:53 +09:00
|
|
|
* @see {@link convertToPdfPoint}
|
|
|
|
* @see {@link convertToViewportRectangle}
|
|
|
|
*/
|
|
|
|
convertToViewportPoint(x, y) {
|
|
|
|
return Util.applyTransform([x, y], this.transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts PDF rectangle to the viewport coordinates.
|
2018-06-04 19:37:00 +09:00
|
|
|
* @param {Array} rect - The xMin, yMin, xMax and yMax coordinates.
|
2019-10-13 01:14:29 +09:00
|
|
|
* @returns {Array} Array containing corresponding coordinates of the
|
|
|
|
* rectangle in the viewport coordinate space.
|
2018-06-04 19:36:53 +09:00
|
|
|
* @see {@link convertToViewportPoint}
|
|
|
|
*/
|
|
|
|
convertToViewportRectangle(rect) {
|
2019-03-02 06:28:19 +09:00
|
|
|
const topLeft = Util.applyTransform([rect[0], rect[1]], this.transform);
|
|
|
|
const bottomRight = Util.applyTransform([rect[2], rect[3]], this.transform);
|
|
|
|
return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];
|
2018-06-04 19:36:53 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts viewport coordinates to the PDF location. For examples, useful
|
|
|
|
* for converting canvas pixel location into PDF one.
|
2018-06-04 19:37:00 +09:00
|
|
|
* @param {number} x - The x-coordinate.
|
|
|
|
* @param {number} y - The y-coordinate.
|
2023-03-09 23:51:55 +09:00
|
|
|
* @returns {Array} Array containing `x`- and `y`-coordinates of the
|
2018-06-04 19:37:00 +09:00
|
|
|
* point in the PDF coordinate space.
|
2018-06-04 19:36:53 +09:00
|
|
|
* @see {@link convertToViewportPoint}
|
|
|
|
*/
|
|
|
|
convertToPdfPoint(x, y) {
|
|
|
|
return Util.applyInverseTransform([x, y], this.transform);
|
|
|
|
}
|
|
|
|
}
|
2018-06-04 19:36:26 +09:00
|
|
|
|
2019-09-29 08:18:48 +09:00
|
|
|
class RenderingCancelledException extends BaseException {
|
2023-06-14 22:40:25 +09:00
|
|
|
constructor(msg, extraDelay = 0) {
|
2021-08-09 19:02:49 +09:00
|
|
|
super(msg, "RenderingCancelledException");
|
2022-12-14 20:34:16 +09:00
|
|
|
this.extraDelay = extraDelay;
|
2017-03-13 21:32:23 +09:00
|
|
|
}
|
2019-09-29 08:18:48 +09:00
|
|
|
}
|
2017-03-13 21:32:23 +09:00
|
|
|
|
2021-03-16 19:56:31 +09:00
|
|
|
function isDataScheme(url) {
|
|
|
|
const ii = url.length;
|
|
|
|
let i = 0;
|
|
|
|
while (i < ii && url[i].trim() === "") {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return url.substring(i, i + 5).toLowerCase() === "data:";
|
|
|
|
}
|
|
|
|
|
2021-02-24 21:02:58 +09:00
|
|
|
function isPdfFile(filename) {
|
|
|
|
return typeof filename === "string" && /\.pdf$/i.test(filename);
|
|
|
|
}
|
|
|
|
|
2020-08-03 19:19:48 +09:00
|
|
|
/**
|
2021-03-16 19:56:31 +09:00
|
|
|
* Gets the filename from a given URL.
|
2020-08-03 19:19:48 +09:00
|
|
|
* @param {string} url
|
2022-11-23 18:40:30 +09:00
|
|
|
* @param {boolean} [onlyStripPath]
|
2021-03-16 19:56:31 +09:00
|
|
|
* @returns {string}
|
2020-08-03 19:19:48 +09:00
|
|
|
*/
|
2022-11-23 18:40:30 +09:00
|
|
|
function getFilenameFromUrl(url, onlyStripPath = false) {
|
|
|
|
if (!onlyStripPath) {
|
2022-11-23 19:48:08 +09:00
|
|
|
[url] = url.split(/[#?]/, 1);
|
2022-11-23 18:40:30 +09:00
|
|
|
}
|
2022-11-23 19:48:08 +09:00
|
|
|
return url.substring(url.lastIndexOf("/") + 1);
|
2016-03-03 09:48:21 +09:00
|
|
|
}
|
2016-03-29 04:49:22 +09:00
|
|
|
|
2021-03-16 19:56:31 +09:00
|
|
|
/**
|
|
|
|
* Returns the filename or guessed filename from the url (see issue 3455).
|
|
|
|
* @param {string} url - The original PDF location.
|
|
|
|
* @param {string} defaultFilename - The value returned if the filename is
|
|
|
|
* unknown, or the protocol is unsupported.
|
|
|
|
* @returns {string} Guessed PDF filename.
|
|
|
|
*/
|
|
|
|
function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
|
|
|
|
if (typeof url !== "string") {
|
|
|
|
return defaultFilename;
|
|
|
|
}
|
|
|
|
if (isDataScheme(url)) {
|
|
|
|
warn('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.');
|
|
|
|
return defaultFilename;
|
|
|
|
}
|
|
|
|
const reURI = /^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
|
|
|
|
// SCHEME HOST 1.PATH 2.QUERY 3.REF
|
|
|
|
// Pattern to get last matching NAME.pdf
|
|
|
|
const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
|
|
|
const splitURI = reURI.exec(url);
|
|
|
|
let suggestedFilename =
|
|
|
|
reFilename.exec(splitURI[1]) ||
|
|
|
|
reFilename.exec(splitURI[2]) ||
|
|
|
|
reFilename.exec(splitURI[3]);
|
|
|
|
if (suggestedFilename) {
|
|
|
|
suggestedFilename = suggestedFilename[0];
|
|
|
|
if (suggestedFilename.includes("%")) {
|
|
|
|
// URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
|
|
|
|
try {
|
|
|
|
suggestedFilename = reFilename.exec(
|
|
|
|
decodeURIComponent(suggestedFilename)
|
|
|
|
)[0];
|
2023-06-12 18:46:11 +09:00
|
|
|
} catch {
|
2021-03-16 19:56:31 +09:00
|
|
|
// Possible (extremely rare) errors:
|
|
|
|
// URIError "Malformed URI", e.g. for "%AA.pdf"
|
|
|
|
// TypeError "null has no properties", e.g. for "%2F.pdf"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return suggestedFilename || defaultFilename;
|
|
|
|
}
|
|
|
|
|
2017-12-06 21:59:03 +09:00
|
|
|
class StatTimer {
|
2022-11-11 20:20:43 +09:00
|
|
|
started = Object.create(null);
|
|
|
|
|
|
|
|
times = [];
|
2017-12-06 21:59:03 +09:00
|
|
|
|
|
|
|
time(name) {
|
|
|
|
if (name in this.started) {
|
2019-10-23 20:45:31 +09:00
|
|
|
warn(`Timer is already running for ${name}`);
|
2017-12-06 21:59:03 +09:00
|
|
|
}
|
|
|
|
this.started[name] = Date.now();
|
|
|
|
}
|
|
|
|
|
|
|
|
timeEnd(name) {
|
|
|
|
if (!(name in this.started)) {
|
2019-10-23 20:45:31 +09:00
|
|
|
warn(`Timer has not been started for ${name}`);
|
2017-12-06 21:59:03 +09:00
|
|
|
}
|
|
|
|
this.times.push({
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
name,
|
|
|
|
start: this.started[name],
|
|
|
|
end: Date.now(),
|
2017-12-06 21:59:03 +09:00
|
|
|
});
|
|
|
|
// Remove timer from started so it can be called again.
|
|
|
|
delete this.started[name];
|
|
|
|
}
|
|
|
|
|
|
|
|
toString() {
|
|
|
|
// Find the longest name for padding purposes.
|
2020-01-24 21:21:16 +09:00
|
|
|
const outBuf = [];
|
|
|
|
let longest = 0;
|
2022-11-11 20:20:43 +09:00
|
|
|
for (const { name } of this.times) {
|
|
|
|
longest = Math.max(name.length, longest);
|
2017-12-06 21:59:03 +09:00
|
|
|
}
|
2022-11-11 20:20:43 +09:00
|
|
|
for (const { name, start, end } of this.times) {
|
|
|
|
outBuf.push(`${name.padEnd(longest)} ${end - start}ms\n`);
|
2017-12-06 21:59:03 +09:00
|
|
|
}
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
return outBuf.join("");
|
2017-12-06 21:59:03 +09:00
|
|
|
}
|
|
|
|
}
|
2017-12-06 21:51:04 +09:00
|
|
|
|
2019-02-24 23:22:25 +09:00
|
|
|
function isValidFetchUrl(url, baseUrl) {
|
2023-06-22 22:02:54 +09:00
|
|
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
|
|
|
throw new Error("Not implemented: isValidFetchUrl");
|
|
|
|
}
|
2019-02-24 23:22:25 +09:00
|
|
|
try {
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
const { protocol } = baseUrl ? new URL(url, baseUrl) : new URL(url);
|
2019-02-24 23:22:25 +09:00
|
|
|
// The Fetch API only supports the http/https protocols, and not file/ftp.
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
return protocol === "http:" || protocol === "https:";
|
2023-06-12 18:46:11 +09:00
|
|
|
} catch {
|
2019-02-24 23:22:25 +09:00
|
|
|
return false; // `new URL()` will throw on incorrect data.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-03 19:19:48 +09:00
|
|
|
/**
|
|
|
|
* @param {string} src
|
2020-12-08 01:11:32 +09:00
|
|
|
* @param {boolean} [removeScriptElement]
|
2020-08-03 19:19:48 +09:00
|
|
|
* @returns {Promise<void>}
|
|
|
|
*/
|
2020-12-08 01:11:32 +09:00
|
|
|
function loadScript(src, removeScriptElement = false) {
|
2018-06-07 20:52:40 +09:00
|
|
|
return new Promise((resolve, reject) => {
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
const script = document.createElement("script");
|
2018-06-07 20:52:40 +09:00
|
|
|
script.src = src;
|
|
|
|
|
2020-12-08 01:11:32 +09:00
|
|
|
script.onload = function (evt) {
|
|
|
|
if (removeScriptElement) {
|
|
|
|
script.remove();
|
|
|
|
}
|
|
|
|
resolve(evt);
|
|
|
|
};
|
2020-04-14 19:28:14 +09:00
|
|
|
script.onerror = function () {
|
2018-06-07 20:52:40 +09:00
|
|
|
reject(new Error(`Cannot load script at: ${script.src}`));
|
|
|
|
};
|
2022-06-12 19:20:25 +09:00
|
|
|
(document.head || document.documentElement).append(script);
|
2018-06-07 20:52:40 +09:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-02 19:45:14 +09:00
|
|
|
// Deprecated API function -- display regardless of the `verbosity` setting.
|
|
|
|
function deprecated(details) {
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
console.log("Deprecated API usage: " + details);
|
2019-03-02 19:45:14 +09:00
|
|
|
}
|
|
|
|
|
2019-04-22 04:21:01 +09:00
|
|
|
let pdfDateStringRegex;
|
|
|
|
|
|
|
|
class PDFDateString {
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
/**
|
|
|
|
* Convert a PDF date string to a JavaScript `Date` object.
|
|
|
|
*
|
|
|
|
* The PDF date string format is described in section 7.9.4 of the official
|
|
|
|
* PDF 32000-1:2008 specification. However, in the PDF 1.7 reference (sixth
|
|
|
|
* edition) Adobe describes the same format including a trailing apostrophe.
|
|
|
|
* This syntax in incorrect, but Adobe Acrobat creates PDF files that contain
|
|
|
|
* them. We ignore all apostrophes as they are not necessary for date parsing.
|
|
|
|
*
|
|
|
|
* Moreover, Adobe Acrobat doesn't handle changing the date to universal time
|
|
|
|
* and doesn't use the user's time zone (effectively ignoring the HH' and mm'
|
|
|
|
* parts of the date string).
|
|
|
|
*
|
|
|
|
* @param {string} input
|
|
|
|
* @returns {Date|null}
|
|
|
|
*/
|
2019-04-22 04:21:01 +09:00
|
|
|
static toDateObject(input) {
|
2022-02-24 01:02:19 +09:00
|
|
|
if (!input || typeof input !== "string") {
|
2019-04-22 04:21:01 +09:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lazily initialize the regular expression.
|
2023-05-19 01:52:54 +09:00
|
|
|
pdfDateStringRegex ||= new RegExp(
|
|
|
|
"^D:" + // Prefix (required)
|
|
|
|
"(\\d{4})" + // Year (required)
|
|
|
|
"(\\d{2})?" + // Month (optional)
|
|
|
|
"(\\d{2})?" + // Day (optional)
|
|
|
|
"(\\d{2})?" + // Hour (optional)
|
|
|
|
"(\\d{2})?" + // Minute (optional)
|
|
|
|
"(\\d{2})?" + // Second (optional)
|
|
|
|
"([Z|+|-])?" + // Universal time relation (optional)
|
|
|
|
"(\\d{2})?" + // Offset hour (optional)
|
|
|
|
"'?" + // Splitting apostrophe (optional)
|
|
|
|
"(\\d{2})?" + // Offset minute (optional)
|
|
|
|
"'?" // Trailing apostrophe (optional)
|
|
|
|
);
|
2019-04-22 04:21:01 +09:00
|
|
|
|
|
|
|
// Optional fields that don't satisfy the requirements from the regular
|
|
|
|
// expression (such as incorrect digit counts or numbers that are out of
|
|
|
|
// range) will fall back the defaults from the specification.
|
|
|
|
const matches = pdfDateStringRegex.exec(input);
|
|
|
|
if (!matches) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// JavaScript's `Date` object expects the month to be between 0 and 11
|
|
|
|
// instead of 1 and 12, so we have to correct for that.
|
|
|
|
const year = parseInt(matches[1], 10);
|
|
|
|
let month = parseInt(matches[2], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
month = month >= 1 && month <= 12 ? month - 1 : 0;
|
2019-04-22 04:21:01 +09:00
|
|
|
let day = parseInt(matches[3], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
day = day >= 1 && day <= 31 ? day : 1;
|
2019-04-22 04:21:01 +09:00
|
|
|
let hour = parseInt(matches[4], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
hour = hour >= 0 && hour <= 23 ? hour : 0;
|
2019-04-22 04:21:01 +09:00
|
|
|
let minute = parseInt(matches[5], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
minute = minute >= 0 && minute <= 59 ? minute : 0;
|
2019-04-22 04:21:01 +09:00
|
|
|
let second = parseInt(matches[6], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
second = second >= 0 && second <= 59 ? second : 0;
|
|
|
|
const universalTimeRelation = matches[7] || "Z";
|
2019-04-22 04:21:01 +09:00
|
|
|
let offsetHour = parseInt(matches[8], 10);
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;
|
2019-04-22 04:21:01 +09:00
|
|
|
let offsetMinute = parseInt(matches[9], 10) || 0;
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;
|
2019-04-22 04:21:01 +09:00
|
|
|
|
|
|
|
// Universal time relation 'Z' means that the local time is equal to the
|
|
|
|
// universal time, whereas the relations '+'/'-' indicate that the local
|
|
|
|
// time is later respectively earlier than the universal time. Every date
|
|
|
|
// is normalized to universal time.
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
if (universalTimeRelation === "-") {
|
2019-04-22 04:21:01 +09:00
|
|
|
hour += offsetHour;
|
|
|
|
minute += offsetMinute;
|
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).
Prettier is being used for a couple of reasons:
- To be consistent with `mozilla-central`, where Prettier is already in use across the tree.
- To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.
Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.
*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.
(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-25 23:59:37 +09:00
|
|
|
} else if (universalTimeRelation === "+") {
|
2019-04-22 04:21:01 +09:00
|
|
|
hour -= offsetHour;
|
|
|
|
minute -= offsetMinute;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Date(Date.UTC(year, month, day, hour, minute, second));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-18 19:31:58 +09:00
|
|
|
/**
|
|
|
|
* NOTE: This is (mostly) intended to support printing of XFA forms.
|
|
|
|
*/
|
|
|
|
function getXfaPageViewport(xfaPage, { scale = 1, rotation = 0 }) {
|
|
|
|
const { width, height } = xfaPage.attributes.style;
|
|
|
|
const viewBox = [0, 0, parseInt(width), parseInt(height)];
|
|
|
|
|
|
|
|
return new PageViewport({
|
|
|
|
viewBox,
|
|
|
|
scale,
|
|
|
|
rotation,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-14 01:23:10 +09:00
|
|
|
function getRGB(color) {
|
|
|
|
if (color.startsWith("#")) {
|
|
|
|
const colorRGB = parseInt(color.slice(1), 16);
|
|
|
|
return [
|
|
|
|
(colorRGB & 0xff0000) >> 16,
|
|
|
|
(colorRGB & 0x00ff00) >> 8,
|
|
|
|
colorRGB & 0x0000ff,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (color.startsWith("rgb(")) {
|
|
|
|
// getComputedStyle(...).color returns a `rgb(R, G, B)` color.
|
|
|
|
return color
|
|
|
|
.slice(/* "rgb(".length */ 4, -1) // Strip out "rgb(" and ")".
|
|
|
|
.split(",")
|
|
|
|
.map(x => parseInt(x));
|
|
|
|
}
|
|
|
|
|
2022-07-25 05:19:09 +09:00
|
|
|
if (color.startsWith("rgba(")) {
|
|
|
|
return color
|
|
|
|
.slice(/* "rgba(".length */ 5, -1) // Strip out "rgba(" and ")".
|
|
|
|
.split(",")
|
|
|
|
.map(x => parseInt(x))
|
|
|
|
.slice(0, 3);
|
|
|
|
}
|
|
|
|
|
2022-06-14 01:23:10 +09:00
|
|
|
warn(`Not a valid color format: "${color}"`);
|
|
|
|
return [0, 0, 0];
|
|
|
|
}
|
|
|
|
|
2022-06-29 22:39:02 +09:00
|
|
|
function getColorValues(colors) {
|
|
|
|
const span = document.createElement("span");
|
|
|
|
span.style.visibility = "hidden";
|
|
|
|
document.body.append(span);
|
|
|
|
for (const name of colors.keys()) {
|
|
|
|
span.style.color = name;
|
|
|
|
const computedColor = window.getComputedStyle(span).color;
|
|
|
|
colors.set(name, getRGB(computedColor));
|
|
|
|
}
|
|
|
|
span.remove();
|
|
|
|
}
|
|
|
|
|
2022-08-05 21:46:44 +09:00
|
|
|
function getCurrentTransform(ctx) {
|
|
|
|
const { a, b, c, d, e, f } = ctx.getTransform();
|
|
|
|
return [a, b, c, d, e, f];
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCurrentTransformInverse(ctx) {
|
|
|
|
const { a, b, c, d, e, f } = ctx.getTransform().invertSelf();
|
|
|
|
return [a, b, c, d, e, f];
|
|
|
|
}
|
|
|
|
|
2022-11-22 02:48:37 +09:00
|
|
|
/**
|
|
|
|
* @param {HTMLDivElement} div
|
|
|
|
* @param {PageViewport} viewport
|
|
|
|
* @param {boolean} mustFlip
|
|
|
|
* @param {boolean} mustRotate
|
|
|
|
*/
|
|
|
|
function setLayerDimensions(
|
|
|
|
div,
|
|
|
|
viewport,
|
|
|
|
mustFlip = false,
|
|
|
|
mustRotate = true
|
|
|
|
) {
|
2022-12-08 20:37:18 +09:00
|
|
|
if (viewport instanceof PageViewport) {
|
|
|
|
const { pageWidth, pageHeight } = viewport.rawDims;
|
2022-11-22 02:48:37 +09:00
|
|
|
const { style } = div;
|
|
|
|
|
|
|
|
// TODO: Investigate if it could be interesting to use the css round
|
|
|
|
// function (https://developer.mozilla.org/en-US/docs/Web/CSS/round):
|
|
|
|
// const widthStr =
|
|
|
|
// `round(down, var(--scale-factor) * ${pageWidth}px, 1px)`;
|
|
|
|
// const heightStr =
|
|
|
|
// `round(down, var(--scale-factor) * ${pageHeight}px, 1px)`;
|
|
|
|
const widthStr = `calc(var(--scale-factor) * ${pageWidth}px)`;
|
|
|
|
const heightStr = `calc(var(--scale-factor) * ${pageHeight}px)`;
|
|
|
|
|
2022-12-08 20:37:18 +09:00
|
|
|
if (!mustFlip || viewport.rotation % 180 === 0) {
|
2022-11-22 02:48:37 +09:00
|
|
|
style.width = widthStr;
|
|
|
|
style.height = heightStr;
|
|
|
|
} else {
|
|
|
|
style.width = heightStr;
|
|
|
|
style.height = widthStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mustRotate) {
|
2022-12-08 20:37:18 +09:00
|
|
|
div.setAttribute("data-main-rotation", viewport.rotation);
|
2022-11-22 02:48:37 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-02 21:25:33 +09:00
|
|
|
export {
|
2022-07-29 00:59:03 +09:00
|
|
|
AnnotationPrefix,
|
2021-01-09 23:37:44 +09:00
|
|
|
deprecated,
|
|
|
|
DOMCanvasFactory,
|
2017-04-02 21:25:33 +09:00
|
|
|
DOMCMapReaderFactory,
|
[api-minor] Extend general transfer function support to browsers without `OffscreenCanvas`
This patch extends PR 16115 to work in all browsers, regardless of their `OffscreenCanvas` support, such that transfer functions will be applied to general rendering (and not just image data).
In order to do this we introduce the `BaseFilterFactory` that is then extended in browsers/Node.js environments, similar to all the other factories used in the API, such that we always have the necessary factory available in `src/display/canvas.js`.
These changes help simplify the existing `putBinaryImageData` function, and the new method can easily be stubbed-out in the Firefox PDF Viewer.
*Please note:* This patch removes the old *partial* transfer function support, which only applied to image data, from Node.js environments since the `node-canvas` package currently doesn't support filters. However, this should hopefully be fine given that:
- Transfer functions are not very commonly used in PDF documents.
- Browsers in general, and Firefox in particular, are the *primary* development target for the PDF.js library.
- The FAQ only lists Node.js as *mostly* supported, see https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support
2023-03-12 23:47:01 +09:00
|
|
|
DOMFilterFactory,
|
2020-12-11 10:32:18 +09:00
|
|
|
DOMStandardFontDataFactory,
|
2017-07-24 07:09:18 +09:00
|
|
|
DOMSVGFactory,
|
2022-06-29 22:39:02 +09:00
|
|
|
getColorValues,
|
2022-08-05 21:46:44 +09:00
|
|
|
getCurrentTransform,
|
|
|
|
getCurrentTransformInverse,
|
2021-01-09 23:37:44 +09:00
|
|
|
getFilenameFromUrl,
|
2021-03-16 19:56:31 +09:00
|
|
|
getPdfFilenameFromUrl,
|
2022-06-14 01:23:10 +09:00
|
|
|
getRGB,
|
2021-06-18 19:31:58 +09:00
|
|
|
getXfaPageViewport,
|
Improve memory usage around the `BasePdfManager.docBaseUrl` parameter (PR 7689 follow-up)
While there is nothing *outright* wrong with the existing implementation, it can however lead to increased memory usage in one particular case (that I completely overlooked when implementing this):
For "data:"-URLs, which by definition contains the entire PDF document and can thus be arbitrarily large, we obviously want to avoid sending, storing, and/or logging the "raw" docBaseUrl in that case.
To address this, this patch makes the following changes:
- Ignore any non-string in the `docBaseUrl` option passed to `getDocument`, since those are unsupported anyway, already on the main-thread.
- Ignore "data:"-URLs in the `docBaseUrl` option passed to `getDocument`, to avoid having to send what could potentially be a *very* long string to the worker-thread.
- Parse the `docBaseUrl` option *directly* in the `BasePdfManager`-constructors, on the worker-thread, to avoid having to store the "raw" docBaseUrl in the first place.
2021-03-16 19:56:39 +09:00
|
|
|
isDataScheme,
|
2021-02-24 21:02:58 +09:00
|
|
|
isPdfFile,
|
2019-02-27 04:24:06 +09:00
|
|
|
isValidFetchUrl,
|
2018-06-07 20:52:40 +09:00
|
|
|
loadScript,
|
2021-01-09 23:37:44 +09:00
|
|
|
PageViewport,
|
2019-04-22 04:21:01 +09:00
|
|
|
PDFDateString,
|
2021-09-11 18:11:32 +09:00
|
|
|
PixelsPerInch,
|
2021-01-09 23:37:44 +09:00
|
|
|
RenderingCancelledException,
|
2022-11-22 02:48:37 +09:00
|
|
|
setLayerDimensions,
|
2021-01-09 23:37:44 +09:00
|
|
|
StatTimer,
|
2017-04-02 21:25:33 +09:00
|
|
|
};
|