Merge pull request #11013 from timvandermeij/annotations-quadpoints
[api-minor] Implement quadpoints for annotations in the core layer
This commit is contained in:
commit
be70ee236d
@ -146,6 +146,39 @@ class AnnotationFactory {
|
||||
}
|
||||
}
|
||||
|
||||
function getQuadPoints(dict, rect) {
|
||||
if (!dict.has('QuadPoints')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The region is described as a number of quadrilaterals.
|
||||
// Each quadrilateral must consist of eight coordinates.
|
||||
const quadPoints = dict.getArray('QuadPoints');
|
||||
if (!Array.isArray(quadPoints) || quadPoints.length % 8 > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const quadPointsLists = [];
|
||||
for (let i = 0, ii = quadPoints.length / 8; i < ii; i++) {
|
||||
// Each series of eight numbers represents the coordinates for one
|
||||
// quadrilateral in the order [x1, y1, x2, y2, x3, y3, x4, y4].
|
||||
// Convert this to an array of objects with x and y coordinates.
|
||||
quadPointsLists.push([]);
|
||||
for (let j = i * 8, jj = (i * 8) + 8; j < jj; j += 2) {
|
||||
const x = quadPoints[j];
|
||||
const y = quadPoints[j + 1];
|
||||
|
||||
// The quadpoints should be ignored if any coordinate in the array
|
||||
// lies outside the region specified by the rectangle.
|
||||
if (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) {
|
||||
return null;
|
||||
}
|
||||
quadPointsLists[i].push({ x, y, });
|
||||
}
|
||||
}
|
||||
return quadPointsLists;
|
||||
}
|
||||
|
||||
function getTransformMatrix(rect, bbox, matrix) {
|
||||
// 12.5.5: Algorithm: Appearance streams
|
||||
let bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
|
||||
@ -1042,6 +1075,11 @@ class LinkAnnotation extends Annotation {
|
||||
|
||||
this.data.annotationType = AnnotationType.LINK;
|
||||
|
||||
const quadPoints = getQuadPoints(params.dict, this.rectangle);
|
||||
if (quadPoints) {
|
||||
this.data.quadPoints = quadPoints;
|
||||
}
|
||||
|
||||
Catalog.parseDestDictionary({
|
||||
destDict: params.dict,
|
||||
resultObj: this.data,
|
||||
@ -1211,6 +1249,11 @@ class HighlightAnnotation extends MarkupAnnotation {
|
||||
super(parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.HIGHLIGHT;
|
||||
|
||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
||||
if (quadPoints) {
|
||||
this.data.quadPoints = quadPoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1219,6 +1262,11 @@ class UnderlineAnnotation extends MarkupAnnotation {
|
||||
super(parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.UNDERLINE;
|
||||
|
||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
||||
if (quadPoints) {
|
||||
this.data.quadPoints = quadPoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1227,6 +1275,11 @@ class SquigglyAnnotation extends MarkupAnnotation {
|
||||
super(parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.SQUIGGLY;
|
||||
|
||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
||||
if (quadPoints) {
|
||||
this.data.quadPoints = quadPoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1235,6 +1288,11 @@ class StrikeOutAnnotation extends MarkupAnnotation {
|
||||
super(parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.STRIKEOUT;
|
||||
|
||||
const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
|
||||
if (quadPoints) {
|
||||
this.data.quadPoints = quadPoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1262,4 +1320,5 @@ export {
|
||||
AnnotationBorderStyle,
|
||||
AnnotationFactory,
|
||||
MarkupAnnotation,
|
||||
getQuadPoints,
|
||||
};
|
||||
|
@ -14,7 +14,8 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
Annotation, AnnotationBorderStyle, AnnotationFactory, MarkupAnnotation
|
||||
Annotation, AnnotationBorderStyle, AnnotationFactory, getQuadPoints,
|
||||
MarkupAnnotation
|
||||
} from '../../src/core/annotation';
|
||||
import {
|
||||
AnnotationBorderStyleType, AnnotationFieldFlag, AnnotationFlag,
|
||||
@ -118,6 +119,69 @@ describe('annotation', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getQuadPoints', function() {
|
||||
let dict, rect;
|
||||
|
||||
beforeEach(function(done) {
|
||||
dict = new Dict();
|
||||
rect = [];
|
||||
done();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
dict = null;
|
||||
rect = null;
|
||||
});
|
||||
|
||||
it('should ignore missing quadpoints', function() {
|
||||
expect(getQuadPoints(dict, rect)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should ignore non-array values', function() {
|
||||
dict.set('QuadPoints', 'foo');
|
||||
expect(getQuadPoints(dict, rect)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should ignore arrays where the length is not a multiple of eight',
|
||||
function() {
|
||||
dict.set('QuadPoints', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
expect(getQuadPoints(dict, rect)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should ignore quadpoints if one coordinate lies outside the rectangle',
|
||||
function() {
|
||||
rect = [10, 10, 20, 20];
|
||||
const inputs = [
|
||||
[11, 11, 12, 12, 9, 13, 14, 14], // Smaller than lower x coordinate.
|
||||
[11, 11, 12, 12, 13, 9, 14, 14], // Smaller than lower y coordinate.
|
||||
[11, 11, 12, 12, 21, 13, 14, 14], // Larger than upper x coordinate.
|
||||
[11, 11, 12, 12, 13, 21, 14, 14], // Larger than upper y coordinate.
|
||||
];
|
||||
for (const input of inputs) {
|
||||
dict.set('QuadPoints', input);
|
||||
expect(getQuadPoints(dict, rect)).toEqual(null);
|
||||
}
|
||||
});
|
||||
|
||||
it('should process valid quadpoints arrays', function() {
|
||||
rect = [10, 10, 20, 20];
|
||||
dict.set('QuadPoints', [
|
||||
11, 11, 12, 12, 13, 13, 14, 14,
|
||||
15, 15, 16, 16, 17, 17, 18, 18,
|
||||
]);
|
||||
expect(getQuadPoints(dict, rect)).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
[
|
||||
{ x: 15, y: 15, }, { x: 16, y: 16, },
|
||||
{ x: 17, y: 17, }, { x: 18, y: 18, },
|
||||
],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Annotation', function() {
|
||||
let dict, ref;
|
||||
|
||||
@ -1001,6 +1065,49 @@ describe('annotation', function() {
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should not set quadpoints if not defined', function(done) {
|
||||
const annotationDict = new Dict();
|
||||
annotationDict.set('Type', Name.get('Annot'));
|
||||
annotationDict.set('Subtype', Name.get('Link'));
|
||||
|
||||
const annotationRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: annotationRef, data: annotationDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, annotationRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.LINK);
|
||||
expect(data.quadPoints).toBeUndefined();
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should set quadpoints if defined', function(done) {
|
||||
const annotationDict = new Dict();
|
||||
annotationDict.set('Type', Name.get('Annot'));
|
||||
annotationDict.set('Subtype', Name.get('Link'));
|
||||
annotationDict.set('Rect', [10, 10, 20, 20]);
|
||||
annotationDict.set('QuadPoints', [11, 11, 12, 12, 13, 13, 14, 14]);
|
||||
|
||||
const annotationRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: annotationRef, data: annotationDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, annotationRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.LINK);
|
||||
expect(data.quadPoints).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
]);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('WidgetAnnotation', function() {
|
||||
@ -1862,4 +1969,184 @@ describe('annotation', function() {
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('HightlightAnnotation', function() {
|
||||
it('should not set quadpoints if not defined', function(done) {
|
||||
const highlightDict = new Dict();
|
||||
highlightDict.set('Type', Name.get('Annot'));
|
||||
highlightDict.set('Subtype', Name.get('Highlight'));
|
||||
|
||||
const highlightRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: highlightRef, data: highlightDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, highlightRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.HIGHLIGHT);
|
||||
expect(data.quadPoints).toBeUndefined();
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should set quadpoints if defined', function(done) {
|
||||
const highlightDict = new Dict();
|
||||
highlightDict.set('Type', Name.get('Annot'));
|
||||
highlightDict.set('Subtype', Name.get('Highlight'));
|
||||
highlightDict.set('Rect', [10, 10, 20, 20]);
|
||||
highlightDict.set('QuadPoints', [11, 11, 12, 12, 13, 13, 14, 14]);
|
||||
|
||||
const highlightRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: highlightRef, data: highlightDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, highlightRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.HIGHLIGHT);
|
||||
expect(data.quadPoints).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
]);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UnderlineAnnotation', function() {
|
||||
it('should not set quadpoints if not defined', function(done) {
|
||||
const underlineDict = new Dict();
|
||||
underlineDict.set('Type', Name.get('Annot'));
|
||||
underlineDict.set('Subtype', Name.get('Underline'));
|
||||
|
||||
const underlineRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: underlineRef, data: underlineDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, underlineRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.UNDERLINE);
|
||||
expect(data.quadPoints).toBeUndefined();
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should set quadpoints if defined', function(done) {
|
||||
const underlineDict = new Dict();
|
||||
underlineDict.set('Type', Name.get('Annot'));
|
||||
underlineDict.set('Subtype', Name.get('Underline'));
|
||||
underlineDict.set('Rect', [10, 10, 20, 20]);
|
||||
underlineDict.set('QuadPoints', [11, 11, 12, 12, 13, 13, 14, 14]);
|
||||
|
||||
const underlineRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: underlineRef, data: underlineDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, underlineRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.UNDERLINE);
|
||||
expect(data.quadPoints).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
]);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SquigglyAnnotation', function() {
|
||||
it('should not set quadpoints if not defined', function(done) {
|
||||
const squigglyDict = new Dict();
|
||||
squigglyDict.set('Type', Name.get('Annot'));
|
||||
squigglyDict.set('Subtype', Name.get('Squiggly'));
|
||||
|
||||
const squigglyRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: squigglyRef, data: squigglyDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, squigglyRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.SQUIGGLY);
|
||||
expect(data.quadPoints).toBeUndefined();
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should set quadpoints if defined', function(done) {
|
||||
const squigglyDict = new Dict();
|
||||
squigglyDict.set('Type', Name.get('Annot'));
|
||||
squigglyDict.set('Subtype', Name.get('Squiggly'));
|
||||
squigglyDict.set('Rect', [10, 10, 20, 20]);
|
||||
squigglyDict.set('QuadPoints', [11, 11, 12, 12, 13, 13, 14, 14]);
|
||||
|
||||
const squigglyRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: squigglyRef, data: squigglyDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, squigglyRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.SQUIGGLY);
|
||||
expect(data.quadPoints).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
]);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('StrikeOutAnnotation', function() {
|
||||
it('should not set quadpoints if not defined', function(done) {
|
||||
const strikeOutDict = new Dict();
|
||||
strikeOutDict.set('Type', Name.get('Annot'));
|
||||
strikeOutDict.set('Subtype', Name.get('StrikeOut'));
|
||||
|
||||
const strikeOutRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: strikeOutRef, data: strikeOutDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, strikeOutRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.STRIKEOUT);
|
||||
expect(data.quadPoints).toBeUndefined();
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
|
||||
it('should set quadpoints if defined', function(done) {
|
||||
const strikeOutDict = new Dict();
|
||||
strikeOutDict.set('Type', Name.get('Annot'));
|
||||
strikeOutDict.set('Subtype', Name.get('StrikeOut'));
|
||||
strikeOutDict.set('Rect', [10, 10, 20, 20]);
|
||||
strikeOutDict.set('QuadPoints', [11, 11, 12, 12, 13, 13, 14, 14]);
|
||||
|
||||
const strikeOutRef = Ref.get(121, 0);
|
||||
const xref = new XRefMock([
|
||||
{ ref: strikeOutRef, data: strikeOutDict, }
|
||||
]);
|
||||
|
||||
AnnotationFactory.create(xref, strikeOutRef, pdfManagerMock,
|
||||
idFactoryMock).then(({ data, }) => {
|
||||
expect(data.annotationType).toEqual(AnnotationType.STRIKEOUT);
|
||||
expect(data.quadPoints).toEqual([
|
||||
[
|
||||
{ x: 11, y: 11, }, { x: 12, y: 12, },
|
||||
{ x: 13, y: 13, }, { x: 14, y: 14, },
|
||||
],
|
||||
]);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user