From 012e15f7a36133994cf4c078f2888701f998ce5d Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sat, 5 Dec 2020 21:27:38 +0100 Subject: [PATCH] Fix non-standard quadpoints orders for annotations This change requires us to use valid quadpoints arrays in the existing unit tests too due to the normalization. --- src/core/annotation.js | 31 ++++++++- test/pdfs/.gitignore | 1 + test/pdfs/quadpoints.pdf | Bin 0 -> 33054 bytes test/test_manifest.json | 7 ++ test/unit/annotation_spec.js | 122 +++++++++++++++++++++-------------- 5 files changed, 112 insertions(+), 49 deletions(-) create mode 100644 test/pdfs/quadpoints.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index 2e4cbbb62..d26ddeafb 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -227,7 +227,36 @@ function getQuadPoints(dict, rect) { quadPointsLists[i].push({ x, y }); } } - return quadPointsLists; + + // The PDF specification states in section 12.5.6.10 (figure 64) that the + // order of the quadpoints should be bottom left, bottom right, top right + // and top left. However, in practice PDF files use a different order, + // namely bottom left, bottom right, top left and top right (this is also + // mentioned on https://github.com/highkite/pdfAnnotate#QuadPoints), so + // this is the actual order we should work with. However, the situation is + // even worse since Adobe's own applications and other applications violate + // the specification and create annotations with other orders, namely top + // left, top right, bottom left and bottom right or even top left, top right, + // bottom right and bottom left. To avoid inconsistency and broken rendering, + // we normalize all lists to put the quadpoints in the same standard order + // (see https://stackoverflow.com/a/10729881). + return quadPointsLists.map(quadPointsList => { + const [minX, maxX, minY, maxY] = quadPointsList.reduce( + ([mX, MX, mY, MY], quadPoint) => [ + Math.min(mX, quadPoint.x), + Math.max(MX, quadPoint.x), + Math.min(mY, quadPoint.y), + Math.max(MY, quadPoint.y), + ], + [Number.MAX_VALUE, Number.MIN_VALUE, Number.MAX_VALUE, Number.MIN_VALUE] + ); + return [ + { x: minX, y: maxY }, + { x: maxX, y: maxY }, + { x: minX, y: minY }, + { x: maxX, y: minY }, + ]; + }); } function getTransformMatrix(rect, bbox, matrix) { diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 82936b8a7..6b7ae9e9a 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -392,6 +392,7 @@ !issue11442_reduced.pdf !issue11549_reduced.pdf !issue8097_reduced.pdf +!quadpoints.pdf !transparent.pdf !xobject-image.pdf !ccitt_EndOfBlock_false.pdf diff --git a/test/pdfs/quadpoints.pdf b/test/pdfs/quadpoints.pdf new file mode 100644 index 0000000000000000000000000000000000000000..72ac73dae02fe2d1227209e4e4751d8b0b2050e7 GIT binary patch literal 33054 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