Skip to content

Commit 5ec5018

Browse files
committed
[Annotation] Use the clip-path property when an annotation has some quad points
This way it'll avoid to split a div in multiple divs having the same id (which is supposed to be unique).
1 parent b8447eb commit 5ec5018

File tree

2 files changed

+45
-79
lines changed

2 files changed

+45
-79
lines changed

src/display/annotation_layer.js

+34-75
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
AnnotationBorderStyleType,
2323
AnnotationEditorType,
2424
AnnotationType,
25-
assert,
2625
FeatureTest,
2726
LINE_FACTOR,
2827
shadow,
@@ -182,7 +181,7 @@ class AnnotationElement {
182181
this.container = this._createContainer(ignoreBorder);
183182
}
184183
if (createQuadrilaterals) {
185-
this.quadrilaterals = this._createQuadrilaterals(ignoreBorder);
184+
this._createQuadrilaterals();
186185
}
187186
}
188187

@@ -417,26 +416,41 @@ class AnnotationElement {
417416
* @private
418417
* @param {boolean} ignoreBorder
419418
* @memberof AnnotationElement
420-
* @returns {Array<HTMLElement>} An array of section elements.
421419
*/
422-
_createQuadrilaterals(ignoreBorder = false) {
423-
if (!this.data.quadPoints) {
424-
return null;
420+
_createQuadrilaterals() {
421+
const { quadPoints } = this.data;
422+
if (!quadPoints || quadPoints.length === 1) {
423+
return;
425424
}
426425

427-
const quadrilaterals = [];
428-
const savedRect = this.data.rect;
429-
for (const quadPoint of this.data.quadPoints) {
430-
this.data.rect = [
431-
quadPoint[2].x,
432-
quadPoint[2].y,
433-
quadPoint[1].x,
434-
quadPoint[1].y,
435-
];
436-
quadrilaterals.push(this._createContainer(ignoreBorder));
426+
const { svgFactory } = this;
427+
const svg = svgFactory.createElement("svg");
428+
svg.classList.add("quadrilateralsContainer");
429+
430+
svg.setAttribute("width", 0);
431+
svg.setAttribute("height", 0);
432+
const defs = svgFactory.createElement("defs");
433+
svg.append(defs);
434+
const clipPath = svgFactory.createElement("clipPath");
435+
const id = `clippath_${this.data.id}`;
436+
clipPath.setAttribute("id", id);
437+
clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
438+
defs.append(clipPath);
439+
440+
const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect;
441+
const width = rectTrX - rectBlX;
442+
const height = rectTrY - rectBlY;
443+
for (const [, { x: trX, y: trY }, { x: blX, y: blY }] of quadPoints) {
444+
const rect = svgFactory.createElement("rect");
445+
rect.setAttribute("x", (blX - rectBlX) / width);
446+
rect.setAttribute("y", (rectTrY - trY) / height);
447+
rect.setAttribute("width", (trX - blX) / width);
448+
rect.setAttribute("height", (trY - blY) / height);
449+
clipPath.append(rect);
437450
}
438-
this.data.rect = savedRect;
439-
return quadrilaterals;
451+
452+
this.container.append(svg);
453+
this.container.style.clipPath = `url(#${id})`;
440454
}
441455

442456
/**
@@ -450,18 +464,8 @@ class AnnotationElement {
450464
* @memberof AnnotationElement
451465
*/
452466
_createPopup(trigger, data) {
453-
let container = this.container;
454-
if (this.quadrilaterals) {
455-
trigger ||= this.quadrilaterals;
456-
container = this.quadrilaterals[0];
457-
}
458-
459-
// If no trigger element is specified, create it.
460-
if (!trigger) {
461-
trigger = document.createElement("div");
462-
trigger.classList.add("popupTriggerArea");
463-
container.append(trigger);
464-
}
467+
const container = this.container;
468+
trigger ||= this.container;
465469

466470
const popupElement = new PopupElement({
467471
container,
@@ -481,25 +485,6 @@ class AnnotationElement {
481485
container.append(popup);
482486
}
483487

484-
/**
485-
* Render the quadrilaterals of the annotation.
486-
*
487-
* @private
488-
* @param {string} className
489-
* @memberof AnnotationElement
490-
* @returns {Array<HTMLElement>} An array of section elements.
491-
*/
492-
_renderQuadrilaterals(className) {
493-
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
494-
assert(this.quadrilaterals, "Missing quadrilaterals during rendering");
495-
}
496-
497-
for (const quadrilateral of this.quadrilaterals) {
498-
quadrilateral.classList.add(className);
499-
}
500-
return this.quadrilaterals;
501-
}
502-
503488
/**
504489
* Render the annotation's HTML element(s).
505490
*
@@ -626,16 +611,6 @@ class LinkAnnotationElement extends AnnotationElement {
626611
}
627612
}
628613

629-
if (this.quadrilaterals) {
630-
return this._renderQuadrilaterals("linkAnnotation").map(
631-
(quadrilateral, index) => {
632-
const linkElement = index === 0 ? link : link.cloneNode();
633-
quadrilateral.append(linkElement);
634-
return quadrilateral;
635-
}
636-
);
637-
}
638-
639614
this.container.classList.add("linkAnnotation");
640615
if (isBound) {
641616
this.container.append(link);
@@ -2411,10 +2386,6 @@ class HighlightAnnotationElement extends AnnotationElement {
24112386
this._createPopup(null, this.data);
24122387
}
24132388

2414-
if (this.quadrilaterals) {
2415-
return this._renderQuadrilaterals("highlightAnnotation");
2416-
}
2417-
24182389
this.container.classList.add("highlightAnnotation");
24192390
return this.container;
24202391
}
@@ -2440,10 +2411,6 @@ class UnderlineAnnotationElement extends AnnotationElement {
24402411
this._createPopup(null, this.data);
24412412
}
24422413

2443-
if (this.quadrilaterals) {
2444-
return this._renderQuadrilaterals("underlineAnnotation");
2445-
}
2446-
24472414
this.container.classList.add("underlineAnnotation");
24482415
return this.container;
24492416
}
@@ -2469,10 +2436,6 @@ class SquigglyAnnotationElement extends AnnotationElement {
24692436
this._createPopup(null, this.data);
24702437
}
24712438

2472-
if (this.quadrilaterals) {
2473-
return this._renderQuadrilaterals("squigglyAnnotation");
2474-
}
2475-
24762439
this.container.classList.add("squigglyAnnotation");
24772440
return this.container;
24782441
}
@@ -2498,10 +2461,6 @@ class StrikeOutAnnotationElement extends AnnotationElement {
24982461
this._createPopup(null, this.data);
24992462
}
25002463

2501-
if (this.quadrilaterals) {
2502-
return this._renderQuadrilaterals("strikeoutAnnotation");
2503-
}
2504-
25052464
this.container.classList.add("strikeoutAnnotation");
25062465
return this.container;
25072466
}

web/annotation_layer_builder.css

+11-4
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,9 @@
239239
appearance: none;
240240
}
241241

242-
.annotationLayer .popupTriggerArea {
242+
.annotationLayer .fileAttachmentAnnotation .popupTriggerArea {
243243
height: 100%;
244244
width: 100%;
245-
}
246-
247-
.annotationLayer .fileAttachmentAnnotation .popupTriggerArea {
248245
position: absolute;
249246
}
250247

@@ -335,3 +332,13 @@
335332
width: 100%;
336333
display: inline-block;
337334
}
335+
336+
.annotationLayer svg.quadrilateralsContainer {
337+
contain: strict;
338+
width: 0;
339+
height: 0;
340+
position: absolute;
341+
top: 0;
342+
left: 0;
343+
z-index: -1;
344+
}

0 commit comments

Comments
 (0)