diff --git a/src/core/annotation.js b/src/core/annotation.js index 6086928c5..b9bec56ff 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -367,10 +367,6 @@ function getPdfColorArray(color) { } function getQuadPoints(dict, rect) { - if (!dict.has("QuadPoints")) { - return null; - } - // The region is described as a number of quadrilaterals. // Each quadrilateral must consist of eight coordinates. const quadPoints = dict.getArray("QuadPoints"); @@ -387,54 +383,49 @@ function getQuadPoints(dict, rect) { // Each series of eight numbers represents the coordinates for one // quadrilateral in the order [x1, y1, x2, y2, x3, y3, x4, y4]. // Convert this to an array of objects with x and y coordinates. - quadPointsLists.push([]); + let minX = Infinity, + maxX = -Infinity, + minY = Infinity, + maxY = -Infinity; for (let j = i * 8, jj = i * 8 + 8; j < jj; j += 2) { const x = quadPoints[j]; const y = quadPoints[j + 1]; - // The quadpoints should be ignored if any coordinate in the array - // lies outside the region specified by the rectangle. The rectangle - // can be `null` for markup annotations since their rectangle may be - // incorrect (fixes bug 1538111). - if ( - rect !== null && - (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) - ) { - return null; - } - quadPointsLists[i].push({ x, y }); + minX = Math.min(x, minX); + maxX = Math.max(x, maxX); + minY = Math.min(y, minY); + maxY = Math.max(y, maxY); } - } - - // 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 [ + // The quadpoints should be ignored if any coordinate in the array + // lies outside the region specified by the rectangle. The rectangle + // can be `null` for markup annotations since their rectangle may be + // incorrect (fixes bug 1538111). + if ( + rect !== null && + (minX < rect[0] || maxX > rect[2] || minY < rect[1] || maxY > rect[3]) + ) { + return null; + } + // 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). + quadPointsLists.push([ { x: minX, y: maxY }, { x: maxX, y: maxY }, { x: minX, y: minY }, { x: maxX, y: minY }, - ]; - }); + ]); + } + return quadPointsLists; } function getTransformMatrix(rect, bbox, matrix) {