diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 4838a29ea..3caf1929d 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2385,6 +2385,14 @@ class PartialEvaluator { }); } + function applyInverseRotation(x, y, matrix) { + const scale = Math.hypot(matrix[0], matrix[1]); + return [ + (matrix[0] * x + matrix[1] * y) / scale, + (matrix[2] * x + matrix[3] * y) / scale, + ]; + } + function compareWithLastPosition() { if ( !combineTextItems || @@ -2404,9 +2412,8 @@ class PartialEvaluator { return; } - let rotate = 0; + let rotate = -1; // Take into account the rotation is the current transform. - // Only rotations with an angle of 0, 90, 180 or 270 are considered. if ( currentTransform[0] && currentTransform[1] === 0 && @@ -2418,28 +2425,40 @@ class PartialEvaluator { currentTransform[0] === 0 && currentTransform[3] === 0 ) { - rotate += currentTransform[1] > 0 ? 90 : 270; + rotate = currentTransform[1] > 0 ? 90 : 270; } - if (rotate !== 0) { - switch (rotate) { - case 90: - [posX, posY] = [posY, posX]; - [lastPosX, lastPosY] = [lastPosY, lastPosX]; - break; - case 180: - [posX, posY, lastPosX, lastPosY] = [ - -posX, - -posY, - -lastPosX, - -lastPosY, - ]; - break; - case 270: - [posX, posY] = [-posY, -posX]; - [lastPosX, lastPosY] = [-lastPosY, -lastPosX]; - break; - } + switch (rotate) { + case 0: + break; + case 90: + [posX, posY] = [posY, posX]; + [lastPosX, lastPosY] = [lastPosY, lastPosX]; + break; + case 180: + [posX, posY, lastPosX, lastPosY] = [ + -posX, + -posY, + -lastPosX, + -lastPosY, + ]; + break; + case 270: + [posX, posY] = [-posY, -posX]; + [lastPosX, lastPosY] = [-lastPosY, -lastPosX]; + break; + default: + // This is not a 0, 90, 180, 270 rotation so: + // - remove the scale factor from the matrix to get a rotation matrix + // - apply the inverse (which is the transposed) to the positions + // and we can then compare positions of the glyphes to detect + // a whitespace. + [posX, posY] = applyInverseRotation(posX, posY, currentTransform); + [lastPosX, lastPosY] = applyInverseRotation( + lastPosX, + lastPosY, + textContentItem.prevTransform + ); } if (textState.font.vertical) { diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 2627c9fc3..9a245d595 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -506,3 +506,4 @@ !poppler-90-0-fuzzed.pdf !issue14415.pdf !issue14307.pdf +!issue14497.pdf diff --git a/test/pdfs/issue14497.pdf b/test/pdfs/issue14497.pdf new file mode 100755 index 000000000..cbc5e5de1 Binary files /dev/null and b/test/pdfs/issue14497.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 6d397afc4..ad6d7c200 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -6238,5 +6238,11 @@ "link": true, "lastPage": 1, "type": "text" + }, + { "id": "issue14497", + "file": "pdfs/issue14497.pdf", + "md5": "7f795a92caa612117b6928f8bb4c5b65", + "rounds": 1, + "type": "text" } ]