Skip to content

Commit

Permalink
Merge pull request #19142 from calixteman/rotated_ink
Browse files Browse the repository at this point in the history
Fix the clickable area for rotated ink annotations
  • Loading branch information
calixteman authored Dec 2, 2024
2 parents d448953 + 1460a81 commit 36b1ba8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 23 deletions.
57 changes: 34 additions & 23 deletions src/display/annotation_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2815,37 +2815,48 @@ class InkAnnotationElement extends AnnotationElement {
// Create an invisible polyline with the same points that acts as the
// trigger for the popup.
const {
data: { rect, inkLists, borderStyle, popupRef },
data: { rect, rotation, inkLists, borderStyle, popupRef },
} = this;
const { width, height } = getRectDims(rect);
let { width, height } = getRectDims(rect);
let transform;

// PDF coordinates are calculated from a bottom left origin, so
// transform the polyline coordinates to a top left origin for the
// SVG element.
switch (rotation) {
case 90:
transform = `rotate(90) translate(${-rect[0]},${rect[3] - height}) scale(1,-1)`;
[width, height] = [height, width];
break;
case 180:
transform = `rotate(180) translate(${-rect[0] - width},${rect[3] - height}) scale(1,-1)`;
break;
case 270:
transform = `rotate(270) translate(${-rect[0] - width},${rect[3]}) scale(1,-1)`;
[width, height] = [height, width];
break;
default:
transform = `translate(${-rect[0]},${rect[3]}) scale(1,-1)`;
break;
}

const svg = this.svgFactory.create(
width,
height,
/* skipDimensions = */ true
);
const basePolyline = this.svgFactory.createElement(this.svgElementName);
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
// won't be possible to open/close the popup (note e.g. issue 11122).
basePolyline.setAttribute("stroke-width", borderStyle.width || 1);
basePolyline.setAttribute("stroke", "transparent");
basePolyline.setAttribute("fill", "transparent");
basePolyline.setAttribute("transform", transform);

for (const inkList of inkLists) {
// Convert the ink list 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 points = [];
for (let i = 0, ii = inkList.length; i < ii; i += 2) {
const x = inkList[i] - rect[0];
const y = rect[3] - inkList[i + 1];
points.push(`${x},${y}`);
}
points = points.join(" ");

const polyline = this.svgFactory.createElement(this.svgElementName);
for (let i = 0, ii = inkLists.length; i < ii; i++) {
const polyline = i < ii - 1 ? basePolyline.cloneNode() : basePolyline;
this.#polylines.push(polyline);
polyline.setAttribute("points", points);
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
// won't be possible to open/close the popup (note e.g. issue 11122).
polyline.setAttribute("stroke-width", borderStyle.width || 1);
polyline.setAttribute("stroke", "transparent");
polyline.setAttribute("fill", "transparent");

polyline.setAttribute("points", inkLists[i].join(","));
svg.append(polyline);
}

Expand Down
35 changes: 35 additions & 0 deletions test/integration/annotation_spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import {
closePages,
getQuerySelector,
getRect,
getSelector,
loadAndWait,
} from "./test_utils.mjs";
Expand Down Expand Up @@ -654,4 +655,38 @@ describe("ResetForm action", () => {
});
});
});

describe("Rotated annotation and its clickable area", () => {
describe("issue14438.pdf", () => {
let pages;

beforeAll(async () => {
pages = await loadAndWait(
"rotated_ink.pdf",
"[data-annotation-id='18R']"
);
});

afterAll(async () => {
await closePages(pages);
});

it("must check that the clickable area has been rotated", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
const rect = await getRect(page, "[data-annotation-id='18R']");
const promisePopup = page.waitForSelector(
"[data-annotation-id='19R']",
{ visible: true }
);
await page.mouse.move(
rect.x + rect.width * 0.1,
rect.y + rect.height * 0.9
);
await promisePopup;
})
);
});
});
});
});
1 change: 1 addition & 0 deletions test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -684,3 +684,4 @@
!issue19083.pdf
!issue19120.pdf
!bug1934157.pdf
!rotated_ink.pdf
Binary file added test/pdfs/rotated_ink.pdf
Binary file not shown.

0 comments on commit 36b1ba8

Please sign in to comment.