Skip to content

Commit c55541f

Browse files
committed
Merge pull request #7352 from Snuffleupagus/popup-annotation-inherit-parent-flags
Let non-viewable Popup Annotations inherit the parent's Annotation Flags if the parent is viewable
2 parents 47b929b + 98fe094 commit c55541f

File tree

5 files changed

+91
-30
lines changed

5 files changed

+91
-30
lines changed

src/core/annotation.js

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -190,28 +190,49 @@ var Annotation = (function AnnotationClosure() {
190190
}
191191

192192
Annotation.prototype = {
193+
/**
194+
* @private
195+
*/
196+
_hasFlag: function Annotation_hasFlag(flags, flag) {
197+
return !!(flags & flag);
198+
},
199+
200+
/**
201+
* @private
202+
*/
203+
_isViewable: function Annotation_isViewable(flags) {
204+
return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
205+
!this._hasFlag(flags, AnnotationFlag.HIDDEN) &&
206+
!this._hasFlag(flags, AnnotationFlag.NOVIEW);
207+
},
208+
209+
/**
210+
* @private
211+
*/
212+
_isPrintable: function AnnotationFlag_isPrintable(flags) {
213+
return this._hasFlag(flags, AnnotationFlag.PRINT) &&
214+
!this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
215+
!this._hasFlag(flags, AnnotationFlag.HIDDEN);
216+
},
217+
193218
/**
194219
* @return {boolean}
195220
*/
196221
get viewable() {
197-
if (this.flags) {
198-
return !this.hasFlag(AnnotationFlag.INVISIBLE) &&
199-
!this.hasFlag(AnnotationFlag.HIDDEN) &&
200-
!this.hasFlag(AnnotationFlag.NOVIEW);
222+
if (this.flags === 0) {
223+
return true;
201224
}
202-
return true;
225+
return this._isViewable(this.flags);
203226
},
204227

205228
/**
206229
* @return {boolean}
207230
*/
208231
get printable() {
209-
if (this.flags) {
210-
return this.hasFlag(AnnotationFlag.PRINT) &&
211-
!this.hasFlag(AnnotationFlag.INVISIBLE) &&
212-
!this.hasFlag(AnnotationFlag.HIDDEN);
232+
if (this.flags === 0) {
233+
return false;
213234
}
214-
return false;
235+
return this._isPrintable(this.flags);
215236
},
216237

217238
/**
@@ -224,11 +245,7 @@ var Annotation = (function AnnotationClosure() {
224245
* @see {@link shared/util.js}
225246
*/
226247
setFlags: function Annotation_setFlags(flags) {
227-
if (isInt(flags)) {
228-
this.flags = flags;
229-
} else {
230-
this.flags = 0;
231-
}
248+
this.flags = (isInt(flags) && flags > 0) ? flags : 0;
232249
},
233250

234251
/**
@@ -242,10 +259,7 @@ var Annotation = (function AnnotationClosure() {
242259
* @see {@link shared/util.js}
243260
*/
244261
hasFlag: function Annotation_hasFlag(flag) {
245-
if (this.flags) {
246-
return (this.flags & flag) > 0;
247-
}
248-
return false;
262+
return this._hasFlag(this.flags, flag);
249263
},
250264

251265
/**
@@ -823,6 +837,16 @@ var PopupAnnotation = (function PopupAnnotationClosure() {
823837
this.setColor(parentItem.getArray('C'));
824838
this.data.color = this.color;
825839
}
840+
841+
// If the Popup annotation is not viewable, but the parent annotation is,
842+
// that is most likely a bug. Fallback to inherit the flags from the parent
843+
// annotation (this is consistent with the behaviour in Adobe Reader).
844+
if (!this.viewable) {
845+
var parentFlags = parentItem.get('F');
846+
if (this._isViewable(parentFlags)) {
847+
this.setFlags(parentFlags);
848+
}
849+
}
826850
}
827851

828852
Util.inherit(PopupAnnotation, Annotation, {});

test/pdfs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
!pr4922.pdf
100100
!pr6531_1.pdf
101101
!pr6531_2.pdf
102+
!pr7352.pdf
102103
!bug900822.pdf
103104
!issue918.pdf
104105
!issue1905.pdf

test/pdfs/pr7352.pdf

1.61 KB
Binary file not shown.

test/test_manifest.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,6 +1838,14 @@
18381838
"type": "eq",
18391839
"annotations": true
18401840
},
1841+
{ "id": "pr7352",
1842+
"file": "pdfs/pr7352.pdf",
1843+
"md5": "336abca4b313cb215b0569883f1f683d",
1844+
"link": false,
1845+
"rounds": 1,
1846+
"type": "eq",
1847+
"annotations": true
1848+
},
18411849
{ "id": "issue1002",
18421850
"file": "pdfs/issue1002.pdf",
18431851
"md5": "af62d6cd95079322d4af18edd960d15c",

test/unit/annotation_layer_spec.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ describe('Annotation layer', function() {
1515
}
1616
};
1717

18+
var annotationFactory;
19+
20+
beforeAll(function (done) {
21+
annotationFactory = new AnnotationFactory();
22+
done();
23+
});
24+
25+
afterAll(function () {
26+
annotationFactory = null;
27+
});
28+
1829
describe('Annotation', function() {
1930
it('should set and get flags', function() {
2031
var dict = new Dict();
@@ -185,17 +196,6 @@ describe('Annotation layer', function() {
185196
});
186197

187198
describe('LinkAnnotation', function() {
188-
var annotationFactory;
189-
190-
beforeAll(function (done) {
191-
annotationFactory = new AnnotationFactory();
192-
done();
193-
});
194-
195-
afterAll(function () {
196-
annotationFactory = null;
197-
});
198-
199199
it('should correctly parse a URI action', function() {
200200
var actionDict = new Dict();
201201
actionDict.set('Type', Name.get('Action'));
@@ -358,4 +358,32 @@ describe('Annotation layer', function() {
358358
expect(annotation.file.content).toEqual(stringToBytes('Test attachment'));
359359
});
360360
});
361+
362+
describe('PopupAnnotation', function() {
363+
it('should inherit the parent flags when the Popup is not viewable, ' +
364+
'but the parent is (PR 7352)', function () {
365+
var parentDict = new Dict();
366+
parentDict.set('Type', Name.get('Annot'));
367+
parentDict.set('Subtype', Name.get('Text'));
368+
parentDict.set('F', 28); // viewable
369+
370+
var popupDict = new Dict();
371+
popupDict.set('Type', Name.get('Annot'));
372+
popupDict.set('Subtype', Name.get('Popup'));
373+
popupDict.set('F', 25); // not viewable
374+
popupDict.set('Parent', parentDict);
375+
376+
var xrefMock = new XrefMock([popupDict]);
377+
var popupRef = new Ref(13, 0);
378+
379+
var popupAnnotation = annotationFactory.create(xrefMock, popupRef);
380+
var data = popupAnnotation.data;
381+
expect(data.annotationType).toEqual(AnnotationType.POPUP);
382+
383+
// Should not modify the `annotationFlags` returned e.g. through the API.
384+
expect(data.annotationFlags).toEqual(25);
385+
// The Popup should inherit the `viewable` property of the parent.
386+
expect(popupAnnotation.viewable).toEqual(true);
387+
});
388+
});
361389
});

0 commit comments

Comments
 (0)