From 0776cd9b900989af49ef1de94b741c2399d12272 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Sat, 18 Sep 2021 20:22:29 +0200 Subject: [PATCH] Annotation - Use border and background colors from MK dictionary - it aims to fix #13003; - set the bg and fg colors as they're in the pdf; - put a transparent overlay to help to see the fields. --- src/core/annotation.js | 42 ++++++++++++++++++++++++++------ src/display/annotation_layer.js | 18 +++++++++++++- test/test_manifest.json | 7 ++++++ web/annotation_layer_builder.css | 18 ++++++-------- web/xfa_layer_builder.css | 4 +-- 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/core/annotation.js b/src/core/annotation.js index ecd5fa77c..0a8c1f11b 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -231,12 +231,12 @@ class AnnotationFactory { } } -function getRgbColor(color) { - const rgbColor = new Uint8ClampedArray(3); +function getRgbColor(color, defaultColor = new Uint8ClampedArray(3)) { if (!Array.isArray(color)) { - return rgbColor; + return defaultColor; } + const rgbColor = defaultColor || new Uint8ClampedArray(3); switch (color.length) { case 0: // Transparent, which we indicate with a null value return null; @@ -254,7 +254,7 @@ function getRgbColor(color) { return rgbColor; default: - return rgbColor; + return defaultColor; } } @@ -365,6 +365,7 @@ class Annotation { this.setColor(dict.getArray("C")); this.setBorderStyle(dict); this.setAppearance(dict); + this.setBorderAndBackgroundColors(dict.get("MK")); this._streams = []; if (this.appearance) { @@ -376,6 +377,8 @@ class Annotation { annotationFlags: this.flags, borderStyle: this.borderStyle, color: this.color, + backgroundColor: this.backgroundColor, + borderColor: this.borderColor, contentsObj: this._contents, hasAppearance: !!this.appearance, id: params.id, @@ -603,6 +606,23 @@ class Annotation { this.color = getRgbColor(color); } + /** + * Set the color for background and border if any. + * The default values are transparent. + * + * @public + * @memberof Annotation + * @param {Dict} mk - The MK dictionary + */ + setBorderAndBackgroundColors(mk) { + if (mk instanceof Dict) { + this.borderColor = getRgbColor(mk.getArray("BC"), null); + this.backgroundColor = getRgbColor(mk.getArray("BG"), null); + } else { + this.borderColor = this.backgroundColor = null; + } + } + /** * Set the border style (as AnnotationBorderStyle object). * @@ -765,6 +785,8 @@ class Annotation { id: this.data.id, actions: this.data.actions, name: this.data.fieldName, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, type: "", kidIds: this.data.kidIds, page: this.data.pageIndex, @@ -1874,6 +1896,8 @@ class TextWidgetAnnotation extends WidgetAnnotation { rect: this.data.rect, actions: this.data.actions, page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, type: "text", }; } @@ -2304,6 +2328,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { hidden: this.data.hidden, actions: this.data.actions, page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, type, }; } @@ -2385,6 +2411,8 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { actions: this.data.actions, items: this.data.options, page: this.data.pageIndex, + strokeColor: this.data.borderColor, + fillColor: this.data.backgroundColor, type, }; } @@ -2549,7 +2577,7 @@ class LineAnnotation extends MarkupAnnotation { let fillColor = null, interiorColor = parameters.dict.getArray("IC"); if (interiorColor) { - interiorColor = getRgbColor(interiorColor); + interiorColor = getRgbColor(interiorColor, null); fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null; @@ -2613,7 +2641,7 @@ class SquareAnnotation extends MarkupAnnotation { let fillColor = null, interiorColor = parameters.dict.getArray("IC"); if (interiorColor) { - interiorColor = getRgbColor(interiorColor); + interiorColor = getRgbColor(interiorColor, null); fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null; @@ -2662,7 +2690,7 @@ class CircleAnnotation extends MarkupAnnotation { let fillColor = null; let interiorColor = parameters.dict.getArray("IC"); if (interiorColor) { - interiorColor = getRgbColor(interiorColor); + interiorColor = getRgbColor(interiorColor, null); fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null; diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 087c05a0b..ebf794087 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -244,7 +244,8 @@ class AnnotationElement { break; } - if (data.color) { + const borderColor = data.borderColor || data.color || null; + if (borderColor) { container.style.borderColor = Util.makeHexColor( data.color[0] | 0, data.color[1] | 0, @@ -645,6 +646,14 @@ class WidgetAnnotationElement extends AnnotationElement { } } + _setBackgroundColor(element) { + const color = this.data.backgroundColor || null; + element.style.backgroundColor = + color === null + ? "transparent" + : Util.makeHexColor(color[0], color[1], color[2]); + } + _dispatchEventFromSandbox(actions, jsEvent) { const setColor = (jsName, styleName, event) => { const color = event.detail[jsName]; @@ -971,6 +980,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { } this._setTextStyle(element); + this._setBackgroundColor(element); this.container.appendChild(element); return this.container; @@ -1074,6 +1084,8 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { ); } + this._setBackgroundColor(element); + this.container.appendChild(element); return this.container; } @@ -1151,6 +1163,8 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { ); } + this._setBackgroundColor(element); + this.container.appendChild(element); return this.container; } @@ -1382,6 +1396,8 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { }); } + this._setBackgroundColor(selectElement); + this.container.appendChild(selectElement); return this.container; } diff --git a/test/test_manifest.json b/test/test_manifest.json index 9343cbb19..aa2f82b34 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -5975,5 +5975,12 @@ "value": true } } + }, + { "id": "issue13003", + "file": "pdfs/issue13003.pdf", + "md5": "a4c00bd6456d3c16b9bd44957caa4ab6", + "rounds": 1, + "type": "eq", + "annotations": true } ] diff --git a/web/annotation_layer_builder.css b/web/annotation_layer_builder.css index f0201cd32..14373e367 100644 --- a/web/annotation_layer_builder.css +++ b/web/annotation_layer_builder.css @@ -13,6 +13,10 @@ * limitations under the License. */ +:root { + --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); +} + .annotationLayer section { position: absolute; text-align: initial; @@ -45,7 +49,7 @@ .annotationLayer .choiceWidgetAnnotation select, .annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { - background-color: rgba(0, 54, 255, 0.13); + background-image: var(--annotation-unfocused-field-background); border: 1px solid transparent; box-sizing: border-box; font-size: 9px; @@ -100,6 +104,8 @@ .annotationLayer .choiceWidgetAnnotation select :focus, .annotationLayer .buttonWidgetAnnotation.checkBox :focus, .annotationLayer .buttonWidgetAnnotation.radioButton :focus { + background-image: none; + background-color: transparent; outline: auto; } @@ -141,16 +147,6 @@ padding-right: 0; } -.annotationLayer .textWidgetAnnotation input.comb:focus { - /* - * Letter spacing is placed on the right side of each character. Hence, the - * letter spacing of the last character may be placed outside the visible - * area, causing horizontal scrolling. We avoid this by extending the width - * when the element has focus and revert this when it loses focus. - */ - width: 103%; -} - .annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { appearance: none; diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css index b2ee798f7..68807fb1f 100644 --- a/web/xfa_layer_builder.css +++ b/web/xfa_layer_builder.css @@ -14,7 +14,7 @@ */ :root { - --unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); } .xfaLayer .highlight { @@ -202,7 +202,7 @@ flex: 1 1 auto; border: none; resize: none; - background-image: var(--unfocused-field-background); + background-image: var(--xfa-unfocused-field-background); } .xfaTop > .xfaTextfield,