Implement support for polyline annotations

This commit is contained in:
Tim van der Meij 2017-09-17 20:18:22 +02:00
parent c84c23c4cb
commit 99b17a494d
No known key found for this signature in database
GPG Key ID: 8C3FD2925A5F2762
3 changed files with 88 additions and 1 deletions

View File

@ -87,6 +87,9 @@ class AnnotationFactory {
case 'Circle': case 'Circle':
return new CircleAnnotation(parameters); return new CircleAnnotation(parameters);
case 'PolyLine':
return new PolylineAnnotation(parameters);
case 'Highlight': case 'Highlight':
return new HighlightAnnotation(parameters); return new HighlightAnnotation(parameters);
@ -913,6 +916,30 @@ class CircleAnnotation extends Annotation {
} }
} }
class PolylineAnnotation extends Annotation {
constructor(parameters) {
super(parameters);
this.data.annotationType = AnnotationType.POLYLINE;
// The vertices array is an array of numbers representing the alternating
// horizontal and vertical coordinates, respectively, of each vertex.
// Convert this to an array of objects with x and y coordinates.
let dict = parameters.dict;
let rawVertices = dict.getArray('Vertices');
this.data.vertices = [];
for (let i = 0, ii = rawVertices.length; i < ii; i += 2) {
this.data.vertices.push({
x: rawVertices[i],
y: rawVertices[i + 1],
});
}
this._preparePopup(dict);
}
}
class HighlightAnnotation extends Annotation { class HighlightAnnotation extends Annotation {
constructor(parameters) { constructor(parameters) {
super(parameters); super(parameters);

View File

@ -80,6 +80,9 @@ class AnnotationElementFactory {
case AnnotationType.CIRCLE: case AnnotationType.CIRCLE:
return new CircleAnnotationElement(parameters); return new CircleAnnotationElement(parameters);
case AnnotationType.POLYLINE:
return new PolylineAnnotationElement(parameters);
case AnnotationType.HIGHLIGHT: case AnnotationType.HIGHLIGHT:
return new HighlightAnnotationElement(parameters); return new HighlightAnnotationElement(parameters);
@ -601,7 +604,7 @@ class PopupAnnotationElement extends AnnotationElement {
render() { render() {
// Do not render popup annotations for parent elements with these types as // Do not render popup annotations for parent elements with these types as
// they create the popups themselves (because of custom trigger divs). // they create the popups themselves (because of custom trigger divs).
const IGNORE_TYPES = ['Line', 'Square', 'Circle']; const IGNORE_TYPES = ['Line', 'Square', 'Circle', 'PolyLine'];
this.container.className = 'popupAnnotation'; this.container.className = 'popupAnnotation';
@ -911,6 +914,62 @@ class CircleAnnotationElement extends AnnotationElement {
} }
} }
class PolylineAnnotationElement extends AnnotationElement {
constructor(parameters) {
let isRenderable = !!(parameters.data.hasPopup ||
parameters.data.title || parameters.data.contents);
super(parameters, isRenderable, /* ignoreBorder = */ true);
}
/**
* Render the polyline annotation's HTML element in the empty container.
*
* @public
* @memberof PolylineAnnotationElement
* @returns {HTMLSectionElement}
*/
render() {
this.container.className = 'polylineAnnotation';
// Create an invisible polyline with the same points that acts as the
// trigger for the popup. Only the polyline itself should trigger the
// popup, not the entire container.
let data = this.data;
let width = data.rect[2] - data.rect[0];
let height = data.rect[3] - data.rect[1];
let svg = this.svgFactory.create(width, height);
// Convert the vertices array to a single points string that the SVG
// polyline element expects ("x1,y1 x2,y2 ..."). PDF coordinates are
// calculated from a bottom left origin, so transform the polyline
// coordinates to a top left origin for the SVG element.
let vertices = data.vertices;
let points = [];
for (let i = 0, ii = vertices.length; i < ii; i++) {
let x = vertices[i].x - data.rect[0];
let y = data.rect[3] - vertices[i].y;
points.push(x + ',' + y);
}
points = points.join(' ');
let borderWidth = data.borderStyle.width;
let polyline = this.svgFactory.createElement('svg:polyline');
polyline.setAttribute('points', points);
polyline.setAttribute('stroke-width', borderWidth);
polyline.setAttribute('stroke', 'transparent');
polyline.setAttribute('fill', 'none');
svg.appendChild(polyline);
this.container.append(svg);
// Create the popup ourselves so that we can bind it to the polyline
// instead of to the entire container (which is the default).
this._createPopup(this.container, polyline, data);
return this.container;
}
}
class HighlightAnnotationElement extends AnnotationElement { class HighlightAnnotationElement extends AnnotationElement {
constructor(parameters) { constructor(parameters) {
let isRenderable = !!(parameters.data.hasPopup || let isRenderable = !!(parameters.data.hasPopup ||

View File

@ -191,6 +191,7 @@
.annotationLayer .lineAnnotation svg line, .annotationLayer .lineAnnotation svg line,
.annotationLayer .squareAnnotation svg rect, .annotationLayer .squareAnnotation svg rect,
.annotationLayer .circleAnnotation svg ellipse, .annotationLayer .circleAnnotation svg ellipse,
.annotationLayer .polylineAnnotation svg polyline,
.annotationLayer .stampAnnotation, .annotationLayer .stampAnnotation,
.annotationLayer .fileAttachmentAnnotation { .annotationLayer .fileAttachmentAnnotation {
cursor: pointer; cursor: pointer;