Merge pull request #8950 from timvandermeij/polygon-polyline-annotations

Implement support for polyline and polygon annotations
This commit is contained in:
Jonas Jenwald 2017-09-24 15:16:14 +02:00 committed by GitHub
commit 10727572a2
6 changed files with 125 additions and 1 deletions

View File

@ -87,6 +87,12 @@ class AnnotationFactory {
case 'Circle': case 'Circle':
return new CircleAnnotation(parameters); return new CircleAnnotation(parameters);
case 'PolyLine':
return new PolylineAnnotation(parameters);
case 'Polygon':
return new PolygonAnnotation(parameters);
case 'Highlight': case 'Highlight':
return new HighlightAnnotation(parameters); return new HighlightAnnotation(parameters);
@ -913,6 +919,39 @@ 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 PolygonAnnotation extends PolylineAnnotation {
constructor(parameters) {
// Polygons are specific forms of polylines, so reuse their logic.
super(parameters);
this.data.annotationType = AnnotationType.POLYGON;
}
}
class HighlightAnnotation extends Annotation { class HighlightAnnotation extends Annotation {
constructor(parameters) { constructor(parameters) {
super(parameters); super(parameters);

View File

@ -80,6 +80,12 @@ 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.POLYGON:
return new PolygonAnnotationElement(parameters);
case AnnotationType.HIGHLIGHT: case AnnotationType.HIGHLIGHT:
return new HighlightAnnotationElement(parameters); return new HighlightAnnotationElement(parameters);
@ -601,7 +607,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', 'Polygon'];
this.container.className = 'popupAnnotation'; this.container.className = 'popupAnnotation';
@ -911,6 +917,75 @@ 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);
this.containerClassName = 'polylineAnnotation';
this.svgElementName = 'svg:polyline';
}
/**
* Render the polyline annotation's HTML element in the empty container.
*
* @public
* @memberof PolylineAnnotationElement
* @returns {HTMLSectionElement}
*/
render() {
this.container.className = this.containerClassName;
// 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(this.svgElementName);
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 PolygonAnnotationElement extends PolylineAnnotationElement {
constructor(parameters) {
// Polygons are specific forms of polylines, so reuse their logic.
super(parameters);
this.containerClassName = 'polygonAnnotation';
this.svgElementName = 'svg:polygon';
}
}
class HighlightAnnotationElement extends AnnotationElement { class HighlightAnnotationElement extends AnnotationElement {
constructor(parameters) { constructor(parameters) {
let isRenderable = !!(parameters.data.hasPopup || let isRenderable = !!(parameters.data.hasPopup ||

View File

@ -292,6 +292,7 @@
!annotation-text-widget.pdf !annotation-text-widget.pdf
!annotation-choice-widget.pdf !annotation-choice-widget.pdf
!annotation-button-widget.pdf !annotation-button-widget.pdf
!annotation-polyline-polygon.pdf
!zero_descent.pdf !zero_descent.pdf
!operator-in-TJ-array.pdf !operator-in-TJ-array.pdf
!issue7878.pdf !issue7878.pdf

Binary file not shown.

View File

@ -3660,6 +3660,13 @@
"type": "eq", "type": "eq",
"forms": true "forms": true
}, },
{ "id": "annotation-polyline-polygon",
"file": "pdfs/annotation-polyline-polygon.pdf",
"md5": "e68611602f58c8ca70cc40575ba3b04e",
"rounds": 1,
"type": "eq",
"annotations": true
},
{ "id": "issue6108", { "id": "issue6108",
"file": "pdfs/issue6108.pdf", "file": "pdfs/issue6108.pdf",
"md5": "8961cb55149495989a80bf0487e0f076", "md5": "8961cb55149495989a80bf0487e0f076",

View File

@ -191,6 +191,8 @@
.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 .polygonAnnotation svg polygon,
.annotationLayer .stampAnnotation, .annotationLayer .stampAnnotation,
.annotationLayer .fileAttachmentAnnotation { .annotationLayer .fileAttachmentAnnotation {
cursor: pointer; cursor: pointer;