Skip to content

Commit a69adf0

Browse files
Merge pull request #14500 from calixteman/14497
Take into account all rotations before comparing glyph positions
2 parents 5c3b245 + 3a7004c commit a69adf0

File tree

4 files changed

+48
-22
lines changed

4 files changed

+48
-22
lines changed

src/core/evaluator.js

+41-22
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,14 @@ class PartialEvaluator {
23852385
});
23862386
}
23872387

2388+
function applyInverseRotation(x, y, matrix) {
2389+
const scale = Math.hypot(matrix[0], matrix[1]);
2390+
return [
2391+
(matrix[0] * x + matrix[1] * y) / scale,
2392+
(matrix[2] * x + matrix[3] * y) / scale,
2393+
];
2394+
}
2395+
23882396
function compareWithLastPosition() {
23892397
if (
23902398
!combineTextItems ||
@@ -2404,9 +2412,8 @@ class PartialEvaluator {
24042412
return;
24052413
}
24062414

2407-
let rotate = 0;
2415+
let rotate = -1;
24082416
// Take into account the rotation is the current transform.
2409-
// Only rotations with an angle of 0, 90, 180 or 270 are considered.
24102417
if (
24112418
currentTransform[0] &&
24122419
currentTransform[1] === 0 &&
@@ -2418,28 +2425,40 @@ class PartialEvaluator {
24182425
currentTransform[0] === 0 &&
24192426
currentTransform[3] === 0
24202427
) {
2421-
rotate += currentTransform[1] > 0 ? 90 : 270;
2428+
rotate = currentTransform[1] > 0 ? 90 : 270;
24222429
}
24232430

2424-
if (rotate !== 0) {
2425-
switch (rotate) {
2426-
case 90:
2427-
[posX, posY] = [posY, posX];
2428-
[lastPosX, lastPosY] = [lastPosY, lastPosX];
2429-
break;
2430-
case 180:
2431-
[posX, posY, lastPosX, lastPosY] = [
2432-
-posX,
2433-
-posY,
2434-
-lastPosX,
2435-
-lastPosY,
2436-
];
2437-
break;
2438-
case 270:
2439-
[posX, posY] = [-posY, -posX];
2440-
[lastPosX, lastPosY] = [-lastPosY, -lastPosX];
2441-
break;
2442-
}
2431+
switch (rotate) {
2432+
case 0:
2433+
break;
2434+
case 90:
2435+
[posX, posY] = [posY, posX];
2436+
[lastPosX, lastPosY] = [lastPosY, lastPosX];
2437+
break;
2438+
case 180:
2439+
[posX, posY, lastPosX, lastPosY] = [
2440+
-posX,
2441+
-posY,
2442+
-lastPosX,
2443+
-lastPosY,
2444+
];
2445+
break;
2446+
case 270:
2447+
[posX, posY] = [-posY, -posX];
2448+
[lastPosX, lastPosY] = [-lastPosY, -lastPosX];
2449+
break;
2450+
default:
2451+
// This is not a 0, 90, 180, 270 rotation so:
2452+
// - remove the scale factor from the matrix to get a rotation matrix
2453+
// - apply the inverse (which is the transposed) to the positions
2454+
// and we can then compare positions of the glyphes to detect
2455+
// a whitespace.
2456+
[posX, posY] = applyInverseRotation(posX, posY, currentTransform);
2457+
[lastPosX, lastPosY] = applyInverseRotation(
2458+
lastPosX,
2459+
lastPosY,
2460+
textContentItem.prevTransform
2461+
);
24432462
}
24442463

24452464
if (textState.font.vertical) {

test/pdfs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,4 @@
506506
!poppler-90-0-fuzzed.pdf
507507
!issue14415.pdf
508508
!issue14307.pdf
509+
!issue14497.pdf

test/pdfs/issue14497.pdf

32.7 KB
Binary file not shown.

test/test_manifest.json

+6
Original file line numberDiff line numberDiff line change
@@ -6238,5 +6238,11 @@
62386238
"link": true,
62396239
"lastPage": 1,
62406240
"type": "text"
6241+
},
6242+
{ "id": "issue14497",
6243+
"file": "pdfs/issue14497.pdf",
6244+
"md5": "7f795a92caa612117b6928f8bb4c5b65",
6245+
"rounds": 1,
6246+
"type": "text"
62416247
}
62426248
]

0 commit comments

Comments
 (0)