From 6100ab4b18008d4c2fdf68abb04f34297a234dae Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Tue, 20 Sep 2016 00:04:11 +0200 Subject: [PATCH 1/2] Text widget annotations: implement comb support --- src/core/annotation.js | 5 ++ src/display/annotation_layer.js | 8 +++ test/annotation_layer_test.css | 6 +++ test/pdfs/annotation-text-widget.pdf | Bin 91256 -> 93171 bytes test/test_manifest.json | 4 +- test/unit/annotation_layer_spec.js | 78 ++++++++++++++++++++++++++- web/annotation_layer_builder.css | 16 ++++++ 7 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/core/annotation.js b/src/core/annotation.js index 42f49c2edb36e..bf4a5a716293b 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -715,6 +715,11 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { // Process field flags for the display layer. this.data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY); this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE); + this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) && + !this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) && + !this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) && + !this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) && + this.data.maxLen !== null; } Util.inherit(TextWidgetAnnotation, WidgetAnnotation, { diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 5324476a81460..d8d7ac5511a53 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -461,6 +461,14 @@ var TextWidgetAnnotationElement = ( if (this.data.maxLen !== null) { element.maxLength = this.data.maxLen; } + + if (this.data.comb) { + var fieldWidth = this.data.rect[2] - this.data.rect[0]; + var combWidth = fieldWidth / this.data.maxLen; + + element.classList.add('comb'); + element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)'; + } } else { element = document.createElement('div'); element.textContent = this.data.fieldValue; diff --git a/test/annotation_layer_test.css b/test/annotation_layer_test.css index ae5881c62801f..df5dea06cf89e 100644 --- a/test/annotation_layer_test.css +++ b/test/annotation_layer_test.css @@ -67,6 +67,12 @@ border: 1px solid transparent; } +.annotationLayer .textWidgetAnnotation input.comb { + font-family: monospace; + padding-left: 2px; + padding-right: 0; +} + .annotationLayer .popupAnnotation { display: block !important; } diff --git a/test/pdfs/annotation-text-widget.pdf b/test/pdfs/annotation-text-widget.pdf index d6c959c1a5faefe62a5c0f94305d6cf09dc1a14a..6cf0b77ccc64bf24664b5e219b23d21fc7b04de4 100644 GIT binary patch delta 14422 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Ē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 Date: Wed, 21 Sep 2016 21:06:44 +0200 Subject: [PATCH 2/2] Widget annotations: simplify field flag handling Directly use the hexadecimal representation, just like the `AnnotationFlags`, to avoid calculations and to improve readability. This allows us to simplify the unit tests for text widget annotations as well. --- src/core/annotation.js | 7 +++--- src/shared/util.js | 38 +++++++++++++++--------------- test/unit/annotation_layer_spec.js | 35 +++++++++------------------ 3 files changed, 33 insertions(+), 47 deletions(-) diff --git a/src/core/annotation.js b/src/core/annotation.js index bf4a5a716293b..1bcab54b48dfb 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -678,14 +678,13 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() { * * @public * @memberof WidgetAnnotation - * @param {number} flag - Bit position, numbered from one instead of - * zero, to check + * @param {number} flag - Hexadecimal representation for an annotation + * field characteristic * @return {boolean} * @see {@link shared/util.js} */ hasFieldFlag: function WidgetAnnotation_hasFieldFlag(flag) { - var mask = 1 << (flag - 1); - return !!(this.data.fieldFlags & mask); + return !!(this.data.fieldFlags & flag); }, }); diff --git a/src/shared/util.js b/src/shared/util.js index 853cc1a3455a4..48876dad31159 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -94,25 +94,25 @@ var AnnotationFlag = { }; var AnnotationFieldFlag = { - READONLY: 1, - REQUIRED: 2, - NOEXPORT: 3, - MULTILINE: 13, - PASSWORD: 14, - NOTOGGLETOOFF: 15, - RADIO: 16, - PUSHBUTTON: 17, - COMBO: 18, - EDIT: 19, - SORT: 20, - FILESELECT: 21, - MULTISELECT: 22, - DONOTSPELLCHECK: 23, - DONOTSCROLL: 24, - COMB: 25, - RICHTEXT: 26, - RADIOSINUNISON: 26, - COMMITONSELCHANGE: 27, + READONLY: 0x0000001, + REQUIRED: 0x0000002, + NOEXPORT: 0x0000004, + MULTILINE: 0x0001000, + PASSWORD: 0x0002000, + NOTOGGLETOOFF: 0x0004000, + RADIO: 0x0008000, + PUSHBUTTON: 0x0010000, + COMBO: 0x0020000, + EDIT: 0x0040000, + SORT: 0x0080000, + FILESELECT: 0x0100000, + MULTISELECT: 0x0200000, + DONOTSPELLCHECK: 0x0400000, + DONOTSCROLL: 0x0800000, + COMB: 0x1000000, + RICHTEXT: 0x2000000, + RADIOSINUNISON: 0x2000000, + COMMITONSELCHANGE: 0x4000000, }; var AnnotationBorderStyleType = { diff --git a/test/unit/annotation_layer_spec.js b/test/unit/annotation_layer_spec.js index fb34b242371f8..a1e38168ea31b 100644 --- a/test/unit/annotation_layer_spec.js +++ b/test/unit/annotation_layer_spec.js @@ -505,13 +505,10 @@ describe('Annotation layer', function() { it('should set valid text alignment, maximum length and flags', function() { - var flags = 0; - flags |= 1 << (AnnotationFieldFlag.READONLY - 1); - flags |= 1 << (AnnotationFieldFlag.MULTILINE - 1); - textWidgetDict.set('Q', 1); textWidgetDict.set('MaxLen', 20); - textWidgetDict.set('Ff', flags); + textWidgetDict.set('Ff', AnnotationFieldFlag.READONLY + + AnnotationFieldFlag.MULTILINE); var textWidgetRef = new Ref(84, 0); var xref = new XRefMock([ @@ -526,10 +523,7 @@ describe('Annotation layer', function() { }); it('should reject comb fields without a maximum length', function() { - var flags = 0; - flags |= 1 << (AnnotationFieldFlag.COMB - 1); - - textWidgetDict.set('Ff', flags); + textWidgetDict.set('Ff', AnnotationFieldFlag.COMB); var textWidgetRef = new Ref(46, 0); var xref = new XRefMock([ @@ -541,11 +535,8 @@ describe('Annotation layer', function() { }); it('should accept comb fields with a maximum length', function() { - var flags = 0; - flags |= 1 << (AnnotationFieldFlag.COMB - 1); - textWidgetDict.set('MaxLen', 20); - textWidgetDict.set('Ff', flags); + textWidgetDict.set('Ff', AnnotationFieldFlag.COMB); var textWidgetRef = new Ref(46, 0); var xref = new XRefMock([ @@ -558,20 +549,16 @@ describe('Annotation layer', function() { it('should only accept comb fields when the flags are valid', function() { var invalidFieldFlags = [ - AnnotationFieldFlag.MULTILINE, - AnnotationFieldFlag.PASSWORD, + AnnotationFieldFlag.MULTILINE, AnnotationFieldFlag.PASSWORD, AnnotationFieldFlag.FILESELECT ]; - // The field may not use combs until all invalid flags are unset. - for (var i = 0, ii = invalidFieldFlags.length; i <= ii; i++) { - var flags = 0; - flags |= 1 << (AnnotationFieldFlag.COMB - 1); - - for (var j = 0, jj = invalidFieldFlags.length; j < jj; j++) { - flags |= 1 << (invalidFieldFlags[j] - 1); - } + // Start with all invalid flags set and remove them one by one. + // The field may only use combs when all invalid flags are unset. + var flags = AnnotationFieldFlag.COMB + AnnotationFieldFlag.MULTILINE + + AnnotationFieldFlag.PASSWORD + AnnotationFieldFlag.FILESELECT; + for (var i = 0, ii = invalidFieldFlags.length; i <= ii; i++) { textWidgetDict.set('MaxLen', 20); textWidgetDict.set('Ff', flags); @@ -588,7 +575,7 @@ describe('Annotation layer', function() { // Remove the last invalid flag for the next iteration. if (!valid) { - invalidFieldFlags.splice(-1, 1); + flags -= invalidFieldFlags.splice(-1, 1); } } });