Skip to content

Commit 6f8796d

Browse files
committed
Handle the case where all the image data are in the alpha channel (bug 1975719)
and add an error message in case where there is no data in the image.
1 parent 2d0ba7d commit 6f8796d

6 files changed

Lines changed: 86 additions & 19 deletions

File tree

l10n/en-US/viewer.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ pdfjs-editor-add-signature-save-checkbox = Save signature
614614
pdfjs-editor-add-signature-save-warning-message = You’ve reached the limit of 5 saved signatures. Remove one to save more.
615615
pdfjs-editor-add-signature-image-upload-error-title = Couldn’t upload image
616616
pdfjs-editor-add-signature-image-upload-error-description = Check your network connection or try another image.
617+
pdfjs-editor-add-signature-image-no-data-error-title = Can’t convert this image into a signature
618+
pdfjs-editor-add-signature-image-no-data-error-description = Please try uploading a different image.
617619
pdfjs-editor-add-signature-error-close-button = Close
618620
619621
## Dialog buttons

src/display/editor/drawers/signaturedraw.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -366,21 +366,12 @@ class SignatureExtractor {
366366
let max = -Infinity;
367367
let min = Infinity;
368368
for (let i = 0, ii = out.length; i < ii; i++) {
369-
const A = buf[(i << 2) + 3];
370-
if (A === 0) {
371-
max = out[i] = 0xff;
372-
continue;
373-
}
374369
const pix = (out[i] = buf[i << 2]);
375-
if (pix > max) {
376-
max = pix;
377-
}
378-
if (pix < min) {
379-
min = pix;
380-
}
370+
max = Math.max(max, pix);
371+
min = Math.min(min, pix);
381372
}
382373
const ratio = 255 / (max - min);
383-
for (let i = 0; i < N; i++) {
374+
for (let i = 0, ii = out.length; i < ii; i++) {
384375
out[i] = (out[i] - min) * ratio;
385376
}
386377

@@ -468,6 +459,8 @@ class SignatureExtractor {
468459
}
469460
const offscreen = new OffscreenCanvas(newWidth, newHeight);
470461
const ctx = offscreen.getContext("2d", { willReadFrequently: true });
462+
ctx.fillStyle = "white";
463+
ctx.fillRect(0, 0, newWidth, newHeight);
471464
ctx.filter = "grayscale(1)";
472465
ctx.drawImage(
473466
bitmap,

test/integration/signature_editor_spec.mjs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,4 +718,47 @@ describe("Signature Editor", () => {
718718
);
719719
});
720720
});
721+
722+
describe("Bug 1975719", () => {
723+
let pages;
724+
725+
beforeEach(async () => {
726+
pages = await loadAndWait("empty.pdf", ".annotationEditorLayer");
727+
});
728+
729+
afterEach(async () => {
730+
await closePages(pages);
731+
});
732+
733+
it("must check that an error is displayed with a monochrome image", async () => {
734+
await Promise.all(
735+
pages.map(async ([_, page]) => {
736+
await switchToSignature(page);
737+
738+
await page.click("#editorSignatureAddSignature");
739+
740+
await page.waitForSelector("#addSignatureDialog", {
741+
visible: true,
742+
});
743+
await page.click("#addSignatureImageButton");
744+
await page.waitForSelector("#addSignatureImagePlaceholder", {
745+
visible: true,
746+
});
747+
const input = await page.$("#addSignatureFilePicker");
748+
await input.uploadFile(
749+
`${path.join(__dirname, "../images/red.png")}`
750+
);
751+
await page.waitForSelector("#addSignatureError", { visible: true });
752+
await page.waitForSelector(
753+
"#addSignatureErrorTitle[data-l10n-id='pdfjs-editor-add-signature-image-no-data-error-title']"
754+
);
755+
await page.waitForSelector(
756+
"#addSignatureErrorDescription[data-l10n-id='pdfjs-editor-add-signature-image-no-data-error-description']"
757+
);
758+
await page.click("#addSignatureErrorCloseButton");
759+
await page.waitForSelector("#addSignatureError", { visible: false });
760+
})
761+
);
762+
});
763+
});
721764
});

web/signature_manager.js

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class SignatureManager {
5656

5757
#errorBar;
5858

59+
#errorDescription;
60+
61+
#errorTitle;
62+
5963
#extractedSignatureData = null;
6064

6165
#imagePath = null;
@@ -123,6 +127,8 @@ class SignatureManager {
123127
addButton,
124128
errorCloseButton,
125129
errorBar,
130+
errorTitle,
131+
errorDescription,
126132
saveCheckbox,
127133
saveContainer,
128134
},
@@ -142,6 +148,8 @@ class SignatureManager {
142148
this.#drawPlaceholder = drawPlaceholder;
143149
this.#drawThickness = drawThickness;
144150
this.#errorBar = errorBar;
151+
this.#errorTitle = errorTitle;
152+
this.#errorDescription = errorDescription;
145153
this.#imageSVG = imageSVG;
146154
this.#imagePlaceholder = imagePlaceholder;
147155
this.#imagePicker = imagePicker;
@@ -161,6 +169,12 @@ class SignatureManager {
161169

162170
SignatureManager.#l10nDescription ||= Object.freeze({
163171
signature: "pdfjs-editor-add-signature-description-default-when-drawing",
172+
errorUploadTitle: "pdfjs-editor-add-signature-image-upload-error-title",
173+
errorUploadDescription:
174+
"pdfjs-editor-add-signature-image-upload-error-description",
175+
errorNoDataTitle: "pdfjs-editor-add-signature-image-no-data-error-title",
176+
errorNoDataDescription:
177+
"pdfjs-editor-add-signature-image-no-data-error-description",
164178
});
165179

166180
dialog.addEventListener("close", this.#close.bind(this));
@@ -506,6 +520,18 @@ class SignatureManager {
506520
);
507521
}
508522

523+
#showError(type) {
524+
this.#errorTitle.setAttribute(
525+
"data-l10n-id",
526+
SignatureManager.#l10nDescription[`error${type}Title`]
527+
);
528+
this.#errorDescription.setAttribute(
529+
"data-l10n-id",
530+
SignatureManager.#l10nDescription[`error${type}Description`]
531+
);
532+
this.#errorBar.hidden = false;
533+
}
534+
509535
#initImageTab(reset) {
510536
if (reset) {
511537
this.#resetTab("image");
@@ -539,7 +565,7 @@ class SignatureManager {
539565
async () => {
540566
const file = this.#imagePicker.files?.[0];
541567
if (!file || !SupportedImageMimeTypes.includes(file.type)) {
542-
this.#errorBar.hidden = false;
568+
this.#showError("Upload");
543569
this.#dialog.classList.toggle("waiting", false);
544570
return;
545571
}
@@ -601,18 +627,19 @@ class SignatureManager {
601627
console.error("SignatureManager.#extractSignature.", e);
602628
}
603629
if (!data) {
604-
this.#errorBar.hidden = false;
630+
this.#showError("Upload");
605631
this.#dialog.classList.toggle("waiting", false);
606632
return;
607633
}
608634

609-
const { outline } = (this.#extractedSignatureData =
635+
const lineData = (this.#extractedSignatureData =
610636
this.#currentEditor.getFromImage(data.bitmap));
611-
612-
if (!outline) {
637+
if (!lineData) {
638+
this.#showError("NoData");
613639
this.#dialog.classList.toggle("waiting", false);
614640
return;
615641
}
642+
const { outline } = lineData;
616643

617644
this.#imagePlaceholder.hidden = true;
618645
this.#disableButtons(true);

web/viewer.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,8 @@
735735
<div id="addSignatureError" hidden="true" class="messageBar">
736736
<div>
737737
<div>
738-
<span class="title" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-title"></span>
739-
<span class="description" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-description"></span>
738+
<span id="addSignatureErrorTitle" class="title" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-title"></span>
739+
<span id="addSignatureErrorDescription" class="description" data-l10n-id="pdfjs-editor-add-signature-image-upload-error-description"></span>
740740
</div>
741741
<button id="addSignatureErrorCloseButton" class="closeButton" type="button" tabindex="0"><span data-l10n-id="pdfjs-editor-add-signature-error-close-button"></span></button>
742742
</div>

web/viewer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ function getViewerConfiguration() {
227227
saveContainer: document.getElementById("addSignatureSaveContainer"),
228228
saveCheckbox: document.getElementById("addSignatureSaveCheckbox"),
229229
errorBar: document.getElementById("addSignatureError"),
230+
errorTitle: document.getElementById("addSignatureErrorTitle"),
231+
errorDescription: document.getElementById("addSignatureErrorDescription"),
230232
errorCloseButton: document.getElementById("addSignatureErrorCloseButton"),
231233
cancelButton: document.getElementById("addSignatureCancelButton"),
232234
addButton: document.getElementById("addSignatureAddButton"),

0 commit comments

Comments
 (0)