Take all the viewBox into account when computing the coordinates of an annotation in the page (fixes #15789)
This commit is contained in:
parent
fe3df4dcb4
commit
4f0bfabe7a
@ -68,8 +68,17 @@ class AnnotationEditor {
|
||||
this.div = null;
|
||||
this._uiManager = parameters.uiManager;
|
||||
|
||||
this.rotation = this.parent.viewport.rotation;
|
||||
this.pageDimensions = this.parent.pageDimensions;
|
||||
const {
|
||||
rotation,
|
||||
viewBox: [pageLLx, pageLLy, pageURx, pageURy],
|
||||
} = this.parent.viewport;
|
||||
this.rotation = rotation;
|
||||
const pageWidth = pageURx - pageLLx;
|
||||
const pageHeight = pageURy - pageLLy;
|
||||
|
||||
this.pageDimensions = [pageWidth, pageHeight];
|
||||
this.pageTranslation = [pageLLx, pageLLy];
|
||||
|
||||
const [width, height] = this.parentDimensions;
|
||||
this.x = parameters.x / width;
|
||||
this.y = parameters.y / height;
|
||||
@ -341,6 +350,7 @@ class AnnotationEditor {
|
||||
getRect(tx, ty) {
|
||||
const scale = this.parentScale;
|
||||
const [pageWidth, pageHeight] = this.pageDimensions;
|
||||
const [pageX, pageY] = this.pageTranslation;
|
||||
const shiftX = tx / scale;
|
||||
const shiftY = ty / scale;
|
||||
const x = this.x * pageWidth;
|
||||
@ -351,31 +361,31 @@ class AnnotationEditor {
|
||||
switch (this.rotation) {
|
||||
case 0:
|
||||
return [
|
||||
x + shiftX,
|
||||
pageHeight - y - shiftY - height,
|
||||
x + shiftX + width,
|
||||
pageHeight - y - shiftY,
|
||||
x + shiftX + pageX,
|
||||
pageHeight - y - shiftY - height + pageY,
|
||||
x + shiftX + width + pageX,
|
||||
pageHeight - y - shiftY + pageY,
|
||||
];
|
||||
case 90:
|
||||
return [
|
||||
x + shiftY,
|
||||
pageHeight - y + shiftX,
|
||||
x + shiftY + height,
|
||||
pageHeight - y + shiftX + width,
|
||||
x + shiftY + pageX,
|
||||
pageHeight - y + shiftX + pageY,
|
||||
x + shiftY + height + pageX,
|
||||
pageHeight - y + shiftX + width + pageY,
|
||||
];
|
||||
case 180:
|
||||
return [
|
||||
x - shiftX - width,
|
||||
pageHeight - y + shiftY,
|
||||
x - shiftX,
|
||||
pageHeight - y + shiftY + height,
|
||||
x - shiftX - width + pageX,
|
||||
pageHeight - y + shiftY + pageY,
|
||||
x - shiftX + pageX,
|
||||
pageHeight - y + shiftY + height + pageY,
|
||||
];
|
||||
case 270:
|
||||
return [
|
||||
x - shiftY - height,
|
||||
pageHeight - y - shiftX - width,
|
||||
x - shiftY,
|
||||
pageHeight - y - shiftX,
|
||||
x - shiftY - height + pageX,
|
||||
pageHeight - y - shiftX - width + pageY,
|
||||
x - shiftY + pageX,
|
||||
pageHeight - y - shiftX + pageY,
|
||||
];
|
||||
default:
|
||||
throw new Error("Invalid rotation");
|
||||
|
@ -547,24 +547,9 @@ describe("Editor", () => {
|
||||
await page.mouse.click(rect.x + 100, rect.y + 100);
|
||||
await page.type(`${getEditorSelector(currentId)} .internal`, data);
|
||||
|
||||
const editorRect = await page.$eval(
|
||||
getEditorSelector(currentId),
|
||||
el => {
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Commit.
|
||||
await page.mouse.click(
|
||||
editorRect.x,
|
||||
editorRect.y + 2 * editorRect.height
|
||||
);
|
||||
await page.keyboard.press("Escape");
|
||||
await page.waitForTimeout(10);
|
||||
|
||||
await waitForSelectedEditor(page, getEditorSelector(currentId));
|
||||
await waitForStorageEntries(page, currentId + 1);
|
||||
@ -646,4 +631,88 @@ describe("Editor", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("issue 15789", () => {
|
||||
let pages;
|
||||
|
||||
beforeAll(async () => {
|
||||
pages = await loadAndWait("issue15789.pdf", ".annotationEditorLayer");
|
||||
pages = await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await page.select("#scaleSelect", "1");
|
||||
return [browserName, page];
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
it("must take the media box into account", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
await page.click("#editorFreeText");
|
||||
let currentId = 0;
|
||||
|
||||
for (let step = 0; step < 3; step++) {
|
||||
const rect = await page.$eval(".annotationEditorLayer", el => {
|
||||
// With Chrome something is wrong when serializing a DomRect,
|
||||
// hence we extract the values and just return them.
|
||||
const { x, y, width, height } = el.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
});
|
||||
|
||||
const data = `Hello ${step}`;
|
||||
const x = rect.x + 0.1 * rect.width;
|
||||
const y = rect.y + 0.1 * rect.height;
|
||||
await page.mouse.click(x, y);
|
||||
await page.type(`${getEditorSelector(currentId)} .internal`, data);
|
||||
|
||||
// Commit.
|
||||
await page.keyboard.press("Escape");
|
||||
await page.waitForTimeout(10);
|
||||
|
||||
await page.evaluate(() => {
|
||||
document.getElementById("pageRotateCw").click();
|
||||
});
|
||||
currentId += 1;
|
||||
await page.waitForTimeout(10);
|
||||
}
|
||||
|
||||
const serialize = proprName =>
|
||||
page.evaluate(
|
||||
name =>
|
||||
[
|
||||
...window.PDFViewerApplication.pdfDocument.annotationStorage.serializable.values(),
|
||||
].map(x => x[name]),
|
||||
proprName
|
||||
);
|
||||
|
||||
const rects = (await serialize("rect")).map(rect =>
|
||||
rect.slice(0, 2).map(x => Math.floor(x))
|
||||
);
|
||||
const expected = [
|
||||
[-28, 695],
|
||||
[-38, -10],
|
||||
[501, -20],
|
||||
];
|
||||
// Dimensions aren't exactly the same from a platform to an other
|
||||
// so we're a bit tolerant here with the numbers.
|
||||
// Anyway the goal is to check that the bottom left corner of the
|
||||
// media box is taken into account.
|
||||
// The pdf has a media box equals to [-99 -99 612.0 792.0].
|
||||
const diffs = rects.map(
|
||||
(rect, i) =>
|
||||
Math.abs(rect[0] - expected[i][0]) < 10 &&
|
||||
Math.abs(rect[1] - expected[i][1]) < 10
|
||||
);
|
||||
|
||||
expect(diffs)
|
||||
.withContext(`In ${browserName}`)
|
||||
.toEqual([true, true, true]);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -559,3 +559,4 @@
|
||||
!bug1802888.pdf
|
||||
!issue15759.pdf
|
||||
!issue15753.pdf
|
||||
!issue15789.pdf
|
||||
|
BIN
test/pdfs/issue15789.pdf
Executable file
BIN
test/pdfs/issue15789.pdf
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user