From 35863cd54ba12f8c0e7e965f750a8dd1938a676a Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Tue, 2 Jan 2024 18:53:33 +0100 Subject: [PATCH] [Editor] Take into account the crop box when saving/printing some highlighted text (bug 1872721) --- src/display/editor/highlight.js | 30 +++++++++++--------- test/pdfs/.gitignore | 1 + test/pdfs/bug1872721.pdf | Bin 0 -> 10080 bytes test/test_manifest.json | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 13 deletions(-) create mode 100755 test/pdfs/bug1872721.pdf diff --git a/src/display/editor/highlight.js b/src/display/editor/highlight.js index af21bb5be7386..2845afee2d3ff 100644 --- a/src/display/editor/highlight.js +++ b/src/display/editor/highlight.js @@ -361,14 +361,15 @@ class HighlightEditor extends AnnotationEditor { this.parent?.drawLayer.removeClass(this.#outlineId, "selected"); } - #serializeBoxes() { + #serializeBoxes(rect) { const [pageWidth, pageHeight] = this.pageDimensions; const boxes = this.#boxes; const quadPoints = new Array(boxes.length * 8); + const [tx, ty] = rect; let i = 0; for (const { x, y, width, height } of boxes) { - const sx = x * pageWidth; - const sy = (1 - y - height) * pageHeight; + const sx = tx + x * pageWidth; + const sy = ty + (1 - y - height) * pageHeight; // The specifications say that the rectangle should start from the bottom // left corner and go counter-clockwise. // But when opening the file in Adobe Acrobat it appears that this isn't @@ -382,12 +383,11 @@ class HighlightEditor extends AnnotationEditor { return quadPoints; } - #serializeOutlines() { + #serializeOutlines(rect) { const [pageWidth, pageHeight] = this.pageDimensions; const width = this.width * pageWidth; const height = this.height * pageHeight; - const tx = this.x * pageWidth; - const ty = (1 - this.y - this.height) * pageHeight; + const [tx, ty] = rect; const outlines = []; for (const outline of this.#highlightOutlines.outlines) { const points = new Array(outline.length); @@ -404,18 +404,22 @@ class HighlightEditor extends AnnotationEditor { static deserialize(data, parent, uiManager) { const editor = super.deserialize(data, parent, uiManager); - const { rect, color, quadPoints } = data; + const { + rect: [blX, blY, trX, trY], + color, + quadPoints, + } = data; editor.color = Util.makeHexColor(...color); editor.#opacity = data.opacity; const [pageWidth, pageHeight] = editor.pageDimensions; - editor.width = (rect[2] - rect[0]) / pageWidth; - editor.height = (rect[3] - rect[1]) / pageHeight; + editor.width = (trX - blX) / pageWidth; + editor.height = (trY - blY) / pageHeight; const boxes = (editor.#boxes = []); for (let i = 0; i < quadPoints.length; i += 8) { boxes.push({ - x: quadPoints[4] / pageWidth, - y: 1 - quadPoints[i + 5] / pageHeight, + x: (quadPoints[4] - trX) / pageWidth, + y: (trY - (1 - quadPoints[i + 5])) / pageHeight, width: (quadPoints[i + 2] - quadPoints[i]) / pageWidth, height: (quadPoints[i + 5] - quadPoints[i + 1]) / pageHeight, }); @@ -439,8 +443,8 @@ class HighlightEditor extends AnnotationEditor { annotationType: AnnotationEditorType.HIGHLIGHT, color, opacity: this.#opacity, - quadPoints: this.#serializeBoxes(), - outlines: this.#serializeOutlines(), + quadPoints: this.#serializeBoxes(rect), + outlines: this.#serializeOutlines(rect), pageIndex: this.pageIndex, rect, rotation: 0, diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index ce8b9fa1b46be..4d3eefaadbf02 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -620,3 +620,4 @@ !issue17215.pdf !bug1863910.pdf !bug1865341.pdf +!bug1872721.pdf diff --git a/test/pdfs/bug1872721.pdf b/test/pdfs/bug1872721.pdf new file mode 100755 index 0000000000000000000000000000000000000000..bb3ec1023e2d2bfa48887d0a100c514f6ed358e7 GIT binary patch literal 10080 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 literal 0 HcmV?d00001 diff --git a/test/test_manifest.json b/test/test_manifest.json index 5b9480fd7c1bb..aece61a101437 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -8411,5 +8411,52 @@ "rotation": 0 } } + }, + { + "id": "bug1872721-highlight-editor-save-print", + "file": "pdfs/bug1872721.pdf", + "md5": "8318654cda60dc71df9e62a3c78cf193", + "rounds": 1, + "type": "eq", + "save": true, + "print": true, + "annotationStorage": { + "pdfjs_internal_editor_0": { + "annotationType": 9, + "color": [ 83, 255, 188 ], + "opacity": 1, + "quadPoints": [ + 209.0454157057542, + 718.4044878560951, + 270.0049972773625, + 718.4044878560951, + 209.0454157057542, + 731.7427487256604, + 270.0049972773625, + 731.7427487256604 + ], + "outlines": [ + [ + 197.85841250000001, + 709.458959, + 197.85841250000001, + 722.8621772, + 259.003853, + 722.8621772, + 259.003853, + 709.458959 + ] + ], + "pageIndex": 0, + "rect": [ + 197.85841250000001, + 709.458959, + 259.003853, + 722.8621772 + ], + "rotation": 0, + "structTreeParentId": null + } + } } ]