mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-03 04:47:21 +02:00
Compare commits
12 Commits
d74619847d
...
a8ad7d6485
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8ad7d6485 | ||
|
|
319d239f41 | ||
|
|
e4795f639c | ||
|
|
643c44b631 | ||
|
|
0cbb2b1d13 | ||
|
|
bec6287b0a | ||
|
|
7bc7416111 | ||
|
|
ee34c5c648 | ||
|
|
92adc7ea1b | ||
|
|
2ff6829e47 | ||
|
|
4ebcc996d0 | ||
|
|
216e17afc5 |
@ -529,8 +529,8 @@ pdfjs-editor-add-signature-dialog-title = Gehitu sinadura
|
|||||||
## Tab names
|
## Tab names
|
||||||
|
|
||||||
# Type is a verb (you can type your name as signature)
|
# Type is a verb (you can type your name as signature)
|
||||||
pdfjs-editor-add-signature-type-button = Mota
|
pdfjs-editor-add-signature-type-button = Idatzi
|
||||||
.title = Mota
|
.title = Idatzi
|
||||||
# Draw is a verb (you can draw your signature)
|
# Draw is a verb (you can draw your signature)
|
||||||
pdfjs-editor-add-signature-draw-button = Marraztu
|
pdfjs-editor-add-signature-draw-button = Marraztu
|
||||||
.title = Marraztu
|
.title = Marraztu
|
||||||
|
|||||||
@ -316,6 +316,9 @@ pdfjs-highlight-floating-button1 =
|
|||||||
.title = Evidenzie
|
.title = Evidenzie
|
||||||
.aria-label = Evidenzie
|
.aria-label = Evidenzie
|
||||||
pdfjs-highlight-floating-button-label = Evidenzie
|
pdfjs-highlight-floating-button-label = Evidenzie
|
||||||
|
pdfjs-editor-signature-button =
|
||||||
|
.title = Zonte firme
|
||||||
|
pdfjs-editor-signature-button-label = Zonte firme
|
||||||
|
|
||||||
## Remove button for the various kind of editor.
|
## Remove button for the various kind of editor.
|
||||||
|
|
||||||
@ -345,6 +348,9 @@ pdfjs-editor-stamp-add-image-button-label = Zonte imagjin
|
|||||||
pdfjs-editor-free-highlight-thickness-input = Spessôr
|
pdfjs-editor-free-highlight-thickness-input = Spessôr
|
||||||
pdfjs-editor-free-highlight-thickness-title =
|
pdfjs-editor-free-highlight-thickness-title =
|
||||||
.title = Modifiche il spessôr de selezion pai elements che no son testuâi
|
.title = Modifiche il spessôr de selezion pai elements che no son testuâi
|
||||||
|
pdfjs-editor-signature-add-signature-button =
|
||||||
|
.title = Zonte gnove firme
|
||||||
|
pdfjs-editor-signature-add-signature-button-label = Zonte gnove firme
|
||||||
# .default-content is used as a placeholder in an empty text editor.
|
# .default-content is used as a placeholder in an empty text editor.
|
||||||
pdfjs-free-text2 =
|
pdfjs-free-text2 =
|
||||||
.aria-label = Editôr di test
|
.aria-label = Editôr di test
|
||||||
@ -570,12 +576,18 @@ pdfjs-editor-add-signature-error-close-button = Siere
|
|||||||
|
|
||||||
pdfjs-editor-add-signature-cancel-button = Anule
|
pdfjs-editor-add-signature-cancel-button = Anule
|
||||||
pdfjs-editor-add-signature-add-button = Zonte
|
pdfjs-editor-add-signature-add-button = Zonte
|
||||||
|
pdfjs-editor-edit-signature-update-button = Inzorne
|
||||||
|
|
||||||
## Main menu for adding/removing signatures
|
## Main menu for adding/removing signatures
|
||||||
|
|
||||||
|
pdfjs-editor-delete-signature-button =
|
||||||
|
.title = Gjave firme
|
||||||
|
pdfjs-editor-delete-signature-button-label = Gjave firme
|
||||||
|
|
||||||
## Editor toolbar
|
## Editor toolbar
|
||||||
|
|
||||||
|
pdfjs-editor-add-signature-edit-button-label = Modifiche descrizion
|
||||||
|
|
||||||
## Edit signature description dialog
|
## Edit signature description dialog
|
||||||
|
|
||||||
|
pdfjs-editor-edit-signature-dialog-title = Modifiche descrizion
|
||||||
|
|||||||
@ -316,6 +316,9 @@ pdfjs-highlight-floating-button1 =
|
|||||||
.title = Markearje
|
.title = Markearje
|
||||||
.aria-label = Markearje
|
.aria-label = Markearje
|
||||||
pdfjs-highlight-floating-button-label = Markearje
|
pdfjs-highlight-floating-button-label = Markearje
|
||||||
|
pdfjs-editor-signature-button =
|
||||||
|
.title = Hantekening tafoegje
|
||||||
|
pdfjs-editor-signature-button-label = Hantekening tafoegje
|
||||||
|
|
||||||
## Remove button for the various kind of editor.
|
## Remove button for the various kind of editor.
|
||||||
|
|
||||||
@ -345,6 +348,9 @@ pdfjs-editor-stamp-add-image-button-label = Ofbylding tafoegje
|
|||||||
pdfjs-editor-free-highlight-thickness-input = Tsjokte
|
pdfjs-editor-free-highlight-thickness-input = Tsjokte
|
||||||
pdfjs-editor-free-highlight-thickness-title =
|
pdfjs-editor-free-highlight-thickness-title =
|
||||||
.title = Tsjokte wizigje by aksintuearring fan oare items as tekst
|
.title = Tsjokte wizigje by aksintuearring fan oare items as tekst
|
||||||
|
pdfjs-editor-signature-add-signature-button =
|
||||||
|
.title = Nije hantekening tafoegje
|
||||||
|
pdfjs-editor-signature-add-signature-button-label = Nije hantekening tafoegje
|
||||||
# .default-content is used as a placeholder in an empty text editor.
|
# .default-content is used as a placeholder in an empty text editor.
|
||||||
pdfjs-free-text2 =
|
pdfjs-free-text2 =
|
||||||
.aria-label = Tekstbewurker
|
.aria-label = Tekstbewurker
|
||||||
@ -570,12 +576,17 @@ pdfjs-editor-add-signature-error-close-button = Slute
|
|||||||
|
|
||||||
pdfjs-editor-add-signature-cancel-button = Annulearje
|
pdfjs-editor-add-signature-cancel-button = Annulearje
|
||||||
pdfjs-editor-add-signature-add-button = Tafoegje
|
pdfjs-editor-add-signature-add-button = Tafoegje
|
||||||
|
pdfjs-editor-edit-signature-update-button = Bywurkje
|
||||||
|
|
||||||
## Main menu for adding/removing signatures
|
## Main menu for adding/removing signatures
|
||||||
|
|
||||||
|
pdfjs-editor-delete-signature-button =
|
||||||
|
.title = Hantekening fuortsmite
|
||||||
|
pdfjs-editor-delete-signature-button-label = Hantekening fuortsmite
|
||||||
|
|
||||||
## Editor toolbar
|
## Editor toolbar
|
||||||
|
|
||||||
|
pdfjs-editor-add-signature-edit-button-label = Beskriuwing bewurkje
|
||||||
|
|
||||||
## Edit signature description dialog
|
## Edit signature description dialog
|
||||||
|
|
||||||
|
|||||||
@ -566,6 +566,9 @@ pdfjs-editor-add-signature-clear-button-label = Emboguete teraguapy
|
|||||||
pdfjs-editor-add-signature-clear-button =
|
pdfjs-editor-add-signature-clear-button =
|
||||||
.title = Emboguete teraguapy
|
.title = Emboguete teraguapy
|
||||||
pdfjs-editor-add-signature-save-checkbox = Eñongatu teraguapy
|
pdfjs-editor-add-signature-save-checkbox = Eñongatu teraguapy
|
||||||
|
pdfjs-editor-add-signature-save-warning-message = Ehupytýma 5 mboheraguapy ñongatupyre. Embogue peteĩ eñongatukuaa jey hag̃ua.
|
||||||
|
pdfjs-editor-add-signature-image-upload-error-title = Ndaikatúi ojehupi pe ta’ãnga
|
||||||
|
pdfjs-editor-add-signature-image-upload-error-description = Ehechajey ne ñanduti oikópa térã aha’ã ambue ta’ãnga ndive.
|
||||||
pdfjs-editor-add-signature-error-close-button = Mboty
|
pdfjs-editor-add-signature-error-close-button = Mboty
|
||||||
|
|
||||||
## Dialog buttons
|
## Dialog buttons
|
||||||
|
|||||||
@ -39,6 +39,9 @@ pdfjs-open-file-button-label = Բացել
|
|||||||
pdfjs-print-button =
|
pdfjs-print-button =
|
||||||
.title = Տպել
|
.title = Տպել
|
||||||
pdfjs-print-button-label = Տպել
|
pdfjs-print-button-label = Տպել
|
||||||
|
pdfjs-save-button =
|
||||||
|
.title = Պահպանել
|
||||||
|
pdfjs-save-button-label = Պահպանել
|
||||||
# Used in Firefox for Android as a label for the download button (“download” is a verb).
|
# 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.
|
# Length of the translation matters since we are in a mobile context, with limited screen estate.
|
||||||
pdfjs-download-button-label = Ներբեռնել
|
pdfjs-download-button-label = Ներբեռնել
|
||||||
@ -256,6 +259,7 @@ pdfjs-free-text-default-content = Սկսել մուտքագրումը…
|
|||||||
|
|
||||||
## Alt-text dialog
|
## Alt-text dialog
|
||||||
|
|
||||||
|
pdfjs-editor-alt-text-save-button = Պահպանել
|
||||||
|
|
||||||
## Editor resizers
|
## Editor resizers
|
||||||
## This is used in an aria label to help to understand the role of the resizer.
|
## This is used in an aria label to help to understand the role of the resizer.
|
||||||
|
|||||||
@ -525,6 +525,7 @@ pdfjs-editor-undo-bar-close-button-label = Kapat
|
|||||||
|
|
||||||
## Add a signature dialog
|
## Add a signature dialog
|
||||||
|
|
||||||
|
pdfjs-editor-add-signature-dialog-label = Bu pencereden PDF belgesine eklemek üzere imza oluşturabilirsiniz. Adınızı düzenleyebilir (adınız alt metin olarak da kullanılır) ve isterseniz ileride tekrar kullanmak üzere imzayı kaydedebilirsiniz.
|
||||||
pdfjs-editor-add-signature-dialog-title = İmza ekle
|
pdfjs-editor-add-signature-dialog-title = İmza ekle
|
||||||
|
|
||||||
## Tab names
|
## Tab names
|
||||||
|
|||||||
@ -173,8 +173,8 @@ pdfjs-print-progress-message = 正在準備列印文件…
|
|||||||
# $progress (Number) - percent value
|
# $progress (Number) - percent value
|
||||||
pdfjs-print-progress-percent = { $progress }%
|
pdfjs-print-progress-percent = { $progress }%
|
||||||
pdfjs-print-progress-close-button = 取消
|
pdfjs-print-progress-close-button = 取消
|
||||||
pdfjs-printing-not-supported = 警告: 此瀏覽器未完整支援列印功能。
|
pdfjs-printing-not-supported = 警告:此瀏覽器未完整支援列印功能。
|
||||||
pdfjs-printing-not-ready = 警告: 此 PDF 未完成下載以供列印。
|
pdfjs-printing-not-ready = 警告:此 PDF 未完成下載以供列印。
|
||||||
|
|
||||||
## Tooltips and alt text for side panel toolbar buttons
|
## Tooltips and alt text for side panel toolbar buttons
|
||||||
|
|
||||||
|
|||||||
@ -632,13 +632,26 @@ class AES256Cipher extends AESBaseCipher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PDF17 {
|
class PDFBase {
|
||||||
|
constructor() {
|
||||||
|
if (
|
||||||
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
|
this.constructor === PDFBase
|
||||||
|
) {
|
||||||
|
unreachable("Cannot initialize PDFBase.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_hash(password, input, userBytes) {
|
||||||
|
unreachable("Abstract method `_hash` called");
|
||||||
|
}
|
||||||
|
|
||||||
checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
|
checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
|
||||||
const hashData = new Uint8Array(password.length + 56);
|
const hashData = new Uint8Array(password.length + 56);
|
||||||
hashData.set(password, 0);
|
hashData.set(password, 0);
|
||||||
hashData.set(ownerValidationSalt, password.length);
|
hashData.set(ownerValidationSalt, password.length);
|
||||||
hashData.set(userBytes, password.length + ownerValidationSalt.length);
|
hashData.set(userBytes, password.length + ownerValidationSalt.length);
|
||||||
const result = calculateSHA256(hashData, 0, hashData.length);
|
const result = this._hash(password, hashData, userBytes);
|
||||||
return isArrayEqual(result, ownerPassword);
|
return isArrayEqual(result, ownerPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +659,7 @@ class PDF17 {
|
|||||||
const hashData = new Uint8Array(password.length + 8);
|
const hashData = new Uint8Array(password.length + 8);
|
||||||
hashData.set(password, 0);
|
hashData.set(password, 0);
|
||||||
hashData.set(userValidationSalt, password.length);
|
hashData.set(userValidationSalt, password.length);
|
||||||
const result = calculateSHA256(hashData, 0, hashData.length);
|
const result = this._hash(password, hashData, []);
|
||||||
return isArrayEqual(result, userPassword);
|
return isArrayEqual(result, userPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +668,7 @@ class PDF17 {
|
|||||||
hashData.set(password, 0);
|
hashData.set(password, 0);
|
||||||
hashData.set(ownerKeySalt, password.length);
|
hashData.set(ownerKeySalt, password.length);
|
||||||
hashData.set(userBytes, password.length + ownerKeySalt.length);
|
hashData.set(userBytes, password.length + ownerKeySalt.length);
|
||||||
const key = calculateSHA256(hashData, 0, hashData.length);
|
const key = this._hash(password, hashData, userBytes);
|
||||||
const cipher = new AES256Cipher(key);
|
const cipher = new AES256Cipher(key);
|
||||||
return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
|
return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
|
||||||
}
|
}
|
||||||
@ -665,14 +678,20 @@ class PDF17 {
|
|||||||
hashData.set(password, 0);
|
hashData.set(password, 0);
|
||||||
hashData.set(userKeySalt, password.length);
|
hashData.set(userKeySalt, password.length);
|
||||||
// `key` is the decryption key for the UE string.
|
// `key` is the decryption key for the UE string.
|
||||||
const key = calculateSHA256(hashData, 0, hashData.length);
|
const key = this._hash(password, hashData, []);
|
||||||
const cipher = new AES256Cipher(key);
|
const cipher = new AES256Cipher(key);
|
||||||
return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
|
return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PDF20 {
|
class PDF17 extends PDFBase {
|
||||||
#hash(password, input, userBytes) {
|
_hash(password, input, userBytes) {
|
||||||
|
return calculateSHA256(input, 0, input.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PDF20 extends PDFBase {
|
||||||
|
_hash(password, input, userBytes) {
|
||||||
// This refers to Algorithm 2.B as defined in ISO 32000-2.
|
// This refers to Algorithm 2.B as defined in ISO 32000-2.
|
||||||
let k = calculateSHA256(input, 0, input.length).subarray(0, 32);
|
let k = calculateSHA256(input, 0, input.length).subarray(0, 32);
|
||||||
let e = [0];
|
let e = [0];
|
||||||
@ -713,43 +732,6 @@ class PDF20 {
|
|||||||
}
|
}
|
||||||
return k.subarray(0, 32);
|
return k.subarray(0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) {
|
|
||||||
const hashData = new Uint8Array(password.length + 56);
|
|
||||||
hashData.set(password, 0);
|
|
||||||
hashData.set(ownerValidationSalt, password.length);
|
|
||||||
hashData.set(userBytes, password.length + ownerValidationSalt.length);
|
|
||||||
const result = this.#hash(password, hashData, userBytes);
|
|
||||||
return isArrayEqual(result, ownerPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkUserPassword(password, userValidationSalt, userPassword) {
|
|
||||||
const hashData = new Uint8Array(password.length + 8);
|
|
||||||
hashData.set(password, 0);
|
|
||||||
hashData.set(userValidationSalt, password.length);
|
|
||||||
const result = this.#hash(password, hashData, []);
|
|
||||||
return isArrayEqual(result, userPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) {
|
|
||||||
const hashData = new Uint8Array(password.length + 56);
|
|
||||||
hashData.set(password, 0);
|
|
||||||
hashData.set(ownerKeySalt, password.length);
|
|
||||||
hashData.set(userBytes, password.length + ownerKeySalt.length);
|
|
||||||
const key = this.#hash(password, hashData, userBytes);
|
|
||||||
const cipher = new AES256Cipher(key);
|
|
||||||
return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16));
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserKey(password, userKeySalt, userEncryption) {
|
|
||||||
const hashData = new Uint8Array(password.length + 8);
|
|
||||||
hashData.set(password, 0);
|
|
||||||
hashData.set(userKeySalt, password.length);
|
|
||||||
// `key` is the decryption key for the UE string.
|
|
||||||
const key = this.#hash(password, hashData, []);
|
|
||||||
const cipher = new AES256Cipher(key);
|
|
||||||
return cipher.decryptBlock(userEncryption, false, new Uint8Array(16));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CipherTransform {
|
class CipherTransform {
|
||||||
|
|||||||
@ -933,9 +933,14 @@ class Lexer {
|
|||||||
if (ch < /* '0' = */ 0x30 || ch > /* '9' = */ 0x39) {
|
if (ch < /* '0' = */ 0x30 || ch > /* '9' = */ 0x39) {
|
||||||
const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`;
|
const msg = `Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`;
|
||||||
|
|
||||||
if (isWhiteSpace(ch) || ch === /* EOF = */ -1) {
|
if (
|
||||||
|
isWhiteSpace(ch) ||
|
||||||
|
/* '(' = */ ch === 0x28 ||
|
||||||
|
/* '<' = */ ch === 0x3c ||
|
||||||
|
ch === /* EOF = */ -1
|
||||||
|
) {
|
||||||
// This is consistent with Adobe Reader (fixes issue9252.pdf,
|
// This is consistent with Adobe Reader (fixes issue9252.pdf,
|
||||||
// issue15604.pdf, bug1753983.pdf).
|
// issue15604.pdf, bug1753983.pdf, bug1953099.pdf).
|
||||||
info(`Lexer.getNumber - "${msg}".`);
|
info(`Lexer.getNumber - "${msg}".`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
getCurrentTransform,
|
getCurrentTransform,
|
||||||
getCurrentTransformInverse,
|
getCurrentTransformInverse,
|
||||||
|
OutputScale,
|
||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
} from "./display_utils.js";
|
} from "./display_utils.js";
|
||||||
import {
|
import {
|
||||||
@ -811,7 +812,7 @@ function getImageSmoothingEnabled(transform, interpolate) {
|
|||||||
scale[0] = Math.fround(scale[0]);
|
scale[0] = Math.fround(scale[0]);
|
||||||
scale[1] = Math.fround(scale[1]);
|
scale[1] = Math.fround(scale[1]);
|
||||||
const actualScale = Math.fround(
|
const actualScale = Math.fround(
|
||||||
(globalThis.devicePixelRatio || 1) * PixelsPerInch.PDF_TO_CSS_UNITS
|
OutputScale.pixelRatio * PixelsPerInch.PDF_TO_CSS_UNITS
|
||||||
);
|
);
|
||||||
return scale[0] <= actualScale && scale[1] <= actualScale;
|
return scale[0] <= actualScale && scale[1] <= actualScale;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -620,7 +620,7 @@ function setLayerDimensions(
|
|||||||
*/
|
*/
|
||||||
class OutputScale {
|
class OutputScale {
|
||||||
constructor() {
|
constructor() {
|
||||||
const pixelRatio = window.devicePixelRatio || 1;
|
const { pixelRatio } = OutputScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {number} Horizontal scale.
|
* @type {number} Horizontal scale.
|
||||||
@ -673,6 +673,10 @@ class OutputScale {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get pixelRatio() {
|
||||||
|
return globalThis.devicePixelRatio || 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
|
// See https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { setLayerDimensions } from "./display_utils.js";
|
import { OutputScale, setLayerDimensions } from "./display_utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} TextLayerParameters
|
* @typedef {Object} TextLayerParameters
|
||||||
@ -115,7 +115,7 @@ class TextLayer {
|
|||||||
}
|
}
|
||||||
this.#container = this.#rootContainer = container;
|
this.#container = this.#rootContainer = container;
|
||||||
|
|
||||||
this.#scale = viewport.scale * (globalThis.devicePixelRatio || 1);
|
this.#scale = viewport.scale * OutputScale.pixelRatio;
|
||||||
this.#rotation = viewport.rotation;
|
this.#rotation = viewport.rotation;
|
||||||
this.#layoutTextParams = {
|
this.#layoutTextParams = {
|
||||||
div: null,
|
div: null,
|
||||||
@ -205,7 +205,7 @@ class TextLayer {
|
|||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
update({ viewport, onBefore = null }) {
|
update({ viewport, onBefore = null }) {
|
||||||
const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
|
const scale = viewport.scale * OutputScale.pixelRatio;
|
||||||
const rotation = viewport.rotation;
|
const rotation = viewport.rotation;
|
||||||
|
|
||||||
if (rotation !== this.#rotation) {
|
if (rotation !== this.#rotation) {
|
||||||
|
|||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { shadow } from "../shared/util.js";
|
import { OutputScale, stopEvent } from "./display_utils.js";
|
||||||
import { stopEvent } from "./display_utils.js";
|
|
||||||
|
|
||||||
class TouchManager {
|
class TouchManager {
|
||||||
#container;
|
#container;
|
||||||
@ -65,6 +64,10 @@ class TouchManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: Don't shadow this value since `devicePixelRatio` may change if the
|
||||||
|
* window resolution changes, e.g. if the viewer is moved to another monitor.
|
||||||
|
*/
|
||||||
get MIN_TOUCH_DISTANCE_TO_PINCH() {
|
get MIN_TOUCH_DISTANCE_TO_PINCH() {
|
||||||
// The 35 is coming from:
|
// The 35 is coming from:
|
||||||
// https://searchfox.org/mozilla-central/source/gfx/layers/apz/src/GestureEventListener.cpp#36
|
// https://searchfox.org/mozilla-central/source/gfx/layers/apz/src/GestureEventListener.cpp#36
|
||||||
@ -72,11 +75,7 @@ class TouchManager {
|
|||||||
// The properties TouchEvent::screenX/Y are in screen CSS pixels:
|
// The properties TouchEvent::screenX/Y are in screen CSS pixels:
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Touch/screenX#examples
|
// https://developer.mozilla.org/en-US/docs/Web/API/Touch/screenX#examples
|
||||||
// MIN_TOUCH_DISTANCE_TO_PINCH is in CSS pixels.
|
// MIN_TOUCH_DISTANCE_TO_PINCH is in CSS pixels.
|
||||||
return shadow(
|
return 35 / OutputScale.pixelRatio;
|
||||||
this,
|
|
||||||
"MIN_TOUCH_DISTANCE_TO_PINCH",
|
|
||||||
35 / (window.devicePixelRatio || 1)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#onTouchStart(evt) {
|
#onTouchStart(evt) {
|
||||||
|
|||||||
@ -20,6 +20,7 @@ const {
|
|||||||
DrawLayer,
|
DrawLayer,
|
||||||
getDocument,
|
getDocument,
|
||||||
GlobalWorkerOptions,
|
GlobalWorkerOptions,
|
||||||
|
OutputScale,
|
||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
shadow,
|
shadow,
|
||||||
TextLayer,
|
TextLayer,
|
||||||
@ -876,7 +877,7 @@ class Driver {
|
|||||||
page => {
|
page => {
|
||||||
// Default to creating the test images at the devices pixel ratio,
|
// Default to creating the test images at the devices pixel ratio,
|
||||||
// unless the test explicitly specifies an output scale.
|
// unless the test explicitly specifies an output scale.
|
||||||
const outputScale = task.outputScale || window.devicePixelRatio;
|
const outputScale = task.outputScale || OutputScale.pixelRatio;
|
||||||
let viewport = page.getViewport({
|
let viewport = page.getViewport({
|
||||||
scale: PixelsPerInch.PDF_TO_CSS_UNITS,
|
scale: PixelsPerInch.PDF_TO_CSS_UNITS,
|
||||||
});
|
});
|
||||||
|
|||||||
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -16,6 +16,7 @@
|
|||||||
!bug1727053.pdf
|
!bug1727053.pdf
|
||||||
!issue18408_reduced.pdf
|
!issue18408_reduced.pdf
|
||||||
!bug1907000_reduced.pdf
|
!bug1907000_reduced.pdf
|
||||||
|
!bug1953099.pdf
|
||||||
!issue11913.pdf
|
!issue11913.pdf
|
||||||
!issue2391-1.pdf
|
!issue2391-1.pdf
|
||||||
!issue2391-2.pdf
|
!issue2391-2.pdf
|
||||||
|
|||||||
BIN
test/pdfs/bug1953099.pdf
Normal file
BIN
test/pdfs/bug1953099.pdf
Normal file
Binary file not shown.
@ -10414,6 +10414,14 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "bug1953099",
|
||||||
|
"file": "pdfs/bug1953099.pdf",
|
||||||
|
"md5": "15295cfa4999ccc08442423fca96c28f",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "bug1899804_print",
|
"id": "bug1899804_print",
|
||||||
"file": "pdfs/bug1899804.pdf",
|
"file": "pdfs/bug1899804.pdf",
|
||||||
|
|||||||
@ -152,7 +152,17 @@ describe("parser", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should treat a single decimal point, or minus/plus sign, as zero", function () {
|
it("should treat a single decimal point, or minus/plus sign, as zero", function () {
|
||||||
const validNums = [".", "-", "+", "-.", "+.", "-\r\n.", "+\r\n."];
|
const validNums = [
|
||||||
|
".",
|
||||||
|
"-",
|
||||||
|
"+",
|
||||||
|
"-.",
|
||||||
|
"+.",
|
||||||
|
"-\r\n.",
|
||||||
|
"+\r\n.",
|
||||||
|
"-(",
|
||||||
|
"-<",
|
||||||
|
];
|
||||||
for (const number of validNums) {
|
for (const number of validNums) {
|
||||||
const validInput = new StringStream(number);
|
const validInput = new StringStream(number);
|
||||||
const validLexer = new Lexer(validInput);
|
const validLexer = new Lexer(validInput);
|
||||||
|
|||||||
@ -50,6 +50,7 @@ import {
|
|||||||
InvalidPDFException,
|
InvalidPDFException,
|
||||||
isDataScheme,
|
isDataScheme,
|
||||||
isPdfFile,
|
isPdfFile,
|
||||||
|
OutputScale,
|
||||||
PDFWorker,
|
PDFWorker,
|
||||||
ResponseException,
|
ResponseException,
|
||||||
shadow,
|
shadow,
|
||||||
@ -2091,7 +2092,7 @@ const PDFViewerApplication = {
|
|||||||
pdfViewer.refresh();
|
pdfViewer.refresh();
|
||||||
}
|
}
|
||||||
const mediaQueryList = window.matchMedia(
|
const mediaQueryList = window.matchMedia(
|
||||||
`(resolution: ${window.devicePixelRatio || 1}dppx)`
|
`(resolution: ${OutputScale.pixelRatio}dppx)`
|
||||||
);
|
);
|
||||||
mediaQueryList.addEventListener("change", addWindowResolutionChange, {
|
mediaQueryList.addEventListener("change", addWindowResolutionChange, {
|
||||||
once: true,
|
once: true,
|
||||||
|
|||||||
@ -33,23 +33,32 @@
|
|||||||
--radio-border-color: #8f8f9d;
|
--radio-border-color: #8f8f9d;
|
||||||
--radio-checked-border-color: #0060df;
|
--radio-checked-border-color: #0060df;
|
||||||
|
|
||||||
--button-secondary-bg-color: #f0f0f4;
|
--button-secondary-bg-color: rgb(21 20 26 / 0.07);
|
||||||
--button-secondary-fg-color: var(--text-primary-color);
|
--button-secondary-fg-color: var(--text-primary-color);
|
||||||
--button-secondary-border-color: var(--button-secondary-bg-color);
|
--button-secondary-border-color: var(--button-secondary-bg-color);
|
||||||
--button-secondary-hover-bg-color: var(--button-secondary-bg-color);
|
--button-secondary-active-bg-color: rgb(21 20 26 / 0.21);
|
||||||
|
--button-secondary-active-fg-color: var(--button-secondary-fg-color);
|
||||||
|
--button-secondary-active-border-color: var(--button-secondary-bg-color);
|
||||||
|
--button-secondary-hover-bg-color: rgb(21 20 26 / 0.14);
|
||||||
--button-secondary-hover-fg-color: var(--button-secondary-fg-color);
|
--button-secondary-hover-fg-color: var(--button-secondary-fg-color);
|
||||||
--button-secondary-hover-border-color: var(--button-secondary-hover-bg-color);
|
--button-secondary-hover-border-color: var(--button-secondary-hover-bg-color);
|
||||||
|
|
||||||
--button-primary-bg-color: #0060df;
|
--button-primary-bg-color: #0060df;
|
||||||
--button-primary-fg-color: #fbfbfe;
|
--button-primary-fg-color: #fbfbfe;
|
||||||
--button-primary-border-color: var(--button-primary-bg-color);
|
--button-primary-border-color: var(--button-primary-bg-color);
|
||||||
--button-primary-hover-bg-color: var(--button-primary-bg-color);
|
--button-primary-active-bg-color: #054096;
|
||||||
|
--button-primary-active-fg-color: var(--button-primary-fg-color);
|
||||||
|
--button-primary-active-border-color: var(--button-primary-active-bg-color);
|
||||||
|
--button-primary-hover-bg-color: #0250bb;
|
||||||
--button-primary-hover-fg-color: var(--button-primary-fg-color);
|
--button-primary-hover-fg-color: var(--button-primary-fg-color);
|
||||||
--button-primary-hover-border-color: var(--button-primary-hover-bg-color);
|
--button-primary-hover-border-color: var(--button-primary-hover-bg-color);
|
||||||
|
|
||||||
--button-disabled-bg-color: color-mix(in srgb, currentcolor, transparent 60%);
|
--button-disabled-bg-color: color-mix(in srgb, currentcolor, transparent 60%);
|
||||||
--button-disabled-fg-color: var(--button-disabled-bg-color);
|
--button-disabled-fg-color: var(--button-disabled-bg-color);
|
||||||
|
|
||||||
|
--input-text-bg-color: white;
|
||||||
|
--input-text-fg-color: var(--text-primary-color);
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
--dialog-bg-color: #1c1b22;
|
--dialog-bg-color: #1c1b22;
|
||||||
--dialog-border-color: #1c1b22;
|
--dialog-border-color: #1c1b22;
|
||||||
@ -67,9 +76,15 @@
|
|||||||
--radio-checked-bg-color: #15141a;
|
--radio-checked-bg-color: #15141a;
|
||||||
--radio-checked-border-color: #0df;
|
--radio-checked-border-color: #0df;
|
||||||
|
|
||||||
--button-secondary-bg-color: #2b2a33;
|
--button-secondary-bg-color: rgb(251 251 254 / 0.07);
|
||||||
|
--button-secondary-active-bg-color: rgb(251 251 254 / 0.21);
|
||||||
|
--button-secondary-hover-bg-color: rgb(251 251 254 / 0.14);
|
||||||
--button-primary-bg-color: #0df;
|
--button-primary-bg-color: #0df;
|
||||||
--button-primary-fg-color: #15141a;
|
--button-primary-fg-color: #15141a;
|
||||||
|
--button-primary-active-bg-color: #aaf2ff;
|
||||||
|
--button-primary-hover-bg-color: #80ebff;
|
||||||
|
|
||||||
|
--input-text-bg-color: #42414d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (forced-colors: active) {
|
@media screen and (forced-colors: active) {
|
||||||
@ -92,19 +107,31 @@
|
|||||||
--radio-border-color: ButtonText;
|
--radio-border-color: ButtonText;
|
||||||
--radio-checked-border-color: ButtonText;
|
--radio-checked-border-color: ButtonText;
|
||||||
|
|
||||||
--button-secondary-bg-color: ButtonFace;
|
--button-secondary-bg-color: HighlightText;
|
||||||
--button-secondary-fg-color: ButtonText;
|
--button-secondary-fg-color: ButtonText;
|
||||||
--button-secondary-border-color: ButtonText;
|
--button-secondary-border-color: ButtonText;
|
||||||
--button-secondary-hover-bg-color: AccentColor;
|
--button-secondary-active-bg-color: HighlightText;
|
||||||
--button-secondary-hover-fg-color: AccentColorText;
|
--button-secondary-active-fg-color: SelectedItem;
|
||||||
|
--button-secondary-active-border-color: ButtonText;
|
||||||
|
--button-secondary-hover-bg-color: HighlightText;
|
||||||
|
--button-secondary-hover-fg-color: SelectedItem;
|
||||||
|
--button-secondary-hover-border-color: SelectedItem;
|
||||||
|
|
||||||
--button-primary-bg-color: ButtonText;
|
--button-primary-bg-color: ButtonText;
|
||||||
--button-primary-fg-color: ButtonFace;
|
--button-primary-fg-color: HighlightText;
|
||||||
--button-primary-hover-bg-color: AccentColor;
|
--button-primary-border-color: ButtonText;
|
||||||
--button-primary-hover-fg-color: AccentColorText;
|
--button-primary-active-bg-color: SelectedItem;
|
||||||
|
--button-primary-active-fg-color: HighlightText;
|
||||||
|
--button-primary-active-border-color: ButtonText;
|
||||||
|
--button-primary-hover-bg-color: SelectedItem;
|
||||||
|
--button-primary-hover-fg-color: HighlightText;
|
||||||
|
--button-primary-hover-border-color: SelectedItem;
|
||||||
|
|
||||||
--button-disabled-bg-color: GrayText;
|
--button-disabled-bg-color: GrayText;
|
||||||
--button-disabled-fg-color: ButtonFace;
|
--button-disabled-fg-color: ButtonFace;
|
||||||
|
|
||||||
|
--input-text-bg-color: HighlightText;
|
||||||
|
--input-text-fg-color: FieldText;
|
||||||
}
|
}
|
||||||
|
|
||||||
font: message-box;
|
font: message-box;
|
||||||
@ -205,7 +232,8 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
font: menu;
|
font: menu;
|
||||||
font-weight: 600;
|
font-weight: 590;
|
||||||
|
font-size: 13px;
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
@ -217,6 +245,7 @@
|
|||||||
|
|
||||||
> span {
|
> span {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.secondaryButton {
|
&.secondaryButton {
|
||||||
@ -229,6 +258,12 @@
|
|||||||
background-color: var(--button-secondary-hover-bg-color);
|
background-color: var(--button-secondary-hover-bg-color);
|
||||||
border-color: var(--button-secondary-hover-border-color);
|
border-color: var(--button-secondary-hover-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: var(--button-secondary-active-fg-color);
|
||||||
|
background-color: var(--button-secondary-active-bg-color);
|
||||||
|
border-color: var(--button-secondary-active-border-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.primaryButton {
|
&.primaryButton {
|
||||||
@ -242,6 +277,12 @@
|
|||||||
background-color: var(--button-primary-hover-bg-color);
|
background-color: var(--button-primary-hover-bg-color);
|
||||||
border-color: var(--button-primary-hover-border-color);
|
border-color: var(--button-primary-hover-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: var(--button-primary-active-fg-color);
|
||||||
|
background-color: var(--button-primary-active-bg-color);
|
||||||
|
border-color: var(--button-primary-active-border-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@ -282,6 +323,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
background-color: var(--input-text-bg-color);
|
||||||
|
color: var(--input-text-fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
.messageBar {
|
.messageBar {
|
||||||
--message-bar-bg-color: #ffebcd;
|
--message-bar-bg-color: #ffebcd;
|
||||||
--message-bar-fg-color: #15141a;
|
--message-bar-fg-color: #15141a;
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { BasePDFPageView } from "./base_pdf_page_view.js";
|
import { BasePDFPageView } from "./base_pdf_page_view.js";
|
||||||
|
import { OutputScale } from "pdfjs-lib";
|
||||||
import { RenderingStates } from "./ui_utils.js";
|
import { RenderingStates } from "./ui_utils.js";
|
||||||
|
|
||||||
/** @typedef {import("./interfaces").IRenderableView} IRenderableView */
|
/** @typedef {import("./interfaces").IRenderableView} IRenderableView */
|
||||||
@ -153,7 +154,7 @@ class PDFPageDetailView extends BasePDFPageView {
|
|||||||
// but we can reduce it to make sure that we stay within the maxCanvasPixels
|
// but we can reduce it to make sure that we stay within the maxCanvasPixels
|
||||||
// limit.
|
// limit.
|
||||||
const visiblePixels =
|
const visiblePixels =
|
||||||
visibleWidth * visibleHeight * (window.devicePixelRatio || 1) ** 2;
|
visibleWidth * visibleHeight * OutputScale.pixelRatio ** 2;
|
||||||
const maxDetailToVisibleLinearRatio = Math.sqrt(
|
const maxDetailToVisibleLinearRatio = Math.sqrt(
|
||||||
maxCanvasPixels / visiblePixels
|
maxCanvasPixels / visiblePixels
|
||||||
);
|
);
|
||||||
@ -228,18 +229,18 @@ class PDFPageDetailView extends BasePDFPageView {
|
|||||||
|
|
||||||
const area = this.#detailArea;
|
const area = this.#detailArea;
|
||||||
|
|
||||||
const { devicePixelRatio = 1 } = window;
|
const { pixelRatio } = OutputScale;
|
||||||
const transform = [
|
const transform = [
|
||||||
devicePixelRatio,
|
pixelRatio,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
devicePixelRatio,
|
pixelRatio,
|
||||||
-area.minX * devicePixelRatio,
|
-area.minX * pixelRatio,
|
||||||
-area.minY * devicePixelRatio,
|
-area.minY * pixelRatio,
|
||||||
];
|
];
|
||||||
|
|
||||||
canvas.width = area.width * devicePixelRatio;
|
canvas.width = area.width * pixelRatio;
|
||||||
canvas.height = area.height * devicePixelRatio;
|
canvas.height = area.height * pixelRatio;
|
||||||
const { style } = canvas;
|
const { style } = canvas;
|
||||||
style.width = `${(area.width * 100) / width}%`;
|
style.width = `${(area.width * 100) / width}%`;
|
||||||
style.height = `${(area.height * 100) / height}%`;
|
style.height = `${(area.height * 100) / height}%`;
|
||||||
|
|||||||
@ -50,10 +50,14 @@
|
|||||||
--primary-color: var(--text-primary-color);
|
--primary-color: var(--text-primary-color);
|
||||||
--description-input-color: var(--primary-color);
|
--description-input-color: var(--primary-color);
|
||||||
--border-color: #8f8f9d;
|
--border-color: #8f8f9d;
|
||||||
|
--open-link-fg: var(--link-fg-color);
|
||||||
|
--open-link-hover-fg: var(--link-hover-fg-color);
|
||||||
|
|
||||||
@media screen and (forced-colors: active) {
|
@media screen and (forced-colors: active) {
|
||||||
--primary-color: ButtonText;
|
--primary-color: ButtonText;
|
||||||
--border-color: ButtonText;
|
--border-color: ButtonText;
|
||||||
|
--open-link-fg: ButtonText;
|
||||||
|
--open-link-hover-fg: ButtonText;
|
||||||
}
|
}
|
||||||
|
|
||||||
width: 570px;
|
width: 570px;
|
||||||
@ -82,9 +86,7 @@
|
|||||||
|
|
||||||
.inputWithClearButton {
|
.inputWithClearButton {
|
||||||
--button-dimension: 24px;
|
--button-dimension: 24px;
|
||||||
|
--clear-button-icon: url(images/messageBar_closingButton.svg);
|
||||||
--closing-button-icon: url(images/messageBar_closingButton.svg);
|
|
||||||
--closing-button-color: var(--primary-color);
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -97,10 +99,8 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
padding-inline: 8px calc(4px + var(--button-dimension));
|
padding-inline: 8px calc(4px + var(--button-dimension));
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: transparent;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
color: var(--description-input-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.clearInputButton {
|
.clearInputButton {
|
||||||
@ -110,9 +110,9 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: var(--button-dimension);
|
width: var(--button-dimension);
|
||||||
height: var(--button-dimension);
|
height: var(--button-dimension);
|
||||||
background-color: var(--closing-button-color);
|
background-color: var(--input-text-fg-color);
|
||||||
mask-size: cover;
|
mask-size: cover;
|
||||||
mask-image: var(--closing-button-icon);
|
mask-image: var(--clear-button-icon);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
@ -465,9 +465,18 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--signature-placeholder-color);
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
color: var(--open-link-fg);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--open-link-hover-fg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user