Merge pull request #20085 from calixteman/bug1975719

Handle the case where all the image data are in the alpha channel (bug 1975719)
This commit is contained in:
calixteman 2025-07-14 22:44:19 +02:00 committed by GitHub
commit ac2a0c5080
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 86 additions and 19 deletions

View File

@ -614,6 +614,8 @@ pdfjs-editor-add-signature-save-checkbox = Save signature
pdfjs-editor-add-signature-save-warning-message = Youve reached the limit of 5 saved signatures. Remove one to save more.
pdfjs-editor-add-signature-image-upload-error-title = Couldnt upload image
pdfjs-editor-add-signature-image-upload-error-description = Check your network connection or try another image.
pdfjs-editor-add-signature-image-no-data-error-title = Cant convert this image into a signature
pdfjs-editor-add-signature-image-no-data-error-description = Please try uploading a different image.
pdfjs-editor-add-signature-error-close-button = Close
## Dialog buttons

View File

@ -366,21 +366,12 @@ class SignatureExtractor {
let max = -Infinity;
let min = Infinity;
for (let i = 0, ii = out.length; i < ii; i++) {
const A = buf[(i << 2) + 3];
if (A === 0) {
max = out[i] = 0xff;
continue;
}
const pix = (out[i] = buf[i << 2]);
if (pix > max) {
max = pix;
}
if (pix < min) {
min = pix;
}
max = Math.max(max, pix);
min = Math.min(min, pix);
}
const ratio = 255 / (max - min);
for (let i = 0; i < N; i++) {
for (let i = 0, ii = out.length; i < ii; i++) {
out[i] = (out[i] - min) * ratio;
}
@ -468,6 +459,8 @@ class SignatureExtractor {
}
const offscreen = new OffscreenCanvas(newWidth, newHeight);
const ctx = offscreen.getContext("2d", { willReadFrequently: true });
ctx.fillStyle = "white";
ctx.fillRect(0, 0, newWidth, newHeight);
ctx.filter = "grayscale(1)";
ctx.drawImage(
bitmap,

View File

@ -727,4 +727,47 @@ describe("Signature Editor", () => {
);
});
});
describe("Bug 1975719", () => {
let pages;
beforeEach(async () => {
pages = await loadAndWait("empty.pdf", ".annotationEditorLayer");
});
afterEach(async () => {
await closePages(pages);
});
it("must check that an error is displayed with a monochrome image", async () => {
await Promise.all(
pages.map(async ([_, page]) => {
await switchToSignature(page);
await page.click("#editorSignatureAddSignature");
await page.waitForSelector("#addSignatureDialog", {
visible: true,
});
await page.click("#addSignatureImageButton");
await page.waitForSelector("#addSignatureImagePlaceholder", {
visible: true,
});
const input = await page.$("#addSignatureFilePicker");
await input.uploadFile(
`${path.join(__dirname, "../images/red.png")}`
);
await page.waitForSelector("#addSignatureError", { visible: true });
await page.waitForSelector(
"#addSignatureErrorTitle[data-l10n-id='pdfjs-editor-add-signature-image-no-data-error-title']"
);
await page.waitForSelector(
"#addSignatureErrorDescription[data-l10n-id='pdfjs-editor-add-signature-image-no-data-error-description']"
);
await page.click("#addSignatureErrorCloseButton");
await page.waitForSelector("#addSignatureError", { visible: false });
})
);
});
});
});

View File

@ -56,6 +56,10 @@ class SignatureManager {
#errorBar;
#errorDescription;
#errorTitle;
#extractedSignatureData = null;
#imagePath = null;
@ -123,6 +127,8 @@ class SignatureManager {
addButton,
errorCloseButton,
errorBar,
errorTitle,
errorDescription,
saveCheckbox,
saveContainer,
},
@ -142,6 +148,8 @@ class SignatureManager {
this.#drawPlaceholder = drawPlaceholder;
this.#drawThickness = drawThickness;
this.#errorBar = errorBar;
this.#errorTitle = errorTitle;
this.#errorDescription = errorDescription;
this.#imageSVG = imageSVG;
this.#imagePlaceholder = imagePlaceholder;
this.#imagePicker = imagePicker;
@ -161,6 +169,12 @@ class SignatureManager {
SignatureManager.#l10nDescription ||= Object.freeze({
signature: "pdfjs-editor-add-signature-description-default-when-drawing",
errorUploadTitle: "pdfjs-editor-add-signature-image-upload-error-title",
errorUploadDescription:
"pdfjs-editor-add-signature-image-upload-error-description",
errorNoDataTitle: "pdfjs-editor-add-signature-image-no-data-error-title",
errorNoDataDescription:
"pdfjs-editor-add-signature-image-no-data-error-description",
});
dialog.addEventListener("close", this.#close.bind(this));
@ -506,6 +520,18 @@ class SignatureManager {
);
}
#showError(type) {
this.#errorTitle.setAttribute(
"data-l10n-id",
SignatureManager.#l10nDescription[`error${type}Title`]
);
this.#errorDescription.setAttribute(
"data-l10n-id",
SignatureManager.#l10nDescription[`error${type}Description`]
);
this.#errorBar.hidden = false;
}
#initImageTab(reset) {
if (reset) {
this.#resetTab("image");
@ -539,7 +565,7 @@ class SignatureManager {
async () => {
const file = this.#imagePicker.files?.[0];
if (!file || !SupportedImageMimeTypes.includes(file.type)) {
this.#errorBar.hidden = false;
this.#showError("Upload");
this.#dialog.classList.toggle("waiting", false);
return;
}
@ -601,18 +627,19 @@ class SignatureManager {
console.error("SignatureManager.#extractSignature.", e);
}
if (!data) {
this.#errorBar.hidden = false;
this.#showError("Upload");
this.#dialog.classList.toggle("waiting", false);
return;
}
const { outline } = (this.#extractedSignatureData =
const lineData = (this.#extractedSignatureData =
this.#currentEditor.getFromImage(data.bitmap));
if (!outline) {
if (!lineData) {
this.#showError("NoData");
this.#dialog.classList.toggle("waiting", false);
return;
}
const { outline } = lineData;
this.#imagePlaceholder.hidden = true;
this.#disableButtons(true);

View File

@ -735,8 +735,8 @@ See https://github.com/adobe-type-tools/cmap-resources
<div id="addSignatureError" hidden="true" class="messageBar">
<div>
<div>
<span class="title" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-title"></span>
<span class="description" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-description"></span>
<span id="addSignatureErrorTitle" class="title" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-title"></span>
<span id="addSignatureErrorDescription" class="description" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-description"></span>
</div>
<button id="addSignatureErrorCloseButton" class="closeButton" type="button" tabindex="0"><span data-l10n-id="pdfjs-editor-add-signature-error-close-button"></span></button>
</div>

View File

@ -227,6 +227,8 @@ function getViewerConfiguration() {
saveContainer: document.getElementById("addSignatureSaveContainer"),
saveCheckbox: document.getElementById("addSignatureSaveCheckbox"),
errorBar: document.getElementById("addSignatureError"),
errorTitle: document.getElementById("addSignatureErrorTitle"),
errorDescription: document.getElementById("addSignatureErrorDescription"),
errorCloseButton: document.getElementById("addSignatureErrorCloseButton"),
cancelButton: document.getElementById("addSignatureCancelButton"),
addButton: document.getElementById("addSignatureAddButton"),