Compare commits

..

No commits in common. "master" and "v4.0.379" have entirely different histories.

233 changed files with 12958 additions and 19834 deletions

View File

@ -8,5 +8,4 @@ external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

View File

@ -142,10 +142,9 @@
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-multi-str": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-symbol": "error",
"no-new-wrappers": "error",
"no-new": "error",
"no-octal-escape": "error",
"no-octal": "error",
"no-redeclare": "error",
@ -243,9 +242,9 @@
}],
// ECMAScript 6
"arrow-body-style": ["error", "as-needed"],
"constructor-super": "error",
"no-class-assign": "error",
"no-confusing-arrow": "error",
"no-const-assign": "error",
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
@ -258,7 +257,6 @@
"avoidQuotes": true,
}],
"prefer-const": "error",
"require-yield": "error",
"sort-imports": ["error", {
"ignoreCase": true,
}],

View File

@ -1,6 +0,0 @@
# Auto-format `.js` files with ESLint/Prettier
de36b2aabab2b7fd647d9591f959c4540129541d
# Auto-format `.css` files with Stylelint/Prettier
8aa2718d225ad701a5b8a2788b42d221f1e4327d
# Auto-format `.json` files with Prettier
29de9bdce6c9785574994fda0e51533d796a9bb4

View File

@ -1,12 +0,0 @@
build/
l10n/
docs/
node_modules/
external/bcmaps/
external/builder/fixtures/
external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

View File

@ -5,14 +5,5 @@
"semi": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"overrides": [
{
files: ["tsconfig.json"],
options: {
parser: "json",
},
},
]
"useTabs": false
}

View File

@ -8,5 +8,4 @@ external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

View File

@ -55,17 +55,12 @@ Next, install Node.js via the [official package](https://nodejs.org) or via
[nvm](https://github.com/creationix/nvm). You need to install the gulp package
globally (see also [gulp's getting started](https://github.com/gulpjs/gulp/tree/master/docs/getting-started)):
$ npm install -g gulp-cli@^2.3.0
If you prefer to not install `gulp-cli` globally, you have to prefix all the `gulp` commands with `npx` (for example, `npx gulp server` instead of `gulp server`).
$ npm install -g gulp-cli
If everything worked out, install all dependencies for PDF.js:
$ npm install
> [!NOTE]
> On MacOS M1/M2 you may see some `node-gyp`-related errors when running `npm install`. This is because one of our dependencies, `"canvas"`, does not provide pre-built binaries for this platform and instead `npm` will try to build it from source. Please make sure to first install the necessary native dependencies using `brew`: https://github.com/Automattic/node-canvas#compiling.
Finally, you need to start a local web server as some browsers do not allow opening
PDF files using a `file://` URL. Run:

View File

@ -272,7 +272,7 @@ const PDFViewerApplication = {
});
this.pdfLinkService = linkService;
this.l10n = new pdfjsViewer.GenericL10n();
this.l10n = pdfjsViewer.NullL10n;
const container = document.getElementById("viewerContainer");
const pdfViewer = new pdfjsViewer.PDFViewer({

View File

@ -47,7 +47,7 @@ limitations under the License.
}
var scheme = url.slice(0, schemeIndex).toLowerCase();
if (schemes.includes(scheme)) {
url = url.split("#", 1)[0];
url = url.split("#")[0];
if (url.charAt(schemeIndex) === ":") {
url = encodeURIComponent(url);
}

View File

@ -11,30 +11,32 @@
},
"permissions": [
"fileBrowserHandler",
"webRequest",
"webRequestBlocking",
"webRequest", "webRequestBlocking",
"<all_urls>",
"tabs",
"webNavigation",
"storage"
],
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "ftp://*/*", "file://*/*"],
"run_at": "document_start",
"all_frames": true,
"css": ["contentstyle.css"],
"js": ["contentscript.js"]
}
],
"content_scripts": [{
"matches": [
"http://*/*",
"https://*/*",
"ftp://*/*",
"file://*/*"
],
"run_at": "document_start",
"all_frames": true,
"css": ["contentstyle.css"],
"js": ["contentscript.js"]
}],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"file_browser_handlers": [
{
"id": "open-as-pdf",
"default_title": "Open with PDF Viewer",
"file_filters": ["filesystem:*.pdf"]
}
],
"file_browser_handlers": [{
"id": "open-as-pdf",
"default_title": "Open with PDF Viewer",
"file_filters": [
"filesystem:*.pdf"
]
}],
"storage": {
"managed_schema": "preferences_schema.json"
},

View File

@ -5,7 +5,11 @@
"title": "Theme",
"description": "The theme to use.\n0 = Use system theme.\n1 = Light theme.\n2 = Dark theme.",
"type": "integer",
"enum": [0, 1, 2],
"enum": [
0,
1,
2
],
"default": 2
},
"showPreviousViewOnLoad": {
@ -17,7 +21,11 @@
"title": "View position on load",
"description": "The position in the document upon load.\n -1 = Default (uses OpenAction if available, otherwise equal to `viewOnLoad = 0`).\n 0 = The last viewed page/position.\n 1 = The initial page/position.",
"type": "integer",
"enum": [-1, 0, 1],
"enum": [
-1,
0,
1
],
"default": 0
},
"defaultZoomDelay": {
@ -37,7 +45,13 @@
"title": "Sidebar state on load",
"description": "Controls the state of the sidebar upon load.\n -1 = Default (uses PageMode if available, otherwise the last position if available/enabled).\n 0 = Do not show sidebar.\n 1 = Show thumbnails in sidebar.\n 2 = Show document outline in sidebar.\n 3 = Show attachments in sidebar.",
"type": "integer",
"enum": [-1, 0, 1, 2, 3],
"enum": [
-1,
0,
1,
2,
3
],
"default": -1
},
"enableHandToolOnLoad": {
@ -45,15 +59,14 @@
"type": "boolean",
"default": false
},
"enableML": {
"type": "boolean",
"default": false
},
"cursorToolOnLoad": {
"title": "Cursor tool on load",
"description": "The cursor tool that is enabled upon load.\n 0 = Text selection tool.\n 1 = Hand tool.",
"type": "integer",
"enum": [0, 1],
"enum": [
0,
1
],
"default": 0
},
"pdfBugEnabled": {
@ -72,18 +85,10 @@
"type": "boolean",
"default": false
},
"enableHighlightFloatingButton": {
"type": "boolean",
"default": false
},
"highlightEditorColors": {
"type": "string",
"default": "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F"
},
"enableStampEditor": {
"type": "boolean",
"default": true
},
"disableRange": {
"title": "Disable range requests",
"description": "Whether to disable range requests (not recommended).",
@ -115,14 +120,23 @@
"title": "Text layer mode",
"description": "Controls if the text layer is enabled, and the selection mode that is used.\n 0 = Disabled.\n 1 = Enabled.",
"type": "integer",
"enum": [0, 1],
"enum": [
0,
1
],
"default": 1
},
"externalLinkTarget": {
"title": "External links target window",
"description": "Controls how external links will be opened.\n 0 = default.\n 1 = replaces current window.\n 2 = new window/tab.\n 3 = parent.\n 4 = in top window.",
"type": "integer",
"enum": [0, 1, 2, 3, 4],
"enum": [
0,
1,
2,
3,
4
],
"default": 0
},
"disablePageLabels": {
@ -142,12 +156,22 @@
},
"annotationMode": {
"type": "integer",
"enum": [0, 1, 2, 3],
"enum": [
0,
1,
2,
3
],
"default": 2
},
"annotationEditorMode": {
"type": "integer",
"enum": [-1, 0, 3, 15],
"enum": [
-1,
0,
3,
15
],
"default": 0
},
"enablePermissions": {
@ -178,14 +202,25 @@
"title": "Scroll mode on load",
"description": "Controls how the viewer scrolls upon load.\n -1 = Default (uses the last position if available/enabled).\n 3 = Page scrolling.\n 0 = Vertical scrolling.\n 1 = Horizontal scrolling.\n 2 = Wrapped scrolling.",
"type": "integer",
"enum": [-1, 0, 1, 2, 3],
"enum": [
-1,
0,
1,
2,
3
],
"default": -1
},
"spreadModeOnLoad": {
"title": "Spread mode on load",
"description": "Whether the viewer should join pages into spreads upon load.\n -1 = Default (uses the last position if available/enabled).\n 0 = No spreads.\n 1 = Odd spreads.\n 2 = Even spreads.",
"type": "integer",
"enum": [-1, 0, 1, 2],
"enum": [
-1,
0,
1,
2
],
"default": -1
},
"forcePageColors": {

View File

@ -1,253 +0,0 @@
import { types as t, transformSync } from "@babel/core";
import fs from "fs";
import { join as joinPaths } from "path";
import vm from "vm";
const PDFJS_PREPROCESSOR_NAME = "PDFJSDev";
const ROOT_PREFIX = "$ROOT/";
function isPDFJSPreprocessor(obj) {
return obj.type === "Identifier" && obj.name === PDFJS_PREPROCESSOR_NAME;
}
function evalWithDefines(code, defines) {
if (!code || !code.trim()) {
throw new Error("No JavaScript expression given");
}
return vm.runInNewContext(code, defines, { displayErrors: false });
}
function handlePreprocessorAction(ctx, actionName, args, path) {
try {
const arg = args[0];
switch (actionName) {
case "test":
if (!t.isStringLiteral(arg)) {
throw new Error("No code for testing is given");
}
return !!evalWithDefines(arg.value, ctx.defines);
case "eval":
if (!t.isStringLiteral(arg)) {
throw new Error("No code for eval is given");
}
const result = evalWithDefines(arg.value, ctx.defines);
if (
typeof result === "boolean" ||
typeof result === "string" ||
typeof result === "number" ||
typeof result === "object"
) {
return result;
}
break;
case "json":
if (!t.isStringLiteral(arg)) {
throw new Error("Path to JSON is not provided");
}
let jsonPath = arg.value;
if (jsonPath.startsWith(ROOT_PREFIX)) {
jsonPath = joinPaths(
ctx.rootPath,
jsonPath.substring(ROOT_PREFIX.length)
);
}
return JSON.parse(fs.readFileSync(jsonPath, "utf8"));
}
throw new Error("Unsupported action");
} catch (e) {
throw path.buildCodeFrameError(
"Could not process " +
PDFJS_PREPROCESSOR_NAME +
"." +
actionName +
": " +
e.message
);
}
}
function babelPluginPDFJSPreprocessor(babel, ctx) {
return {
name: "babel-plugin-pdfjs-preprocessor",
manipulateOptions({ parserOpts }) {
parserOpts.attachComment = false;
},
visitor: {
"ExportNamedDeclaration|ImportDeclaration": ({ node }) => {
if (node.source && ctx.map?.[node.source.value]) {
node.source.value = ctx.map[node.source.value];
}
},
"IfStatement|ConditionalExpression": {
exit(path) {
const { node } = path;
if (t.isBooleanLiteral(node.test)) {
// if (true) stmt1; => stmt1
// if (false) stmt1; else stmt2; => stmt2
if (node.test.value === true) {
path.replaceWith(node.consequent);
} else if (node.alternate) {
path.replaceWith(node.alternate);
} else {
path.remove(node);
}
}
},
},
UnaryExpression: {
exit(path) {
const { node } = path;
if (
node.operator === "typeof" &&
isPDFJSPreprocessor(node.argument)
) {
// typeof PDFJSDev => 'object'
path.replaceWith(t.stringLiteral("object"));
return;
}
if (node.operator === "!" && t.isBooleanLiteral(node.argument)) {
// !true => false, !false => true
path.replaceWith(t.booleanLiteral(!node.argument.value));
}
},
},
LogicalExpression: {
exit(path) {
const { node } = path;
if (!t.isBooleanLiteral(node.left)) {
return;
}
switch (node.operator) {
case "&&":
// true && expr => expr
// false && expr => false
path.replaceWith(
node.left.value === true ? node.right : node.left
);
break;
case "||":
// true || expr => true
// false || expr => expr
path.replaceWith(
node.left.value === true ? node.left : node.right
);
break;
}
},
},
BinaryExpression: {
exit(path) {
const { node } = path;
switch (node.operator) {
case "==":
case "===":
case "!=":
case "!==":
if (t.isLiteral(node.left) && t.isLiteral(node.right)) {
// folding == and != check that can be statically evaluated
const { confident, value } = path.evaluate();
if (confident) {
path.replaceWith(t.booleanLiteral(value));
}
}
}
},
},
CallExpression(path) {
const { node } = path;
if (
t.isMemberExpression(node.callee) &&
isPDFJSPreprocessor(node.callee.object) &&
t.isIdentifier(node.callee.property) &&
!node.callee.computed
) {
// PDFJSDev.xxxx(arg1, arg2, ...) => transform
const action = node.callee.property.name;
const result = handlePreprocessorAction(
ctx,
action,
node.arguments,
path
);
path.replaceWith(t.inherits(t.valueToNode(result), path.node));
}
if (t.isIdentifier(node.callee, { name: "__non_webpack_import__" })) {
if (node.arguments.length !== 1) {
throw new Error("Invalid `__non_webpack_import__` usage.");
}
// Replace it with a standard `import`-call and
// ensure that Webpack will leave it alone.
const source = node.arguments[0];
source.leadingComments = [
{
type: "CommentBlock",
value: "webpackIgnore: true",
},
];
path.replaceWith(t.importExpression(source));
}
},
BlockStatement: {
// Visit node in post-order so that recursive flattening
// of blocks works correctly.
exit(path) {
const { node } = path;
let subExpressionIndex = 0;
while (subExpressionIndex < node.body.length) {
switch (node.body[subExpressionIndex].type) {
case "EmptyStatement":
// Removing empty statements from the blocks.
node.body.splice(subExpressionIndex, 1);
continue;
case "BlockStatement":
// Block statements inside a block are flattened
// into the parent one.
const subChildren = node.body[subExpressionIndex].body;
node.body.splice(subExpressionIndex, 1, ...subChildren);
subExpressionIndex += Math.max(subChildren.length - 1, 0);
continue;
case "ReturnStatement":
case "ThrowStatement":
// Removing dead code after return or throw.
node.body.splice(
subExpressionIndex + 1,
node.body.length - subExpressionIndex - 1
);
break;
}
subExpressionIndex++;
}
},
},
Function: {
exit(path) {
if (!t.isBlockStatement(path.node.body)) {
// Arrow function with expression body
return;
}
const { body } = path.node.body;
if (
body.length > 0 &&
t.isReturnStatement(body.at(-1), { argument: null })
) {
// Function body ends with return without arg -- removing it.
body.pop();
}
},
},
},
};
}
function preprocessPDFJSCode(ctx, content) {
return transformSync(content, {
configFile: false,
plugins: [[babelPluginPDFJSPreprocessor, ctx]],
}).code;
}
export { babelPluginPDFJSPreprocessor, preprocessPDFJSCode };

View File

@ -1,10 +1,10 @@
function test() {
"test";
"1";
"2";
"3";
if ("test") {
"5";
}
"4";
"test";
"1";
"2";
"3";
if ("test") {
"5";
}
"4";
}

View File

@ -1,17 +1,17 @@
function f1() {
"1";
"2";
"1";
"2";
}
function f2() {
"1";
"2";
"1";
"2";
}
function f3() {
if ("1") {
"1";
}
"2";
if ("3") {
"4";
}
if ("1") {
"1";
}
"2";
if ("3") {
"4";
}
}

View File

@ -10,6 +10,6 @@ var i = true;
var j = false;
var k = false;
var l = true;
var m = false;
var m = '1' === true;
var n = false;
var o = true;

View File

@ -1,21 +1,13 @@
function f1() {}
function f1() {
}
function f2() {
return 1;
return 1;
}
function f3() {
var i = 0;
throw "test";
var i = 0;
throw "test";
}
function f4() {
var i = 0;
var i = 0;
}
var obj = {
method1() {},
method2() {}
};
class C {
method1() {}
method2() {}
}
var arrow1 = () => {};
var arrow2 = () => {};

View File

@ -23,15 +23,3 @@ function f4() {
var j = 0;
}
var obj = {
method1() { return; var i = 0; },
method2() { return; },
};
class C {
method1() { return; var i = 0; }
method2() { return; }
}
var arrow1 = () => { return; var i = 0; };
var arrow2 = () => { return; };

View File

@ -3,19 +3,11 @@ var b = true;
var c = true;
var d = false;
var e = true;
var f = "text";
var f = 'text';
var g = {
obj: {
i: 1
},
j: 2
};
var h = {
test: "test"
"obj": { "i": 1 },
"j": 2
};
var h = { 'test': 'test' };
var i = '0';
var j = {
i: 1
};
var k = false;
var l = true;
var j = { "i": 1 };

View File

@ -8,5 +8,3 @@ var g = PDFJSDev.eval('OBJ');
var h = PDFJSDev.json('$ROOT/external/builder/fixtures_esprima/evals.json');
var i = typeof PDFJSDev === 'undefined' ? PDFJSDev.eval('FALSE') : '0';
var j = typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('OBJ.obj') : '0';
var k = !PDFJSDev.test('TRUE');
var l = !PDFJSDev.test('FALSE');

View File

@ -1 +1 @@
{ "test": "test" }
{ 'test': 'test' }

View File

@ -1,18 +1,17 @@
if ('test') {
"1";
"1";
}
{
"1";
"1";
}
{
"1";
"1";
}
;
{
"2";
"2";
}
;
if ('1') {
"1";
}
function f1() {
"1";
"1";
}

View File

@ -23,12 +23,3 @@ if (true && false) {
if (true && false || '1') {
"1";
}
function f1() {
if (true) {
"1";
}
if (false) {
"2";
}
}

View File

@ -1,4 +1,7 @@
import { Test } from "import-name";
import { Test } from 'import-name';
import { Test2 } from './non-alias';
export { Test3 } from "import-name";
await import( /*webpackIgnore: true*/"./non-alias");
export {
Test3
} from 'import-name';
var Imp = require('import-name');
var Imp2 = require('./non-alias');

View File

@ -1,4 +1,5 @@
import { Test } from 'import-alias';
import { Test2 } from './non-alias';
export { Test3 } from 'import-alias';
await __non_webpack_import__("./non-alias");
var Imp = require('import-alias');
var Imp2 = require('./non-alias');

347
external/builder/preprocessor2.mjs vendored Normal file
View File

@ -0,0 +1,347 @@
import * as acorn from "acorn";
import escodegen from "@javascript-obfuscator/escodegen";
import fs from "fs";
import path from "path";
import vm from "vm";
const PDFJS_PREPROCESSOR_NAME = "PDFJSDev";
const ROOT_PREFIX = "$ROOT/";
const ACORN_ECMA_VERSION = 2022;
function isLiteral(obj, value) {
return obj.type === "Literal" && obj.value === value;
}
function isPDFJSPreprocessor(obj) {
return obj.type === "Identifier" && obj.name === PDFJS_PREPROCESSOR_NAME;
}
function evalWithDefines(code, defines, loc) {
if (!code || !code.trim()) {
throw new Error("No JavaScript expression given");
}
return vm.runInNewContext(code, defines, { displayErrors: false });
}
function handlePreprocessorAction(ctx, actionName, args, loc) {
try {
let arg;
switch (actionName) {
case "test":
arg = args[0];
if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") {
throw new Error("No code for testing is given");
}
const isTrue = !!evalWithDefines(arg.value, ctx.defines);
return { type: "Literal", value: isTrue, loc };
case "eval":
arg = args[0];
if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") {
throw new Error("No code for eval is given");
}
const result = evalWithDefines(arg.value, ctx.defines);
if (
typeof result === "boolean" ||
typeof result === "string" ||
typeof result === "number"
) {
return { type: "Literal", value: result, loc };
}
if (typeof result === "object") {
const parsedObj = acorn.parse("(" + JSON.stringify(result) + ")", {
ecmaVersion: ACORN_ECMA_VERSION,
});
parsedObj.body[0].expression.loc = loc;
return parsedObj.body[0].expression;
}
break;
case "json":
arg = args[0];
if (!arg || arg.type !== "Literal" || typeof arg.value !== "string") {
throw new Error("Path to JSON is not provided");
}
let jsonPath = arg.value;
if (jsonPath.indexOf(ROOT_PREFIX) === 0) {
jsonPath = path.join(
ctx.rootPath,
jsonPath.substring(ROOT_PREFIX.length)
);
}
const jsonContent = fs.readFileSync(jsonPath).toString();
const parsedJSON = acorn.parse("(" + jsonContent + ")", {
ecmaVersion: ACORN_ECMA_VERSION,
});
parsedJSON.body[0].expression.loc = loc;
return parsedJSON.body[0].expression;
}
throw new Error("Unsupported action");
} catch (e) {
throw new Error(
"Could not process " +
PDFJS_PREPROCESSOR_NAME +
"." +
actionName +
" at " +
JSON.stringify(loc) +
"\n" +
e.name +
": " +
e.message
);
}
}
function postprocessNode(ctx, node) {
switch (node.type) {
case "ExportNamedDeclaration":
case "ImportDeclaration":
if (
node.source &&
node.source.type === "Literal" &&
ctx.map &&
ctx.map[node.source.value]
) {
const newValue = ctx.map[node.source.value];
node.source.value = node.source.raw = newValue;
}
break;
case "IfStatement":
if (isLiteral(node.test, true)) {
// if (true) stmt1; => stmt1
return node.consequent;
} else if (isLiteral(node.test, false)) {
// if (false) stmt1; else stmt2; => stmt2
return node.alternate || { type: "EmptyStatement", loc: node.loc };
}
break;
case "ConditionalExpression":
if (isLiteral(node.test, true)) {
// true ? stmt1 : stmt2 => stmt1
return node.consequent;
} else if (isLiteral(node.test, false)) {
// false ? stmt1 : stmt2 => stmt2
return node.alternate;
}
break;
case "UnaryExpression":
if (node.operator === "typeof" && isPDFJSPreprocessor(node.argument)) {
// typeof PDFJSDev => 'object'
return { type: "Literal", value: "object", loc: node.loc };
}
if (
node.operator === "!" &&
node.argument.type === "Literal" &&
typeof node.argument.value === "boolean"
) {
// !true => false, !false => true
return { type: "Literal", value: !node.argument.value, loc: node.loc };
}
break;
case "LogicalExpression":
switch (node.operator) {
case "&&":
if (isLiteral(node.left, true)) {
return node.right;
}
if (isLiteral(node.left, false)) {
return node.left;
}
break;
case "||":
if (isLiteral(node.left, true)) {
return node.left;
}
if (isLiteral(node.left, false)) {
return node.right;
}
break;
}
break;
case "BinaryExpression":
switch (node.operator) {
case "==":
case "===":
case "!=":
case "!==":
if (
node.left.type === "Literal" &&
node.right.type === "Literal" &&
typeof node.left.value === typeof node.right.value
) {
// folding two literals == and != check
switch (typeof node.left.value) {
case "string":
case "boolean":
case "number":
const equal = node.left.value === node.right.value;
return {
type: "Literal",
value: (node.operator[0] === "=") === equal,
loc: node.loc,
};
}
}
break;
}
break;
case "CallExpression":
if (
node.callee.type === "MemberExpression" &&
isPDFJSPreprocessor(node.callee.object) &&
node.callee.property.type === "Identifier"
) {
// PDFJSDev.xxxx(arg1, arg2, ...) => transform
const action = node.callee.property.name;
return handlePreprocessorAction(ctx, action, node.arguments, node.loc);
}
// require('string')
if (
node.callee.type === "Identifier" &&
node.callee.name === "require" &&
node.arguments.length === 1 &&
node.arguments[0].type === "Literal" &&
ctx.map &&
ctx.map[node.arguments[0].value]
) {
const requireName = node.arguments[0];
requireName.value = requireName.raw = ctx.map[requireName.value];
}
break;
case "BlockStatement":
let subExpressionIndex = 0;
while (subExpressionIndex < node.body.length) {
switch (node.body[subExpressionIndex].type) {
case "EmptyStatement":
// Removing empty statements from the blocks.
node.body.splice(subExpressionIndex, 1);
continue;
case "BlockStatement":
// Block statements inside a block are moved to the parent one.
const subChildren = node.body[subExpressionIndex].body;
Array.prototype.splice.apply(node.body, [
subExpressionIndex,
1,
...subChildren,
]);
subExpressionIndex += Math.max(subChildren.length - 1, 0);
continue;
case "ReturnStatement":
case "ThrowStatement":
// Removing dead code after return or throw.
node.body.splice(
subExpressionIndex + 1,
node.body.length - subExpressionIndex - 1
);
break;
}
subExpressionIndex++;
}
break;
case "FunctionDeclaration":
case "FunctionExpression":
const block = node.body;
if (
block.body.length > 0 &&
block.body.at(-1).type === "ReturnStatement" &&
!block.body.at(-1).argument
) {
// Function body ends with return without arg -- removing it.
block.body.pop();
}
break;
}
return node;
}
function fixComments(ctx, node) {
if (!ctx.saveComments) {
return;
}
// Fixes double comments in the escodegen output.
delete node.trailingComments;
// Removes ESLint and other service comments.
if (node.leadingComments) {
const CopyrightRegExp = /\bcopyright\b/i;
const BlockCommentRegExp = /^\s*(globals|eslint|falls through)\b/;
const LineCommentRegExp = /^\s*eslint\b/;
let i = 0;
while (i < node.leadingComments.length) {
const type = node.leadingComments[i].type;
const value = node.leadingComments[i].value;
if (ctx.saveComments === "copyright") {
// Remove all comments, except Copyright notices and License headers.
if (!(type === "Block" && CopyrightRegExp.test(value))) {
node.leadingComments.splice(i, 1);
continue;
}
} else if (
(type === "Block" && BlockCommentRegExp.test(value)) ||
(type === "Line" && LineCommentRegExp.test(value))
) {
node.leadingComments.splice(i, 1);
continue;
}
i++;
}
}
}
function traverseTree(ctx, node) {
// generic node processing
for (const i in node) {
const child = node[i];
if (typeof child === "object" && child !== null && child.type) {
const result = traverseTree(ctx, child);
if (result !== child) {
node[i] = result;
}
} else if (Array.isArray(child)) {
child.forEach(function (childItem, index) {
if (
typeof childItem === "object" &&
childItem !== null &&
childItem.type
) {
const result = traverseTree(ctx, childItem);
if (result !== childItem) {
child[index] = result;
}
}
});
}
}
node = postprocessNode(ctx, node) || node;
fixComments(ctx, node);
return node;
}
function preprocessPDFJSCode(ctx, code) {
const format = ctx.format || {
indent: {
style: " ",
},
};
const parseOptions = {
ecmaVersion: ACORN_ECMA_VERSION,
locations: true,
sourceFile: ctx.sourceFile,
sourceType: "module",
};
const codegenOptions = {
format,
parse(input) {
return acorn.parse(input, { ecmaVersion: ACORN_ECMA_VERSION });
},
sourceMap: ctx.sourceMap,
sourceMapWithCode: ctx.sourceMap,
};
const syntax = acorn.parse(code, parseOptions);
traverseTree(ctx, syntax);
return escodegen.generate(syntax, codegenOptions);
}
export { preprocessPDFJSCode };

View File

@ -42,12 +42,6 @@ files.forEach(function (expectationFilename) {
if (out !== expectation) {
errors++;
// Allow regenerating the expected output using
// OVERWRITE=true node ./external/builder/test-fixtures.mjs
if (process.env.OVERWRITE) {
fs.writeFileSync(expectationFilename, out + "\n");
}
console.log("Assertion failed for " + inFilename);
console.log("--------------------------------------------------");
console.log("EXPECTED:");

View File

@ -1,7 +1,7 @@
import { fileURLToPath } from "url";
import fs from "fs";
import path from "path";
import { preprocessPDFJSCode } from "./babel-plugin-pdfjs-preprocessor.mjs";
import { preprocessPDFJSCode } from "./preprocessor2.mjs";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@ -48,12 +48,6 @@ files.forEach(function (expectationFilename) {
if (out !== expectation) {
errors++;
// Allow regenerating the expected output using
// OVERWRITE=true node ./external/builder/test-fixtures_esprima.mjs
if (process.env.OVERWRITE) {
fs.writeFileSync(expectationFilename, out + "\n");
}
console.log("Assertion failed for " + inFilename);
console.log("--------------------------------------------------");
console.log("EXPECTED:");

View File

@ -14,6 +14,7 @@
*/
import fs from "fs";
import https from "https";
import path from "path";
// Fetches all languages that have an *active* translation in mozilla-central.
@ -21,34 +22,47 @@ import path from "path";
const DEFAULT_LOCALE = "en-US";
const EXCLUDE_LANG_CODES = new Set(["ca-valencia", "ja-JP-mac"]);
const EXCLUDE_LANG_CODES = ["ca-valencia", "ja-JP-mac"];
function normalizeText(s) {
return s.replaceAll(/\r\n?/g, "\n").replaceAll("\uFEFF", "");
}
async function downloadLanguageCodes() {
function downloadLanguageCodes() {
console.log("Downloading language codes...\n");
const ALL_LOCALES =
"https://hg.mozilla.org/mozilla-central/raw-file/tip/browser/locales/all-locales";
const response = await fetch(ALL_LOCALES);
if (!response.ok) {
throw new Error(response.statusText);
}
const content = await response.text();
// Remove any leading/trailing white-space.
const langCodes = normalizeText(content.trim()).split("\n");
// Remove all locales that we don't want to download below.
return langCodes.filter(
langCode => langCode !== DEFAULT_LOCALE && !EXCLUDE_LANG_CODES.has(langCode)
);
return new Promise(function (resolve) {
https.get(ALL_LOCALES, function (response) {
if (response.statusCode === 200) {
let content = "";
response.setEncoding("utf8");
response.on("data", function (chunk) {
content += chunk;
});
response.on("end", function () {
content = content.trim(); // Remove any leading/trailing white-space.
const langCodes = normalizeText(content).split("\n");
// Remove all locales that we don't want to download below.
for (const langCode of [DEFAULT_LOCALE, ...EXCLUDE_LANG_CODES]) {
const i = langCodes.indexOf(langCode);
if (i > -1) {
langCodes.splice(i, 1);
}
}
resolve(langCodes);
});
} else {
resolve([]);
}
});
});
}
async function downloadLanguageFiles(root, langCode) {
console.log(`Downloading ${langCode}...`);
function downloadLanguageFiles(root, langCode) {
console.log("Downloading " + langCode + "...");
// Constants for constructing the URLs. Translations are taken from the
// Nightly channel as those are the most recent ones.
@ -57,27 +71,41 @@ async function downloadLanguageFiles(root, langCode) {
// Defines which files to download for each language.
const files = ["viewer.ftl"];
let downloadsLeft = files.length;
const outputDir = path.join(root, langCode);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
// Download the necessary files for this language.
for (const fileName of files) {
const outputPath = path.join(outputDir, fileName);
const url = MOZ_CENTRAL_ROOT + langCode + MOZ_CENTRAL_PDFJS_DIR + fileName;
return new Promise(function (resolve) {
// Download the necessary files for this language.
files.forEach(function (fileName) {
const outputPath = path.join(outputDir, fileName);
const url =
MOZ_CENTRAL_ROOT + langCode + MOZ_CENTRAL_PDFJS_DIR + fileName;
const response = await fetch(url);
if (!response.ok) {
// Not all files exist for each language. Files without translations
// have been removed (https://bugzilla.mozilla.org/show_bug.cgi?id=1443175).
continue;
}
const content = await response.text();
fs.writeFileSync(outputPath, normalizeText(content), "utf8");
}
https.get(url, function (response) {
// Not all files exist for each language. Files without translations
// have been removed (https://bugzilla.mozilla.org/show_bug.cgi?id=1443175).
if (response.statusCode === 200) {
let content = "";
response.setEncoding("utf8");
response.on("data", function (chunk) {
content += chunk;
});
response.on("end", function () {
fs.writeFileSync(outputPath, normalizeText(content), "utf8");
if (--downloadsLeft === 0) {
resolve();
}
});
} else if (--downloadsLeft === 0) {
resolve();
}
});
});
});
}
async function downloadL10n(root) {

File diff suppressed because one or more lines are too long

41
external/webpack/pdfjsdev-loader.mjs vendored Normal file
View File

@ -0,0 +1,41 @@
/* Copyright 2017 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.
*/
import path from "path";
import { preprocessPDFJSCode } from "../builder/preprocessor2.mjs";
export default function (source) {
// Options must be specified, ignoring request if not.
if (!this.query || typeof this.query !== "object") {
return source;
}
this.cacheable();
const filePath = this.resourcePath;
const context = this.rootContext;
const sourcePath = path.relative(context, filePath).split(path.sep).join("/");
const ctx = Object.create(this.query);
ctx.sourceMap = true;
ctx.sourceFile = sourcePath;
const callback = this.callback;
const sourceAndMap = preprocessPDFJSCode(ctx, source);
const map = sourceAndMap.map.toJSON();
// escodegen does not embed source -- setting map's sourcesContent.
map.sourcesContent = [source];
callback(null, sourceAndMap.code, map);
return undefined;
}

View File

@ -14,10 +14,6 @@
*/
/* eslint-env node */
import {
babelPluginPDFJSPreprocessor,
preprocessPDFJSCode,
} from "./external/builder/babel-plugin-pdfjs-preprocessor.mjs";
import { exec, spawn, spawnSync } from "child_process";
import autoprefixer from "autoprefixer";
import babel from "@babel/core";
@ -34,12 +30,12 @@ import postcssDirPseudoClass from "postcss-dir-pseudo-class";
import postcssDiscardComments from "postcss-discard-comments";
import postcssNesting from "postcss-nesting";
import { preprocess } from "./external/builder/builder.mjs";
import { preprocessPDFJSCode } from "./external/builder/preprocessor2.mjs";
import rename from "gulp-rename";
import replace from "gulp-replace";
import rimraf from "rimraf";
import stream from "stream";
import streamqueue from "streamqueue";
import TerserPlugin from "terser-webpack-plugin";
import through from "through2";
import Vinyl from "vinyl";
import webpack2 from "webpack";
@ -208,18 +204,15 @@ function createWebpackConfig(
!bundleDefines.MOZCENTRAL &&
!bundleDefines.CHROME &&
!bundleDefines.LIB &&
!bundleDefines.MINIFIED &&
!bundleDefines.TESTING &&
!disableSourceMaps;
const isModule = output.library?.type === "module";
const isMinified = bundleDefines.MINIFIED;
const skipBabel = bundleDefines.SKIP_BABEL;
const babelExcludeRegExp = [
// `core-js`, see https://github.com/zloirock/core-js/issues/514,
// should be excluded from processing.
/node_modules[\\/]core-js/,
];
// `core-js`, see https://github.com/zloirock/core-js/issues/514,
// should be excluded from processing.
const babelExcludes = ["node_modules[\\\\\\/]core-js"];
const babelExcludeRegExp = new RegExp(`(${babelExcludes.join("|")})`);
const babelPresets = skipBabel
? undefined
@ -227,22 +220,14 @@ function createWebpackConfig(
[
"@babel/preset-env",
{
corejs: "3.36.0",
corejs: "3.34.0",
exclude: ["web.structured-clone"],
shippedProposals: true,
useBuiltIns: "usage",
},
],
];
const babelPlugins = [
[
babelPluginPDFJSPreprocessor,
{
rootPath: __dirname,
defines: bundleDefines,
},
],
];
const babelPlugins = [];
const plugins = [];
if (!disableLicenseHeader) {
@ -272,9 +257,8 @@ function createWebpackConfig(
const viewerAlias = {
"web-alt_text_manager": "web/alt_text_manager.js",
"web-annotation_editor_params": "web/annotation_editor_params.js",
"web-download_manager": "",
"web-external_services": "",
"web-null_l10n": "",
"web-com": "",
"web-l10n_utils": "web/stubs.js",
"web-pdf_attachment_viewer": "web/pdf_attachment_viewer.js",
"web-pdf_cursor_tools": "web/pdf_cursor_tools.js",
"web-pdf_document_properties": "web/pdf_document_properties.js",
@ -284,7 +268,6 @@ function createWebpackConfig(
"web-pdf_presentation_mode": "web/pdf_presentation_mode.js",
"web-pdf_sidebar": "web/pdf_sidebar.js",
"web-pdf_thumbnail_viewer": "web/pdf_thumbnail_viewer.js",
"web-preferences": "",
"web-print_service": "",
"web-secondary_toolbar": "web/secondary_toolbar.js",
"web-toolbar": "web/toolbar.js",
@ -293,10 +276,7 @@ function createWebpackConfig(
libraryAlias["display-fetch_stream"] = "src/display/fetch_stream.js";
libraryAlias["display-network"] = "src/display/network.js";
viewerAlias["web-download_manager"] = "web/download_manager.js";
viewerAlias["web-external_services"] = "web/chromecom.js";
viewerAlias["web-null_l10n"] = "web/l10n.js";
viewerAlias["web-preferences"] = "web/chromecom.js";
viewerAlias["web-com"] = "web/chromecom.js";
viewerAlias["web-print_service"] = "web/pdf_print_service.js";
} else if (bundleDefines.GENERIC) {
// Aliases defined here must also be replicated in the paths section of
@ -307,24 +287,20 @@ function createWebpackConfig(
libraryAlias["display-node_stream"] = "src/display/node_stream.js";
libraryAlias["display-node_utils"] = "src/display/node_utils.js";
viewerAlias["web-download_manager"] = "web/download_manager.js";
viewerAlias["web-external_services"] = "web/genericcom.js";
viewerAlias["web-null_l10n"] = "web/genericl10n.js";
viewerAlias["web-preferences"] = "web/genericcom.js";
viewerAlias["web-com"] = "web/genericcom.js";
viewerAlias["web-l10n_utils"] = "web/l10n_utils.js";
viewerAlias["web-print_service"] = "web/pdf_print_service.js";
} else if (bundleDefines.MOZCENTRAL) {
if (bundleDefines.GECKOVIEW) {
const gvAlias = {
"web-l10n_utils": "web/stubs.js",
"web-toolbar": "web/toolbar-geckoview.js",
};
for (const key in viewerAlias) {
viewerAlias[key] = gvAlias[key] || "web/stubs-geckoview.js";
}
}
viewerAlias["web-download_manager"] = "web/firefoxcom.js";
viewerAlias["web-external_services"] = "web/firefoxcom.js";
viewerAlias["web-null_l10n"] = "web/l10n.js";
viewerAlias["web-preferences"] = "web/firefoxcom.js";
viewerAlias["web-com"] = "web/firefoxcom.js";
viewerAlias["web-print_service"] = "web/firefox_print_service.js";
}
const alias = { ...basicAlias, ...libraryAlias, ...viewerAlias };
@ -336,28 +312,7 @@ function createWebpackConfig(
mode: "production",
optimization: {
mangleExports: false,
minimize: isMinified,
minimizer: !isMinified
? undefined
: [
new TerserPlugin({
extractComments: false,
parallel: false,
terserOptions: {
compress: {
// V8 chokes on very long sequences, work around that.
sequences: false,
},
mangle: {
// Ensure that the `tweakWebpackOutput` function works.
reserved: ["__webpack_exports__"],
},
keep_classnames: true,
keep_fnames: true,
module: isModule,
},
}),
],
minimize: false,
},
experiments,
output,
@ -380,6 +335,14 @@ function createWebpackConfig(
targets: BABEL_TARGETS,
},
},
{
loader: path.join(__dirname, "external/webpack/pdfjsdev-loader.mjs"),
options: {
rootPath: __dirname,
saveComments: false,
defines: bundleDefines,
},
},
],
},
// Avoid shadowing actual Node.js variables with polyfills, by disabling
@ -443,24 +406,24 @@ function checkChromePreferencesFile(chromePrefsPath, webPrefs) {
}
function tweakWebpackOutput(jsName) {
const replacer = [
" __webpack_exports__ = {};",
",__webpack_exports__={};",
" __webpack_exports__ = await __webpack_exports__;",
"\\(__webpack_exports__=await __webpack_exports__\\)",
];
const replacer = ["__non_webpack_import__\\("];
if (jsName) {
replacer.push(
" __webpack_exports__ = {};",
" __webpack_exports__ = await __webpack_exports__;"
);
}
const regex = new RegExp(`(${replacer.join("|")})`, "gm");
return replace(regex, match => {
switch (match) {
case "__non_webpack_import__(":
return "import(/* webpackIgnore: true */ ";
case " __webpack_exports__ = {};":
return ` __webpack_exports__ = globalThis.${jsName} = {};`;
case ",__webpack_exports__={};":
return `,__webpack_exports__=globalThis.${jsName}={};`;
case " __webpack_exports__ = await __webpack_exports__;":
return ` __webpack_exports__ = globalThis.${jsName} = await (globalThis.${jsName}Promise = __webpack_exports__);`;
case "(__webpack_exports__=await __webpack_exports__)":
return `(__webpack_exports__=globalThis.${jsName}=await (globalThis.${jsName}Promise=__webpack_exports__))`;
}
return match;
});
@ -468,7 +431,7 @@ function tweakWebpackOutput(jsName) {
function createMainBundle(defines) {
const mainFileConfig = createWebpackConfig(defines, {
filename: defines.MINIFIED ? "pdf.min.mjs" : "pdf.mjs",
filename: "pdf.mjs",
library: {
type: "module",
},
@ -492,13 +455,15 @@ function createScriptingBundle(defines, extraOptions = undefined) {
);
return gulp
.src("./src/pdf.scripting.js")
.pipe(webpack2Stream(scriptingFileConfig));
.pipe(webpack2Stream(scriptingFileConfig))
.pipe(tweakWebpackOutput());
}
function createSandboxExternal(defines) {
const licenseHeader = fs.readFileSync("./src/license_header.js").toString();
const ctx = {
saveComments: false,
defines,
};
return gulp
@ -532,9 +497,7 @@ function createSandboxBundle(defines, extraOptions = undefined) {
const sandboxFileConfig = createWebpackConfig(
sandboxDefines,
{
filename: sandboxDefines.MINIFIED
? "pdf.sandbox.min.mjs"
: "pdf.sandbox.mjs",
filename: "pdf.sandbox.mjs",
library: {
type: "module",
},
@ -550,7 +513,7 @@ function createSandboxBundle(defines, extraOptions = undefined) {
function createWorkerBundle(defines) {
const workerFileConfig = createWebpackConfig(defines, {
filename: defines.MINIFIED ? "pdf.worker.min.mjs" : "pdf.worker.mjs",
filename: "pdf.worker.mjs",
library: {
type: "module",
},
@ -574,7 +537,10 @@ function createWebBundle(defines, options) {
defaultPreferencesDir: options.defaultPreferencesDir,
}
);
return gulp.src("./web/viewer.js").pipe(webpack2Stream(viewerFileConfig));
return gulp
.src("./web/viewer.js")
.pipe(webpack2Stream(viewerFileConfig))
.pipe(tweakWebpackOutput());
}
function createGVWebBundle(defines, options) {
@ -592,7 +558,8 @@ function createGVWebBundle(defines, options) {
);
return gulp
.src("./web/viewer-geckoview.js")
.pipe(webpack2Stream(viewerFileConfig));
.pipe(webpack2Stream(viewerFileConfig))
.pipe(tweakWebpackOutput());
}
function createComponentsBundle(defines) {
@ -610,9 +577,7 @@ function createComponentsBundle(defines) {
function createImageDecodersBundle(defines) {
const componentsFileConfig = createWebpackConfig(defines, {
filename: defines.MINIFIED
? "pdf.image_decoders.min.mjs"
: "pdf.image_decoders.mjs",
filename: "pdf.image_decoders.mjs",
library: {
type: "module",
},
@ -726,9 +691,6 @@ function createTestSource(testsName, { bot = false, xfaOnly = false } = {}) {
const testProcess = startNode(args, { cwd: TEST_DIR, stdio: "inherit" });
testProcess.on("close", function (code) {
if (code !== 0) {
throw new Error(`Running ${testsName} tests failed.`);
}
source.push(null);
});
return undefined;
@ -760,10 +722,6 @@ function makeRef(done, bot) {
const testProcess = startNode(args, { cwd: TEST_DIR, stdio: "inherit" });
testProcess.on("close", function (code) {
if (code !== 0) {
done(new Error("Creating reference images failed."));
return;
}
done();
});
}
@ -863,17 +821,11 @@ async function parseDefaultPreferences(dir) {
"./" + DEFAULT_PREFERENCES_DIR + dir + "app_options.mjs"
);
const browserPrefs = AppOptions.getAll(
OptionKind.BROWSER,
/* defaultOnly = */ true
);
const browserPrefs = AppOptions.getAll(OptionKind.BROWSER);
if (Object.keys(browserPrefs).length === 0) {
throw new Error("No browser preferences found.");
}
const prefs = AppOptions.getAll(
OptionKind.PREFERENCE,
/* defaultOnly = */ true
);
const prefs = AppOptions.getAll(OptionKind.PREFERENCE);
if (Object.keys(prefs).length === 0) {
throw new Error("No default preferences found.");
}
@ -1127,8 +1079,7 @@ function buildComponents(defines, dir) {
"web/images/loading-icon.gif",
"web/images/altText_*.svg",
"web/images/editor-toolbar-*.svg",
"web/images/toolbarButton-{editorHighlight,menuArrow}.svg",
"web/images/cursor-*.svg",
"web/images/toolbarButton-menuArrow.svg",
];
return merge([
@ -1218,6 +1169,68 @@ function buildMinified(defines, dir) {
]);
}
async function parseMinified(dir) {
const pdfFile = fs.readFileSync(dir + "build/pdf.mjs").toString();
const pdfWorkerFile = fs
.readFileSync(dir + "build/pdf.worker.mjs")
.toString();
const pdfSandboxFile = fs
.readFileSync(dir + "build/pdf.sandbox.mjs")
.toString();
const pdfImageDecodersFile = fs
.readFileSync(dir + "image_decoders/pdf.image_decoders.mjs")
.toString();
console.log();
console.log("### Minifying js files");
const { minify } = await import("terser");
const options = {
compress: {
// V8 chokes on very long sequences, work around that.
sequences: false,
},
keep_classnames: true,
keep_fnames: true,
module: true,
};
fs.writeFileSync(
dir + "build/pdf.min.mjs",
(await minify(pdfFile, options)).code
);
fs.writeFileSync(
dir + "build/pdf.worker.min.mjs",
(await minify(pdfWorkerFile, options)).code
);
fs.writeFileSync(
dir + "build/pdf.sandbox.min.mjs",
(await minify(pdfSandboxFile, options)).code
);
fs.writeFileSync(
dir + "image_decoders/pdf.image_decoders.min.mjs",
(await minify(pdfImageDecodersFile, options)).code
);
console.log();
console.log("### Cleaning js files");
fs.unlinkSync(dir + "build/pdf.mjs");
fs.unlinkSync(dir + "build/pdf.worker.mjs");
fs.unlinkSync(dir + "build/pdf.sandbox.mjs");
fs.renameSync(dir + "build/pdf.min.mjs", dir + "build/pdf.mjs");
fs.renameSync(dir + "build/pdf.worker.min.mjs", dir + "build/pdf.worker.mjs");
fs.renameSync(
dir + "build/pdf.sandbox.min.mjs",
dir + "build/pdf.sandbox.mjs"
);
fs.renameSync(
dir + "image_decoders/pdf.image_decoders.min.mjs",
dir + "image_decoders/pdf.image_decoders.mjs"
);
}
gulp.task(
"minified",
gulp.series(
@ -1239,6 +1252,10 @@ gulp.task(
const defines = { ...DEFINES, MINIFIED: true, GENERIC: true };
return buildMinified(defines, MINIFIED_DIR);
},
async function compressMinified(done) {
await parseMinified(MINIFIED_DIR);
done();
}
)
);
@ -1274,6 +1291,10 @@ gulp.task(
};
return buildMinified(defines, MINIFIED_LEGACY_DIR);
},
async function compressMinifiedLegacy(done) {
await parseMinified(MINIFIED_LEGACY_DIR);
done();
}
)
);
@ -1531,14 +1552,26 @@ gulp.task("types", function (done) {
});
function buildLibHelper(bundleDefines, inputStream, outputDir) {
function babelPluginReplaceNonWebpackImport(b) {
return {
visitor: {
Identifier(curPath, state) {
if (curPath.node.name === "__non_webpack_import__") {
curPath.replaceWith(b.types.identifier("import"));
}
},
},
};
}
function preprocessLib(content) {
const skipBabel = bundleDefines.SKIP_BABEL;
content = preprocessPDFJSCode(ctx, content);
content = babel.transform(content, {
sourceType: "module",
presets: skipBabel
? undefined
: [["@babel/preset-env", { loose: false, modules: false }]],
plugins: [[babelPluginPDFJSPreprocessor, ctx]],
plugins: [babelPluginReplaceNonWebpackImport],
targets: BABEL_TARGETS,
}).code;
content = content.replaceAll(
@ -1549,6 +1582,7 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) {
}
const ctx = {
rootPath: __dirname,
saveComments: false,
defines: bundleDefines,
map: {
"pdfjs-lib": "../pdf.js",
@ -1558,7 +1592,7 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) {
"display-node_utils": "./node_utils.js",
"fluent-bundle": "../../../node_modules/@fluent/bundle/esm/index.js",
"fluent-dom": "../../../node_modules/@fluent/dom/esm/index.js",
"web-null_l10n": "../web/genericl10n.js",
"web-l10n_utils": "../web/l10n_utils.js",
},
};
const licenseHeaderLibre = fs
@ -1902,7 +1936,7 @@ gulp.task(
gulp.task("lint", function (done) {
console.log();
console.log("### Linting JS/CSS/JSON files");
console.log("### Linting JS/CSS files");
// Ensure that we lint the Firefox specific *.jsm files too.
const esLintOptions = [
@ -1925,16 +1959,6 @@ gulp.task("lint", function (done) {
styleLintOptions.push("--fix");
}
const prettierOptions = [
"node_modules/prettier/bin/prettier.cjs",
"**/*.json",
];
if (process.argv.includes("--fix")) {
prettierOptions.push("--log-level", "silent", "--write");
} else {
prettierOptions.push("--log-level", "warn", "--check");
}
const esLintProcess = startNode(esLintOptions, { stdio: "inherit" });
esLintProcess.on("close", function (esLintCode) {
if (esLintCode !== 0) {
@ -1948,16 +1972,8 @@ gulp.task("lint", function (done) {
done(new Error("Stylelint failed."));
return;
}
const prettierProcess = startNode(prettierOptions, { stdio: "inherit" });
prettierProcess.on("close", function (prettierCode) {
if (prettierCode !== 0) {
done(new Error("Prettier failed."));
return;
}
console.log("files checked, no errors found");
done();
});
console.log("files checked, no errors found");
done();
});
});
});
@ -2047,7 +2063,8 @@ gulp.task(
console.log("### Starting local server");
const { WebServer } = await import("./test/webserver.mjs");
const server = new WebServer({ port: 8888 });
const server = new WebServer();
server.port = 8888;
server.start();
}
)
@ -2228,20 +2245,36 @@ gulp.task(
])
.pipe(gulp.dest(DIST_DIR + "legacy/build/")),
gulp
.src(MINIFIED_DIR + "build/{pdf,pdf.worker,pdf.sandbox}.min.mjs")
.src(MINIFIED_DIR + "build/pdf.mjs")
.pipe(rename("pdf.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "build/")),
gulp
.src(MINIFIED_DIR + "image_decoders/pdf.image_decoders.min.mjs")
.src(MINIFIED_DIR + "build/pdf.worker.mjs")
.pipe(rename("pdf.worker.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "build/")),
gulp
.src(MINIFIED_DIR + "build/pdf.sandbox.mjs")
.pipe(rename("pdf.sandbox.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "build/")),
gulp
.src(MINIFIED_DIR + "image_decoders/pdf.image_decoders.mjs")
.pipe(rename("pdf.image_decoders.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "image_decoders/")),
gulp
.src(
MINIFIED_LEGACY_DIR + "build/{pdf,pdf.worker,pdf.sandbox}.min.mjs"
)
.src(MINIFIED_LEGACY_DIR + "build/pdf.mjs")
.pipe(rename("pdf.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "legacy/build/")),
gulp
.src(
MINIFIED_LEGACY_DIR + "image_decoders/pdf.image_decoders.min.mjs"
)
.src(MINIFIED_LEGACY_DIR + "build/pdf.worker.mjs")
.pipe(rename("pdf.worker.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "legacy/build/")),
gulp
.src(MINIFIED_LEGACY_DIR + "build/pdf.sandbox.mjs")
.pipe(rename("pdf.sandbox.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "legacy/build/")),
gulp
.src(MINIFIED_LEGACY_DIR + "image_decoders/pdf.image_decoders.mjs")
.pipe(rename("pdf.image_decoders.min.mjs"))
.pipe(gulp.dest(DIST_DIR + "legacy/image_decoders/")),
gulp
.src(COMPONENTS_DIR + "**/*", { base: COMPONENTS_DIR })

View File

@ -39,24 +39,9 @@ pdfjs-open-file-button-label = افتح
pdfjs-print-button =
.title = اطبع
pdfjs-print-button-label = اطبع
pdfjs-save-button =
.title = احفظ
pdfjs-save-button-label = احفظ
# Used in Firefox for Android as a tooltip for the download button (“download” is a verb).
pdfjs-download-button =
.title = نزّل
# Used in Firefox for Android as a label for the download button (“download” is a verb).
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-download-button-label = نزّل
pdfjs-bookmark-button =
.title = الصفحة الحالية (عرض URL من الصفحة الحالية)
pdfjs-bookmark-button-label = الصفحة الحالية
# Used in Firefox for Android.
pdfjs-open-in-app-button =
.title = افتح في تطبيق
# Used in Firefox for Android.
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-open-in-app-button-label = افتح في تطبيق
## Secondary toolbar and context menu
@ -216,7 +201,6 @@ pdfjs-find-next-button =
pdfjs-find-next-button-label = التالي
pdfjs-find-highlight-checkbox = أبرِز الكل
pdfjs-find-match-case-checkbox-label = طابق حالة الأحرف
pdfjs-find-match-diacritics-checkbox-label = طابِق الحركات
pdfjs-find-entire-word-checkbox-label = كلمات كاملة
pdfjs-find-reached-top = تابعت من الأسفل بعدما وصلت إلى بداية المستند
pdfjs-find-reached-bottom = تابعت من الأعلى بعدما وصلت إلى نهاية المستند
@ -272,18 +256,9 @@ pdfjs-web-fonts-disabled = خطوط الوب مُعطّلة: تعذّر استخ
## Editing
## Remove button for the various kind of editor.
##
## Alt-text dialog
## Editor resizers
## This is used in an aria label to help to understand the role of the resizer.
## Color picker

View File

@ -303,9 +303,8 @@ pdfjs-editor-ink-button-label = Маляваць
pdfjs-editor-stamp-button =
.title = Дадаць або змяніць выявы
pdfjs-editor-stamp-button-label = Дадаць або змяніць выявы
pdfjs-editor-highlight-button =
.title = Вылучэнне
pdfjs-editor-highlight-button-label = Вылучэнне
pdfjs-editor-remove-button =
.title = Выдаліць
## Remove button for the various kind of editor.
@ -329,10 +328,6 @@ pdfjs-editor-ink-opacity-input = Непразрыстасць
pdfjs-editor-stamp-add-image-button =
.title = Дадаць выяву
pdfjs-editor-stamp-add-image-button-label = Дадаць выяву
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Таўшчыня
pdfjs-editor-free-highlight-thickness-title =
.title = Змяняць таўшчыню пры вылучэнні іншых элементаў, акрамя тэксту
pdfjs-free-text =
.aria-label = Тэкставы рэдактар
pdfjs-free-text-default-content = Пачніце набор тэксту…

View File

@ -39,24 +39,6 @@ pdfjs-open-file-button-label = Отваряне
pdfjs-print-button =
.title = Отпечатване
pdfjs-print-button-label = Отпечатване
pdfjs-save-button =
.title = Запазване
pdfjs-save-button-label = Запазване
# Used in Firefox for Android as a tooltip for the download button (“download” is a verb).
pdfjs-download-button =
.title = Изтегляне
# Used in Firefox for Android as a label for the download button (“download” is a verb).
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-download-button-label = Изтегляне
pdfjs-bookmark-button =
.title = Текуща страница (преглед на адреса на страницата)
pdfjs-bookmark-button-label = Текуща страница
# Used in Firefox for Android.
pdfjs-open-in-app-button =
.title = Отваряне в приложение
# Used in Firefox for Android.
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-open-in-app-button-label = Отваряне в приложение
## Secondary toolbar and context menu
@ -81,9 +63,6 @@ pdfjs-cursor-text-select-tool-button-label = Инструмент за избо
pdfjs-cursor-hand-tool-button =
.title = Включване на инструмента ръка
pdfjs-cursor-hand-tool-button-label = Инструмент ръка
pdfjs-scroll-page-button =
.title = Използване на плъзгане на страници
pdfjs-scroll-page-button-label = Плъзгане на страници
pdfjs-scroll-vertical-button =
.title = Използване на вертикално плъзгане
pdfjs-scroll-vertical-button-label = Вертикално плъзгане
@ -175,8 +154,6 @@ pdfjs-printing-not-ready = Внимание: Този PDF файл не е на
pdfjs-toggle-sidebar-button =
.title = Превключване на страничната лента
pdfjs-toggle-sidebar-notification-button =
.title = Превключване на страничната лента (документът има структура/прикачени файлове/слоеве)
pdfjs-toggle-sidebar-button-label = Превключване на страничната лента
pdfjs-document-outline-button =
.title = Показване на структурата на документа (двукратно щракване за свиване/разгъване на всичко)
@ -184,19 +161,12 @@ pdfjs-document-outline-button-label = Структура на документа
pdfjs-attachments-button =
.title = Показване на притурките
pdfjs-attachments-button-label = Притурки
pdfjs-layers-button =
.title = Показване на слоевете (двукратно щракване за възстановяване на всички слоеве към състоянието по подразбиране)
pdfjs-layers-button-label = Слоеве
pdfjs-thumbs-button =
.title = Показване на миниатюрите
pdfjs-thumbs-button-label = Миниатюри
pdfjs-current-outline-item-button =
.title = Намиране на текущия елемент от структурата
pdfjs-current-outline-item-button-label = Текущ елемент от структурата
pdfjs-findbar-button =
.title = Намиране в документа
pdfjs-findbar-button-label = Търсене
pdfjs-additional-layers = Допълнителни слоеве
## Thumbnails panel item (tooltip and alt text for images)
@ -222,25 +192,9 @@ pdfjs-find-next-button =
pdfjs-find-next-button-label = Следваща
pdfjs-find-highlight-checkbox = Открояване на всички
pdfjs-find-match-case-checkbox-label = Съвпадение на регистъра
pdfjs-find-match-diacritics-checkbox-label = Без производни букви
pdfjs-find-entire-word-checkbox-label = Цели думи
pdfjs-find-reached-top = Достигнато е началото на документа, продължаване от края
pdfjs-find-reached-bottom = Достигнат е краят на документа, продължаване от началото
# Variables:
# $current (Number) - the index of the currently active find result
# $total (Number) - the total number of matches in the document
pdfjs-find-match-count =
{ $total ->
[one] { $current } от { $total } съвпадение
*[other] { $current } от { $total } съвпадения
}
# Variables:
# $limit (Number) - the maximum number of matches
pdfjs-find-match-count-limit =
{ $limit ->
[one] Повече от { $limit } съвпадение
*[other] Повече от { $limit } съвпадения
}
pdfjs-find-not-found = Фразата не е намерена
## Predefined zoom values
@ -255,10 +209,6 @@ pdfjs-page-scale-percent = { $scale }%
## PDF page
# Variables:
# $page (Number) - the page number
pdfjs-page-landmark =
.aria-label = Страница { $page }
## Loading indicator messages
@ -270,10 +220,6 @@ pdfjs-rendering-error = Грешка при изчертаване на стра
## Annotations
# Variables:
# $date (Date) - the modification date of the annotation
# $time (Time) - the modification time of the annotation
pdfjs-annotation-date-string = { $date }, { $time }
# .alt: This is used as a tooltip.
# Variables:
# $type (String) - an annotation type from a list defined in the PDF spec
@ -292,93 +238,10 @@ pdfjs-web-fonts-disabled = Уеб-шрифтовете са забранени:
## Editing
pdfjs-editor-free-text-button =
.title = Текст
pdfjs-editor-free-text-button-label = Текст
pdfjs-editor-ink-button =
.title = Рисуване
pdfjs-editor-ink-button-label = Рисуване
pdfjs-editor-stamp-button =
.title = Добавяне или променяне на изображения
pdfjs-editor-stamp-button-label = Добавяне или променяне на изображения
pdfjs-editor-remove-button =
.title = Премахване
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = Премахване на рисунката
pdfjs-editor-remove-freetext-button =
.title = Премахване на текста
pdfjs-editor-remove-stamp-button =
.title = Пермахване на изображението
pdfjs-editor-remove-highlight-button =
.title = Премахване на открояването
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Цвят
pdfjs-editor-free-text-size-input = Размер
pdfjs-editor-ink-color-input = Цвят
pdfjs-editor-ink-thickness-input = Дебелина
pdfjs-editor-ink-opacity-input = Прозрачност
pdfjs-editor-stamp-add-image-button =
.title = Добавяне на изображение
pdfjs-editor-stamp-add-image-button-label = Добавяне на изображение
pdfjs-free-text =
.aria-label = Текстов редактор
pdfjs-free-text-default-content = Започнете да пишете…
pdfjs-ink =
.aria-label = Промяна на рисунка
pdfjs-ink-canvas =
.aria-label = Изображение, създадено от потребител
## Alt-text dialog
# Alternative text (alt text) helps when people can't see the image.
pdfjs-editor-alt-text-button-label = Алтернативен текст
pdfjs-editor-alt-text-edit-button-label = Промяна на алтернативния текст
pdfjs-editor-alt-text-dialog-label = Изберете от възможностите
pdfjs-editor-alt-text-dialog-description = Алтернативният текст помага на потребителите, когато не могат да видят изображението или то не се зарежда.
pdfjs-editor-alt-text-add-description-label = Добавяне на описание
pdfjs-editor-alt-text-add-description-description = Стремете се към 1-2 изречения, описващи предмета, настройката или действията.
pdfjs-editor-alt-text-mark-decorative-label = Отбелязване като декоративно
pdfjs-editor-alt-text-mark-decorative-description = Използва се за орнаменти или декоративни изображения, като контури и водни знаци.
pdfjs-editor-alt-text-cancel-button = Отказ
pdfjs-editor-alt-text-save-button = Запазване
pdfjs-editor-alt-text-decorative-tooltip = Отбелязване като декоративно
# .placeholder: This is a placeholder for the alt text input area
pdfjs-editor-alt-text-textarea =
.placeholder = Например, „Млад мъж седи на маса и се храни“
## Editor resizers
## This is used in an aria label to help to understand the role of the resizer.
pdfjs-editor-resizer-label-top-left = Горен ляв ъгъл — преоразмеряване
pdfjs-editor-resizer-label-top-middle = Горе в средата — преоразмеряване
pdfjs-editor-resizer-label-top-right = Горен десен ъгъл — преоразмеряване
pdfjs-editor-resizer-label-middle-right = Дясно в средата — преоразмеряване
pdfjs-editor-resizer-label-bottom-right = Долен десен ъгъл — преоразмеряване
pdfjs-editor-resizer-label-bottom-middle = Долу в средата — преоразмеряване
pdfjs-editor-resizer-label-bottom-left = Долен ляв ъгъл — преоразмеряване
pdfjs-editor-resizer-label-middle-left = Ляво в средата — преоразмеряване
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Цвят на открояване
pdfjs-editor-colorpicker-button =
.title = Промяна на цвят
pdfjs-editor-colorpicker-dropdown =
.aria-label = Избор на цвят
pdfjs-editor-colorpicker-yellow =
.title = Жълто
pdfjs-editor-colorpicker-green =
.title = Зелено
pdfjs-editor-colorpicker-blue =
.title = Синьо
pdfjs-editor-colorpicker-pink =
.title = Розово
pdfjs-editor-colorpicker-red =
.title = Червено

View File

@ -48,13 +48,6 @@ pdfjs-download-button =
# Used in Firefox for Android as a label for the download button (“download” is a verb).
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-download-button-label = Pellgargañ
pdfjs-bookmark-button-label = Pajenn a-vremañ
# Used in Firefox for Android.
pdfjs-open-in-app-button =
.title = Digeriñ en arload
# Used in Firefox for Android.
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-open-in-app-button-label = Digeriñ en arload
## Secondary toolbar and context menu
@ -274,9 +267,6 @@ pdfjs-editor-free-text-button-label = Testenn
pdfjs-editor-ink-button =
.title = Tresañ
pdfjs-editor-ink-button-label = Tresañ
pdfjs-editor-stamp-button =
.title = Ouzhpennañ pe aozañ skeudennoù
pdfjs-editor-stamp-button-label = Ouzhpennañ pe aozañ skeudennoù
## Remove button for the various kind of editor.
@ -287,21 +277,9 @@ pdfjs-editor-stamp-button-label = Ouzhpennañ pe aozañ skeudennoù
pdfjs-editor-free-text-color-input = Liv
pdfjs-editor-free-text-size-input = Ment
pdfjs-editor-ink-color-input = Liv
pdfjs-editor-ink-thickness-input = Tevder
pdfjs-editor-ink-opacity-input = Boullder
pdfjs-editor-stamp-add-image-button =
.title = Ouzhpennañ ur skeudenn
pdfjs-editor-stamp-add-image-button-label = Ouzhpennañ ur skeudenn
pdfjs-free-text =
.aria-label = Aozer testennoù
pdfjs-ink =
.aria-label = Aozer tresoù
pdfjs-ink-canvas =
.aria-label = Skeudenn bet krouet gant an implijer·ez
## Alt-text dialog
pdfjs-editor-alt-text-add-description-label = Ouzhpennañ un deskrivadur
pdfjs-editor-alt-text-cancel-button = Nullañ
pdfjs-editor-alt-text-save-button = Enrollañ

View File

@ -305,9 +305,8 @@ pdfjs-editor-ink-button-label = Kreslení
pdfjs-editor-stamp-button =
.title = Přidání či úprava obrázků
pdfjs-editor-stamp-button-label = Přidání či úprava obrázků
pdfjs-editor-highlight-button =
.title = Zvýraznění
pdfjs-editor-highlight-button-label = Zvýraznění
pdfjs-editor-remove-button =
.title = Odebrat
## Remove button for the various kind of editor.
@ -331,10 +330,6 @@ pdfjs-editor-ink-opacity-input = Průhlednost
pdfjs-editor-stamp-add-image-button =
.title = Přidat obrázek
pdfjs-editor-stamp-add-image-button-label = Přidat obrázek
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tloušťka
pdfjs-editor-free-highlight-thickness-title =
.title = Změna tloušťky při zvýrazňování jiných položek než textu
pdfjs-free-text =
.aria-label = Textový editor
pdfjs-free-text-default-content = Začněte psát…

View File

@ -23,11 +23,11 @@ pdfjs-of-pages = o { $pagesCount }
# $pagesCount (Number) - the total number of pages in the document
pdfjs-page-of-pages = ({ $pageNumber } o { $pagesCount })
pdfjs-zoom-out-button =
.title = Lleihau
pdfjs-zoom-out-button-label = Lleihau
.title = Chwyddo Allan
pdfjs-zoom-out-button-label = Chwyddo Allan
pdfjs-zoom-in-button =
.title = Cynyddu
pdfjs-zoom-in-button-label = Cynyddu
.title = Chwyddo Mewn
pdfjs-zoom-in-button-label = Chwyddo Mewn
pdfjs-zoom-select =
.title = Chwyddo
pdfjs-presentation-mode-button =
@ -44,10 +44,10 @@ pdfjs-save-button =
pdfjs-save-button-label = Cadw
# Used in Firefox for Android as a tooltip for the download button (“download” is a verb).
pdfjs-download-button =
.title = Llwytho i lawr
.title = Llwytho i Lawr
# Used in Firefox for Android as a label for the download button (“download” is a verb).
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-download-button-label = Llwytho i lawr
pdfjs-download-button-label = Llwytho i Lawr
pdfjs-bookmark-button =
.title = Tudalen Gyfredol (Gweld URL o'r Dudalen Gyfredol)
pdfjs-bookmark-button-label = Tudalen Gyfredol
@ -309,9 +309,8 @@ pdfjs-editor-ink-button-label = Lluniadu
pdfjs-editor-stamp-button =
.title = Ychwanegu neu olygu delweddau
pdfjs-editor-stamp-button-label = Ychwanegu neu olygu delweddau
pdfjs-editor-highlight-button =
.title = Amlygu
pdfjs-editor-highlight-button-label = Amlygu
pdfjs-editor-remove-button =
.title = Tynnu
## Remove button for the various kind of editor.
@ -335,10 +334,6 @@ pdfjs-editor-ink-opacity-input = Didreiddedd
pdfjs-editor-stamp-add-image-button =
.title = Ychwanegu delwedd
pdfjs-editor-stamp-add-image-button-label = Ychwanegu delwedd
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Trwch
pdfjs-editor-free-highlight-thickness-title =
.title = Newid trwch wrth amlygu eitemau heblaw testun
pdfjs-free-text =
.aria-label = Golygydd Testun
pdfjs-free-text-default-content = Cychwyn teipio…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Tegn
pdfjs-editor-stamp-button =
.title = Tilføj eller rediger billeder
pdfjs-editor-stamp-button-label = Tilføj eller rediger billeder
pdfjs-editor-highlight-button =
.title = Fremhæv
pdfjs-editor-highlight-button-label = Fremhæv
pdfjs-editor-remove-button =
.title = Fjern
## Remove button for the various kind of editor.
@ -313,8 +312,6 @@ pdfjs-editor-remove-freetext-button =
.title = Fjern tekst
pdfjs-editor-remove-stamp-button =
.title = Fjern billede
pdfjs-editor-remove-highlight-button =
.title = Fjern fremhævning
##
@ -327,10 +324,6 @@ pdfjs-editor-ink-opacity-input = Uigennemsigtighed
pdfjs-editor-stamp-add-image-button =
.title = Tilføj billede
pdfjs-editor-stamp-add-image-button-label = Tilføj billede
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tykkelse
pdfjs-editor-free-highlight-thickness-title =
.title = Ændr tykkelse, når andre elementer end tekst fremhæves
pdfjs-free-text =
.aria-label = Teksteditor
pdfjs-free-text-default-content = Begynd at skrive…
@ -368,22 +361,3 @@ pdfjs-editor-resizer-label-bottom-right = Nederste højre hjørne - tilpas stør
pdfjs-editor-resizer-label-bottom-middle = Nederst i midten - tilpas størrelse
pdfjs-editor-resizer-label-bottom-left = Nederste venstre hjørne - tilpas størrelse
pdfjs-editor-resizer-label-middle-left = Midten til venstre — tilpas størrelse
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Fremhævningsfarve
pdfjs-editor-colorpicker-button =
.title = Skift farve
pdfjs-editor-colorpicker-dropdown =
.aria-label = Farvevalg
pdfjs-editor-colorpicker-yellow =
.title = Gul
pdfjs-editor-colorpicker-green =
.title = Grøn
pdfjs-editor-colorpicker-blue =
.title = Blå
pdfjs-editor-colorpicker-pink =
.title = Lyserød
pdfjs-editor-colorpicker-red =
.title = Rød

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Zeichnen
pdfjs-editor-stamp-button =
.title = Grafiken hinzufügen oder bearbeiten
pdfjs-editor-stamp-button-label = Grafiken hinzufügen oder bearbeiten
pdfjs-editor-highlight-button =
.title = Hervorheben
pdfjs-editor-highlight-button-label = Hervorheben
pdfjs-editor-remove-button =
.title = Entfernen
## Remove button for the various kind of editor.
@ -322,15 +321,11 @@ pdfjs-editor-remove-highlight-button =
pdfjs-editor-free-text-color-input = Farbe
pdfjs-editor-free-text-size-input = Größe
pdfjs-editor-ink-color-input = Farbe
pdfjs-editor-ink-thickness-input = Linienstärke
pdfjs-editor-ink-thickness-input = Dicke
pdfjs-editor-ink-opacity-input = Deckkraft
pdfjs-editor-stamp-add-image-button =
.title = Grafik hinzufügen
pdfjs-editor-stamp-add-image-button-label = Grafik hinzufügen
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Linienstärke
pdfjs-editor-free-highlight-thickness-title =
.title = Linienstärke beim Hervorheben anderer Elemente als Text ändern
pdfjs-free-text =
.aria-label = Texteditor
pdfjs-free-text-default-content = Schreiben beginnen…

View File

@ -305,9 +305,8 @@ pdfjs-editor-ink-button-label = Kresliś
pdfjs-editor-stamp-button =
.title = Wobraze pśidaś abo wobźěłaś
pdfjs-editor-stamp-button-label = Wobraze pśidaś abo wobźěłaś
pdfjs-editor-highlight-button =
.title = Wuzwignuś
pdfjs-editor-highlight-button-label = Wuzwignuś
pdfjs-editor-remove-button =
.title = Wótwónoźeś
## Remove button for the various kind of editor.
@ -331,10 +330,6 @@ pdfjs-editor-ink-opacity-input = Opacita
pdfjs-editor-stamp-add-image-button =
.title = Wobraz pśidaś
pdfjs-editor-stamp-add-image-button-label = Wobraz pśidaś
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tłustosć
pdfjs-editor-free-highlight-thickness-title =
.title = Tłustosć změniś, gaž se zapiski wuzwiguju, kótarež tekst njejsu
pdfjs-free-text =
.aria-label = Tekstowy editor
pdfjs-free-text-default-content = Zachopśo pisaś…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Σχέδιο
pdfjs-editor-stamp-button =
.title = Προσθήκη ή επεξεργασία εικόνων
pdfjs-editor-stamp-button-label = Προσθήκη ή επεξεργασία εικόνων
pdfjs-editor-highlight-button =
.title = Επισήμανση
pdfjs-editor-highlight-button-label = Επισήμανση
pdfjs-editor-remove-button =
.title = Αφαίρεση
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Αδιαφάνεια
pdfjs-editor-stamp-add-image-button =
.title = Προσθήκη εικόνας
pdfjs-editor-stamp-add-image-button-label = Προσθήκη εικόνας
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Πάχος
pdfjs-editor-free-highlight-thickness-title =
.title = Αλλαγή πάχους κατά την επισήμανση στοιχείων εκτός κειμένου
pdfjs-free-text =
.aria-label = Επεξεργασία κειμένου
pdfjs-free-text-default-content = Ξεκινήστε να πληκτρολογείτε…

View File

@ -286,12 +286,6 @@ pdfjs-editor-ink-button-label = Draw
pdfjs-editor-stamp-button =
.title = Add or edit images
pdfjs-editor-stamp-button-label = Add or edit images
## Remove button for the various kind of editor.
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Colour
pdfjs-editor-free-text-size-input = Size
@ -315,22 +309,3 @@ pdfjs-ink-canvas =
## Editor resizers
## This is used in an aria label to help to understand the role of the resizer.
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Highlight colour
pdfjs-editor-colorpicker-button =
.title = Change colour
pdfjs-editor-colorpicker-dropdown =
.aria-label = Colour choices
pdfjs-editor-colorpicker-yellow =
.title = Yellow
pdfjs-editor-colorpicker-green =
.title = Green
pdfjs-editor-colorpicker-blue =
.title = Blue
pdfjs-editor-colorpicker-pink =
.title = Pink
pdfjs-editor-colorpicker-red =
.title = Red

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Draw
pdfjs-editor-stamp-button =
.title = Add or edit images
pdfjs-editor-stamp-button-label = Add or edit images
pdfjs-editor-highlight-button =
.title = Highlight
pdfjs-editor-highlight-button-label = Highlight
pdfjs-editor-remove-button =
.title = Remove
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacity
pdfjs-editor-stamp-add-image-button =
.title = Add image
pdfjs-editor-stamp-add-image-button-label = Add image
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Thickness
pdfjs-editor-free-highlight-thickness-title =
.title = Change thickness when highlighting items other than text
pdfjs-free-text =
.aria-label = Text Editor
pdfjs-free-text-default-content = Start typing…

View File

@ -58,6 +58,14 @@ pdfjs-bookmark-button =
.title = Current Page (View URL from Current Page)
pdfjs-bookmark-button-label = Current Page
# Used in Firefox for Android.
pdfjs-open-in-app-button =
.title = Open in app
# Used in Firefox for Android.
# Length of the translation matters since we are in a mobile context, with limited screen estate.
pdfjs-open-in-app-button-label = Open in app
## Secondary toolbar and context menu
pdfjs-tools-button =
@ -318,8 +326,6 @@ pdfjs-editor-stamp-button-label = Add or edit images
pdfjs-editor-highlight-button =
.title = Highlight
pdfjs-editor-highlight-button-label = Highlight
pdfjs-highlight-floating-button =
.title = Highlight
## Remove button for the various kind of editor.
@ -343,10 +349,6 @@ pdfjs-editor-ink-opacity-input = Opacity
pdfjs-editor-stamp-add-image-button =
.title = Add image
pdfjs-editor-stamp-add-image-button-label = Add image
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Thickness
pdfjs-editor-free-highlight-thickness-title =
.title = Change thickness when highlighting items other than text
pdfjs-free-text =
.aria-label = Text Editor
@ -407,10 +409,3 @@ pdfjs-editor-colorpicker-pink =
.title = Pink
pdfjs-editor-colorpicker-red =
.title = Red
## Show all highlights
## This is a toggle button to show/hide all the highlights.
pdfjs-editor-highlight-show-all-button-label = Show all
pdfjs-editor-highlight-show-all-button =
.title = Show all

View File

@ -301,23 +301,6 @@ pdfjs-editor-ink-button-label = Desegni
pdfjs-editor-stamp-button =
.title = Aldoni aŭ modifi bildojn
pdfjs-editor-stamp-button-label = Aldoni aŭ modifi bildojn
pdfjs-editor-highlight-button =
.title = Elstarigi
pdfjs-editor-highlight-button-label = Elstarigi
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = Forigi desegnon
pdfjs-editor-remove-freetext-button =
.title = Forigi tekston
pdfjs-editor-remove-stamp-button =
.title = Forigi bildon
pdfjs-editor-remove-highlight-button =
.title = Forigi elstaraĵon
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Koloro
pdfjs-editor-free-text-size-input = Grando
@ -327,10 +310,6 @@ pdfjs-editor-ink-opacity-input = Maldiafaneco
pdfjs-editor-stamp-add-image-button =
.title = Aldoni bildon
pdfjs-editor-stamp-add-image-button-label = Aldoni bildon
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Dikeco
pdfjs-editor-free-highlight-thickness-title =
.title = Ŝanĝi dikecon dum elstarigo de netekstaj elementoj
pdfjs-free-text =
.aria-label = Tekstan redaktilon
pdfjs-free-text-default-content = Ektajpi…
@ -368,22 +347,3 @@ pdfjs-editor-resizer-label-bottom-right = Malsupra deksta angulo — ŝanĝi gra
pdfjs-editor-resizer-label-bottom-middle = Malsupra mezo — ŝanĝi grandon
pdfjs-editor-resizer-label-bottom-left = Malsupra maldekstra angulo — ŝanĝi grandon
pdfjs-editor-resizer-label-middle-left = Maldekstra mezo — ŝanĝi grandon
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Elstarigi koloron
pdfjs-editor-colorpicker-button =
.title = Ŝanĝi koloron
pdfjs-editor-colorpicker-dropdown =
.aria-label = Elekto de koloroj
pdfjs-editor-colorpicker-yellow =
.title = Flava
pdfjs-editor-colorpicker-green =
.title = Verda
pdfjs-editor-colorpicker-blue =
.title = Blua
pdfjs-editor-colorpicker-pink =
.title = Roza
pdfjs-editor-colorpicker-red =
.title = Ruĝa

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Dibujar
pdfjs-editor-stamp-button =
.title = Agregar o editar imágenes
pdfjs-editor-stamp-button-label = Agregar o editar imágenes
pdfjs-editor-highlight-button =
.title = Resaltar
pdfjs-editor-highlight-button-label = Resaltar
pdfjs-editor-remove-button =
.title = Eliminar
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacidad
pdfjs-editor-stamp-add-image-button =
.title = Agregar una imagen
pdfjs-editor-stamp-add-image-button-label = Agregar una imagen
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grosor
pdfjs-editor-free-highlight-thickness-title =
.title = Cambiar el grosor al resaltar elementos que no sean texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Empezar a tipear…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Dibujar
pdfjs-editor-stamp-button =
.title = Añadir o editar imágenes
pdfjs-editor-stamp-button-label = Añadir o editar imágenes
pdfjs-editor-highlight-button =
.title = Destacar
pdfjs-editor-highlight-button-label = Destacar
pdfjs-editor-remove-button =
.title = Eliminar
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacidad
pdfjs-editor-stamp-add-image-button =
.title = Añadir imagen
pdfjs-editor-stamp-add-image-button-label = Añadir imagen
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grosor
pdfjs-editor-free-highlight-thickness-title =
.title = Cambia el grosor al resaltar elementos que no sean texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Empieza a escribir…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Dibujar
pdfjs-editor-stamp-button =
.title = Añadir o editar imágenes
pdfjs-editor-stamp-button-label = Añadir o editar imágenes
pdfjs-editor-highlight-button =
.title = Resaltar
pdfjs-editor-highlight-button-label = Resaltar
pdfjs-editor-remove-button =
.title = Eliminar
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacidad
pdfjs-editor-stamp-add-image-button =
.title = Añadir imagen
pdfjs-editor-stamp-add-image-button-label = Añadir imagen
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grosor
pdfjs-editor-free-highlight-thickness-title =
.title = Cambiar el grosor al resaltar elementos que no sean texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Empezar a escribir…

View File

@ -301,23 +301,6 @@ pdfjs-editor-ink-button-label = Marrazkia
pdfjs-editor-stamp-button =
.title = Gehitu edo editatu irudiak
pdfjs-editor-stamp-button-label = Gehitu edo editatu irudiak
pdfjs-editor-highlight-button =
.title = Nabarmendu
pdfjs-editor-highlight-button-label = Nabarmendu
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = Kendu marrazkia
pdfjs-editor-remove-freetext-button =
.title = Kendu testua
pdfjs-editor-remove-stamp-button =
.title = Kendu irudia
pdfjs-editor-remove-highlight-button =
.title = Kendu nabarmentzea
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Kolorea
pdfjs-editor-free-text-size-input = Tamaina
@ -327,10 +310,6 @@ pdfjs-editor-ink-opacity-input = Opakutasuna
pdfjs-editor-stamp-add-image-button =
.title = Gehitu irudia
pdfjs-editor-stamp-add-image-button-label = Gehitu irudia
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Loditasuna
pdfjs-editor-free-highlight-thickness-title =
.title = Aldatu loditasuna testua ez beste elementuak nabarmentzean
pdfjs-free-text =
.aria-label = Testu-editorea
pdfjs-free-text-default-content = Hasi idazten…
@ -368,22 +347,3 @@ pdfjs-editor-resizer-label-bottom-right = Beheko eskuineko izkina — aldatu tam
pdfjs-editor-resizer-label-bottom-middle = Behean erdian — aldatu tamaina
pdfjs-editor-resizer-label-bottom-left = Beheko ezkerreko izkina — aldatu tamaina
pdfjs-editor-resizer-label-middle-left = Erdian ezkerrean — aldatu tamaina
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Nabarmentze kolorea
pdfjs-editor-colorpicker-button =
.title = Aldatu kolorea
pdfjs-editor-colorpicker-dropdown =
.aria-label = Kolore-aukerak
pdfjs-editor-colorpicker-yellow =
.title = Horia
pdfjs-editor-colorpicker-green =
.title = Berdea
pdfjs-editor-colorpicker-blue =
.title = Urdina
pdfjs-editor-colorpicker-pink =
.title = Arrosa
pdfjs-editor-colorpicker-red =
.title = Gorria

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Piirros
pdfjs-editor-stamp-button =
.title = Lisää tai muokkaa kuvia
pdfjs-editor-stamp-button-label = Lisää tai muokkaa kuvia
pdfjs-editor-highlight-button =
.title = Korostus
pdfjs-editor-highlight-button-label = Korostus
pdfjs-editor-remove-button =
.title = Poista
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Peittävyys
pdfjs-editor-stamp-add-image-button =
.title = Lisää kuva
pdfjs-editor-stamp-add-image-button-label = Lisää kuva
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Paksuus
pdfjs-editor-free-highlight-thickness-title =
.title = Muuta paksuutta korostaessasi muita kohteita kuin tekstiä
pdfjs-free-text =
.aria-label = Tekstimuokkain
pdfjs-free-text-default-content = Aloita kirjoittaminen…

View File

@ -297,9 +297,8 @@ pdfjs-editor-ink-button-label = Dessiner
pdfjs-editor-stamp-button =
.title = Ajouter ou modifier des images
pdfjs-editor-stamp-button-label = Ajouter ou modifier des images
pdfjs-editor-highlight-button =
.title = Surligner
pdfjs-editor-highlight-button-label = Surligner
pdfjs-editor-remove-button =
.title = Supprimer
## Remove button for the various kind of editor.
@ -323,8 +322,6 @@ pdfjs-editor-ink-opacity-input = Opacité
pdfjs-editor-stamp-add-image-button =
.title = Ajouter une image
pdfjs-editor-stamp-add-image-button-label = Ajouter une image
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Épaisseur
pdfjs-free-text =
.aria-label = Éditeur de texte
pdfjs-free-text-default-content = Commencer à écrire…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Dissen
pdfjs-editor-stamp-button =
.title = Zonte o modifiche imagjins
pdfjs-editor-stamp-button-label = Zonte o modifiche imagjins
pdfjs-editor-highlight-button =
.title = Evidenzie
pdfjs-editor-highlight-button-label = Evidenzie
pdfjs-editor-remove-button =
.title = Gjave
## Remove button for the various kind of editor.
@ -313,8 +312,6 @@ pdfjs-editor-remove-freetext-button =
.title = Gjave test
pdfjs-editor-remove-stamp-button =
.title = Gjave imagjin
pdfjs-editor-remove-highlight-button =
.title = Gjave evidenziazion
##
@ -327,10 +324,6 @@ pdfjs-editor-ink-opacity-input = Opacitât
pdfjs-editor-stamp-add-image-button =
.title = Zonte imagjin
pdfjs-editor-stamp-add-image-button-label = Zonte imagjin
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Spessôr
pdfjs-editor-free-highlight-thickness-title =
.title = Modifiche il spessôr de selezion pai elements che no son testuâi
pdfjs-free-text =
.aria-label = Editôr di test
pdfjs-free-text-default-content = Scomence a scrivi…
@ -368,22 +361,3 @@ pdfjs-editor-resizer-label-bottom-right = Cjanton in bas a diestre — ridimensi
pdfjs-editor-resizer-label-bottom-middle = Bande inferiôr tal mieç — ridimensione
pdfjs-editor-resizer-label-bottom-left = Cjanton in bas a çampe — ridimensione
pdfjs-editor-resizer-label-middle-left = Bande di çampe tal mieç — ridimensione
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Colôr par evidenziâ
pdfjs-editor-colorpicker-button =
.title = Cambie colôr
pdfjs-editor-colorpicker-dropdown =
.aria-label = Sieltis di colôr
pdfjs-editor-colorpicker-yellow =
.title = Zâl
pdfjs-editor-colorpicker-green =
.title = Vert
pdfjs-editor-colorpicker-blue =
.title = Blu
pdfjs-editor-colorpicker-pink =
.title = Rose
pdfjs-editor-colorpicker-red =
.title = Ros

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Tekenje
pdfjs-editor-stamp-button =
.title = Ofbyldingen tafoegje of bewurkje
pdfjs-editor-stamp-button-label = Ofbyldingen tafoegje of bewurkje
pdfjs-editor-highlight-button =
.title = Markearje
pdfjs-editor-highlight-button-label = Markearje
pdfjs-editor-remove-button =
.title = Fuortsmite
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Transparânsje
pdfjs-editor-stamp-add-image-button =
.title = Ofbylding tafoegje
pdfjs-editor-stamp-add-image-button-label = Ofbylding tafoegje
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tsjokte
pdfjs-editor-free-highlight-thickness-title =
.title = Tsjokte wizigje by aksintuearring fan oare items as tekst
pdfjs-free-text =
.aria-label = Tekstbewurker
pdfjs-free-text-default-content = Begjin mei typen…

View File

@ -301,18 +301,6 @@ pdfjs-editor-ink-button-label = Debuxo
pdfjs-editor-stamp-button =
.title = Engadir ou editar imaxes
pdfjs-editor-stamp-button-label = Engadir ou editar imaxes
## Remove button for the various kind of editor.
pdfjs-editor-remove-freetext-button =
.title = Eliminar o texto
pdfjs-editor-remove-stamp-button =
.title = Eliminar a imaxe
pdfjs-editor-remove-highlight-button =
.title = Eliminar o resaltado
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Cor
pdfjs-editor-free-text-size-input = Tamaño
@ -322,8 +310,6 @@ pdfjs-editor-ink-opacity-input = Opacidade
pdfjs-editor-stamp-add-image-button =
.title = Engadir imaxe
pdfjs-editor-stamp-add-image-button-label = Engadir imaxe
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grosor
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Comezar a teclear…
@ -359,6 +345,3 @@ pdfjs-editor-resizer-label-bottom-right = Esquina inferior dereita: cambia o tam
pdfjs-editor-resizer-label-bottom-middle = Abaixo medio: cambia o tamaño
pdfjs-editor-resizer-label-bottom-left = Esquina inferior esquerda: cambia o tamaño
pdfjs-editor-resizer-label-middle-left = Medio esquerdo: cambia o tamaño
## Color picker

View File

@ -303,9 +303,6 @@ pdfjs-editor-stamp-button =
pdfjs-editor-stamp-button-label = Embojuaju térã embosakoi taãnga
pdfjs-editor-remove-button =
.title = Mboguete
pdfjs-editor-highlight-button =
.title = Mbosay
pdfjs-editor-highlight-button-label = Mbosay
## Remove button for the various kind of editor.

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = ציור
pdfjs-editor-stamp-button =
.title = הוספה או עריכת תמונות
pdfjs-editor-stamp-button-label = הוספה או עריכת תמונות
pdfjs-editor-highlight-button =
.title = סימון
pdfjs-editor-highlight-button-label = סימון
pdfjs-editor-remove-button =
.title = הסרה
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = אטימות
pdfjs-editor-stamp-add-image-button =
.title = הוספת תמונה
pdfjs-editor-stamp-add-image-button-label = הוספת תמונה
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = עובי
pdfjs-editor-free-highlight-thickness-title =
.title = שינוי עובי בעת הדגשת פריטים שאינם טקסט
pdfjs-free-text =
.aria-label = עורך טקסט
pdfjs-free-text-default-content = להתחיל להקליד…

View File

@ -305,9 +305,8 @@ pdfjs-editor-ink-button-label = Rysować
pdfjs-editor-stamp-button =
.title = Wobrazy přidać abo wobdźěłać
pdfjs-editor-stamp-button-label = Wobrazy přidać abo wobdźěłać
pdfjs-editor-highlight-button =
.title = Wuzběhnyć
pdfjs-editor-highlight-button-label = Wuzběhnyć
pdfjs-editor-remove-button =
.title = Wotstronić
## Remove button for the various kind of editor.
@ -331,10 +330,6 @@ pdfjs-editor-ink-opacity-input = Opacita
pdfjs-editor-stamp-add-image-button =
.title = Wobraz přidać
pdfjs-editor-stamp-add-image-button-label = Wobraz přidać
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tołstosć
pdfjs-editor-free-highlight-thickness-title =
.title = Tołstosć změnić, hdyž so zapiski wuzběhuja, kotrež tekst njejsu
pdfjs-free-text =
.aria-label = Tekstowy editor
pdfjs-free-text-default-content = Započńće pisać…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Rajzolás
pdfjs-editor-stamp-button =
.title = Képek hozzáadása vagy szerkesztése
pdfjs-editor-stamp-button-label = Képek hozzáadása vagy szerkesztése
pdfjs-editor-highlight-button =
.title = Kiemelés
pdfjs-editor-highlight-button-label = Kiemelés
pdfjs-editor-remove-button =
.title = Eltávolítás
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Átlátszatlanság
pdfjs-editor-stamp-add-image-button =
.title = Kép hozzáadása
pdfjs-editor-stamp-add-image-button-label = Kép hozzáadása
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Vastagság
pdfjs-editor-free-highlight-thickness-title =
.title = Vastagság módosítása, ha nem szöveges elemeket emel ki
pdfjs-free-text =
.aria-label = Szövegszerkesztő
pdfjs-free-text-default-content = Kezdjen el gépelni…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Designar
pdfjs-editor-stamp-button =
.title = Adder o rediger imagines
pdfjs-editor-stamp-button-label = Adder o rediger imagines
pdfjs-editor-highlight-button =
.title = Evidentia
pdfjs-editor-highlight-button-label = Evidentia
pdfjs-editor-remove-button =
.title = Remover
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacitate
pdfjs-editor-stamp-add-image-button =
.title = Adder imagine
pdfjs-editor-stamp-add-image-button-label = Adder imagine
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Spissor
pdfjs-editor-free-highlight-thickness-title =
.title = Cambiar spissor evidentiante elementos differente de texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Comenciar a scriber…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Teikna
pdfjs-editor-stamp-button =
.title = Bæta við eða breyta myndum
pdfjs-editor-stamp-button-label = Bæta við eða breyta myndum
pdfjs-editor-highlight-button =
.title = Áherslulita
pdfjs-editor-highlight-button-label = Áherslulita
pdfjs-editor-remove-button =
.title = Fjarlægja
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Ógegnsæi
pdfjs-editor-stamp-add-image-button =
.title = Bæta við mynd
pdfjs-editor-stamp-add-image-button-label = Bæta við mynd
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Þykkt
pdfjs-editor-free-highlight-thickness-title =
.title = Breyta þykkt við áherslulitun annarra atriða en texta
pdfjs-free-text =
.aria-label = Textaritill
pdfjs-free-text-default-content = Byrjaðu að skrifa…

View File

@ -304,9 +304,6 @@ pdfjs-editor-ink-button-label = Disegno
pdfjs-editor-stamp-button =
.title = Aggiungi o rimuovi immagine
pdfjs-editor-stamp-button-label = Aggiungi o rimuovi immagine
pdfjs-editor-highlight-button =
.title = Evidenzia
pdfjs-editor-highlight-button-label = Evidenzia
## Remove button for the various kind of editor.
@ -321,6 +318,8 @@ pdfjs-editor-remove-highlight-button =
##
pdfjs-editor-remove-button =
.title = Rimuovi
# Editor Parameters
pdfjs-editor-free-text-color-input = Colore
pdfjs-editor-free-text-size-input = Dimensione
@ -330,11 +329,6 @@ pdfjs-editor-ink-opacity-input = Opacità
pdfjs-editor-stamp-add-image-button =
.title = Aggiungi immagine
pdfjs-editor-stamp-add-image-button-label = Aggiungi immagine
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Spessore
pdfjs-editor-free-highlight-thickness-title =
.title = Modifica lo spessore della selezione per elementi non testuali
pdfjs-free-text =
.aria-label = Editor di testo
pdfjs-free-text-default-content = Inizia a digitare…
@ -392,3 +386,4 @@ pdfjs-editor-colorpicker-pink =
.title = Rosa
pdfjs-editor-colorpicker-red =
.title = Rosso

View File

@ -293,17 +293,16 @@ pdfjs-web-fonts-disabled = ウェブフォントが無効になっています:
## Editing
pdfjs-editor-free-text-button =
.title = フリーテキスト注釈を追加します
.title = フリーテキスト注釈
pdfjs-editor-free-text-button-label = フリーテキスト注釈
pdfjs-editor-ink-button =
.title = インク注釈を追加します
.title = インク注釈
pdfjs-editor-ink-button-label = インク注釈
pdfjs-editor-stamp-button =
.title = 画像を追加または編集します
pdfjs-editor-stamp-button-label = 画像を追加または編集
pdfjs-editor-highlight-button =
.title = 強調します
pdfjs-editor-highlight-button-label = 強調
pdfjs-editor-remove-button =
.title = 削除
## Remove button for the various kind of editor.
@ -313,8 +312,6 @@ pdfjs-editor-remove-freetext-button =
.title = テキストを削除します
pdfjs-editor-remove-stamp-button =
.title = 画像を削除します
pdfjs-editor-remove-highlight-button =
.title = 強調を削除します
##
@ -327,10 +324,6 @@ pdfjs-editor-ink-opacity-input = 不透明度
pdfjs-editor-stamp-add-image-button =
.title = 画像を追加します
pdfjs-editor-stamp-add-image-button-label = 画像を追加
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = 太さ
pdfjs-editor-free-highlight-thickness-title =
.title = テキスト以外のアイテムを強調する時の太さを変更します
pdfjs-free-text =
.aria-label = フリーテキスト注釈エディター
pdfjs-free-text-default-content = テキストを入力してください...
@ -368,22 +361,3 @@ pdfjs-editor-resizer-label-bottom-right = 右下隅 — サイズ変更
pdfjs-editor-resizer-label-bottom-middle = 下中央 — サイズ変更
pdfjs-editor-resizer-label-bottom-left = 左下隅 — サイズ変更
pdfjs-editor-resizer-label-middle-left = 左中央 — サイズ変更
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = 強調色
pdfjs-editor-colorpicker-button =
.title = 色を変更します
pdfjs-editor-colorpicker-dropdown =
.aria-label = 色の選択
pdfjs-editor-colorpicker-yellow =
.title = 黄色
pdfjs-editor-colorpicker-green =
.title = 緑色
pdfjs-editor-colorpicker-blue =
.title = 青色
pdfjs-editor-colorpicker-pink =
.title = ピンク色
pdfjs-editor-colorpicker-red =
.title = 赤色

View File

@ -220,7 +220,7 @@ pdfjs-find-previous-button-label = წინა
pdfjs-find-next-button =
.title = ფრაზის შემდეგი კონტექსტის პოვნა
pdfjs-find-next-button-label = შემდეგი
pdfjs-find-highlight-checkbox = ყველაფრის მონიშვნა
pdfjs-find-highlight-checkbox = ყველას მონიშვნა
pdfjs-find-match-case-checkbox-label = მთავრულით
pdfjs-find-match-diacritics-checkbox-label = ნიშნებით
pdfjs-find-entire-word-checkbox-label = მთლიანი სიტყვები
@ -303,23 +303,6 @@ pdfjs-editor-stamp-button =
pdfjs-editor-stamp-button-label = სურათების დართვა ან ჩასწორება
pdfjs-editor-remove-button =
.title = მოცილება
pdfjs-editor-highlight-button =
.title = მონიშვნა
pdfjs-editor-highlight-button-label = მონიშვნა
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = დახაზულის მოცილება
pdfjs-editor-remove-freetext-button =
.title = წარწერის მოცილება
pdfjs-editor-remove-stamp-button =
.title = სურათის მოცილება
pdfjs-editor-remove-highlight-button =
.title = მონიშვნის მოცილება
##
# Editor Parameters
pdfjs-editor-free-text-color-input = ფერი
pdfjs-editor-free-text-size-input = ზომა
@ -333,24 +316,24 @@ pdfjs-free-text =
.aria-label = ნაწერის ჩასწორება
pdfjs-free-text-default-content = აკრიფეთ…
pdfjs-ink =
.aria-label = დახაზულის შესწორება
.aria-label = ნახატის ჩასწორება
pdfjs-ink-canvas =
.aria-label = მომხმარებლის შექმნილი სურათი
## Alt-text dialog
# Alternative text (alt text) helps when people can't see the image.
pdfjs-editor-alt-text-button-label = თანდართული წარწერა
pdfjs-editor-alt-text-edit-button-label = თანდართული წარწერის ჩასწორება
pdfjs-editor-alt-text-button-label = დართული წარწერა
pdfjs-editor-alt-text-edit-button-label = დართული წარწერის ჩასწორება
pdfjs-editor-alt-text-dialog-label = არჩევა
pdfjs-editor-alt-text-dialog-description = თანდართული (შემნაცვლებელი) წარწერა გამოსადეგია მათთვის, ვინც ვერ ხედავს სურათებს ან გამოისახება მაშინ, როცა სურათი ვერ ჩაიტვირთება.
pdfjs-editor-alt-text-add-description-label = აღწერილობის მითითება
pdfjs-editor-alt-text-dialog-description = დართული წარწერა (შემნაცვლებელი ტექსტი) გამოსადეგია მათთვის, ვინც ვერ ხედავს სურათებს ან როცა სურათი ვერ იტვირთება.
pdfjs-editor-alt-text-add-description-label = აღწერილობის დამატება
pdfjs-editor-alt-text-add-description-description = განკუთვნილია 1-2 წინადადებით საგნის, მახასიათებლის ან მოქმედების აღსაწერად.
pdfjs-editor-alt-text-mark-decorative-label = მოინიშნოს მორთულობად
pdfjs-editor-alt-text-mark-decorative-description = განკუთვნილია შესამკობი სურათებისთვის, გარსშემოსავლები ჩარჩოებისა და ჭვირნიშნებისთვის.
pdfjs-editor-alt-text-mark-decorative-label = მოინიშნოს მოსართავად
pdfjs-editor-alt-text-mark-decorative-description = გამოიყენება შესამკობი სურათებისთვის, გარსშემოსავლები ჩარჩოებისა და ჭვირნიშნებისთვის.
pdfjs-editor-alt-text-cancel-button = გაუქმება
pdfjs-editor-alt-text-save-button = შენახვა
pdfjs-editor-alt-text-decorative-tooltip = მოინიშნოს მორთულობად
pdfjs-editor-alt-text-decorative-tooltip = მოინიშნოს მოსართავად
# .placeholder: This is a placeholder for the alt text input area
pdfjs-editor-alt-text-textarea =
.placeholder = მაგალითად, „ახალგაზრდა მამაკაცი მაგიდასთან ზის და სადილობს“
@ -366,22 +349,3 @@ pdfjs-editor-resizer-label-bottom-right = ქვევით მარჯვნ
pdfjs-editor-resizer-label-bottom-middle = ქვევით შუაში — ზომაცვლა
pdfjs-editor-resizer-label-bottom-left = ზვევით მარცხნივ — ზომაცვლა
pdfjs-editor-resizer-label-middle-left = შუაში მარცხნივ — ზომაცვლა
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = მოსანიშნი ფერი
pdfjs-editor-colorpicker-button =
.title = ფერის შეცვლა
pdfjs-editor-colorpicker-dropdown =
.aria-label = ფერის არჩევა
pdfjs-editor-colorpicker-yellow =
.title = ყვითელი
pdfjs-editor-colorpicker-green =
.title = მწვანე
pdfjs-editor-colorpicker-blue =
.title = ლურჯი
pdfjs-editor-colorpicker-pink =
.title = ვარდისფერი
pdfjs-editor-colorpicker-red =
.title = წითელი

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Сурет салу
pdfjs-editor-stamp-button =
.title = Суреттерді қосу немесе түзету
pdfjs-editor-stamp-button-label = Суреттерді қосу немесе түзету
pdfjs-editor-highlight-button =
.title = Ерекшелеу
pdfjs-editor-highlight-button-label = Ерекшелеу
pdfjs-editor-remove-button =
.title = Өшіру
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Мөлдірсіздігі
pdfjs-editor-stamp-add-image-button =
.title = Суретті қосу
pdfjs-editor-stamp-add-image-button-label = Суретті қосу
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Қалыңдығы
pdfjs-editor-free-highlight-thickness-title =
.title = Мәтіннен басқа элементтерді ерекшелеу кезінде қалыңдықты өзгерту
pdfjs-free-text =
.aria-label = Мәтін түзеткіші
pdfjs-free-text-default-content = Теруді бастау…

View File

@ -293,9 +293,8 @@ pdfjs-editor-ink-button-label = 그리기
pdfjs-editor-stamp-button =
.title = 이미지 추가 또는 편집
pdfjs-editor-stamp-button-label = 이미지 추가 또는 편집
pdfjs-editor-highlight-button =
.title = 강조
pdfjs-editor-highlight-button-label = 강조
pdfjs-editor-remove-button =
.title = 제거
## Remove button for the various kind of editor.
@ -319,10 +318,6 @@ pdfjs-editor-ink-opacity-input = 불투명도
pdfjs-editor-stamp-add-image-button =
.title = 이미지 추가
pdfjs-editor-stamp-add-image-button-label = 이미지 추가
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = 두께
pdfjs-editor-free-highlight-thickness-title =
.title = 텍스트 이외의 항목을 강조 표시할 때 두께 변경
pdfjs-free-text =
.aria-label = 텍스트 편집기
pdfjs-free-text-default-content = 입력하세요…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Tegn
pdfjs-editor-stamp-button =
.title = Legg til eller rediger bilder
pdfjs-editor-stamp-button-label = Legg til eller rediger bilder
pdfjs-editor-highlight-button =
.title = Markere
pdfjs-editor-highlight-button-label = Markere
pdfjs-editor-remove-button =
.title = Fjern
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Ugjennomsiktighet
pdfjs-editor-stamp-add-image-button =
.title = Legg til bilde
pdfjs-editor-stamp-add-image-button-label = Legg til bilde
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tykkelse
pdfjs-editor-free-highlight-thickness-title =
.title = Endre tykkelse når du markerer andre elementer enn tekst
pdfjs-free-text =
.aria-label = Tekstredigering
pdfjs-free-text-default-content = Begynn å skrive…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Tekenen
pdfjs-editor-stamp-button =
.title = Afbeeldingen toevoegen of bewerken
pdfjs-editor-stamp-button-label = Afbeeldingen toevoegen of bewerken
pdfjs-editor-highlight-button =
.title = Markeren
pdfjs-editor-highlight-button-label = Markeren
pdfjs-editor-remove-button =
.title = Verwijderen
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opaciteit
pdfjs-editor-stamp-add-image-button =
.title = Afbeelding toevoegen
pdfjs-editor-stamp-add-image-button-label = Afbeelding toevoegen
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Dikte
pdfjs-editor-free-highlight-thickness-title =
.title = Dikte wijzigen bij accentuering van andere items dan tekst
pdfjs-free-text =
.aria-label = Tekstbewerker
pdfjs-free-text-default-content = Begin met typen…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = ਵਾਹੋ
pdfjs-editor-stamp-button =
.title = ਚਿੱਤਰ ਜੋੜੋ ਜਾਂ ਸੋਧੋ
pdfjs-editor-stamp-button-label = ਚਿੱਤਰ ਜੋੜੋ ਜਾਂ ਸੋਧੋ
pdfjs-editor-highlight-button =
.title = ਹਾਈਲਾਈਟ
pdfjs-editor-highlight-button-label = ਹਾਈਲਾਈਟ
pdfjs-editor-remove-button =
.title = ਹਟਾਓ
## Remove button for the various kind of editor.
@ -313,8 +312,6 @@ pdfjs-editor-remove-freetext-button =
.title = ਲਿਖਤ ਨੂੰ ਹਟਾਓ
pdfjs-editor-remove-stamp-button =
.title = ਚਿੱਤਰ ਨੂੰ ਹਟਾਓ
pdfjs-editor-remove-highlight-button =
.title = ਹਾਈਲਾਈਟ ਨੂੰ ਹਟਾਓ
##
@ -327,8 +324,6 @@ pdfjs-editor-ink-opacity-input = ਧੁੰਦਲਾਪਨ
pdfjs-editor-stamp-add-image-button =
.title = ਚਿੱਤਰ ਜੋੜੋ
pdfjs-editor-stamp-add-image-button-label = ਚਿੱਤਰ ਜੋੜੋ
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = ਮੋਟਾਈ
pdfjs-free-text =
.aria-label = ਲਿਖਤ ਐਡੀਟਰ
pdfjs-free-text-default-content = …ਲਿਖਣਾ ਸ਼ੁਰੂ ਕਰੋ
@ -366,22 +361,3 @@ pdfjs-editor-resizer-label-bottom-right = ਹੇਠਾਂ ਸੱਜਾ ਕੋਨ
pdfjs-editor-resizer-label-bottom-middle = ਹੇਠਾਂ ਮੱਧ — ਮੁੜ-ਆਕਾਰ ਕਰੋ
pdfjs-editor-resizer-label-bottom-left = ਹੇਠਾਂ ਖੱਬਾ ਕੋਨਾ — ਮੁੜ-ਆਕਾਰ ਕਰੋ
pdfjs-editor-resizer-label-middle-left = ਮੱਧ ਖੱਬਾ — ਮੁੜ-ਆਕਾਰ ਕਰੋ
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = ਹਾਈਟਲਾਈਟ ਦਾ ਰੰਗ
pdfjs-editor-colorpicker-button =
.title = ਰੰਗ ਨੂੰ ਬਦਲੋ
pdfjs-editor-colorpicker-dropdown =
.aria-label = ਰੰਗ ਚੋਣਾਂ
pdfjs-editor-colorpicker-yellow =
.title = ਪੀਲਾ
pdfjs-editor-colorpicker-green =
.title = ਹਰਾ
pdfjs-editor-colorpicker-blue =
.title = ਨੀਲਾ
pdfjs-editor-colorpicker-pink =
.title = ਗੁਲਾਬੀ
pdfjs-editor-colorpicker-red =
.title = ਲਾਲ

View File

@ -303,9 +303,8 @@ pdfjs-editor-ink-button-label = Rysunek
pdfjs-editor-stamp-button =
.title = Dodaj lub edytuj obrazy
pdfjs-editor-stamp-button-label = Dodaj lub edytuj obrazy
pdfjs-editor-highlight-button =
.title = Wyróżnij
pdfjs-editor-highlight-button-label = Wyróżnij
pdfjs-editor-remove-button =
.title = Usuń
## Remove button for the various kind of editor.
@ -329,10 +328,6 @@ pdfjs-editor-ink-opacity-input = Nieprzezroczystość
pdfjs-editor-stamp-add-image-button =
.title = Dodaj obraz
pdfjs-editor-stamp-add-image-button-label = Dodaj obraz
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grubość
pdfjs-editor-free-highlight-thickness-title =
.title = Zmień grubość podczas wyróżniania elementów innych niż tekst
pdfjs-free-text =
.aria-label = Edytor tekstu
pdfjs-free-text-default-content = Zacznij pisać…

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Desenho
pdfjs-editor-stamp-button =
.title = Adicionar ou editar imagens
pdfjs-editor-stamp-button-label = Adicionar ou editar imagens
pdfjs-editor-highlight-button =
.title = Destaque
pdfjs-editor-highlight-button-label = Destaque
pdfjs-editor-remove-button =
.title = Remover
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacidade
pdfjs-editor-stamp-add-image-button =
.title = Adicionar imagem
pdfjs-editor-stamp-add-image-button-label = Adicionar imagem
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Espessura
pdfjs-editor-free-highlight-thickness-title =
.title = Mudar espessura ao destacar itens que não são texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Comece digitando…

View File

@ -301,23 +301,6 @@ pdfjs-editor-ink-button-label = Desenhar
pdfjs-editor-stamp-button =
.title = Adicionar ou editar imagens
pdfjs-editor-stamp-button-label = Adicionar ou editar imagens
pdfjs-editor-highlight-button =
.title = Destaque
pdfjs-editor-highlight-button-label = Destaque
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = Remover desenho
pdfjs-editor-remove-freetext-button =
.title = Remover texto
pdfjs-editor-remove-stamp-button =
.title = Remover imagem
pdfjs-editor-remove-highlight-button =
.title = Remover destaque
##
# Editor Parameters
pdfjs-editor-free-text-color-input = Cor
pdfjs-editor-free-text-size-input = Tamanho
@ -327,10 +310,6 @@ pdfjs-editor-ink-opacity-input = Opacidade
pdfjs-editor-stamp-add-image-button =
.title = Adicionar imagem
pdfjs-editor-stamp-add-image-button-label = Adicionar imagem
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Espessura
pdfjs-editor-free-highlight-thickness-title =
.title = Alterar espessura quando destacar itens que não sejam texto
pdfjs-free-text =
.aria-label = Editor de texto
pdfjs-free-text-default-content = Começar a digitar…
@ -368,22 +347,3 @@ pdfjs-editor-resizer-label-bottom-right = Canto inferior direito — redimension
pdfjs-editor-resizer-label-bottom-middle = Inferior ao centro — redimensionar
pdfjs-editor-resizer-label-bottom-left = Canto inferior esquerdo — redimensionar
pdfjs-editor-resizer-label-middle-left = Centro à esquerda — redimensionar
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = Cor de destaque
pdfjs-editor-colorpicker-button =
.title = Alterar cor
pdfjs-editor-colorpicker-dropdown =
.aria-label = Escolhas de cor
pdfjs-editor-colorpicker-yellow =
.title = Amarelo
pdfjs-editor-colorpicker-green =
.title = Verde
pdfjs-editor-colorpicker-blue =
.title = Azul
pdfjs-editor-colorpicker-pink =
.title = Rosa
pdfjs-editor-colorpicker-red =
.title = Vermelho

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Dissegnar
pdfjs-editor-stamp-button =
.title = Agiuntar u modifitgar maletgs
pdfjs-editor-stamp-button-label = Agiuntar u modifitgar maletgs
pdfjs-editor-highlight-button =
.title = Marcar
pdfjs-editor-highlight-button-label = Marcar
pdfjs-editor-remove-button =
.title = Allontanar
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacitad
pdfjs-editor-stamp-add-image-button =
.title = Agiuntar in maletg
pdfjs-editor-stamp-add-image-button-label = Agiuntar in maletg
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Grossezza
pdfjs-editor-free-highlight-thickness-title =
.title = Midar la grossezza cun relevar elements betg textuals
pdfjs-free-text =
.aria-label = Editur da text
pdfjs-free-text-default-content = Cumenzar a tippar…

View File

@ -303,9 +303,8 @@ pdfjs-editor-ink-button-label = Рисовать
pdfjs-editor-stamp-button =
.title = Добавить или изменить изображения
pdfjs-editor-stamp-button-label = Добавить или изменить изображения
pdfjs-editor-highlight-button =
.title = Выделение
pdfjs-editor-highlight-button-label = Выделение
pdfjs-editor-remove-button =
.title = Удалить
## Remove button for the various kind of editor.
@ -329,10 +328,6 @@ pdfjs-editor-ink-opacity-input = Прозрачность
pdfjs-editor-stamp-add-image-button =
.title = Добавить изображение
pdfjs-editor-stamp-add-image-button-label = Добавить изображение
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Толщина
pdfjs-editor-free-highlight-thickness-title =
.title = Изменить толщину при выделении элементов, кроме текста
pdfjs-free-text =
.aria-label = Текстовый редактор
pdfjs-free-text-default-content = Начните вводить…

View File

@ -128,7 +128,7 @@ pdfjs-document-properties-modification-date = Dátum úpravy:
# $date (Date) - the creation/modification date of the PDF file
# $time (Time) - the creation/modification time of the PDF file
pdfjs-document-properties-date-string = { $date }, { $time }
pdfjs-document-properties-creator = Aplikácia:
pdfjs-document-properties-creator = Vytvoril:
pdfjs-document-properties-producer = Tvorca PDF:
pdfjs-document-properties-version = Verzia PDF:
pdfjs-document-properties-page-count = Počet strán:
@ -156,7 +156,7 @@ pdfjs-document-properties-page-size-dimension-name-string = { $width } × { $hei
# The linearization status of the document; usually called "Fast Web View" in
# English locales of Adobe software.
pdfjs-document-properties-linearized = Rýchle zobrazovanie z webu:
pdfjs-document-properties-linearized = Rýchle Web View:
pdfjs-document-properties-linearized-yes = Áno
pdfjs-document-properties-linearized-no = Nie
pdfjs-document-properties-close-button = Zavrieť
@ -300,14 +300,13 @@ pdfjs-editor-free-text-button =
.title = Text
pdfjs-editor-free-text-button-label = Text
pdfjs-editor-ink-button =
.title = Kresl
.title = Kreslenie
pdfjs-editor-ink-button-label = Kresliť
pdfjs-editor-stamp-button =
.title = Pridať alebo upraviť obrázky
pdfjs-editor-stamp-button-label = Pridať alebo upraviť obrázky
pdfjs-editor-highlight-button =
.title = Zvýrazniť
pdfjs-editor-highlight-button-label = Zvýrazniť
pdfjs-editor-remove-button =
.title = Odstrániť
## Remove button for the various kind of editor.
@ -331,10 +330,6 @@ pdfjs-editor-ink-opacity-input = Priehľadnosť
pdfjs-editor-stamp-add-image-button =
.title = Pridať obrázok
pdfjs-editor-stamp-add-image-button-label = Pridať obrázok
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Hrúbka
pdfjs-editor-free-highlight-thickness-title =
.title = Zmeňte hrúbku pre zvýrazňovanie iných položiek ako textu
pdfjs-free-text =
.aria-label = Textový editor
pdfjs-free-text-default-content = Začnite písať…

View File

@ -283,21 +283,12 @@ pdfjs-editor-free-text-button-label = متن
pdfjs-editor-ink-button =
.title = چھکو
pdfjs-editor-ink-button-label = چھکو
## Remove button for the various kind of editor.
##
# Editor Parameters
pdfjs-editor-free-text-color-input = رنگ
pdfjs-editor-free-text-size-input = سائز
pdfjs-editor-ink-color-input = رنگ
pdfjs-editor-ink-thickness-input = ٹھولھ
pdfjs-editor-ink-opacity-input = دھندلاپن
pdfjs-editor-stamp-add-image-button =
.title = تصویر شامل کرو
pdfjs-editor-stamp-add-image-button-label = تصویر شامل کرو
pdfjs-free-text =
.aria-label = ٹیکسٹ ایڈیٹر
pdfjs-free-text-default-content = ٹائپنگ شروع کرو …
@ -312,16 +303,3 @@ pdfjs-ink-canvas =
## Editor resizers
## This is used in an aria label to help to understand the role of the resizer.
## Color picker
pdfjs-editor-colorpicker-yellow =
.title = پیلا
pdfjs-editor-colorpicker-green =
.title = ساوا
pdfjs-editor-colorpicker-blue =
.title = نیلا
pdfjs-editor-colorpicker-pink =
.title = گلابی
pdfjs-editor-colorpicker-red =
.title = لال

View File

@ -305,9 +305,8 @@ pdfjs-editor-ink-button-label = Riši
pdfjs-editor-stamp-button =
.title = Dodajanje ali urejanje slik
pdfjs-editor-stamp-button-label = Dodajanje ali urejanje slik
pdfjs-editor-highlight-button =
.title = Poudarek
pdfjs-editor-highlight-button-label = Poudarek
pdfjs-editor-remove-button =
.title = Odstrani
## Remove button for the various kind of editor.
@ -331,10 +330,6 @@ pdfjs-editor-ink-opacity-input = Neprosojnost
pdfjs-editor-stamp-add-image-button =
.title = Dodaj sliko
pdfjs-editor-stamp-add-image-button-label = Dodaj sliko
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Debelina
pdfjs-editor-free-highlight-thickness-title =
.title = Spremeni debelino pri označevanju nebesedilnih elementov
pdfjs-free-text =
.aria-label = Urejevalnik besedila
pdfjs-free-text-default-content = Začnite tipkati …

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Rita
pdfjs-editor-stamp-button =
.title = Lägg till eller redigera bilder
pdfjs-editor-stamp-button-label = Lägg till eller redigera bilder
pdfjs-editor-highlight-button =
.title = Markera
pdfjs-editor-highlight-button-label = Markera
pdfjs-editor-remove-button =
.title = Ta bort
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Opacitet
pdfjs-editor-stamp-add-image-button =
.title = Lägg till bild
pdfjs-editor-stamp-add-image-button-label = Lägg till bild
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Tjocklek
pdfjs-editor-free-highlight-thickness-title =
.title = Ändra tjocklek när du markerar andra objekt än text
pdfjs-free-text =
.aria-label = Textredigerare
pdfjs-free-text-default-content = Börja skriva…

View File

@ -293,23 +293,6 @@ pdfjs-editor-ink-button-label = รูปวาด
pdfjs-editor-stamp-button =
.title = เพิ่มหรือแก้ไขภาพ
pdfjs-editor-stamp-button-label = เพิ่มหรือแก้ไขภาพ
pdfjs-editor-highlight-button =
.title = เน้น
pdfjs-editor-highlight-button-label = เน้น
## Remove button for the various kind of editor.
pdfjs-editor-remove-ink-button =
.title = เอาภาพวาดออก
pdfjs-editor-remove-freetext-button =
.title = เอาข้อความออก
pdfjs-editor-remove-stamp-button =
.title = เอาภาพออก
pdfjs-editor-remove-highlight-button =
.title = เอาการเน้นสีออก
##
# Editor Parameters
pdfjs-editor-free-text-color-input = สี
pdfjs-editor-free-text-size-input = ขนาด
@ -319,10 +302,6 @@ pdfjs-editor-ink-opacity-input = ความทึบ
pdfjs-editor-stamp-add-image-button =
.title = เพิ่มภาพ
pdfjs-editor-stamp-add-image-button-label = เพิ่มภาพ
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = ความหนา
pdfjs-editor-free-highlight-thickness-title =
.title = เปลี่ยนความหนาเมื่อเน้นรายการอื่นๆ ที่ไม่ใช่ข้อความ
pdfjs-free-text =
.aria-label = ตัวแก้ไขข้อความ
pdfjs-free-text-default-content = เริ่มพิมพ์…
@ -360,22 +339,3 @@ pdfjs-editor-resizer-label-bottom-right = มุมขวาล่าง — ป
pdfjs-editor-resizer-label-bottom-middle = ตรงกลางด้านล่าง — ปรับขนาด
pdfjs-editor-resizer-label-bottom-left = มุมซ้ายล่าง — ปรับขนาด
pdfjs-editor-resizer-label-middle-left = ตรงกลางด้านซ้าย — ปรับขนาด
## Color picker
# This means "Color used to highlight text"
pdfjs-editor-highlight-colorpicker-label = สีเน้น
pdfjs-editor-colorpicker-button =
.title = เปลี่ยนสี
pdfjs-editor-colorpicker-dropdown =
.aria-label = ทางเลือกสี
pdfjs-editor-colorpicker-yellow =
.title = เหลือง
pdfjs-editor-colorpicker-green =
.title = เขียว
pdfjs-editor-colorpicker-blue =
.title = น้ำเงิน
pdfjs-editor-colorpicker-pink =
.title = ชมพู
pdfjs-editor-colorpicker-red =
.title = แดง

View File

@ -301,9 +301,8 @@ pdfjs-editor-ink-button-label = Çiz
pdfjs-editor-stamp-button =
.title = Resim ekle veya düzenle
pdfjs-editor-stamp-button-label = Resim ekle veya düzenle
pdfjs-editor-highlight-button =
.title = Vurgula
pdfjs-editor-highlight-button-label = Vurgula
pdfjs-editor-remove-button =
.title = Kaldır
## Remove button for the various kind of editor.
@ -327,10 +326,6 @@ pdfjs-editor-ink-opacity-input = Saydamlık
pdfjs-editor-stamp-add-image-button =
.title = Resim ekle
pdfjs-editor-stamp-add-image-button-label = Resim ekle
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Kalınlık
pdfjs-editor-free-highlight-thickness-title =
.title = Metin dışındaki öğeleri vurgularken kalınlığı değiştir
pdfjs-free-text =
.aria-label = Metin düzenleyicisi
pdfjs-free-text-default-content = Yazmaya başlayın…

View File

@ -288,7 +288,7 @@ pdfjs-text-annotation-type =
pdfjs-password-label = Введіть пароль для відкриття цього PDF-файла.
pdfjs-password-invalid = Невірний пароль. Спробуйте ще.
pdfjs-password-ok-button = OK
pdfjs-password-ok-button = Гаразд
pdfjs-password-cancel-button = Скасувати
pdfjs-web-fonts-disabled = Веб-шрифти вимкнено: неможливо використати вбудовані у PDF шрифти.
@ -303,9 +303,8 @@ pdfjs-editor-ink-button-label = Малювати
pdfjs-editor-stamp-button =
.title = Додати чи редагувати зображення
pdfjs-editor-stamp-button-label = Додати чи редагувати зображення
pdfjs-editor-highlight-button =
.title = Підсвітити
pdfjs-editor-highlight-button-label = Підсвітити
pdfjs-editor-remove-button =
.title = Вилучити
## Remove button for the various kind of editor.
@ -329,10 +328,6 @@ pdfjs-editor-ink-opacity-input = Прозорість
pdfjs-editor-stamp-add-image-button =
.title = Додати зображення
pdfjs-editor-stamp-add-image-button-label = Додати зображення
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Товщина
pdfjs-editor-free-highlight-thickness-title =
.title = Змінюйте товщину під час підсвічування елементів, крім тексту
pdfjs-free-text =
.aria-label = Текстовий редактор
pdfjs-free-text-default-content = Почніть вводити…
@ -362,14 +357,14 @@ pdfjs-editor-alt-text-textarea =
## Editor resizers
## This is used in an aria label to help to understand the role of the resizer.
pdfjs-editor-resizer-label-top-left = Верхній лівий кут зміна розміру
pdfjs-editor-resizer-label-top-middle = Вгорі посередині зміна розміру
pdfjs-editor-resizer-label-top-right = Верхній правий кут зміна розміру
pdfjs-editor-resizer-label-middle-right = Праворуч посередині зміна розміру
pdfjs-editor-resizer-label-bottom-right = Нижній правий кут зміна розміру
pdfjs-editor-resizer-label-bottom-middle = Внизу посередині зміна розміру
pdfjs-editor-resizer-label-bottom-left = Нижній лівий кут зміна розміру
pdfjs-editor-resizer-label-middle-left = Ліворуч посередині зміна розміру
pdfjs-editor-resizer-label-top-left = Верхній лівий кут зміна розміру
pdfjs-editor-resizer-label-top-middle = Вгорі посередині зміна розміру
pdfjs-editor-resizer-label-top-right = Верхній правий кут зміна розміру
pdfjs-editor-resizer-label-middle-right = Праворуч посередині зміна розміру
pdfjs-editor-resizer-label-bottom-right = Нижній правий кут зміна розміру
pdfjs-editor-resizer-label-bottom-middle = Внизу посередині зміна розміру
pdfjs-editor-resizer-label-bottom-left = Нижній лівий кут зміна розміру
pdfjs-editor-resizer-label-middle-left = Ліворуч посередині зміна розміру
## Color picker

View File

@ -220,7 +220,7 @@ pdfjs-find-previous-button-label = Trước
pdfjs-find-next-button =
.title = Tìm cụm từ ở phần sau
pdfjs-find-next-button-label = Tiếp
pdfjs-find-highlight-checkbox = Đánh dấu tất cả
pdfjs-find-highlight-checkbox = Tô sáng tất cả
pdfjs-find-match-case-checkbox-label = Phân biệt hoa, thường
pdfjs-find-match-diacritics-checkbox-label = Khớp dấu phụ
pdfjs-find-entire-word-checkbox-label = Toàn bộ từ
@ -293,9 +293,8 @@ pdfjs-editor-ink-button-label = Vẽ
pdfjs-editor-stamp-button =
.title = Thêm hoặc chỉnh sửa hình ảnh
pdfjs-editor-stamp-button-label = Thêm hoặc chỉnh sửa hình ảnh
pdfjs-editor-highlight-button =
.title = Đánh dấu
pdfjs-editor-highlight-button-label = Đánh dấu
pdfjs-editor-remove-button =
.title = Xóa
## Remove button for the various kind of editor.
@ -319,10 +318,6 @@ pdfjs-editor-ink-opacity-input = Độ mờ
pdfjs-editor-stamp-add-image-button =
.title = Thêm hình ảnh
pdfjs-editor-stamp-add-image-button-label = Thêm hình ảnh
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = Độ dày
pdfjs-editor-free-highlight-thickness-title =
.title = Thay đổi độ dày khi đánh dấu các mục không phải là văn bản
pdfjs-free-text =
.aria-label = Trình sửa văn bản
pdfjs-free-text-default-content = Bắt đầu nhập…

View File

@ -293,9 +293,8 @@ pdfjs-editor-ink-button-label = 绘图
pdfjs-editor-stamp-button =
.title = 添加或编辑图像
pdfjs-editor-stamp-button-label = 添加或编辑图像
pdfjs-editor-highlight-button =
.title = 高亮
pdfjs-editor-highlight-button-label = 高亮
pdfjs-editor-remove-button =
.title = 移除
## Remove button for the various kind of editor.
@ -319,10 +318,6 @@ pdfjs-editor-ink-opacity-input = 不透明度
pdfjs-editor-stamp-add-image-button =
.title = 添加图像
pdfjs-editor-stamp-add-image-button-label = 添加图像
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = 粗细
pdfjs-editor-free-highlight-thickness-title =
.title = 更改高亮粗细(用于文本以外项目)
pdfjs-free-text =
.aria-label = 文本编辑器
pdfjs-free-text-default-content = 开始输入…

View File

@ -293,9 +293,8 @@ pdfjs-editor-ink-button-label = 繪圖
pdfjs-editor-stamp-button =
.title = 新增或編輯圖片
pdfjs-editor-stamp-button-label = 新增或編輯圖片
pdfjs-editor-highlight-button =
.title = 強調
pdfjs-editor-highlight-button-label = 強調
pdfjs-editor-remove-button =
.title = 移除
## Remove button for the various kind of editor.
@ -319,10 +318,6 @@ pdfjs-editor-ink-opacity-input = 透​明度
pdfjs-editor-stamp-add-image-button =
.title = 新增圖片
pdfjs-editor-stamp-add-image-button-label = 新增圖片
# This refers to the thickness of the line used for free highlighting (not bound to text)
pdfjs-editor-free-highlight-thickness-input = 線條粗細
pdfjs-editor-free-highlight-thickness-title =
.title = 更改強調文字以外的項目時的線條粗細
pdfjs-free-text =
.aria-label = 文本編輯器
pdfjs-free-text-default-content = 開始打字…

2129
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,34 +2,34 @@
"name": "pdf.js",
"type": "module",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/runtime": "^7.23.9",
"@babel/core": "^7.23.6",
"@babel/preset-env": "^7.23.6",
"@babel/runtime": "^7.23.6",
"@fluent/bundle": "^0.18.0",
"@fluent/dom": "^0.9.0",
"@javascript-obfuscator/escodegen": "2.3.0",
"@jazzer.js/core": "^2.1.0",
"autoprefixer": "^10.4.17",
"acorn": "^8.11.2",
"autoprefixer": "^10.4.16",
"babel-loader": "^9.1.3",
"caniuse-lite": "^1.0.30001587",
"caniuse-lite": "^1.0.30001571",
"canvas": "^2.11.2",
"core-js": "^3.36.0",
"core-js": "^3.34.0",
"cross-env": "^7.0.3",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-fetch-options": "^0.0.5",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jasmine": "^4.1.3",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-mozilla": "^3.3.2",
"eslint-plugin-no-unsanitized": "^4.0.2",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-sort-exports": "^0.9.1",
"eslint-plugin-unicorn": "^51.0.1",
"globals": "^14.0.0",
"eslint-plugin-prettier": "^5.1.1",
"eslint-plugin-sort-exports": "^0.8.0",
"eslint-plugin-unicorn": "^50.0.1",
"globals": "^13.24.0",
"gulp": "^4.0.2",
"gulp-cli": "^2.3.0",
"gulp-postcss": "^10.0.0",
"gulp-postcss": "^9.0.1",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.1.4",
"gulp-zip": "^6.0.0",
@ -41,25 +41,25 @@
"needle": "^3.3.1",
"path2d-polyfill": "^2.0.1",
"pngjs": "^7.0.0",
"postcss": "^8.4.35",
"postcss-dark-theme-class": "^1.2.1",
"postcss": "^8.4.32",
"postcss-dark-theme-class": "^1.1.0",
"postcss-dir-pseudo-class": "^8.0.1",
"postcss-discard-comments": "^6.0.1",
"postcss-nesting": "^12.0.2",
"prettier": "^3.2.5",
"puppeteer": "^22.3.0",
"prettier": "^3.1.1",
"puppeteer": "^21.6.1",
"rimraf": "^3.0.2",
"streamqueue": "^1.1.2",
"stylelint": "^16.2.1",
"stylelint": "^16.0.2",
"stylelint-prettier": "^5.0.0",
"terser-webpack-plugin": "^5.3.10",
"terser": "^5.26.0",
"through2": "^4.0.2",
"tsc-alias": "^1.8.8",
"ttest": "^4.0.0",
"typescript": "^5.3.3",
"typogr": "^0.6.8",
"vinyl": "^3.0.0",
"webpack": "^5.90.2",
"webpack": "^5.89.0",
"webpack-stream": "^7.0.0",
"wintersmith": "^2.5.0",
"yargs": "^17.7.2"

View File

@ -1,5 +1,5 @@
{
"stableVersion": "4.0.379",
"baseVersion": "56ca2fd65858bf0045734fae11c295e290728463",
"versionPrefix": "4.1."
"stableVersion": "4.0.269",
"baseVersion": "0edc490e1beeb9fea62162738d9effef30c70af7",
"versionPrefix": "4.0."
}

View File

@ -79,7 +79,6 @@ class AnnotationFactory {
// with "GoToE" actions, from throwing and thus breaking parsing:
pdfManager.ensureCatalog("attachments"),
]).then(
// eslint-disable-next-line arrow-body-style
([acroForm, xfaDatasets, structTreeRoot, baseUrl, attachments]) => {
return {
pdfManager,
@ -356,19 +355,13 @@ class AnnotationFactory {
);
break;
case AnnotationEditorType.HIGHLIGHT:
if (annotation.quadPoints) {
promises.push(
HighlightAnnotation.createNewAnnotation(
xref,
annotation,
dependencies
)
);
} else {
promises.push(
InkAnnotation.createNewAnnotation(xref, annotation, dependencies)
);
}
promises.push(
HighlightAnnotation.createNewAnnotation(
xref,
annotation,
dependencies
)
);
break;
case AnnotationEditorType.INK:
promises.push(
@ -446,29 +439,16 @@ class AnnotationFactory {
);
break;
case AnnotationEditorType.HIGHLIGHT:
if (annotation.quadPoints) {
promises.push(
HighlightAnnotation.createNewPrintAnnotation(
annotationGlobals,
xref,
annotation,
{
evaluatorOptions: options,
}
)
);
} else {
promises.push(
InkAnnotation.createNewPrintAnnotation(
annotationGlobals,
xref,
annotation,
{
evaluatorOptions: options,
}
)
);
}
promises.push(
HighlightAnnotation.createNewPrintAnnotation(
annotationGlobals,
xref,
annotation,
{
evaluatorOptions: options,
}
)
);
break;
case AnnotationEditorType.INK:
promises.push(
@ -1215,7 +1195,7 @@ class Annotation {
firstPosition ||= item.transform.slice(-2);
buffer.push(item.str);
if (item.hasEOL) {
text.push(buffer.join("").trimEnd());
text.push(buffer.join(""));
buffer.length = 0;
}
}
@ -1227,38 +1207,31 @@ class Annotation {
task,
resources,
includeMarkedContent: true,
keepWhiteSpace: true,
sink,
viewBox,
});
this.reset();
if (buffer.length) {
text.push(buffer.join("").trimEnd());
text.push(buffer.join(""));
}
if (text.length > 1 || text[0]) {
const appearanceDict = this.appearance.dict;
this.data.textPosition = this._transformPoint(
firstPosition,
appearanceDict.getArray("BBox"),
appearanceDict.getArray("Matrix")
);
const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1];
const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0];
const rect = this.data.rect;
const transform = getTransformMatrix(rect, bbox, matrix);
transform[4] -= rect[0];
transform[5] -= rect[1];
firstPosition = Util.applyTransform(firstPosition, transform);
firstPosition = Util.applyTransform(firstPosition, matrix);
this.data.textPosition = firstPosition;
this.data.textContent = text;
}
}
_transformPoint(coords, bbox, matrix) {
const { rect } = this.data;
bbox ||= [0, 0, 1, 1];
matrix ||= [1, 0, 0, 1, 0, 0];
const transform = getTransformMatrix(rect, bbox, matrix);
transform[4] -= rect[0];
transform[5] -= rect[1];
coords = Util.applyTransform(coords, transform);
return Util.applyTransform(coords, matrix);
}
/**
* Get field data for usage in JS sandbox.
*
@ -2134,8 +2107,11 @@ class WidgetAnnotation extends Annotation {
value,
};
const encoder = val =>
isAscii(val) ? val : stringToUTF16String(val, /* bigEndian = */ true);
const encoder = val => {
return isAscii(val)
? val
: stringToUTF16String(val, /* bigEndian = */ true);
};
dict.set("V", Array.isArray(value) ? value.map(encoder) : encoder(value));
this.amendSavedDict(annotationStorage, dict);
@ -3684,10 +3660,6 @@ class LinkAnnotation extends Annotation {
const { dict, annotationGlobals } = params;
this.data.annotationType = AnnotationType.LINK;
// A link is never rendered on the main canvas so we must render its HTML
// version.
this.data.noHTML = false;
const quadPoints = getQuadPoints(dict, this.rectangle);
if (quadPoints) {
this.data.quadPoints = quadPoints;
@ -3795,9 +3767,7 @@ class FreeTextAnnotation extends MarkupAnnotation {
const { evaluatorOptions, xref } = params;
this.data.annotationType = AnnotationType.FREETEXT;
this.setDefaultAppearance(params);
this._hasAppearance = !!this.appearance;
if (this._hasAppearance) {
if (this.appearance) {
const { fontColor, fontSize } = parseAppearanceStream(
this.appearance,
evaluatorOptions,
@ -3805,42 +3775,29 @@ class FreeTextAnnotation extends MarkupAnnotation {
);
this.data.defaultAppearanceData.fontColor = fontColor;
this.data.defaultAppearanceData.fontSize = fontSize || 10;
} else {
} else if (this._isOffscreenCanvasSupported) {
const strokeAlpha = params.dict.get("CA");
const fakeUnicodeFont = new FakeUnicodeFont(xref, "sans-serif");
this.data.defaultAppearanceData.fontSize ||= 10;
const { fontColor, fontSize } = this.data.defaultAppearanceData;
if (this._contents.str) {
this.data.textContent = this._contents.str
.split(/\r\n?|\n/)
.map(line => line.trimEnd());
const { coords, bbox, matrix } = FakeUnicodeFont.getFirstPositionInfo(
this.rectangle,
this.rotation,
fontSize
);
this.data.textPosition = this._transformPoint(coords, bbox, matrix);
}
if (this._isOffscreenCanvasSupported) {
const strokeAlpha = params.dict.get("CA");
const fakeUnicodeFont = new FakeUnicodeFont(xref, "sans-serif");
this.appearance = fakeUnicodeFont.createAppearance(
this._contents.str,
this.rectangle,
this.rotation,
fontSize,
fontColor,
strokeAlpha
);
this._streams.push(this.appearance);
} else {
warn(
"FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly."
);
}
this.appearance = fakeUnicodeFont.createAppearance(
this._contents.str,
this.rectangle,
this.rotation,
fontSize,
fontColor,
strokeAlpha
);
this._streams.push(this.appearance, FakeUnicodeFont.toUnicodeStream);
} else {
warn(
"FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly."
);
}
}
get hasTextContent() {
return this._hasAppearance;
return !!this.appearance;
}
static createNewDict(annotation, xref, { apRef, ap }) {
@ -4361,25 +4318,19 @@ class InkAnnotation extends MarkupAnnotation {
}
static createNewDict(annotation, xref, { apRef, ap }) {
const { color, opacity, paths, outlines, rect, rotation, thickness } =
annotation;
const { color, opacity, paths, rect, rotation, thickness } = annotation;
const ink = new Dict(xref);
ink.set("Type", Name.get("Annot"));
ink.set("Subtype", Name.get("Ink"));
ink.set("CreationDate", `D:${getModificationDate()}`);
ink.set("Rect", rect);
ink.set("InkList", outlines?.points || paths.map(p => p.points));
ink.set(
"InkList",
paths.map(p => p.points)
);
ink.set("F", 4);
ink.set("Rotate", rotation);
if (outlines) {
// Free highlight.
// There's nothing about this in the spec, but it's used when highlighting
// in Edge's viewer. Acrobat takes into account this parameter to indicate
// that the Ink is used for highlighting.
ink.set("IT", Name.get("InkHighlight"));
}
// Line thickness.
const bs = new Dict(xref);
ink.set("BS", bs);
@ -4407,13 +4358,6 @@ class InkAnnotation extends MarkupAnnotation {
}
static async createNewAppearanceStream(annotation, xref, params) {
if (annotation.outlines) {
return this.createNewAppearanceStreamForHighlight(
annotation,
xref,
params
);
}
const { color, rect, paths, thickness, opacity } = annotation;
const appearanceBuffer = [
@ -4431,20 +4375,14 @@ class InkAnnotation extends MarkupAnnotation {
buffer.push(
`${numberToString(bezier[0])} ${numberToString(bezier[1])} m`
);
if (bezier.length === 2) {
buffer.push(
`${numberToString(bezier[0])} ${numberToString(bezier[1])} l S`
);
} else {
for (let i = 2, ii = bezier.length; i < ii; i += 6) {
const curve = bezier
.slice(i, i + 6)
.map(numberToString)
.join(" ");
buffer.push(`${curve} c`);
}
buffer.push("S");
for (let i = 2, ii = bezier.length; i < ii; i += 6) {
const curve = bezier
.slice(i, i + 6)
.map(numberToString)
.join(" ");
buffer.push(`${curve} c`);
}
buffer.push("S");
appearanceBuffer.push(buffer.join("\n"));
}
const appearance = appearanceBuffer.join("\n");
@ -4472,65 +4410,6 @@ class InkAnnotation extends MarkupAnnotation {
return ap;
}
static async createNewAppearanceStreamForHighlight(annotation, xref, params) {
const {
color,
rect,
outlines: { outline },
opacity,
} = annotation;
const appearanceBuffer = [
`${getPdfColor(color, /* isFill */ true)}`,
"/R0 gs",
];
appearanceBuffer.push(
`${numberToString(outline[4])} ${numberToString(outline[5])} m`
);
for (let i = 6, ii = outline.length; i < ii; i += 6) {
if (isNaN(outline[i]) || outline[i] === null) {
appearanceBuffer.push(
`${numberToString(outline[i + 4])} ${numberToString(
outline[i + 5]
)} l`
);
} else {
const curve = outline
.slice(i, i + 6)
.map(numberToString)
.join(" ");
appearanceBuffer.push(`${curve} c`);
}
}
appearanceBuffer.push("h f");
const appearance = appearanceBuffer.join("\n");
const appearanceStreamDict = new Dict(xref);
appearanceStreamDict.set("FormType", 1);
appearanceStreamDict.set("Subtype", Name.get("Form"));
appearanceStreamDict.set("Type", Name.get("XObject"));
appearanceStreamDict.set("BBox", rect);
appearanceStreamDict.set("Length", appearance.length);
const resources = new Dict(xref);
const extGState = new Dict(xref);
resources.set("ExtGState", extGState);
appearanceStreamDict.set("Resources", resources);
const r0 = new Dict(xref);
extGState.set("R0", r0);
r0.set("BM", Name.get("Multiply"));
if (opacity !== 1) {
r0.set("ca", opacity);
r0.set("Type", Name.get("ExtGState"));
}
const ap = new StringStream(appearance);
ap.dict = appearanceStreamDict;
return ap;
}
}
class HighlightAnnotation extends MarkupAnnotation {
@ -4826,7 +4705,9 @@ class StampAnnotation extends MarkupAnnotation {
const jpegBufferPromise = canvas
.convertToBlob({ type: "image/jpeg", quality: 1 })
.then(blob => blob.arrayBuffer());
.then(blob => {
return blob.arrayBuffer();
});
const xobjectName = Name.get("XObject");
const imageName = Name.get("Image");
@ -4964,5 +4845,4 @@ export {
getQuadPoints,
MarkupAnnotation,
PopupAnnotation,
WidgetAnnotation,
};

View File

@ -445,10 +445,20 @@ class Catalog {
continue;
}
groupRefs.put(groupRef);
groups.push(this.#readOptionalContentGroup(groupRef));
const group = this.xref.fetch(groupRef);
groups.push({
id: groupRef.toString(),
name:
typeof group.get("Name") === "string"
? stringToPDFString(group.get("Name"))
: null,
intent:
typeof group.get("Intent") === "string"
? stringToPDFString(group.get("Intent"))
: null,
});
}
config = this.#readOptionalContentConfig(defaultConfig, groupRefs);
config = this._readOptionalContentConfig(defaultConfig, groupRefs);
config.groups = groups;
} catch (ex) {
if (ex instanceof MissingDataException) {
@ -459,65 +469,7 @@ class Catalog {
return shadow(this, "optionalContentConfig", config);
}
#readOptionalContentGroup(groupRef) {
const group = this.xref.fetch(groupRef);
const obj = {
id: groupRef.toString(),
name: null,
intent: null,
usage: {
print: null,
view: null,
},
};
const name = group.get("Name");
if (typeof name === "string") {
obj.name = stringToPDFString(name);
}
let intent = group.getArray("Intent");
if (!Array.isArray(intent)) {
intent = [intent];
}
if (intent.every(i => i instanceof Name)) {
obj.intent = intent.map(i => i.name);
}
const usage = group.get("Usage");
if (!(usage instanceof Dict)) {
return obj;
}
const usageObj = obj.usage;
const print = usage.get("Print");
if (print instanceof Dict) {
const printState = print.get("PrintState");
if (printState instanceof Name) {
switch (printState.name) {
case "ON":
case "OFF":
usageObj.print = { printState: printState.name };
}
}
}
const view = usage.get("View");
if (view instanceof Dict) {
const viewState = view.get("ViewState");
if (viewState instanceof Name) {
switch (viewState.name) {
case "ON":
case "OFF":
usageObj.view = { viewState: viewState.name };
}
}
}
return obj;
}
#readOptionalContentConfig(config, contentGroupRefs) {
_readOptionalContentConfig(config, contentGroupRefs) {
function parseOnOff(refs) {
const onParsed = [];
if (Array.isArray(refs)) {
@ -941,13 +893,14 @@ class Catalog {
case "PrintPageRange":
// The number of elements must be even.
if (Array.isArray(value) && value.length % 2 === 0) {
const isValid = value.every(
(page, i, arr) =>
const isValid = value.every((page, i, arr) => {
return (
Number.isInteger(page) &&
page > 0 &&
(i === 0 || page >= arr[i - 1]) &&
page <= this.numPages
);
);
});
if (isValid) {
prefValue = value;
}

View File

@ -691,9 +691,9 @@ async function createBuiltInCMap(name, fetchBuiltInCMap) {
const cMap = new CMap(true);
if (compressionType === CMapCompressionType.BINARY) {
return new BinaryCMapReader().process(cMapData, cMap, useCMap =>
extendCMap(cMap, fetchBuiltInCMap, useCMap)
);
return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
});
}
if (compressionType === CMapCompressionType.NONE) {
const lexer = new Lexer(new Stream(cMapData));

View File

@ -386,17 +386,6 @@ const XMLEntities = {
/* ' */ 0x27: "&apos;",
};
function* codePointIter(str) {
for (let i = 0, ii = str.length; i < ii; i++) {
const char = str.codePointAt(i);
if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {
// char is represented by two u16
i++;
}
yield char;
}
}
function encodeToXmlString(str) {
const buffer = [];
let start = 0;
@ -611,22 +600,8 @@ function getRotationMatrix(rotation, width, height) {
}
}
/**
* Get the number of bytes to use to represent the given positive integer.
* If n is zero, the function returns 0 which means that we don't need to waste
* a byte to represent it.
* @param {number} x - a positive integer.
* @returns {number}
*/
function getSizeInBytes(x) {
// n bits are required for numbers up to 2^n - 1.
// So for a number x, we need ceil(log2(1 + x)) bits.
return Math.ceil(Math.ceil(Math.log2(1 + x)) / 8);
}
export {
arrayBuffersToBytes,
codePointIter,
collectActions,
encodeToXmlString,
escapePDFName,
@ -635,7 +610,6 @@ export {
getLookupTableFactory,
getNewAnnotationsMap,
getRotationMatrix,
getSizeInBytes,
isAscii,
isWhiteSpace,
log2,

View File

@ -13,14 +13,13 @@
* limitations under the License.
*/
import { Dict, Name } from "./primitives.js";
import {
codePointIter,
escapePDFName,
getRotationMatrix,
numberToString,
stringToUTF16HexString,
} from "./core_utils.js";
import { Dict, Name } from "./primitives.js";
import {
LINE_DESCENT_FACTOR,
LINE_FACTOR,
@ -252,6 +251,35 @@ class FakeUnicodeFont {
);
}
get toUnicodeRef() {
if (!FakeUnicodeFont._toUnicodeRef) {
const toUnicode = `/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo
<< /Registry (Adobe)
/Ordering (UCS) /Supplement 0 >> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
1 beginbfrange
<0000> <FFFF> <0000>
endbfrange
endcmap CMapName currentdict /CMap defineresource pop end end`;
const toUnicodeStream = (FakeUnicodeFont.toUnicodeStream =
new StringStream(toUnicode));
const toUnicodeDict = new Dict(this.xref);
toUnicodeStream.dict = toUnicodeDict;
toUnicodeDict.set("Length", toUnicode.length);
FakeUnicodeFont._toUnicodeRef =
this.xref.getNewPersistentRef(toUnicodeStream);
}
return FakeUnicodeFont._toUnicodeRef;
}
get fontDescriptorRef() {
if (!FakeUnicodeFont._fontDescriptorRef) {
const fontDescriptor = new Dict(this.xref);
@ -322,7 +350,7 @@ class FakeUnicodeFont {
baseFont.set("Subtype", Name.get("Type0"));
baseFont.set("Encoding", Name.get("Identity-H"));
baseFont.set("DescendantFonts", [this.descendantFontRef]);
baseFont.set("ToUnicode", Name.get("Identity-H"));
baseFont.set("ToUnicode", this.toUnicodeRef);
return this.xref.getNewPersistentRef(baseFont);
}
@ -362,26 +390,6 @@ class FakeUnicodeFont {
return this.resources;
}
static getFirstPositionInfo(rect, rotation, fontSize) {
// Get the position of the first char in the rect.
const [x1, y1, x2, y2] = rect;
let w = x2 - x1;
let h = y2 - y1;
if (rotation % 180 !== 0) {
[w, h] = [h, w];
}
const lineHeight = LINE_FACTOR * fontSize;
const lineDescent = LINE_DESCENT_FACTOR * fontSize;
return {
coords: [0, h + lineDescent - lineHeight],
bbox: [0, 0, w, h],
matrix:
rotation !== 0 ? getRotationMatrix(rotation, h, lineHeight) : undefined,
};
}
createAppearance(text, rect, rotation, fontSize, bgColor, strokeAlpha) {
const ctx = this._createContext();
const lines = [];
@ -392,8 +400,8 @@ class FakeUnicodeFont {
// languages, like arabic, it'd be wrong because of ligatures.
const lineWidth = ctx.measureText(line).width;
maxWidth = Math.max(maxWidth, lineWidth);
for (const code of codePointIter(line)) {
const char = String.fromCodePoint(code);
for (const char of line.split("")) {
const code = char.charCodeAt(0);
let width = this.widths.get(code);
if (width === undefined) {
const metrics = ctx.measureText(char);

View File

@ -30,11 +30,7 @@ import {
Util,
warn,
} from "../shared/util.js";
import {
AnnotationFactory,
PopupAnnotation,
WidgetAnnotation,
} from "./annotation.js";
import { AnnotationFactory, PopupAnnotation } from "./annotation.js";
import {
collectActions,
getInheritableProperty,
@ -770,26 +766,19 @@ class Page {
}
const sortedAnnotations = [];
let popupAnnotations, widgetAnnotations;
let popupAnnotations;
// Ensure that PopupAnnotations are handled last, since they depend on
// their parent Annotation in the display layer; fixes issue 11362.
for (const annotation of await Promise.all(annotationPromises)) {
if (!annotation) {
continue;
}
if (annotation instanceof WidgetAnnotation) {
(widgetAnnotations ||= []).push(annotation);
continue;
}
if (annotation instanceof PopupAnnotation) {
(popupAnnotations ||= []).push(annotation);
continue;
}
sortedAnnotations.push(annotation);
}
if (widgetAnnotations) {
sortedAnnotations.push(...widgetAnnotations);
}
if (popupAnnotations) {
sortedAnnotations.push(...popupAnnotations);
}
@ -941,14 +930,7 @@ class PDFDocument {
// Find the end of the first object.
stream.reset();
if (find(stream, ENDOBJ_SIGNATURE)) {
stream.skip(6);
let ch = stream.peekByte();
while (isWhiteSpace(ch)) {
stream.pos++;
ch = stream.peekByte();
}
startXRef = stream.pos - stream.start;
startXRef = stream.pos + 6 - stream.start;
}
} else {
// Find `startxref` by checking backwards from the end of the file.
@ -1595,7 +1577,6 @@ class PDFDocument {
} else {
promise = catalog.getPageDict(pageIndex);
}
// eslint-disable-next-line arrow-body-style
promise = promise.then(([pageDict, ref]) => {
return new Page({
pdfManager: this.pdfManager,

View File

@ -526,22 +526,23 @@ class PartialEvaluator {
const args = group ? [matrix, null] : [matrix, bbox];
operatorList.addOp(OPS.paintFormXObjectBegin, args);
await this.getOperatorList({
return this.getOperatorList({
stream: xobj,
task,
resources: dict.get("Resources") || resources,
operatorList,
initialState,
}).then(function () {
operatorList.addOp(OPS.paintFormXObjectEnd, []);
if (group) {
operatorList.addOp(OPS.endGroup, [groupOptions]);
}
if (optionalContent !== undefined) {
operatorList.addOp(OPS.endMarkedContent, []);
}
});
operatorList.addOp(OPS.paintFormXObjectEnd, []);
if (group) {
operatorList.addOp(OPS.endGroup, [groupOptions]);
}
if (optionalContent !== undefined) {
operatorList.addOp(OPS.endMarkedContent, []);
}
}
_sendImgData(objId, imgData, cacheGlobally = false) {
@ -1006,7 +1007,7 @@ class PartialEvaluator {
});
}
async handleSetFont(
handleSetFont(
resources,
fontArgs,
fontRef,
@ -1018,33 +1019,40 @@ class PartialEvaluator {
) {
const fontName = fontArgs?.[0] instanceof Name ? fontArgs[0].name : null;
let translated = await this.loadFont(
return this.loadFont(
fontName,
fontRef,
resources,
fallbackFontDict,
cssFontInfo
);
)
.then(translated => {
if (!translated.font.isType3Font) {
return translated;
}
return translated
.loadType3Data(this, resources, task)
.then(function () {
// Add the dependencies to the parent operatorList so they are
// resolved before Type3 operatorLists are executed synchronously.
operatorList.addDependencies(translated.type3Dependencies);
if (translated.font.isType3Font) {
try {
await translated.loadType3Data(this, resources, task);
// Add the dependencies to the parent operatorList so they are
// resolved before Type3 operatorLists are executed synchronously.
operatorList.addDependencies(translated.type3Dependencies);
} catch (reason) {
translated = new TranslatedFont({
loadedName: "g_font_error",
font: new ErrorFont(`Type3 font load error: ${reason}`),
dict: translated.font,
evaluatorOptions: this.options,
});
}
}
state.font = translated.font;
translated.send(this.handler);
return translated.loadedName;
return translated;
})
.catch(reason => {
return new TranslatedFont({
loadedName: "g_font_error",
font: new ErrorFont(`Type3 font load error: ${reason}`),
dict: translated.font,
evaluatorOptions: this.options,
});
});
})
.then(translated => {
state.font = translated.font;
translated.send(this.handler);
return translated.loadedName;
});
}
handleText(chars, state) {
@ -1121,8 +1129,8 @@ class PartialEvaluator {
case "Font":
isSimpleGState = false;
promise = promise.then(() =>
this.handleSetFont(
promise = promise.then(() => {
return this.handleSetFont(
resources,
null,
value[0],
@ -1132,8 +1140,8 @@ class PartialEvaluator {
).then(function (loadedName) {
operatorList.addDependency(loadedName);
gStateObj.push([key, [loadedName, value[1]]]);
})
);
});
});
break;
case "BM":
gStateObj.push([key, normalizeBlendMode(value)]);
@ -1146,16 +1154,16 @@ class PartialEvaluator {
if (value instanceof Dict) {
isSimpleGState = false;
promise = promise.then(() =>
this.handleSMask(
promise = promise.then(() => {
return this.handleSMask(
value,
resources,
operatorList,
task,
stateManager,
localColorSpaceCache
)
);
);
});
gStateObj.push([key, true]);
} else {
warn("Unsupported SMask type");
@ -1188,15 +1196,15 @@ class PartialEvaluator {
break;
}
}
await promise;
return promise.then(function () {
if (gStateObj.length > 0) {
operatorList.addOp(OPS.setGState, [gStateObj]);
}
if (gStateObj.length > 0) {
operatorList.addOp(OPS.setGState, [gStateObj]);
}
if (isSimpleGState) {
localGStateCache.set(cacheKey, gStateRef, gStateObj);
}
if (isSimpleGState) {
localGStateCache.set(cacheKey, gStateRef, gStateObj);
}
});
}
loadFont(
@ -1206,7 +1214,6 @@ class PartialEvaluator {
fallbackFontDict = null,
cssFontInfo = null
) {
// eslint-disable-next-line arrow-body-style
const errorFont = async () => {
return new TranslatedFont({
loadedName: "g_font_error",
@ -1386,17 +1393,17 @@ class PartialEvaluator {
const y = args[1] + args[3];
minMax = [
Math.min(args[0], x),
Math.min(args[1], y),
Math.max(args[0], x),
Math.min(args[1], y),
Math.max(args[1], y),
];
break;
case OPS.moveTo:
case OPS.lineTo:
minMax = [args[0], args[1], args[0], args[1]];
minMax = [args[0], args[0], args[1], args[1]];
break;
default:
minMax = [Infinity, Infinity, -Infinity, -Infinity];
minMax = [Infinity, -Infinity, Infinity, -Infinity];
break;
}
operatorList.addOp(OPS.constructPath, [[fn], args, minMax]);
@ -1420,15 +1427,15 @@ class PartialEvaluator {
const x = args[0] + args[2];
const y = args[1] + args[3];
minMax[0] = Math.min(minMax[0], args[0], x);
minMax[1] = Math.min(minMax[1], args[1], y);
minMax[2] = Math.max(minMax[2], args[0], x);
minMax[1] = Math.max(minMax[1], args[0], x);
minMax[2] = Math.min(minMax[2], args[1], y);
minMax[3] = Math.max(minMax[3], args[1], y);
break;
case OPS.moveTo:
case OPS.lineTo:
minMax[0] = Math.min(minMax[0], args[0]);
minMax[1] = Math.min(minMax[1], args[1]);
minMax[2] = Math.max(minMax[2], args[0]);
minMax[1] = Math.max(minMax[1], args[0]);
minMax[2] = Math.min(minMax[2], args[1]);
minMax[3] = Math.max(minMax[3], args[1]);
break;
}
@ -2184,7 +2191,6 @@ class PartialEvaluator {
case OPS.beginMarkedContentProps:
if (!(args[0] instanceof Name)) {
warn(`Expected name for beginMarkedContentProps arg0=${args[0]}`);
operatorList.addOp(OPS.beginMarkedContentProps, ["OC", null]);
continue;
}
if (args[0].name === "OC") {
@ -2205,10 +2211,6 @@ class PartialEvaluator {
warn(
`getOperatorList - ignoring beginMarkedContentProps: "${reason}".`
);
operatorList.addOp(OPS.beginMarkedContentProps, [
"OC",
null,
]);
return;
}
throw reason;
@ -2279,7 +2281,6 @@ class PartialEvaluator {
viewBox,
markedContentData = null,
disableNormalization = false,
keepWhiteSpace = false,
}) {
// Ensure that `resources`/`stateManager` is correctly initialized,
// even if the provided parameter is e.g. `null`.
@ -2346,12 +2347,11 @@ class PartialEvaluator {
twoLastChars[twoLastCharsPos] = char;
twoLastCharsPos = nextPos;
return !keepWhiteSpace && ret;
return ret;
}
function shouldAddWhitepsace() {
return (
!keepWhiteSpace &&
twoLastChars[twoLastCharsPos] !== " " &&
twoLastChars[(twoLastCharsPos + 1) % 2] === " "
);
@ -2554,21 +2554,29 @@ class PartialEvaluator {
};
}
async function handleSetFont(fontName, fontRef) {
const translated = await self.loadFont(fontName, fontRef, resources);
if (translated.font.isType3Font) {
try {
await translated.loadType3Data(self, resources, task);
} catch {
// Ignore Type3-parsing errors, since we only use `loadType3Data`
// here to ensure that we'll always obtain a useful /FontBBox.
}
}
textState.loadedName = translated.loadedName;
textState.font = translated.font;
textState.fontMatrix = translated.font.fontMatrix || FONT_IDENTITY_MATRIX;
function handleSetFont(fontName, fontRef) {
return self
.loadFont(fontName, fontRef, resources)
.then(function (translated) {
if (!translated.font.isType3Font) {
return translated;
}
return translated
.loadType3Data(self, resources, task)
.catch(function () {
// Ignore Type3-parsing errors, since we only use `loadType3Data`
// here to ensure that we'll always obtain a useful /FontBBox.
})
.then(function () {
return translated;
});
})
.then(function (translated) {
textState.loadedName = translated.loadedName;
textState.font = translated.font;
textState.fontMatrix =
translated.font.fontMatrix || FONT_IDENTITY_MATRIX;
});
}
function applyInverseRotation(x, y, matrix) {
@ -2806,10 +2814,6 @@ class PartialEvaluator {
}
}
if (keepWhiteSpace) {
compareWithLastPosition(0);
}
return;
}
@ -2832,7 +2836,7 @@ class PartialEvaluator {
}
let scaledDim = glyphWidth * scale;
if (!keepWhiteSpace && category.isWhitespace) {
if (category.isWhitespace) {
// Don't push a " " in the textContentItem
// (except when it's between two non-spaces chars),
// it will be done (if required) in next call to
@ -3268,7 +3272,6 @@ class PartialEvaluator {
viewBox,
markedContentData,
disableNormalization,
keepWhiteSpace,
})
.then(function () {
if (!sinkWrapper.enqueueInvoked) {
@ -3433,11 +3436,13 @@ class PartialEvaluator {
});
}
async extractDataStructures(dict, properties) {
extractDataStructures(dict, baseDict, properties) {
const xref = this.xref;
let cidToGidBytes;
// 9.10.2
const toUnicodePromise = this.readToUnicode(properties.toUnicode);
const toUnicodePromise = this.readToUnicode(
properties.toUnicode || dict.get("ToUnicode") || baseDict.get("ToUnicode")
);
if (properties.composite) {
// CIDSystemInfo helps to match CID to glyphs
@ -3557,19 +3562,21 @@ class PartialEvaluator {
properties.baseEncodingName = baseEncodingName;
properties.hasEncoding = !!baseEncodingName || differences.length > 0;
properties.dict = dict;
properties.toUnicode = await toUnicodePromise;
const builtToUnicode = await this.buildToUnicode(properties);
properties.toUnicode = builtToUnicode;
if (cidToGidBytes) {
properties.cidToGidMap = this.readCidToGidMap(
cidToGidBytes,
builtToUnicode
);
}
return properties;
return toUnicodePromise
.then(readToUnicode => {
properties.toUnicode = readToUnicode;
return this.buildToUnicode(properties);
})
.then(builtToUnicode => {
properties.toUnicode = builtToUnicode;
if (cidToGidBytes) {
properties.cidToGidMap = this.readCidToGidMap(
cidToGidBytes,
builtToUnicode
);
}
return properties;
});
}
/**
@ -3719,9 +3726,7 @@ class PartialEvaluator {
properties.composite &&
((properties.cMap.builtInCMap &&
!(properties.cMap instanceof IdentityCMap)) ||
// The font is supposed to have a CIDSystemInfo dictionary, but some
// PDFs don't include it (fixes issue 17689), hence the `?'.
(properties.cidSystemInfo?.registry === "Adobe" &&
(properties.cidSystemInfo.registry === "Adobe" &&
(properties.cidSystemInfo.ordering === "GB1" ||
properties.cidSystemInfo.ordering === "CNS1" ||
properties.cidSystemInfo.ordering === "Japan1" ||
@ -3770,70 +3775,70 @@ class PartialEvaluator {
return new IdentityToUnicodeMap(properties.firstChar, properties.lastChar);
}
async readToUnicode(cmapObj) {
readToUnicode(cmapObj) {
if (!cmapObj) {
return null;
return Promise.resolve(null);
}
if (cmapObj instanceof Name) {
const cmap = await CMapFactory.create({
return CMapFactory.create({
encoding: cmapObj,
fetchBuiltInCMap: this._fetchBuiltInCMapBound,
useCMap: null,
});
if (cmap instanceof IdentityCMap) {
return new IdentityToUnicodeMap(0, 0xffff);
}
return new ToUnicodeMap(cmap.getMap());
}
if (cmapObj instanceof BaseStream) {
try {
const cmap = await CMapFactory.create({
encoding: cmapObj,
fetchBuiltInCMap: this._fetchBuiltInCMapBound,
useCMap: null,
});
}).then(function (cmap) {
if (cmap instanceof IdentityCMap) {
return new IdentityToUnicodeMap(0, 0xffff);
}
const map = new Array(cmap.length);
// Convert UTF-16BE
// NOTE: cmap can be a sparse array, so use forEach instead of
// `for(;;)` to iterate over all keys.
cmap.forEach(function (charCode, token) {
// Some cmaps contain *only* CID characters (fixes issue9367.pdf).
if (typeof token === "number") {
map[charCode] = String.fromCodePoint(token);
return;
return new ToUnicodeMap(cmap.getMap());
});
} else if (cmapObj instanceof BaseStream) {
return CMapFactory.create({
encoding: cmapObj,
fetchBuiltInCMap: this._fetchBuiltInCMapBound,
useCMap: null,
}).then(
function (cmap) {
if (cmap instanceof IdentityCMap) {
return new IdentityToUnicodeMap(0, 0xffff);
}
const str = [];
for (let k = 0; k < token.length; k += 2) {
const w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);
if ((w1 & 0xf800) !== 0xd800) {
// w1 < 0xD800 || w1 > 0xDFFF
str.push(w1);
continue;
const map = new Array(cmap.length);
// Convert UTF-16BE
// NOTE: cmap can be a sparse array, so use forEach instead of
// `for(;;)` to iterate over all keys.
cmap.forEach(function (charCode, token) {
// Some cmaps contain *only* CID characters (fixes issue9367.pdf).
if (typeof token === "number") {
map[charCode] = String.fromCodePoint(token);
return;
}
k += 2;
const w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);
str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
const str = [];
for (let k = 0; k < token.length; k += 2) {
const w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);
if ((w1 & 0xf800) !== 0xd800) {
// w1 < 0xD800 || w1 > 0xDFFF
str.push(w1);
continue;
}
k += 2;
const w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);
str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
}
map[charCode] = String.fromCodePoint(...str);
});
return new ToUnicodeMap(map);
},
reason => {
if (reason instanceof AbortException) {
return null;
}
map[charCode] = String.fromCodePoint(...str);
});
return new ToUnicodeMap(map);
} catch (reason) {
if (reason instanceof AbortException) {
return null;
if (this.options.ignoreErrors) {
warn(`readToUnicode - ignoring ToUnicode data: "${reason}".`);
return null;
}
throw reason;
}
if (this.options.ignoreErrors) {
warn(`readToUnicode - ignoring ToUnicode data: "${reason}".`);
return null;
}
throw reason;
}
);
}
return null;
return Promise.resolve(null);
}
readCidToGidMap(glyphsData, toUnicode) {
@ -3962,7 +3967,7 @@ class PartialEvaluator {
isSerifFont(baseFontName) {
// Simulating descriptor flags attribute
const fontNameWoStyle = baseFontName.split("-", 1)[0];
const fontNameWoStyle = baseFontName.split("-")[0];
return (
fontNameWoStyle in getSerifFonts() || /serif/gi.test(fontNameWoStyle)
);
@ -4022,7 +4027,7 @@ class PartialEvaluator {
}
let composite = false;
let hash;
let hash, toUnicode;
if (type.name === "Type0") {
// If font is a composite
// - get the descendant font
@ -4047,8 +4052,6 @@ class PartialEvaluator {
const firstChar = dict.get("FirstChar") || 0,
lastChar = dict.get("LastChar") || (composite ? 0xffff : 0xff);
const descriptor = dict.get("FontDescriptor");
const toUnicode = dict.get("ToUnicode") || baseDict.get("ToUnicode");
if (descriptor) {
hash = new MurmurHash3_64();
@ -4086,6 +4089,7 @@ class PartialEvaluator {
hash.update(`${firstChar}-${lastChar}`); // Fixes issue10665_reduced.pdf
toUnicode = dict.get("ToUnicode") || baseDict.get("ToUnicode");
if (toUnicode instanceof BaseStream) {
const stream = toUnicode.str || toUnicode;
const uint8array = stream.buffer
@ -4170,6 +4174,7 @@ class PartialEvaluator {
cssFontInfo,
}) {
const isType3Font = type === "Type3";
let properties;
if (!descriptor) {
if (isType3Font) {
@ -4192,7 +4197,7 @@ class PartialEvaluator {
const metrics = this.getBaseFontMetrics(baseFontName);
// Simulating descriptor flags attribute
const fontNameWoStyle = baseFontName.split("-", 1)[0];
const fontNameWoStyle = baseFontName.split("-")[0];
const flags =
(this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) |
(metrics.monospace ? FontFlags.FixedPitch : 0) |
@ -4200,7 +4205,7 @@ class PartialEvaluator {
? FontFlags.Symbolic
: FontFlags.Nonsymbolic);
const properties = {
properties = {
type,
name: baseFontName,
loadedName: baseDict.loadedName,
@ -4234,25 +4239,24 @@ class PartialEvaluator {
standardFontName
);
}
const newProperties = await this.extractDataStructures(
dict,
properties
);
if (widths) {
const glyphWidths = [];
let j = firstChar;
for (const width of widths) {
glyphWidths[j++] = this.xref.fetchIfRef(width);
return this.extractDataStructures(dict, dict, properties).then(
newProperties => {
if (widths) {
const glyphWidths = [];
let j = firstChar;
for (const width of widths) {
glyphWidths[j++] = this.xref.fetchIfRef(width);
}
newProperties.widths = glyphWidths;
} else {
newProperties.widths = this.buildCharCodeToWidth(
metrics.widths,
newProperties
);
}
return new Font(baseFontName, file, newProperties);
}
newProperties.widths = glyphWidths;
} else {
newProperties.widths = this.buildCharCodeToWidth(
metrics.widths,
newProperties
);
}
return new Font(baseFontName, file, newProperties);
);
}
}
@ -4356,7 +4360,7 @@ class PartialEvaluator {
}
}
const properties = {
properties = {
type,
name: fontName.name,
subtype,
@ -4399,10 +4403,13 @@ class PartialEvaluator {
properties.vertical = properties.cMap.vertical;
}
const newProperties = await this.extractDataStructures(dict, properties);
this.extractWidths(dict, descriptor, newProperties);
return this.extractDataStructures(dict, baseDict, properties).then(
newProperties => {
this.extractWidths(dict, descriptor, newProperties);
return new Font(fontName.name, fontFile, newProperties);
return new Font(fontName.name, fontFile, newProperties);
}
);
}
static buildFontPaths(font, glyphs, handler, evaluatorOptions) {
@ -4762,128 +4769,124 @@ class EvaluatorPreprocessor {
//
// If variableArgs === true: [0, `numArgs`] expected
// If variableArgs === false: exactly `numArgs` expected
return shadow(
this,
"opMap",
Object.assign(Object.create(null), {
// Graphic state
w: { id: OPS.setLineWidth, numArgs: 1, variableArgs: false },
J: { id: OPS.setLineCap, numArgs: 1, variableArgs: false },
j: { id: OPS.setLineJoin, numArgs: 1, variableArgs: false },
M: { id: OPS.setMiterLimit, numArgs: 1, variableArgs: false },
d: { id: OPS.setDash, numArgs: 2, variableArgs: false },
ri: { id: OPS.setRenderingIntent, numArgs: 1, variableArgs: false },
i: { id: OPS.setFlatness, numArgs: 1, variableArgs: false },
gs: { id: OPS.setGState, numArgs: 1, variableArgs: false },
q: { id: OPS.save, numArgs: 0, variableArgs: false },
Q: { id: OPS.restore, numArgs: 0, variableArgs: false },
cm: { id: OPS.transform, numArgs: 6, variableArgs: false },
return shadow(this, "opMap", {
// Graphic state
w: { id: OPS.setLineWidth, numArgs: 1, variableArgs: false },
J: { id: OPS.setLineCap, numArgs: 1, variableArgs: false },
j: { id: OPS.setLineJoin, numArgs: 1, variableArgs: false },
M: { id: OPS.setMiterLimit, numArgs: 1, variableArgs: false },
d: { id: OPS.setDash, numArgs: 2, variableArgs: false },
ri: { id: OPS.setRenderingIntent, numArgs: 1, variableArgs: false },
i: { id: OPS.setFlatness, numArgs: 1, variableArgs: false },
gs: { id: OPS.setGState, numArgs: 1, variableArgs: false },
q: { id: OPS.save, numArgs: 0, variableArgs: false },
Q: { id: OPS.restore, numArgs: 0, variableArgs: false },
cm: { id: OPS.transform, numArgs: 6, variableArgs: false },
// Path
m: { id: OPS.moveTo, numArgs: 2, variableArgs: false },
l: { id: OPS.lineTo, numArgs: 2, variableArgs: false },
c: { id: OPS.curveTo, numArgs: 6, variableArgs: false },
v: { id: OPS.curveTo2, numArgs: 4, variableArgs: false },
y: { id: OPS.curveTo3, numArgs: 4, variableArgs: false },
h: { id: OPS.closePath, numArgs: 0, variableArgs: false },
re: { id: OPS.rectangle, numArgs: 4, variableArgs: false },
S: { id: OPS.stroke, numArgs: 0, variableArgs: false },
s: { id: OPS.closeStroke, numArgs: 0, variableArgs: false },
f: { id: OPS.fill, numArgs: 0, variableArgs: false },
F: { id: OPS.fill, numArgs: 0, variableArgs: false },
"f*": { id: OPS.eoFill, numArgs: 0, variableArgs: false },
B: { id: OPS.fillStroke, numArgs: 0, variableArgs: false },
"B*": { id: OPS.eoFillStroke, numArgs: 0, variableArgs: false },
b: { id: OPS.closeFillStroke, numArgs: 0, variableArgs: false },
"b*": { id: OPS.closeEOFillStroke, numArgs: 0, variableArgs: false },
n: { id: OPS.endPath, numArgs: 0, variableArgs: false },
// Path
m: { id: OPS.moveTo, numArgs: 2, variableArgs: false },
l: { id: OPS.lineTo, numArgs: 2, variableArgs: false },
c: { id: OPS.curveTo, numArgs: 6, variableArgs: false },
v: { id: OPS.curveTo2, numArgs: 4, variableArgs: false },
y: { id: OPS.curveTo3, numArgs: 4, variableArgs: false },
h: { id: OPS.closePath, numArgs: 0, variableArgs: false },
re: { id: OPS.rectangle, numArgs: 4, variableArgs: false },
S: { id: OPS.stroke, numArgs: 0, variableArgs: false },
s: { id: OPS.closeStroke, numArgs: 0, variableArgs: false },
f: { id: OPS.fill, numArgs: 0, variableArgs: false },
F: { id: OPS.fill, numArgs: 0, variableArgs: false },
"f*": { id: OPS.eoFill, numArgs: 0, variableArgs: false },
B: { id: OPS.fillStroke, numArgs: 0, variableArgs: false },
"B*": { id: OPS.eoFillStroke, numArgs: 0, variableArgs: false },
b: { id: OPS.closeFillStroke, numArgs: 0, variableArgs: false },
"b*": { id: OPS.closeEOFillStroke, numArgs: 0, variableArgs: false },
n: { id: OPS.endPath, numArgs: 0, variableArgs: false },
// Clipping
W: { id: OPS.clip, numArgs: 0, variableArgs: false },
"W*": { id: OPS.eoClip, numArgs: 0, variableArgs: false },
// Clipping
W: { id: OPS.clip, numArgs: 0, variableArgs: false },
"W*": { id: OPS.eoClip, numArgs: 0, variableArgs: false },
// Text
BT: { id: OPS.beginText, numArgs: 0, variableArgs: false },
ET: { id: OPS.endText, numArgs: 0, variableArgs: false },
Tc: { id: OPS.setCharSpacing, numArgs: 1, variableArgs: false },
Tw: { id: OPS.setWordSpacing, numArgs: 1, variableArgs: false },
Tz: { id: OPS.setHScale, numArgs: 1, variableArgs: false },
TL: { id: OPS.setLeading, numArgs: 1, variableArgs: false },
Tf: { id: OPS.setFont, numArgs: 2, variableArgs: false },
Tr: { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false },
Ts: { id: OPS.setTextRise, numArgs: 1, variableArgs: false },
Td: { id: OPS.moveText, numArgs: 2, variableArgs: false },
TD: { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false },
Tm: { id: OPS.setTextMatrix, numArgs: 6, variableArgs: false },
"T*": { id: OPS.nextLine, numArgs: 0, variableArgs: false },
Tj: { id: OPS.showText, numArgs: 1, variableArgs: false },
TJ: { id: OPS.showSpacedText, numArgs: 1, variableArgs: false },
"'": { id: OPS.nextLineShowText, numArgs: 1, variableArgs: false },
'"': {
id: OPS.nextLineSetSpacingShowText,
numArgs: 3,
variableArgs: false,
},
// Text
BT: { id: OPS.beginText, numArgs: 0, variableArgs: false },
ET: { id: OPS.endText, numArgs: 0, variableArgs: false },
Tc: { id: OPS.setCharSpacing, numArgs: 1, variableArgs: false },
Tw: { id: OPS.setWordSpacing, numArgs: 1, variableArgs: false },
Tz: { id: OPS.setHScale, numArgs: 1, variableArgs: false },
TL: { id: OPS.setLeading, numArgs: 1, variableArgs: false },
Tf: { id: OPS.setFont, numArgs: 2, variableArgs: false },
Tr: { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false },
Ts: { id: OPS.setTextRise, numArgs: 1, variableArgs: false },
Td: { id: OPS.moveText, numArgs: 2, variableArgs: false },
TD: { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false },
Tm: { id: OPS.setTextMatrix, numArgs: 6, variableArgs: false },
"T*": { id: OPS.nextLine, numArgs: 0, variableArgs: false },
Tj: { id: OPS.showText, numArgs: 1, variableArgs: false },
TJ: { id: OPS.showSpacedText, numArgs: 1, variableArgs: false },
"'": { id: OPS.nextLineShowText, numArgs: 1, variableArgs: false },
'"': {
id: OPS.nextLineSetSpacingShowText,
numArgs: 3,
variableArgs: false,
},
// Type3 fonts
d0: { id: OPS.setCharWidth, numArgs: 2, variableArgs: false },
d1: {
id: OPS.setCharWidthAndBounds,
numArgs: 6,
variableArgs: false,
},
// Type3 fonts
d0: { id: OPS.setCharWidth, numArgs: 2, variableArgs: false },
d1: {
id: OPS.setCharWidthAndBounds,
numArgs: 6,
variableArgs: false,
},
// Color
CS: { id: OPS.setStrokeColorSpace, numArgs: 1, variableArgs: false },
cs: { id: OPS.setFillColorSpace, numArgs: 1, variableArgs: false },
SC: { id: OPS.setStrokeColor, numArgs: 4, variableArgs: true },
SCN: { id: OPS.setStrokeColorN, numArgs: 33, variableArgs: true },
sc: { id: OPS.setFillColor, numArgs: 4, variableArgs: true },
scn: { id: OPS.setFillColorN, numArgs: 33, variableArgs: true },
G: { id: OPS.setStrokeGray, numArgs: 1, variableArgs: false },
g: { id: OPS.setFillGray, numArgs: 1, variableArgs: false },
RG: { id: OPS.setStrokeRGBColor, numArgs: 3, variableArgs: false },
rg: { id: OPS.setFillRGBColor, numArgs: 3, variableArgs: false },
K: { id: OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: false },
k: { id: OPS.setFillCMYKColor, numArgs: 4, variableArgs: false },
// Color
CS: { id: OPS.setStrokeColorSpace, numArgs: 1, variableArgs: false },
cs: { id: OPS.setFillColorSpace, numArgs: 1, variableArgs: false },
SC: { id: OPS.setStrokeColor, numArgs: 4, variableArgs: true },
SCN: { id: OPS.setStrokeColorN, numArgs: 33, variableArgs: true },
sc: { id: OPS.setFillColor, numArgs: 4, variableArgs: true },
scn: { id: OPS.setFillColorN, numArgs: 33, variableArgs: true },
G: { id: OPS.setStrokeGray, numArgs: 1, variableArgs: false },
g: { id: OPS.setFillGray, numArgs: 1, variableArgs: false },
RG: { id: OPS.setStrokeRGBColor, numArgs: 3, variableArgs: false },
rg: { id: OPS.setFillRGBColor, numArgs: 3, variableArgs: false },
K: { id: OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: false },
k: { id: OPS.setFillCMYKColor, numArgs: 4, variableArgs: false },
// Shading
sh: { id: OPS.shadingFill, numArgs: 1, variableArgs: false },
// Shading
sh: { id: OPS.shadingFill, numArgs: 1, variableArgs: false },
// Images
BI: { id: OPS.beginInlineImage, numArgs: 0, variableArgs: false },
ID: { id: OPS.beginImageData, numArgs: 0, variableArgs: false },
EI: { id: OPS.endInlineImage, numArgs: 1, variableArgs: false },
// Images
BI: { id: OPS.beginInlineImage, numArgs: 0, variableArgs: false },
ID: { id: OPS.beginImageData, numArgs: 0, variableArgs: false },
EI: { id: OPS.endInlineImage, numArgs: 1, variableArgs: false },
// XObjects
Do: { id: OPS.paintXObject, numArgs: 1, variableArgs: false },
MP: { id: OPS.markPoint, numArgs: 1, variableArgs: false },
DP: { id: OPS.markPointProps, numArgs: 2, variableArgs: false },
BMC: { id: OPS.beginMarkedContent, numArgs: 1, variableArgs: false },
BDC: {
id: OPS.beginMarkedContentProps,
numArgs: 2,
variableArgs: false,
},
EMC: { id: OPS.endMarkedContent, numArgs: 0, variableArgs: false },
// XObjects
Do: { id: OPS.paintXObject, numArgs: 1, variableArgs: false },
MP: { id: OPS.markPoint, numArgs: 1, variableArgs: false },
DP: { id: OPS.markPointProps, numArgs: 2, variableArgs: false },
BMC: { id: OPS.beginMarkedContent, numArgs: 1, variableArgs: false },
BDC: {
id: OPS.beginMarkedContentProps,
numArgs: 2,
variableArgs: false,
},
EMC: { id: OPS.endMarkedContent, numArgs: 0, variableArgs: false },
// Compatibility
BX: { id: OPS.beginCompat, numArgs: 0, variableArgs: false },
EX: { id: OPS.endCompat, numArgs: 0, variableArgs: false },
// Compatibility
BX: { id: OPS.beginCompat, numArgs: 0, variableArgs: false },
EX: { id: OPS.endCompat, numArgs: 0, variableArgs: false },
// (reserved partial commands for the lexer)
BM: null,
BD: null,
true: null,
fa: null,
fal: null,
fals: null,
false: null,
nu: null,
nul: null,
null: null,
})
);
// (reserved partial commands for the lexer)
BM: null,
BD: null,
true: null,
fa: null,
fal: null,
fals: null,
false: null,
nu: null,
nul: null,
null: null,
});
}
static MAX_INVALID_PATH_OPS = 10;

View File

@ -48,8 +48,6 @@ const substitutionMap = new Map([
"Thorndale",
"TeX Gyre Termes",
"FreeSerif",
"Linux Libertine O",
"Libertinus Serif",
"DejaVu Serif",
"Bitstream Vera Serif",
"Ubuntu",
@ -150,8 +148,6 @@ const substitutionMap = new Map([
"Cumberland",
"TeX Gyre Cursor",
"FreeMono",
"Linux Libertine Mono O",
"Libertinus Mono",
],
style: NORMAL,
ultimate: "monospace",
@ -327,48 +323,6 @@ function getStyleToAppend(style) {
return "";
}
function getFamilyName(str) {
// See https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/14d466b30a8ab4a9d789977ed94f2c30e7209267/src/fcname.c#L137.
const keywords = new Set([
"thin",
"extralight",
"ultralight",
"demilight",
"semilight",
"light",
"book",
"regular",
"normal",
"medium",
"demibold",
"semibold",
"bold",
"extrabold",
"ultrabold",
"black",
"heavy",
"extrablack",
"ultrablack",
"roman",
"italic",
"oblique",
"ultracondensed",
"extracondensed",
"condensed",
"semicondensed",
"normal",
"semiexpanded",
"expanded",
"extraexpanded",
"ultraexpanded",
"bolditalic",
]);
return str
.split(/[- ,+]+/g)
.filter(tok => !keywords.has(tok.toLowerCase()))
.join(" ");
}
/**
* Generate font description.
* @param {Object} param0, font substitution description.
@ -516,7 +470,7 @@ function getFontSubstitution(
(italic && ITALIC) ||
NORMAL;
substitutionInfo = {
css: `"${getFamilyName(baseFontName)}",${loadedName}`,
css: loadedName,
guessFallback: true,
loadedName,
baseFontName,
@ -538,7 +492,7 @@ function getFontSubstitution(
const fallback = guessFallback ? "" : `,${ultimate}`;
substitutionInfo = {
css: `"${getFamilyName(baseFontName)}",${loadedName}${fallback}`,
css: `${loadedName}${fallback}`,
guessFallback,
loadedName,
baseFontName,

View File

@ -968,7 +968,7 @@ class Font {
// Fallback to checking the font name, in order to improve text-selection,
// since the /Flags-entry is often wrong (fixes issue13845.pdf).
if (!isSerifFont && !properties.isSimulatedFlags) {
const baseName = name.replaceAll(/[,_]/g, "-").split("-", 1)[0],
const baseName = name.replaceAll(/[,_]/g, "-").split("-")[0],
serifFonts = getSerifFonts();
for (const namePart of baseName.split("+")) {
if (serifFonts[namePart]) {
@ -1286,7 +1286,7 @@ class Font {
}
amendFallbackToUnicode(properties);
this.loadedName = fontName.split("-", 1)[0];
this.loadedName = fontName.split("-")[0];
}
checkAndRepair(name, font, properties) {
@ -2093,7 +2093,9 @@ class Font {
endOffset: 0,
});
}
locaEntries.sort((a, b) => a.offset - b.offset);
locaEntries.sort((a, b) => {
return a.offset - b.offset;
});
// Now the offsets are sorted, calculate the end offset of each glyph.
// The last loca entry's endOffset is not calculated since it's the end
// of the data and will be stored on the previous entry's endOffset.
@ -2101,7 +2103,9 @@ class Font {
locaEntries[i].endOffset = locaEntries[i + 1].offset;
}
// Re-sort so glyphs aren't out of order.
locaEntries.sort((a, b) => a.index - b.index);
locaEntries.sort((a, b) => {
return a.index - b.index;
});
// Calculate the endOffset of the "first" glyph correctly when there are
// *multiple* empty ones at the start of the data (fixes issue14618.pdf).
for (i = 0; i < numGlyphs; i++) {
@ -2117,14 +2121,6 @@ class Font {
break;
}
// If the last offset is 0 in the loca table then we can't compute the
// endOffset for the last glyph. So in such a case we set the endOffset
// to the end of the data (fixes issue #17671).
const last = locaEntries.at(-2);
if (last.offset !== 0 && last.endOffset === 0) {
last.endOffset = oldGlyfDataLength;
}
const missingGlyphs = Object.create(null);
let writeOffset = 0;
itemEncode(locaData, 0, writeOffset);

View File

@ -35,7 +35,7 @@ import {
getNewAnnotationsMap,
XRefParseException,
} from "./core_utils.js";
import { Dict, isDict, Ref } from "./primitives.js";
import { Dict, Ref } from "./primitives.js";
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
import { AnnotationFactory } from "./annotation.js";
import { clearGlobalCaches } from "./cleanup_helper.js";
@ -726,8 +726,6 @@ class WorkerMessageHandler {
acroFormRef,
acroForm,
xfaData,
// Use the same kind of XRef as the previous one.
useXrefStream: isDict(xref.topDict, "XRef"),
}).finally(() => {
xref.resetNewTemporaryRef();
});
@ -882,9 +880,6 @@ class WorkerMessageHandler {
.ensureXRef("trailer")
.then(trailer => trailer.get("Prev"));
});
handler.on("GetStartXRefPos", function (data) {
return pdfManager.ensureDoc("startXRef");
});
handler.on("GetAnnotArray", function (data) {
return pdfManager.getPage(data.pageIndex).then(function (page) {
return page.annotations.map(a => a.toString());

View File

@ -18,14 +18,12 @@ import { Dict, isName, Name, Ref } from "./primitives.js";
import {
escapePDFName,
escapeString,
getSizeInBytes,
numberToString,
parseXFAPath,
} from "./core_utils.js";
import { SimpleDOMNode, SimpleXMLParser } from "./xml_parser.js";
import { BaseStream } from "./base_stream.js";
import { calculateMD5 } from "./crypto.js";
import { Stream } from "./stream.js";
async function writeObject(ref, obj, buffer, { encrypt = null }) {
const transform = encrypt?.createCipherTransform(ref.num, ref.gen);
@ -34,7 +32,7 @@ async function writeObject(ref, obj, buffer, { encrypt = null }) {
await writeDict(obj, buffer, transform);
} else if (obj instanceof BaseStream) {
await writeStream(obj, buffer, transform);
} else if (Array.isArray(obj) || ArrayBuffer.isView(obj)) {
} else if (Array.isArray(obj)) {
await writeArray(obj, buffer, transform);
}
buffer.push("\nendobj\n");
@ -134,7 +132,7 @@ async function writeValue(value, buffer, transform) {
buffer.push(`/${escapePDFName(value.name)}`);
} else if (value instanceof Ref) {
buffer.push(`${value.num} ${value.gen} R`);
} else if (Array.isArray(value) || ArrayBuffer.isView(value)) {
} else if (Array.isArray(value)) {
await writeArray(value, buffer, transform);
} else if (typeof value === "string") {
if (transform) {
@ -283,112 +281,6 @@ function updateXFA({ xfaData, xfaDatasetsRef, newRefs, xref }) {
newRefs.push({ ref: xfaDatasetsRef, data });
}
async function getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer) {
buffer.push("xref\n");
const indexes = getIndexes(newRefs);
let indexesPosition = 0;
for (const { ref, data } of newRefs) {
if (ref.num === indexes[indexesPosition]) {
buffer.push(
`${indexes[indexesPosition]} ${indexes[indexesPosition + 1]}\n`
);
indexesPosition += 2;
}
// The EOL is \r\n to make sure that every entry is exactly 20 bytes long.
// (see 7.5.4 - Cross-Reference Table).
buffer.push(
`${baseOffset.toString().padStart(10, "0")} ${Math.min(ref.gen, 0xffff).toString().padStart(5, "0")} n\r\n`
);
baseOffset += data.length;
}
computeIDs(baseOffset, xrefInfo, newXref);
buffer.push("trailer\n");
await writeDict(newXref, buffer);
buffer.push("\nstartxref\n", baseOffset.toString(), "\n%%EOF\n");
}
function getIndexes(newRefs) {
const indexes = [];
for (const { ref } of newRefs) {
if (ref.num === indexes.at(-2) + indexes.at(-1)) {
indexes[indexes.length - 1] += 1;
} else {
indexes.push(ref.num, 1);
}
}
return indexes;
}
async function getXRefStreamTable(
xrefInfo,
baseOffset,
newRefs,
newXref,
buffer
) {
const xrefTableData = [];
let maxOffset = 0;
let maxGen = 0;
for (const { ref, data } of newRefs) {
maxOffset = Math.max(maxOffset, baseOffset);
const gen = Math.min(ref.gen, 0xffff);
maxGen = Math.max(maxGen, gen);
xrefTableData.push([1, baseOffset, gen]);
baseOffset += data.length;
}
newXref.set("Index", getIndexes(newRefs));
const offsetSize = getSizeInBytes(maxOffset);
const maxGenSize = getSizeInBytes(maxGen);
const sizes = [1, offsetSize, maxGenSize];
newXref.set("W", sizes);
computeIDs(baseOffset, xrefInfo, newXref);
const structSize = sizes.reduce((a, x) => a + x, 0);
const data = new Uint8Array(structSize * xrefTableData.length);
const stream = new Stream(data);
stream.dict = newXref;
let offset = 0;
for (const [type, objOffset, gen] of xrefTableData) {
offset = writeInt(type, sizes[0], offset, data);
offset = writeInt(objOffset, sizes[1], offset, data);
offset = writeInt(gen, sizes[2], offset, data);
}
await writeObject(xrefInfo.newRef, stream, buffer, {});
buffer.push("startxref\n", baseOffset.toString(), "\n%%EOF\n");
}
function computeIDs(baseOffset, xrefInfo, newXref) {
if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) {
const md5 = computeMD5(baseOffset, xrefInfo);
newXref.set("ID", [xrefInfo.fileIds[0], md5]);
}
}
function getTrailerDict(xrefInfo, newRefs, useXrefStream) {
const newXref = new Dict(null);
newXref.set("Prev", xrefInfo.startXRef);
const refForXrefTable = xrefInfo.newRef;
if (useXrefStream) {
newRefs.push({ ref: refForXrefTable, data: "" });
newXref.set("Size", refForXrefTable.num + 1);
newXref.set("Type", Name.get("XRef"));
} else {
newXref.set("Size", refForXrefTable.num);
}
if (xrefInfo.rootRef !== null) {
newXref.set("Root", xrefInfo.rootRef);
}
if (xrefInfo.infoRef !== null) {
newXref.set("Info", xrefInfo.infoRef);
}
if (xrefInfo.encryptRef !== null) {
newXref.set("Encrypt", xrefInfo.encryptRef);
}
return newXref;
}
async function incrementalUpdate({
originalData,
xrefInfo,
@ -401,7 +293,6 @@ async function incrementalUpdate({
acroFormRef = null,
acroForm = null,
xfaData = null,
useXrefStream = false,
}) {
await updateAcroform({
xref,
@ -423,6 +314,9 @@ async function incrementalUpdate({
});
}
const newXref = new Dict(null);
const refForXrefTable = xrefInfo.newRef;
let buffer, baseOffset;
const lastByte = originalData.at(-1);
if (lastByte === /* \n */ 0x0a || lastByte === /* \r */ 0x0d) {
@ -434,23 +328,61 @@ async function incrementalUpdate({
baseOffset = originalData.length + 1;
}
const newXref = getTrailerDict(xrefInfo, newRefs, useXrefStream);
newRefs = newRefs.sort(
(a, b) => /* compare the refs */ a.ref.num - b.ref.num
);
for (const { data } of newRefs) {
newXref.set("Size", refForXrefTable.num + 1);
newXref.set("Prev", xrefInfo.startXRef);
newXref.set("Type", Name.get("XRef"));
if (xrefInfo.rootRef !== null) {
newXref.set("Root", xrefInfo.rootRef);
}
if (xrefInfo.infoRef !== null) {
newXref.set("Info", xrefInfo.infoRef);
}
if (xrefInfo.encryptRef !== null) {
newXref.set("Encrypt", xrefInfo.encryptRef);
}
// Add a ref for the new xref and sort them
newRefs.push({ ref: refForXrefTable, data: "" });
newRefs = newRefs.sort((a, b) => {
// compare the refs
return a.ref.num - b.ref.num;
});
const xrefTableData = [[0, 1, 0xffff]];
const indexes = [0, 1];
let maxOffset = 0;
for (const { ref, data } of newRefs) {
maxOffset = Math.max(maxOffset, baseOffset);
xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]);
baseOffset += data.length;
indexes.push(ref.num, 1);
buffer.push(data);
}
await (useXrefStream
? getXRefStreamTable(xrefInfo, baseOffset, newRefs, newXref, buffer)
: getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer));
newXref.set("Index", indexes);
const totalLength = buffer.reduce(
(a, str) => a + str.length,
originalData.length
if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) {
const md5 = computeMD5(baseOffset, xrefInfo);
newXref.set("ID", [xrefInfo.fileIds[0], md5]);
}
const offsetSize = Math.ceil(Math.log2(maxOffset) / 8);
const sizes = [1, offsetSize, 2];
const structSize = sizes[0] + sizes[1] + sizes[2];
const tableLength = structSize * xrefTableData.length;
newXref.set("W", sizes);
newXref.set("Length", tableLength);
buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`);
await writeDict(newXref, buffer, null);
buffer.push(" stream\n");
const bufferLen = buffer.reduce((a, str) => a + str.length, 0);
const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`;
const array = new Uint8Array(
originalData.length + bufferLen + tableLength + footer.length
);
const array = new Uint8Array(totalLength);
// Original data
array.set(originalData);
@ -462,6 +394,16 @@ async function incrementalUpdate({
offset += str.length;
}
// New xref table
for (const [type, objOffset, gen] of xrefTableData) {
offset = writeInt(type, sizes[0], offset, array);
offset = writeInt(objOffset, sizes[1], offset, array);
offset = writeInt(gen, sizes[2], offset, array);
}
// Add the footer
writeString(footer, offset, array);
return array;
}

View File

@ -129,10 +129,12 @@ function getRelevant(data) {
return data
.trim()
.split(/\s+/)
.map(e => ({
excluded: e[0] === "-",
viewname: e.substring(1),
}));
.map(e => {
return {
excluded: e[0] === "-",
viewname: e.substring(1),
};
});
}
function getColor(data, def = [0, 0, 0]) {

View File

@ -1838,10 +1838,9 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
const getItems = event => {
const options = event.target.options;
return Array.prototype.map.call(options, option => ({
displayValue: option.textContent,
exportValue: option.value,
}));
return Array.prototype.map.call(options, option => {
return { displayValue: option.textContent, exportValue: option.value };
});
};
if (this.enableScripting && this.hasJSActions) {
@ -2890,7 +2889,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
* @property {Array} annotations
* @property {PDFPageProxy} page
* @property {IPDFLinkService} linkService
* @property {IDownloadManager} [downloadManager]
* @property {IDownloadManager} downloadManager
* @property {AnnotationStorage} [annotationStorage]
* @property {string} [imageResourcesPath] - Path for image resources, mainly
* for annotation icons. Include trailing slash.

View File

@ -212,42 +212,6 @@ class AnnotationStorage {
? { map, hash: hash.hexdigest(), transfer }
: SerializableEmpty;
}
get editorStats() {
let stats = null;
const typeToEditor = new Map();
for (const value of this.#storage.values()) {
if (!(value instanceof AnnotationEditor)) {
continue;
}
const editorStats = value.telemetryFinalData;
if (!editorStats) {
continue;
}
const { type } = editorStats;
if (!typeToEditor.has(type)) {
typeToEditor.set(type, Object.getPrototypeOf(value).constructor);
}
stats ||= Object.create(null);
const map = (stats[type] ||= new Map());
for (const [key, val] of Object.entries(editorStats)) {
if (key === "type") {
continue;
}
let counters = map.get(key);
if (!counters) {
counters = new Map();
map.set(key, counters);
}
const count = counters.get(val) ?? 0;
counters.set(val, count + 1);
}
}
for (const [type, editor] of typeToEditor) {
stats[type] = editor.computeTelemetryFinalData(stats[type]);
}
return stats;
}
}
/**

Some files were not shown because too many files have changed in this diff Show More