mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-03 04:47:21 +02:00
Compare commits
No commits in common. "e7661983f712671f3bedbb9c233394f3fd7ee6f7" and "1cb14a02d33d62527da79d625870ec550aaecc8b" have entirely different histories.
e7661983f7
...
1cb14a02d3
@ -7,7 +7,6 @@ import noUnsanitized from "eslint-plugin-no-unsanitized";
|
|||||||
import perfectionist from "eslint-plugin-perfectionist";
|
import perfectionist from "eslint-plugin-perfectionist";
|
||||||
import preferMathClamp from "./external/eslint_plugins/prefer-math-clamp.mjs";
|
import preferMathClamp from "./external/eslint_plugins/prefer-math-clamp.mjs";
|
||||||
import prettierRecommended from "eslint-plugin-prettier/recommended";
|
import prettierRecommended from "eslint-plugin-prettier/recommended";
|
||||||
import regexpPlugin from "eslint-plugin-regexp";
|
|
||||||
import unicorn from "eslint-plugin-unicorn";
|
import unicorn from "eslint-plugin-unicorn";
|
||||||
|
|
||||||
const jsFiles = folder => {
|
const jsFiles = folder => {
|
||||||
@ -56,14 +55,6 @@ export default [
|
|||||||
\* ======================================================================== */
|
\* ======================================================================== */
|
||||||
|
|
||||||
prettierRecommended,
|
prettierRecommended,
|
||||||
{
|
|
||||||
files: jsFiles("."),
|
|
||||||
plugins: regexpPlugin.configs["flat/recommended"].plugins,
|
|
||||||
rules: {
|
|
||||||
...regexpPlugin.configs["flat/recommended"].rules,
|
|
||||||
"regexp/no-legacy-features": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
files: ["**/*.json", "**/.*.json"],
|
files: ["**/*.json", "**/.*.json"],
|
||||||
language: "json/json",
|
language: "json/json",
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function watchObjectOrEmbed(elem) {
|
|||||||
// <embed src> <object data>
|
// <embed src> <object data>
|
||||||
var srcAttribute = "src" in elem ? "src" : "data";
|
var srcAttribute = "src" in elem ? "src" : "data";
|
||||||
var path = elem[srcAttribute];
|
var path = elem[srcAttribute];
|
||||||
if (!mimeType && !/\.pdf(?:$|[?#])/i.test(path)) {
|
if (!mimeType && !/\.pdf($|[?#])/i.test(path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
external/builder/builder.mjs
vendored
3
external/builder/builder.mjs
vendored
@ -132,7 +132,7 @@ function preprocess(inFilename, outFilename, defines) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function expand(line) {
|
function expand(line) {
|
||||||
line = line.replaceAll(/__\w+__/g, function (variable) {
|
line = line.replaceAll(/__[\w]+__/g, function (variable) {
|
||||||
variable = variable.substring(2, variable.length - 2);
|
variable = variable.substring(2, variable.length - 2);
|
||||||
if (variable in defines) {
|
if (variable in defines) {
|
||||||
return defines[variable];
|
return defines[variable];
|
||||||
@ -158,7 +158,6 @@ function preprocess(inFilename, outFilename, defines) {
|
|||||||
let state = STATE_NONE;
|
let state = STATE_NONE;
|
||||||
const stack = [];
|
const stack = [];
|
||||||
const control =
|
const control =
|
||||||
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
||||||
/^(?:\/\/|\s*\/\*|\s*<!--)\s*#(if|elif|else|endif|expand|include|error)\b(?:\s+(.*?)(?:\*\/|-->)?$)?/;
|
/^(?:\/\/|\s*\/\*|\s*<!--)\s*#(if|elif|else|endif|expand|include|error)\b(?:\s+(.*?)(?:\*\/|-->)?$)?/;
|
||||||
|
|
||||||
while ((line = readLine()) !== null) {
|
while ((line = readLine()) !== null) {
|
||||||
|
|||||||
2
external/check_l10n/check_l10n.mjs
vendored
2
external/check_l10n/check_l10n.mjs
vendored
@ -43,7 +43,7 @@ function extractFtlIds(ftlPath) {
|
|||||||
const lines = readFileSync(ftlPath, "utf8").split("\n");
|
const lines = readFileSync(ftlPath, "utf8").split("\n");
|
||||||
const ids = [];
|
const ids = [];
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const match = line.match(/^([a-z][a-z0-9-]*)\s*=/i);
|
const match = line.match(/^([a-zA-Z][a-zA-Z0-9-]*)\s*=/);
|
||||||
if (match) {
|
if (match) {
|
||||||
ids.push(match[1]);
|
ids.push(match[1]);
|
||||||
}
|
}
|
||||||
|
|||||||
4
external/cmapscompress/parse.mjs
vendored
4
external/cmapscompress/parse.mjs
vendored
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function parseAdobeCMap(content) {
|
function parseAdobeCMap(content) {
|
||||||
let m = /(\bbegincmap\b[\s\S]+?)\bendcmap\b/.exec(content);
|
let m = /(\bbegincmap\b[\s\S]*?)\bendcmap\b/.exec(content);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
throw new Error("cmap was not found");
|
throw new Error("cmap was not found");
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ function parseAdobeCMap(content) {
|
|||||||
result.usecmap = m[1];
|
result.usecmap = m[1];
|
||||||
}
|
}
|
||||||
const re =
|
const re =
|
||||||
/(\d+)\s+(begincodespacerange|beginnotdefrange|begincidchar|begincidrange|beginbfchar|beginbfrange)\n([\s\S]*?)\n(?:endcodespacerange|endnotdefrange|endcidchar|endcidrange|endbfchar|endbfrange)/g;
|
/(\d+)\s+(begincodespacerange|beginnotdefrange|begincidchar|begincidrange|beginbfchar|beginbfrange)\n([\s\S]*?)\n(endcodespacerange|endnotdefrange|endcidchar|endcidrange|endbfchar|endbfrange)/g;
|
||||||
while ((m = re.exec(body))) {
|
while ((m = re.exec(body))) {
|
||||||
const lines = m[3].toLowerCase().split("\n");
|
const lines = m[3].toLowerCase().split("\n");
|
||||||
|
|
||||||
|
|||||||
@ -1135,7 +1135,7 @@ gulp.task("locale", function () {
|
|||||||
if (!checkDir(dirPath)) {
|
if (!checkDir(dirPath)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!/^[a-z]{2,3}(?:-[A-Z]{2})?$/.test(locale)) {
|
if (!/^[a-z][a-z]([a-z])?(-[A-Z][A-Z])?$/.test(locale)) {
|
||||||
console.log("Skipping invalid locale: " + locale);
|
console.log("Skipping invalid locale: " + locale);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
75
package-lock.json
generated
75
package-lock.json
generated
@ -31,7 +31,6 @@
|
|||||||
"eslint-plugin-no-unsanitized": "^4.1.5",
|
"eslint-plugin-no-unsanitized": "^4.1.5",
|
||||||
"eslint-plugin-perfectionist": "^5.9.0",
|
"eslint-plugin-perfectionist": "^5.9.0",
|
||||||
"eslint-plugin-prettier": "^5.5.5",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-regexp": "^3.1.0",
|
|
||||||
"eslint-plugin-unicorn": "^64.0.0",
|
"eslint-plugin-unicorn": "^64.0.0",
|
||||||
"globals": "^17.6.0",
|
"globals": "^17.6.0",
|
||||||
"gulp": "^5.0.1",
|
"gulp": "^5.0.1",
|
||||||
@ -5463,28 +5462,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-regexp": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-qGXIC3DIKZHcK1H9A9+Byz9gmndY6TTSRkSMTZpNXdyCw2ObSehRgccJv35n9AdUakEjQp5VFNLas6BMXizCZg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
|
||||||
"@eslint-community/regexpp": "^4.11.0",
|
|
||||||
"comment-parser": "^1.4.0",
|
|
||||||
"jsdoc-type-pratt-parser": "^7.0.0",
|
|
||||||
"refa": "^0.12.1",
|
|
||||||
"regexp-ast-analysis": "^0.7.1",
|
|
||||||
"scslre": "^0.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"eslint": ">=9.38.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-unicorn": {
|
"node_modules/eslint-plugin-unicorn": {
|
||||||
"version": "64.0.0",
|
"version": "64.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-64.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-64.0.0.tgz",
|
||||||
@ -7401,16 +7378,6 @@
|
|||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jsdoc-type-pratt-parser": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-dh140MMgjyg3JhJZY/+iEzW+NO5xR2gpbDFKHqotCmexElVntw7GjWjt511+C/Ef02RU5TKYrJo/Xlzk+OLaTw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/jsdoc/node_modules/escape-string-regexp": {
|
"node_modules/jsdoc/node_modules/escape-string-regexp": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
||||||
@ -9125,19 +9092,6 @@
|
|||||||
"node": ">= 10.13.0"
|
"node": ">= 10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/refa": {
|
|
||||||
"version": "0.12.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz",
|
|
||||||
"integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@eslint-community/regexpp": "^4.8.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/regenerate": {
|
"node_modules/regenerate": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
||||||
@ -9158,20 +9112,6 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regexp-ast-analysis": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz",
|
|
||||||
"integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@eslint-community/regexpp": "^4.8.0",
|
|
||||||
"refa": "^0.12.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/regexp-tree": {
|
"node_modules/regexp-tree": {
|
||||||
"version": "0.1.27",
|
"version": "0.1.27",
|
||||||
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
|
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
|
||||||
@ -9506,21 +9446,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/scslre": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@eslint-community/regexpp": "^4.8.0",
|
|
||||||
"refa": "^0.12.0",
|
|
||||||
"regexp-ast-analysis": "^0.7.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.0.0 || >=16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/section-matter": {
|
"node_modules/section-matter": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
"eslint-plugin-no-unsanitized": "^4.1.5",
|
"eslint-plugin-no-unsanitized": "^4.1.5",
|
||||||
"eslint-plugin-perfectionist": "^5.9.0",
|
"eslint-plugin-perfectionist": "^5.9.0",
|
||||||
"eslint-plugin-prettier": "^5.5.5",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-regexp": "^3.1.0",
|
|
||||||
"eslint-plugin-unicorn": "^64.0.0",
|
"eslint-plugin-unicorn": "^64.0.0",
|
||||||
"globals": "^17.6.0",
|
"globals": "^17.6.0",
|
||||||
"gulp": "^5.0.1",
|
"gulp": "^5.0.1",
|
||||||
|
|||||||
@ -564,7 +564,7 @@ function validateFontName(fontFamily, mustWarn = false) {
|
|||||||
} else {
|
} else {
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident.
|
// See https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident.
|
||||||
for (const ident of fontFamily.split(/[ \t]+/)) {
|
for (const ident of fontFamily.split(/[ \t]+/)) {
|
||||||
if (/^(?:\d|-[\d-])/.test(ident) || !/^[\w\\-]+$/.test(ident)) {
|
if (/^(\d|(-(\d|-)))/.test(ident) || !/^[\w-\\]+$/.test(ident)) {
|
||||||
if (mustWarn) {
|
if (mustWarn) {
|
||||||
warn(`FontFamily contains invalid <custom-ident>: ${fontFamily}.`);
|
warn(`FontFamily contains invalid <custom-ident>: ${fontFamily}.`);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1392,7 +1392,7 @@ class PDFDocument {
|
|||||||
}
|
}
|
||||||
let fontFamily = descriptor.get("FontFamily");
|
let fontFamily = descriptor.get("FontFamily");
|
||||||
// For example, "Wingdings 3" is not a valid font name in the css specs.
|
// For example, "Wingdings 3" is not a valid font name in the css specs.
|
||||||
fontFamily = fontFamily.replaceAll(/ +(\d)/g, "$1");
|
fontFamily = fontFamily.replaceAll(/[ ]+(\d)/g, "$1");
|
||||||
const fontWeight = descriptor.get("FontWeight");
|
const fontWeight = descriptor.get("FontWeight");
|
||||||
|
|
||||||
// Angle is expressed in degrees counterclockwise in PDF
|
// Angle is expressed in degrees counterclockwise in PDF
|
||||||
|
|||||||
@ -4203,7 +4203,9 @@ class PartialEvaluator {
|
|||||||
isSerifFont(baseFontName) {
|
isSerifFont(baseFontName) {
|
||||||
// Simulating descriptor flags attribute
|
// Simulating descriptor flags attribute
|
||||||
const fontNameWoStyle = baseFontName.split("-", 1)[0];
|
const fontNameWoStyle = baseFontName.split("-", 1)[0];
|
||||||
return fontNameWoStyle in getSerifFonts() || /serif/i.test(fontNameWoStyle);
|
return (
|
||||||
|
fontNameWoStyle in getSerifFonts() || /serif/gi.test(fontNameWoStyle)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseFontMetrics(name) {
|
getBaseFontMetrics(name) {
|
||||||
@ -4434,13 +4436,6 @@ class PartialEvaluator {
|
|||||||
// FontDescriptor is only required for Type3 fonts when the document
|
// FontDescriptor is only required for Type3 fonts when the document
|
||||||
// is a tagged pdf.
|
// is a tagged pdf.
|
||||||
descriptor = Dict.empty;
|
descriptor = Dict.empty;
|
||||||
} else if (composite) {
|
|
||||||
// Some PDFs omit the FontDescriptor on the descendant CIDFont when
|
|
||||||
// referencing one of the standard Acrobat CJK fonts via a predefined
|
|
||||||
// CMap (e.g. /Encoding /90ms-RKSJ-H with /BaseFont /HeiseiMin-W3).
|
|
||||||
// Fall through so the CMap is loaded by the composite-font path
|
|
||||||
// below; otherwise multi-byte codes would be decoded byte-by-byte.
|
|
||||||
descriptor = Dict.empty;
|
|
||||||
} else {
|
} else {
|
||||||
// Before PDF 1.5 if the font was one of the base 14 fonts, having a
|
// Before PDF 1.5 if the font was one of the base 14 fonts, having a
|
||||||
// FontDescriptor was not required.
|
// FontDescriptor was not required.
|
||||||
|
|||||||
@ -37,10 +37,13 @@ function getFloat214(view, offset) {
|
|||||||
|
|
||||||
function getSubroutineBias(subrs) {
|
function getSubroutineBias(subrs) {
|
||||||
const numSubrs = subrs.length;
|
const numSubrs = subrs.length;
|
||||||
if (numSubrs >= 33900) {
|
let bias = 32768;
|
||||||
return 32768;
|
if (numSubrs < 1240) {
|
||||||
|
bias = 107;
|
||||||
|
} else if (numSubrs < 33900) {
|
||||||
|
bias = 1131;
|
||||||
}
|
}
|
||||||
return numSubrs < 1240 ? 107 : 1131;
|
return bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCmap(data, start, end) {
|
function parseCmap(data, start, end) {
|
||||||
|
|||||||
@ -21,10 +21,6 @@ const NORMAL = {
|
|||||||
style: "normal",
|
style: "normal",
|
||||||
weight: "normal",
|
weight: "normal",
|
||||||
};
|
};
|
||||||
const MEDIUM = {
|
|
||||||
style: "normal",
|
|
||||||
weight: "500",
|
|
||||||
};
|
|
||||||
const BOLD = {
|
const BOLD = {
|
||||||
style: "normal",
|
style: "normal",
|
||||||
weight: "bold",
|
weight: "bold",
|
||||||
@ -368,194 +364,6 @@ const substitutionMap = new Map([
|
|||||||
alias: "\xCB\xCE\xCC\xE5",
|
alias: "\xCB\xCE\xCC\xE5",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// Standard Acrobat CJK fonts. These BaseFont names appear in PDFs that
|
|
||||||
// don't embed a CJK font and rely on the reader having Acrobat's bundled
|
|
||||||
// CJK fonts installed.
|
|
||||||
// Adobe-Japan1 - Mincho (serif).
|
|
||||||
[
|
|
||||||
"HeiseiMin-W3",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"Hiragino Mincho ProN",
|
|
||||||
"Hiragino Mincho Pro",
|
|
||||||
"Yu Mincho",
|
|
||||||
"YuMincho",
|
|
||||||
"Source Han Serif JP",
|
|
||||||
"Noto Serif JP",
|
|
||||||
"Noto Serif CJK JP",
|
|
||||||
"IPAexMincho",
|
|
||||||
"IPAMincho",
|
|
||||||
"Takao Mincho",
|
|
||||||
"MS Mincho",
|
|
||||||
"MS PMincho",
|
|
||||||
],
|
|
||||||
style: NORMAL,
|
|
||||||
ultimate: "serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Adobe-Japan1 - Gothic (sans-serif).
|
|
||||||
[
|
|
||||||
"HeiseiKakuGo-W5",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"Hiragino Kaku Gothic ProN",
|
|
||||||
"Hiragino Kaku Gothic Pro",
|
|
||||||
"Hiragino Sans",
|
|
||||||
"Yu Gothic",
|
|
||||||
"YuGothic",
|
|
||||||
"Source Han Sans JP",
|
|
||||||
"Noto Sans JP",
|
|
||||||
"Noto Sans CJK JP",
|
|
||||||
"IPAexGothic",
|
|
||||||
"IPAGothic",
|
|
||||||
"Takao Gothic",
|
|
||||||
"Meiryo",
|
|
||||||
"MS Gothic",
|
|
||||||
"MS PGothic",
|
|
||||||
],
|
|
||||||
style: MEDIUM,
|
|
||||||
ultimate: "sans-serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Common Adobe-Japan1 variants and Kozuka names.
|
|
||||||
["HeiseiMin-W3-Acro", { alias: "HeiseiMin-W3" }],
|
|
||||||
["HeiseiKakuGo-W5-Acro", { alias: "HeiseiKakuGo-W5" }],
|
|
||||||
["KozMinPro-Regular", { alias: "HeiseiMin-W3" }],
|
|
||||||
["KozMinProVI-Regular", { alias: "HeiseiMin-W3" }],
|
|
||||||
["KozMinPr6N-Regular", { alias: "HeiseiMin-W3" }],
|
|
||||||
["KozGoPro-Regular", { alias: "HeiseiKakuGo-W5" }],
|
|
||||||
["KozGoProVI-Regular", { alias: "HeiseiKakuGo-W5" }],
|
|
||||||
["KozGoPr6N-Regular", { alias: "HeiseiKakuGo-W5" }],
|
|
||||||
|
|
||||||
// Adobe-GB1 - Song (Simplified Chinese serif).
|
|
||||||
[
|
|
||||||
"STSong-Light",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"STSong",
|
|
||||||
"Songti SC",
|
|
||||||
"Source Han Serif SC",
|
|
||||||
"Source Han Serif CN",
|
|
||||||
"Noto Serif SC",
|
|
||||||
"Noto Serif CJK SC",
|
|
||||||
"AR PL UMing CN",
|
|
||||||
"SimSun",
|
|
||||||
"NSimSun",
|
|
||||||
],
|
|
||||||
style: NORMAL,
|
|
||||||
ultimate: "serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Adobe-GB1 - Hei (Simplified Chinese sans-serif).
|
|
||||||
[
|
|
||||||
"STHeiti-Regular",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"STHeiti",
|
|
||||||
"Heiti SC",
|
|
||||||
"PingFang SC",
|
|
||||||
"Source Han Sans SC",
|
|
||||||
"Source Han Sans CN",
|
|
||||||
"Noto Sans SC",
|
|
||||||
"Noto Sans CJK SC",
|
|
||||||
"Microsoft YaHei",
|
|
||||||
"SimHei",
|
|
||||||
"WenQuanYi Zen Hei",
|
|
||||||
],
|
|
||||||
style: NORMAL,
|
|
||||||
ultimate: "sans-serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
["STSongStd-Light", { alias: "STSong-Light" }],
|
|
||||||
["AdobeSongStd-Light", { alias: "STSong-Light" }],
|
|
||||||
["AdobeHeitiStd-Regular", { alias: "STHeiti-Regular" }],
|
|
||||||
// KaiTi (regular script) and FangSong (imitation Song) are different
|
|
||||||
// typographic styles; route to the existing GB2312-keyed entries above.
|
|
||||||
["AdobeKaitiStd-Regular", { alias: "\xBF\xAC\xCC\xE5" }],
|
|
||||||
["AdobeFangsongStd-Regular", { alias: "\xB7\xC2\xCB\xCE" }],
|
|
||||||
|
|
||||||
// Adobe-CNS1 - Sung (Traditional Chinese serif).
|
|
||||||
[
|
|
||||||
"MSung-Light",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"Songti TC",
|
|
||||||
"LiSong Pro",
|
|
||||||
"Source Han Serif TC",
|
|
||||||
"Source Han Serif TW",
|
|
||||||
"Noto Serif TC",
|
|
||||||
"Noto Serif CJK TC",
|
|
||||||
"AR PL UMing TW",
|
|
||||||
"PMingLiU",
|
|
||||||
"MingLiU",
|
|
||||||
"MingLiU_HKSCS",
|
|
||||||
],
|
|
||||||
style: NORMAL,
|
|
||||||
ultimate: "serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Adobe-CNS1 - Hei (Traditional Chinese sans-serif).
|
|
||||||
[
|
|
||||||
"MHei-Medium",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"Heiti TC",
|
|
||||||
"STHeiti",
|
|
||||||
"Source Han Sans TC",
|
|
||||||
"Source Han Sans TW",
|
|
||||||
"Noto Sans TC",
|
|
||||||
"Noto Sans CJK TC",
|
|
||||||
"PingFang TC",
|
|
||||||
"Microsoft JhengHei",
|
|
||||||
],
|
|
||||||
style: MEDIUM,
|
|
||||||
ultimate: "sans-serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
["MSungStd-Light", { alias: "MSung-Light" }],
|
|
||||||
["AdobeMingStd-Light", { alias: "MSung-Light" }],
|
|
||||||
|
|
||||||
// Adobe-Korea1 - Myeongjo (Korean serif).
|
|
||||||
[
|
|
||||||
"HYSMyeongJo-Medium",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"AppleMyungjo",
|
|
||||||
"Source Han Serif KR",
|
|
||||||
"Noto Serif KR",
|
|
||||||
"Noto Serif CJK KR",
|
|
||||||
"Nanum Myeongjo",
|
|
||||||
"Batang",
|
|
||||||
],
|
|
||||||
style: MEDIUM,
|
|
||||||
ultimate: "serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// Adobe-Korea1 - Gothic (Korean sans-serif).
|
|
||||||
[
|
|
||||||
"HYGoThic-Medium",
|
|
||||||
{
|
|
||||||
local: [
|
|
||||||
"Apple SD Gothic Neo",
|
|
||||||
"AppleGothic",
|
|
||||||
"Source Han Sans KR",
|
|
||||||
"Noto Sans KR",
|
|
||||||
"Noto Sans CJK KR",
|
|
||||||
"Nanum Gothic",
|
|
||||||
"Malgun Gothic",
|
|
||||||
"Dotum",
|
|
||||||
"Gulim",
|
|
||||||
],
|
|
||||||
style: MEDIUM,
|
|
||||||
ultimate: "sans-serif",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
["HYSMyeongJoStd-Medium", { alias: "HYSMyeongJo-Medium" }],
|
|
||||||
["AdobeMyungjoStd-Medium", { alias: "HYSMyeongJo-Medium" }],
|
|
||||||
// Bold variants reuse the same fallback list with a bold style override
|
|
||||||
// so the @font-face declaration requests a bold local() match.
|
|
||||||
["HYGoThic-Bold", { alias: "HYGoThic-Medium", style: BOLD }],
|
|
||||||
["AdobeGothicStd-Bold", { alias: "HYGoThic-Medium", style: BOLD }],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const fontAliases = new Map([["Arial-Black", "ArialBlack"]]);
|
const fontAliases = new Map([["Arial-Black", "ArialBlack"]]);
|
||||||
@ -771,8 +579,8 @@ function getFontSubstitution(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Maybe we'll be lucky and the OS will have the font.
|
// Maybe we'll be lucky and the OS will have the font.
|
||||||
const bold = /bold/i.test(baseFontName);
|
const bold = /bold/gi.test(baseFontName);
|
||||||
const italic = /oblique|italic/i.test(baseFontName);
|
const italic = /oblique|italic/gi.test(baseFontName);
|
||||||
const style =
|
const style =
|
||||||
(bold && italic && BOLDITALIC) ||
|
(bold && italic && BOLDITALIC) ||
|
||||||
(bold && BOLD) ||
|
(bold && BOLD) ||
|
||||||
|
|||||||
@ -1235,16 +1235,16 @@ class Font {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bold = /bold/i.test(fontName);
|
this.bold = /bold/gi.test(fontName);
|
||||||
this.italic = /oblique|italic/i.test(fontName);
|
this.italic = /oblique|italic/gi.test(fontName);
|
||||||
|
|
||||||
// Use 'name' instead of 'fontName' here because the original
|
// Use 'name' instead of 'fontName' here because the original
|
||||||
// name ArialBlack for example will be replaced by Helvetica.
|
// name ArialBlack for example will be replaced by Helvetica.
|
||||||
this.black = /Black/.test(name);
|
this.black = /Black/g.test(name);
|
||||||
|
|
||||||
// Use 'name' instead of 'fontName' here because the original
|
// Use 'name' instead of 'fontName' here because the original
|
||||||
// name ArialNarrow for example will be replaced by Helvetica.
|
// name ArialNarrow for example will be replaced by Helvetica.
|
||||||
const isNarrow = /Narrow/.test(name);
|
const isNarrow = /Narrow/g.test(name);
|
||||||
|
|
||||||
// if at least one width is present, remeasure all chars when exists
|
// if at least one width is present, remeasure all chars when exists
|
||||||
this.remeasure =
|
this.remeasure =
|
||||||
|
|||||||
@ -132,7 +132,7 @@ class Lexer {
|
|||||||
this.pos = 0;
|
this.pos = 0;
|
||||||
this.len = data.length;
|
this.len = data.length;
|
||||||
// Sticky regexes: set lastIndex before exec() to match at an exact offset.
|
// Sticky regexes: set lastIndex before exec() to match at an exact offset.
|
||||||
this._numberPattern = /[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?/iy;
|
this._numberPattern = /[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/y;
|
||||||
this._identifierPattern = /[a-z]+/y;
|
this._identifierPattern = /[a-z]+/y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,11 +16,7 @@
|
|||||||
import { stringToBytes, Util, warn } from "../shared/util.js";
|
import { stringToBytes, Util, warn } from "../shared/util.js";
|
||||||
|
|
||||||
function isAscii(str) {
|
function isAscii(str) {
|
||||||
return (
|
return typeof str === "string" && (!str || /^[\x00-\x7F]*$/.test(str));
|
||||||
typeof str === "string" &&
|
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
(!str || /^[\x00-\x7F]*$/.test(str))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the string is null or undefined then it is returned as is.
|
// If the string is null or undefined then it is returned as is.
|
||||||
@ -95,7 +91,6 @@ function stringToPDFString(str, keepEscapeSequence = false) {
|
|||||||
if (keepEscapeSequence || !decoded.includes("\x1b")) {
|
if (keepEscapeSequence || !decoded.includes("\x1b")) {
|
||||||
return decoded;
|
return decoded;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
return decoded.replaceAll(/\x1b[^\x1b]*(?:\x1b|$)/g, "");
|
return decoded.replaceAll(/\x1b[^\x1b]*(?:\x1b|$)/g, "");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
warn(`stringToPDFString: "${ex}".`);
|
warn(`stringToPDFString: "${ex}".`);
|
||||||
|
|||||||
@ -242,7 +242,7 @@ function getUnicodeRangeFor(value, lastPosition = -1) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpecialCharRegExp = /^(\s)|(\p{Mn})|(\p{Cf})$/u;
|
const SpecialCharRegExp = new RegExp("^(\\s)|(\\p{Mn})|(\\p{Cf})$", "u");
|
||||||
const CategoryCache = new Map();
|
const CategoryCache = new Map();
|
||||||
|
|
||||||
function getCharUnicodeCategory(char) {
|
function getCharUnicodeCategory(char) {
|
||||||
|
|||||||
@ -1003,7 +1003,7 @@ class Rename extends ContentObject {
|
|||||||
// is no colon.
|
// is no colon.
|
||||||
if (
|
if (
|
||||||
this[$content].toLowerCase().startsWith("xml") ||
|
this[$content].toLowerCase().startsWith("xml") ||
|
||||||
/[\p{L}_][\p{L}\d._\p{M}-]*/u.test(this[$content])
|
new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*", "u").test(this[$content])
|
||||||
) {
|
) {
|
||||||
warn("XFA - Rename: invalid XFA name");
|
warn("XFA - Rename: invalid XFA name");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ class FontFinder {
|
|||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pattern = /[,\-_ ]|bolditalic|bold|italic|regular|it/gi;
|
const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi;
|
||||||
let name = fontName.replaceAll(pattern, "");
|
let name = fontName.replaceAll(pattern, "");
|
||||||
font = this.fonts.get(name);
|
font = this.fonts.get(name);
|
||||||
if (font) {
|
if (font) {
|
||||||
|
|||||||
@ -116,11 +116,11 @@ const TOKEN = {
|
|||||||
upto: 54,
|
upto: 54,
|
||||||
};
|
};
|
||||||
|
|
||||||
const hexPattern = /^u([0-9a-f]{4,8})/i;
|
const hexPattern = /^[uU]([0-9a-fA-F]{4,8})/;
|
||||||
const numberPattern = /^\d*(?:\.\d*)?(?:E[+-]?\d+)?/i;
|
const numberPattern = /^\d*(?:\.\d*)?(?:[Ee][+-]?\d+)?/;
|
||||||
const dotNumberPattern = /^\d*(?:E[+-]?\d+)?/i;
|
const dotNumberPattern = /^\d*(?:[Ee][+-]?\d+)?/;
|
||||||
const eolPattern = /[\r\n]+/;
|
const eolPattern = /[\r\n]+/;
|
||||||
const identifierPattern = /^[\p{L}_$!][\p{L}\p{N}_$]*/u;
|
const identifierPattern = new RegExp("^[\\p{L}_$!][\\p{L}\\p{N}_$]*", "u");
|
||||||
|
|
||||||
class Token {
|
class Token {
|
||||||
constructor(id, value = null) {
|
constructor(id, value = null) {
|
||||||
|
|||||||
@ -134,7 +134,8 @@ function mapStyle(styleStr, node, richText) {
|
|||||||
? `${style[key]} ${newValue}`
|
? `${style[key]} ${newValue}`
|
||||||
: newValue;
|
: newValue;
|
||||||
} else {
|
} else {
|
||||||
style[key.replaceAll(/-([a-z])/gi, (_, x) => x.toUpperCase())] = newValue;
|
style[key.replaceAll(/-([a-zA-Z])/g, (_, x) => x.toUpperCase())] =
|
||||||
|
newValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1793,14 +1793,16 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
case "deleteWordBackward": {
|
case "deleteWordBackward": {
|
||||||
const match = value
|
const match = value
|
||||||
.substring(0, selectionStart)
|
.substring(0, selectionStart)
|
||||||
.match(/\w*\W*$/);
|
.match(/\w*[^\w]*$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
selStart -= match[0].length;
|
selStart -= match[0].length;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "deleteWordForward": {
|
case "deleteWordForward": {
|
||||||
const match = value.substring(selectionStart).match(/^\W*\w*/);
|
const match = value
|
||||||
|
.substring(selectionStart)
|
||||||
|
.match(/^[^\w]*\w*/);
|
||||||
if (match) {
|
if (match) {
|
||||||
selEnd += match[0].length;
|
selEnd += match[0].length;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,7 +81,6 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||||||
}
|
}
|
||||||
function textdecode(encoding, value) {
|
function textdecode(encoding, value) {
|
||||||
if (encoding) {
|
if (encoding) {
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
if (!/^[\x00-\xFF]+$/.test(value)) {
|
if (!/^[\x00-\xFF]+$/.test(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -185,7 +184,6 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||||||
|
|
||||||
// Firefox also decodes words even where RFC 2047 section 5 states:
|
// Firefox also decodes words even where RFC 2047 section 5 states:
|
||||||
// "An 'encoded-word' MUST NOT appear within a 'quoted-string'."
|
// "An 'encoded-word' MUST NOT appear within a 'quoted-string'."
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) {
|
if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -197,12 +195,12 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||||||
// encoded-text = any printable ASCII character other than ? or space.
|
// encoded-text = any printable ASCII character other than ? or space.
|
||||||
// ... but Firefox permits ? and space.
|
// ... but Firefox permits ? and space.
|
||||||
return value.replaceAll(
|
return value.replaceAll(
|
||||||
/=\?([\w-]*)\?([QB])\?((?:[^?]|\?(?!=))*)\?=/gi,
|
/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g,
|
||||||
function (matches, charset, encoding, text) {
|
function (matches, charset, encoding, text) {
|
||||||
if (encoding === "q" || encoding === "Q") {
|
if (encoding === "q" || encoding === "Q") {
|
||||||
// RFC 2047 section 4.2.
|
// RFC 2047 section 4.2.
|
||||||
text = text.replaceAll("_", " ");
|
text = text.replaceAll("_", " ");
|
||||||
text = text.replaceAll(/=([0-9a-f]{2})/gi, function (match, hex) {
|
text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) {
|
||||||
return String.fromCharCode(parseInt(hex, 16));
|
return String.fromCharCode(parseInt(hex, 16));
|
||||||
});
|
});
|
||||||
return textdecode(charset, text);
|
return textdecode(charset, text);
|
||||||
|
|||||||
@ -296,7 +296,7 @@ class PDFDateString {
|
|||||||
"(\\d{2})?" + // Hour (optional)
|
"(\\d{2})?" + // Hour (optional)
|
||||||
"(\\d{2})?" + // Minute (optional)
|
"(\\d{2})?" + // Minute (optional)
|
||||||
"(\\d{2})?" + // Second (optional)
|
"(\\d{2})?" + // Second (optional)
|
||||||
"([Z|+\\-])?" + // Universal time relation (optional)
|
"([Z|+|-])?" + // Universal time relation (optional)
|
||||||
"(\\d{2})?" + // Offset hour (optional)
|
"(\\d{2})?" + // Offset hour (optional)
|
||||||
"'?" + // Splitting apostrophe (optional)
|
"'?" + // Splitting apostrophe (optional)
|
||||||
"(\\d{2})?" + // Offset minute (optional)
|
"(\\d{2})?" + // Offset minute (optional)
|
||||||
@ -756,7 +756,7 @@ function renderRichText({ html, dir, className }, container) {
|
|||||||
if (typeof html === "string") {
|
if (typeof html === "string") {
|
||||||
const p = document.createElement("p");
|
const p = document.createElement("p");
|
||||||
p.dir = dir || "auto";
|
p.dir = dir || "auto";
|
||||||
const lines = html.split(/\r\n?|\n/);
|
const lines = html.split(/(?:\r\n?|\n)/);
|
||||||
for (let i = 0, ii = lines.length; i < ii; ++i) {
|
for (let i = 0, ii = lines.length; i < ii; ++i) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
p.append(document.createTextNode(line));
|
p.append(document.createTextNode(line));
|
||||||
|
|||||||
@ -132,9 +132,6 @@ class DOMFilterFactory extends BaseFilterFactory {
|
|||||||
if (!this.#_defs) {
|
if (!this.#_defs) {
|
||||||
const div = this.#document.createElement("div");
|
const div = this.#document.createElement("div");
|
||||||
const { style } = div;
|
const { style } = div;
|
||||||
// The pdf colors are mostly in light mode (white background with a black
|
|
||||||
// foreground), so the filters are created in light mode.
|
|
||||||
style.colorScheme = "only light";
|
|
||||||
style.visibility = "hidden";
|
style.visibility = "hidden";
|
||||||
style.contain = "strict";
|
style.contain = "strict";
|
||||||
style.width = style.height = 0;
|
style.width = style.height = 0;
|
||||||
|
|||||||
@ -140,7 +140,7 @@ class PDFNetworkStream extends BasePDFStream {
|
|||||||
const chunk = getArrayBuffer(xhr.response);
|
const chunk = getArrayBuffer(xhr.response);
|
||||||
if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {
|
if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {
|
||||||
const rangeHeader = xhr.getResponseHeader("Content-Range");
|
const rangeHeader = xhr.getResponseHeader("Content-Range");
|
||||||
if (/bytes \d+-\d+\/\d+/.test(rangeHeader)) {
|
if (/bytes (\d+)-(\d+)\/(\d+)/.test(rangeHeader)) {
|
||||||
pendingRequest.onDone(chunk);
|
pendingRequest.onDone(chunk);
|
||||||
} else {
|
} else {
|
||||||
warn(`Missing or invalid "Content-Range" header.`);
|
warn(`Missing or invalid "Content-Range" header.`);
|
||||||
|
|||||||
@ -473,8 +473,7 @@ class TextLayer {
|
|||||||
// OffscreenCanvas.
|
// OffscreenCanvas.
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
canvas.style.cssText =
|
canvas.style.cssText =
|
||||||
"position:absolute;top:0;left:0;width:0;height:0;display:none;" +
|
"position:absolute;top:0;left:0;width:0;height:0;display:none";
|
||||||
"letter-spacing:normal;word-spacing:normal";
|
|
||||||
canvas.lang = lang;
|
canvas.lang = lang;
|
||||||
document.body.append(canvas);
|
document.body.append(canvas);
|
||||||
ctx = canvas.getContext("2d", {
|
ctx = canvas.getContext("2d", {
|
||||||
|
|||||||
@ -26,9 +26,8 @@ class AForm {
|
|||||||
|
|
||||||
// The e-mail address regex below originates from:
|
// The e-mail address regex below originates from:
|
||||||
// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
|
// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
|
||||||
// eslint-disable-next-line regexp/use-ignore-case
|
|
||||||
this._emailRegex = new RegExp(
|
this._emailRegex = new RegExp(
|
||||||
"^[\\w.!#$%&'*+/=?^`{|}~-]+" +
|
"^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+" +
|
||||||
"@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?" +
|
"@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?" +
|
||||||
"(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
"(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
|
||||||
);
|
);
|
||||||
@ -185,12 +184,12 @@ class AForm {
|
|||||||
// comma sep
|
// comma sep
|
||||||
pattern = event.willCommit
|
pattern = event.willCommit
|
||||||
? /^[+-]?(\d+(,\d*)?|,\d+)$/
|
? /^[+-]?(\d+(,\d*)?|,\d+)$/
|
||||||
: /^[+-]?\d*(?:,\d*)?$/;
|
: /^[+-]?\d*,?\d*$/;
|
||||||
} else {
|
} else {
|
||||||
// dot sep
|
// dot sep
|
||||||
pattern = event.willCommit
|
pattern = event.willCommit
|
||||||
? /^[+-]?(\d+(\.\d*)?|\.\d+)$/
|
? /^[+-]?(\d+(\.\d*)?|\.\d+)$/
|
||||||
: /^[+-]?\d*(?:\.\d*)?$/;
|
: /^[+-]?\d*\.?\d*$/;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pattern.test(value)) {
|
if (!pattern.test(value)) {
|
||||||
@ -572,7 +571,7 @@ class AForm {
|
|||||||
event.rc = true;
|
event.rc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const re = /[-()\s]+/g;
|
const re = /([-()]|\s)+/g;
|
||||||
value = value.replaceAll(re, "");
|
value = value.replaceAll(re, "");
|
||||||
for (const format of formats) {
|
for (const format of formats) {
|
||||||
this.#AFSpecial_KeystrokeEx_helper(
|
this.#AFSpecial_KeystrokeEx_helper(
|
||||||
|
|||||||
@ -62,7 +62,6 @@ class Util extends PDFObject {
|
|||||||
throw new TypeError("First argument of printf must be a string");
|
throw new TypeError("First argument of printf must be a string");
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line regexp/no-misleading-capturing-group
|
|
||||||
const pattern = /%(,[0-4])?([+ 0#]+)?(\d+)?(\.\d+)?(.)/g;
|
const pattern = /%(,[0-4])?([+ 0#]+)?(\d+)?(\.\d+)?(.)/g;
|
||||||
const PLUS = 1;
|
const PLUS = 1;
|
||||||
const SPACE = 2;
|
const SPACE = 2;
|
||||||
|
|||||||
@ -1039,7 +1039,7 @@ function normalizeUnicode(str) {
|
|||||||
// required.
|
// required.
|
||||||
// It appears that most the chars here contain some ligatures.
|
// It appears that most the chars here contain some ligatures.
|
||||||
NormalizeRegex =
|
NormalizeRegex =
|
||||||
/([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;
|
/([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;
|
||||||
NormalizationMap = new Map([["ſt", "ſt"]]);
|
NormalizationMap = new Map([["ſt", "ſt"]]);
|
||||||
}
|
}
|
||||||
return str.replaceAll(NormalizeRegex, (_, p1, p2) =>
|
return str.replaceAll(NormalizeRegex, (_, p1, p2) =>
|
||||||
|
|||||||
@ -21,7 +21,7 @@ function rewriteWebArchiveUrl(url) {
|
|||||||
// Without this, an HTML page containing an iframe with the PDF file
|
// Without this, an HTML page containing an iframe with the PDF file
|
||||||
// will be served instead (issue 8920).
|
// will be served instead (issue 8920).
|
||||||
const webArchiveRegex =
|
const webArchiveRegex =
|
||||||
/(^https?:\/\/web\.archive\.org\/web\/)(\d+)(\/https?:\/\/.+)/;
|
/(^https?:\/\/web\.archive\.org\/web\/)(\d+)(\/https?:\/\/.+)/g;
|
||||||
const urlParts = webArchiveRegex.exec(url);
|
const urlParts = webArchiveRegex.exec(url);
|
||||||
if (urlParts) {
|
if (urlParts) {
|
||||||
return `${urlParts[1]}${urlParts[2]}if_${urlParts[3]}`;
|
return `${urlParts[1]}${urlParts[2]}if_${urlParts[3]}`;
|
||||||
|
|||||||
@ -36,7 +36,7 @@ describe("font_fpgm", function () {
|
|||||||
|
|
||||||
verifyTtxOutput(output);
|
verifyTtxOutput(output);
|
||||||
expect(
|
expect(
|
||||||
/(?:ENDF\[ \]|SVTCA\[0\])\s*\/\*.*\*\/\s*<\/assembly>\s*<\/fpgm>/.test(
|
/(ENDF\[ \]|SVTCA\[0\])\s*\/\*.*\*\/\s*<\/assembly>\s*<\/fpgm>/.test(
|
||||||
output
|
output
|
||||||
)
|
)
|
||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
|
|||||||
@ -109,7 +109,7 @@ describe("font_glyf", function () {
|
|||||||
);
|
);
|
||||||
expect(notdef).not.toBeNull();
|
expect(notdef).not.toBeNull();
|
||||||
expect(notdef[1] || "").not.toMatch(
|
expect(notdef[1] || "").not.toMatch(
|
||||||
/<component\b[^>]+glyphName="\.notdef"/
|
/<component\b[^>]*glyphName="\.notdef"/
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -132,7 +132,7 @@ describe("font_glyf", function () {
|
|||||||
const output = await ttx(font.data);
|
const output = await ttx(font.data);
|
||||||
verifyTtxOutput(output);
|
verifyTtxOutput(output);
|
||||||
expect(
|
expect(
|
||||||
/<OS_2>\s*(?:<!--[\s\S]*?-->\s*)?<version value="3"\/>/.test(output)
|
/<OS_2>\s*(<!--[\s\S]*?-->\s*)?<version value="3"\/>/.test(output)
|
||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
expect(/<sCapHeight\b/.test(output)).toEqual(true);
|
expect(/<sCapHeight\b/.test(output)).toEqual(true);
|
||||||
expect(/<usMaxContext\b/.test(output)).toEqual(true);
|
expect(/<usMaxContext\b/.test(output)).toEqual(true);
|
||||||
|
|||||||
@ -49,61 +49,6 @@ import { startBrowser } from "../test.mjs";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
describe("Text layer", () => {
|
describe("Text layer", () => {
|
||||||
describe("Text layout", () => {
|
|
||||||
let pages;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
pages = await loadAndWait(
|
|
||||||
"tracemonkey.pdf",
|
|
||||||
".textLayer .endOfContent",
|
|
||||||
100,
|
|
||||||
{
|
|
||||||
postPageSetup: async page => {
|
|
||||||
await page.evaluate(() => {
|
|
||||||
const style = document.createElement("style");
|
|
||||||
style.textContent = `
|
|
||||||
body,
|
|
||||||
#mainContainer {
|
|
||||||
letter-spacing: 5px;
|
|
||||||
word-spacing: 5px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
document.documentElement.append(style);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async () => {
|
|
||||||
await closePages(pages);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("must ignore inherited text spacing styles", async () => {
|
|
||||||
await Promise.all(
|
|
||||||
pages.map(async ([_, page]) => {
|
|
||||||
const spacing = await page.evaluate(() => {
|
|
||||||
const textLayer = document.querySelector(".textLayer");
|
|
||||||
const span = textLayer.querySelector("span");
|
|
||||||
const textLayerStyle = getComputedStyle(textLayer);
|
|
||||||
const spanStyle = getComputedStyle(span);
|
|
||||||
return {
|
|
||||||
textLayerLetterSpacing: textLayerStyle.letterSpacing,
|
|
||||||
textLayerWordSpacing: textLayerStyle.wordSpacing,
|
|
||||||
spanLetterSpacing: spanStyle.letterSpacing,
|
|
||||||
spanWordSpacing: spanStyle.wordSpacing,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(spacing.textLayerLetterSpacing).toEqual("normal");
|
|
||||||
expect(spacing.spanLetterSpacing).toEqual("normal");
|
|
||||||
expect(["0px", "normal"]).toContain(spacing.textLayerWordSpacing);
|
|
||||||
expect(["0px", "normal"]).toContain(spacing.spanWordSpacing);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Text selection", () => {
|
describe("Text selection", () => {
|
||||||
// page.mouse.move(x, y, { steps: ... }) doesn't work in Firefox, because
|
// page.mouse.move(x, y, { steps: ... }) doesn't work in Firefox, because
|
||||||
// puppeteer will send fractional intermediate positions and Firefox doesn't
|
// puppeteer will send fractional intermediate positions and Firefox doesn't
|
||||||
@ -585,7 +530,7 @@ describe("Text layer", () => {
|
|||||||
// Selection starts mid-word in Heading 1, so assert the stable
|
// Selection starts mid-word in Heading 1, so assert the stable
|
||||||
// trailing content rather than exact full-line boundaries.
|
// trailing content rather than exact full-line boundaries.
|
||||||
.toHaveRoughlySelected(
|
.toHaveRoughlySelected(
|
||||||
/ing 1\s+This paragraph 1\.\s+Heading 2\s+This paragraph 2/
|
/ing 1\s+This paragraph 1\.\s+Heading 2\s+This paragraph 2/s
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -924,4 +924,3 @@
|
|||||||
!Embedded_font.pdf
|
!Embedded_font.pdf
|
||||||
!issue18548_reduced.pdf
|
!issue18548_reduced.pdf
|
||||||
!issue_cff_unsigned_bbox.pdf
|
!issue_cff_unsigned_bbox.pdf
|
||||||
!90ms_rksj_h_sample.pdf
|
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
%PDF-1.4
|
|
||||||
%âãÏÓ
|
|
||||||
|
|
||||||
1 0 obj
|
|
||||||
<< /Type /Catalog /Pages 2 0 R >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
2 0 obj
|
|
||||||
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
3 0 obj
|
|
||||||
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
|
|
||||||
/Contents 4 0 R
|
|
||||||
/Resources << /Font << /F0 5 0 R /F1 7 0 R >> >> >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
4 0 obj
|
|
||||||
<< /Length 92 >>
|
|
||||||
stream
|
|
||||||
BT
|
|
||||||
/F0 14 Tf
|
|
||||||
72 720 Td
|
|
||||||
(Hello ASCII) Tj
|
|
||||||
0 -28 Td
|
|
||||||
/F1 14 Tf
|
|
||||||
<93FA967B8CEA836583588367> Tj
|
|
||||||
ET
|
|
||||||
|
|
||||||
endstream
|
|
||||||
endobj
|
|
||||||
|
|
||||||
5 0 obj
|
|
||||||
<< /Type /Font /Subtype /Type1
|
|
||||||
/BaseFont /Helvetica
|
|
||||||
/Encoding /WinAnsiEncoding >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
6 0 obj
|
|
||||||
<< /Type /Font /Subtype /CIDFontType2
|
|
||||||
/BaseFont /HeiseiMin-W3
|
|
||||||
/CIDSystemInfo << /Registry (Adobe) /Ordering (Japan1) /Supplement 2 >>
|
|
||||||
/DW 1000 >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
7 0 obj
|
|
||||||
<< /Type /Font /Subtype /Type0
|
|
||||||
/BaseFont /HeiseiMin-W3
|
|
||||||
/Encoding /90ms-RKSJ-H
|
|
||||||
/DescendantFonts [6 0 R] >>
|
|
||||||
endobj
|
|
||||||
|
|
||||||
xref
|
|
||||||
0 8
|
|
||||||
0000000000 65535 f
|
|
||||||
0000000016 00000 n
|
|
||||||
0000000066 00000 n
|
|
||||||
0000000124 00000 n
|
|
||||||
0000000267 00000 n
|
|
||||||
0000000410 00000 n
|
|
||||||
0000000514 00000 n
|
|
||||||
0000000685 00000 n
|
|
||||||
trailer
|
|
||||||
<< /Size 8 /Root 1 0 R >>
|
|
||||||
startxref
|
|
||||||
816
|
|
||||||
%%EOF
|
|
||||||
@ -205,7 +205,7 @@ window.onload = function () {
|
|||||||
}
|
}
|
||||||
line = match[1];
|
line = match[1];
|
||||||
match = line.match(
|
match = line.match(
|
||||||
/^(TEST-PASS|TEST-UNEXPECTED-PASS|TEST-KNOWN-FAIL|TEST-UNEXPECTED-FAIL)(\(EXPECTED RANDOM\))? \| ([^|]+) \|(.*)/
|
/^(TEST-PASS|TEST-UNEXPECTED-PASS|TEST-KNOWN-FAIL|TEST-UNEXPECTED-FAIL)(\(EXPECTED RANDOM\)|) \| ([^|]+) \|(.*)/
|
||||||
);
|
);
|
||||||
if (match) {
|
if (match) {
|
||||||
const state = match[1];
|
const state = match[1];
|
||||||
@ -225,7 +225,7 @@ window.onload = function () {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match = line.match(
|
match = line.match(
|
||||||
/^ {2}IMAGE[^:]*\((\d+(?:\.\d*)?)x(\d+(?:\.\d*)?)x(\d+(?:\.\d*)?)\): (.*)$/
|
/^ {2}IMAGE[^:]*\((\d+\.?\d*)x(\d+\.?\d*)x(\d+\.?\d*)\): (.*)$/
|
||||||
);
|
);
|
||||||
if (match) {
|
if (match) {
|
||||||
const item = gTestItems.at(-1);
|
const item = gTestItems.at(-1);
|
||||||
|
|||||||
@ -78,7 +78,7 @@ function parseOptions() {
|
|||||||
// Expand `-X=value` short-option forms into `["-X", "value"]` since
|
// Expand `-X=value` short-option forms into `["-X", "value"]` since
|
||||||
// parseArgs only strips the `=` separator for long options (--foo=bar).
|
// parseArgs only strips the `=` separator for long options (--foo=bar).
|
||||||
const args = process.argv.slice(2).flatMap(arg => {
|
const args = process.argv.slice(2).flatMap(arg => {
|
||||||
const m = arg.match(/^(-[a-z])=(.*)/is);
|
const m = arg.match(/^(-[a-zA-Z])=(.*)/s);
|
||||||
return m ? [m[1], m[2]] : [arg];
|
return m ? [m[1], m[2]] : [arg];
|
||||||
});
|
});
|
||||||
const { values } = parseArgs({
|
const { values } = parseArgs({
|
||||||
@ -423,38 +423,15 @@ async function startRefTest(masterMode, showRefImages) {
|
|||||||
checkRefsTmp();
|
checkRefsTmp();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSessionTimeout(session) {
|
function handleSessionTimeout(session) {
|
||||||
if (session.closed || session.recovering) {
|
if (session.closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const inflightIds = Object.keys(session.tasks);
|
|
||||||
const suffix = inflightIds.length > 0 ? ` (${inflightIds.join(", ")})` : "";
|
|
||||||
console.log(
|
console.log(
|
||||||
`${TEST_UNEXPECTED_FAIL} | test failed ${session.name} has not responded in ${browserTimeout}s${suffix}`
|
`${TEST_UNEXPECTED_FAIL} | test failed ${session.name} has not responded in ${browserTimeout}s`
|
||||||
);
|
);
|
||||||
session.numErrors += session.remaining;
|
session.numErrors += session.remaining;
|
||||||
session.remaining = 0;
|
session.remaining = 0;
|
||||||
session.taskResults = {};
|
|
||||||
session.tasks = {};
|
|
||||||
|
|
||||||
monitorBrowserTimeout(session, null);
|
|
||||||
if (session.page) {
|
|
||||||
session.recovering = true;
|
|
||||||
try {
|
|
||||||
await session.page.reload({
|
|
||||||
timeout: browserTimeout * 1000,
|
|
||||||
waitUntil: "domcontentloaded",
|
|
||||||
});
|
|
||||||
session.recovering = false;
|
|
||||||
monitorBrowserTimeout(session, handleSessionTimeout);
|
|
||||||
return;
|
|
||||||
} catch (err) {
|
|
||||||
console.log(
|
|
||||||
`Failed to reload ${session.name} after timeout: ${err.message}`
|
|
||||||
);
|
|
||||||
session.recovering = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeSession(session.name);
|
closeSession(session.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,15 +768,9 @@ async function handleWsBinaryResult(data) {
|
|||||||
const { browser, id, round, page, failure, lastPageNum, numberOfTasks } =
|
const { browser, id, round, page, failure, lastPageNum, numberOfTasks } =
|
||||||
meta;
|
meta;
|
||||||
const session = getSession(browser);
|
const session = getSession(browser);
|
||||||
if (!session || session.closed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
monitorBrowserTimeout(session, handleSessionTimeout);
|
monitorBrowserTimeout(session, handleSessionTimeout);
|
||||||
|
|
||||||
const taskResults = session.taskResults[id];
|
const taskResults = session.taskResults[id];
|
||||||
if (!taskResults) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!taskResults[round]) {
|
if (!taskResults[round]) {
|
||||||
taskResults[round] = [];
|
taskResults[round] = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4009,25 +4009,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`)
|
|||||||
await loadingTask.destroy();
|
await loadingTask.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("gets text content from a Type0 composite font with no FontDescriptor, using a predefined CMap", async function () {
|
|
||||||
const loadingTask = getDocument(
|
|
||||||
buildGetDocumentParams("90ms_rksj_h_sample.pdf", {
|
|
||||||
cMapUrl: CMAP_URL,
|
|
||||||
useWorkerFetch: false,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const pdfDoc = await loadingTask.promise;
|
|
||||||
const pdfPage = await pdfDoc.getPage(1);
|
|
||||||
const { items } = await pdfPage.getTextContent({
|
|
||||||
disableNormalization: true,
|
|
||||||
});
|
|
||||||
const text = mergeText(items);
|
|
||||||
|
|
||||||
expect(text).toEqual("Hello ASCII\n日本語テスト");
|
|
||||||
|
|
||||||
await loadingTask.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("gets text content with a rised text", async function () {
|
it("gets text content with a rised text", async function () {
|
||||||
const loadingTask = getDocument(buildGetDocumentParams("issue16221.pdf"));
|
const loadingTask = getDocument(buildGetDocumentParams("issue16221.pdf"));
|
||||||
const pdfDoc = await loadingTask.promise;
|
const pdfDoc = await loadingTask.promise;
|
||||||
|
|||||||
@ -91,7 +91,7 @@ describe("custom ownerDocument", function () {
|
|||||||
|
|
||||||
const checkFont = font => /g_d\d+_f1/.test(font.family);
|
const checkFont = font => /g_d\d+_f1/.test(font.family);
|
||||||
const checkFontFaceRule = rule =>
|
const checkFontFaceRule = rule =>
|
||||||
/^@font-face \{font-family:"g_d\d+_f1";src:/.test(rule);
|
/^@font-face {font-family:"g_d\d+_f1";src:/.test(rule);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
globalThis.FontFace = function MockFontFace(name) {
|
globalThis.FontFace = function MockFontFace(name) {
|
||||||
|
|||||||
@ -546,96 +546,4 @@ describe("getFontSubstitution", function () {
|
|||||||
/^"ArialBlack",g_d(\d+)_sf(\d+),sans-serif$/
|
/^"ArialBlack",g_d(\d+)_sf(\d+),sans-serif$/
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should substitute HeiseiMin-W3", () => {
|
|
||||||
const fontName = "HeiseiMin-W3";
|
|
||||||
const fontSubstitution = getFontSubstitution(
|
|
||||||
new Map(),
|
|
||||||
idFactory,
|
|
||||||
localFontPath,
|
|
||||||
fontName,
|
|
||||||
undefined,
|
|
||||||
"CIDFontType2"
|
|
||||||
);
|
|
||||||
expect(fontSubstitution).toEqual(
|
|
||||||
jasmine.objectContaining({
|
|
||||||
guessFallback: false,
|
|
||||||
baseFontName: "HeiseiMin-W3",
|
|
||||||
src:
|
|
||||||
"local(Hiragino Mincho ProN),local(Hiragino Mincho Pro)," +
|
|
||||||
"local(Yu Mincho),local(YuMincho),local(Source Han Serif JP)," +
|
|
||||||
"local(Noto Serif JP),local(Noto Serif CJK JP)," +
|
|
||||||
"local(IPAexMincho),local(IPAMincho),local(Takao Mincho)," +
|
|
||||||
"local(MS Mincho),local(MS PMincho)",
|
|
||||||
style: {
|
|
||||||
style: "normal",
|
|
||||||
weight: "normal",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
expect(fontSubstitution.css).toMatch(
|
|
||||||
/^"HeiseiMin W3",g_d(\d+)_sf(\d+),serif$/
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should substitute a Kozuka Mincho alias", () => {
|
|
||||||
const fontName = "KozMinPr6N-Regular";
|
|
||||||
const fontSubstitution = getFontSubstitution(
|
|
||||||
new Map(),
|
|
||||||
idFactory,
|
|
||||||
localFontPath,
|
|
||||||
fontName,
|
|
||||||
undefined,
|
|
||||||
"CIDFontType0"
|
|
||||||
);
|
|
||||||
expect(fontSubstitution).toEqual(
|
|
||||||
jasmine.objectContaining({
|
|
||||||
guessFallback: false,
|
|
||||||
baseFontName: "KozMinPr6N-Regular",
|
|
||||||
src:
|
|
||||||
"local(Hiragino Mincho ProN),local(Hiragino Mincho Pro)," +
|
|
||||||
"local(Yu Mincho),local(YuMincho),local(Source Han Serif JP)," +
|
|
||||||
"local(Noto Serif JP),local(Noto Serif CJK JP)," +
|
|
||||||
"local(IPAexMincho),local(IPAMincho),local(Takao Mincho)," +
|
|
||||||
"local(MS Mincho),local(MS PMincho)",
|
|
||||||
style: {
|
|
||||||
style: "normal",
|
|
||||||
weight: "normal",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
expect(fontSubstitution.css).toMatch(
|
|
||||||
/^"KozMinPr6N",g_d(\d+)_sf(\d+),serif$/
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should substitute HYGoThic-Medium", () => {
|
|
||||||
const fontName = "HYGoThic-Medium";
|
|
||||||
const fontSubstitution = getFontSubstitution(
|
|
||||||
new Map(),
|
|
||||||
idFactory,
|
|
||||||
localFontPath,
|
|
||||||
fontName,
|
|
||||||
undefined,
|
|
||||||
"CIDFontType2"
|
|
||||||
);
|
|
||||||
expect(fontSubstitution).toEqual(
|
|
||||||
jasmine.objectContaining({
|
|
||||||
guessFallback: false,
|
|
||||||
baseFontName: "HYGoThic-Medium",
|
|
||||||
src:
|
|
||||||
"local(Apple SD Gothic Neo),local(AppleGothic)," +
|
|
||||||
"local(Source Han Sans KR),local(Noto Sans KR)," +
|
|
||||||
"local(Noto Sans CJK KR),local(Nanum Gothic)," +
|
|
||||||
"local(Malgun Gothic),local(Dotum),local(Gulim)",
|
|
||||||
style: {
|
|
||||||
style: "normal",
|
|
||||||
weight: "500",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
expect(fontSubstitution.css).toMatch(
|
|
||||||
/^"HYGoThic",g_d(\d+)_sf(\d+),sans-serif$/
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1115,7 +1115,7 @@ const PDFViewerApplication = {
|
|||||||
// - The title may contain incorrectly encoded characters, which thus
|
// - The title may contain incorrectly encoded characters, which thus
|
||||||
// looks broken, hence we ignore the Metadata entry when it contains
|
// looks broken, hence we ignore the Metadata entry when it contains
|
||||||
// characters from the Specials Unicode block (fixes bug 1605526).
|
// characters from the Specials Unicode block (fixes bug 1605526).
|
||||||
if (title !== "Untitled" && !/[\uFFF0-\uFFFF]/.test(title)) {
|
if (title !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(title)) {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
|||||||
|
|
||||||
const isAndroid = /Android/.test(userAgent);
|
const isAndroid = /Android/.test(userAgent);
|
||||||
const isIOS =
|
const isIOS =
|
||||||
/\b(?:iPad|iPhone|iPod)(?=;)/.test(userAgent) ||
|
/\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) ||
|
||||||
(platform === "MacIntel" && maxTouchPoints > 1);
|
(platform === "MacIntel" && maxTouchPoints > 1);
|
||||||
|
|
||||||
// Limit canvas size to 5 mega-pixels on mobile.
|
// Limit canvas size to 5 mega-pixels on mobile.
|
||||||
|
|||||||
@ -138,8 +138,7 @@ class Autolinker {
|
|||||||
static findLinks(text) {
|
static findLinks(text) {
|
||||||
// Regex can be tested and verified at https://regex101.com/r/rXoLiT/2.
|
// Regex can be tested and verified at https://regex101.com/r/rXoLiT/2.
|
||||||
this.#regex ??=
|
this.#regex ??=
|
||||||
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|(?=\p{L})[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[[\p{P}--\-]<>]]+(?:\.[\S--[[\p{P}--\-]<>]]+)+)/gmv;
|
||||||
/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|(?=\p{L})[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[[\p{P}--\-]<>]]+(?:\.[\S--[[\p{P}--\-]<>]]+)+)/gv;
|
|
||||||
|
|
||||||
const [normalizedText, diffs] = normalize(text, { ignoreDashEOL: true });
|
const [normalizedText, diffs] = normalize(text, { ignoreDashEOL: true });
|
||||||
const matches = normalizedText.matchAll(this.#regex);
|
const matches = normalizedText.matchAll(this.#regex);
|
||||||
|
|||||||
@ -36,8 +36,8 @@ if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) {
|
|||||||
// Run this code outside DOMContentLoaded to make sure that the URL
|
// Run this code outside DOMContentLoaded to make sure that the URL
|
||||||
// is rewritten as soon as possible.
|
// is rewritten as soon as possible.
|
||||||
const queryString = document.location.search.slice(1);
|
const queryString = document.location.search.slice(1);
|
||||||
const m = /(?:^|&)file=([^&]*)/.exec(queryString);
|
const m = /(^|&)file=([^&]*)/.exec(queryString);
|
||||||
let defaultUrl = m ? decodeURIComponent(m[1]) : "";
|
let defaultUrl = m ? decodeURIComponent(m[2]) : "";
|
||||||
if (!defaultUrl && queryString.startsWith("DNR:")) {
|
if (!defaultUrl && queryString.startsWith("DNR:")) {
|
||||||
// Redirected via DNR, see registerPdfRedirectRule in pdfHandler.js.
|
// Redirected via DNR, see registerPdfRedirectRule in pdfHandler.js.
|
||||||
defaultUrl = queryString.slice(4);
|
defaultUrl = queryString.slice(4);
|
||||||
|
|||||||
@ -115,7 +115,10 @@ class FontView {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ext = MIMETYPE_TO_EXTENSION.get(font.mimetype) ?? "font";
|
const ext = MIMETYPE_TO_EXTENSION.get(font.mimetype) ?? "font";
|
||||||
const name = (font.name || font.loadedName).replaceAll(/[^\w-]/g, "_");
|
const name = (font.name || font.loadedName).replaceAll(
|
||||||
|
/[^a-z0-9_-]/gi,
|
||||||
|
"_"
|
||||||
|
);
|
||||||
const blob = new Blob([font.data], { type: font.mimetype });
|
const blob = new Blob([font.data], { type: font.mimetype });
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
|
|||||||
@ -75,8 +75,8 @@ let DIACRITICS_EXCEPTION_STR; // Lazily initialized, see below.
|
|||||||
|
|
||||||
const DIACRITICS_REG_EXP = /\p{M}+/gu;
|
const DIACRITICS_REG_EXP = /\p{M}+/gu;
|
||||||
const SPECIAL_CHARS_REG_EXP = /([+^$|])|(\p{P}+)|(\s+)|(\p{M})|(\p{L})/gu;
|
const SPECIAL_CHARS_REG_EXP = /([+^$|])|(\p{P}+)|(\s+)|(\p{M})|(\p{L})/gu;
|
||||||
const NOT_DIACRITIC_FROM_END_REG_EXP = /(\P{M})\p{M}*$/u;
|
const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u;
|
||||||
const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*(\P{M})/u;
|
const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u;
|
||||||
|
|
||||||
// The range [AC00-D7AF] corresponds to the Hangul syllables.
|
// The range [AC00-D7AF] corresponds to the Hangul syllables.
|
||||||
// The few other chars are some CJK Compatibility Ideographs.
|
// The few other chars are some CJK Compatibility Ideographs.
|
||||||
@ -149,7 +149,7 @@ function normalize(text, options = {}) {
|
|||||||
];
|
];
|
||||||
normalizationRegex = new RegExp(
|
normalizationRegex = new RegExp(
|
||||||
regexps.map(r => `(${r})`).join("|"),
|
regexps.map(r => `(${r})`).join("|"),
|
||||||
"gmu"
|
"gum"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hasSyllables) {
|
if (hasSyllables) {
|
||||||
|
|||||||
@ -22,8 +22,6 @@
|
|||||||
overflow: clip;
|
overflow: clip;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
letter-spacing: normal;
|
|
||||||
word-spacing: normal;
|
|
||||||
text-size-adjust: none;
|
text-size-adjust: none;
|
||||||
forced-color-adjust: none;
|
forced-color-adjust: none;
|
||||||
transform-origin: 0 0;
|
transform-origin: 0 0;
|
||||||
|
|||||||
@ -175,7 +175,6 @@ function parseQueryString(query) {
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
const InvisibleCharsRegExp = /[\x00-\x1F]/g;
|
const InvisibleCharsRegExp = /[\x00-\x1F]/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -267,11 +266,14 @@ function approximateFraction(x) {
|
|||||||
b = q;
|
b = q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let result;
|
||||||
// Select closest of the neighbours to x.
|
// Select closest of the neighbours to x.
|
||||||
if (x_ - a / b < c / d - x_) {
|
if (x_ - a / b < c / d - x_) {
|
||||||
return x_ === x ? [a, b] : [b, a];
|
result = x_ === x ? [a, b] : [b, a];
|
||||||
|
} else {
|
||||||
|
result = x_ === x ? [c, d] : [d, c];
|
||||||
}
|
}
|
||||||
return x_ === x ? [c, d] : [d, c];
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user