Use positive dimensions for text chunks in the text layer (issue #14415).

This commit is contained in:
Calixte Denizet 2022-01-04 21:36:25 +01:00
parent 2ca432d318
commit 6cdae5ac4d
4 changed files with 38 additions and 16 deletions

View File

@ -2367,8 +2367,8 @@ class PartialEvaluator {
return {
str,
dir: bidiResult.dir,
width: textChunk.totalWidth,
height: textChunk.totalHeight,
width: Math.abs(textChunk.totalWidth),
height: Math.abs(textChunk.totalHeight),
transform: textChunk.transform,
fontName: textChunk.fontName,
hasEOL: textChunk.hasEOL,
@ -2459,7 +2459,11 @@ class PartialEvaluator {
if (textState.font.vertical) {
const advanceY = (lastPosY - posY) / textContentItem.textAdvanceScale;
const advanceX = posX - lastPosX;
if (advanceY < textContentItem.negativeSpaceMax) {
// When the total height of the current chunk is negative
// then we're writing from bottom to top.
const textOrientation = Math.sign(textContentItem.height);
if (advanceY < textOrientation * textContentItem.negativeSpaceMax) {
if (
Math.abs(advanceX) >
0.5 * textContentItem.width /* not the same column */
@ -2476,15 +2480,21 @@ class PartialEvaluator {
appendEOL();
return;
}
if (advanceY <= textContentItem.trackingSpaceMin) {
if (advanceY <= textOrientation * textContentItem.trackingSpaceMin) {
textContentItem.height += advanceY;
} else if (!addFakeSpaces(advanceY, textContentItem.prevTransform)) {
} else if (
!addFakeSpaces(
advanceY,
textContentItem.prevTransform,
textOrientation
)
) {
if (textContentItem.str.length === 0) {
textContent.items.push({
str: " ",
dir: "ltr",
width: 0,
height: advanceY,
height: Math.abs(advanceY),
transform: textContentItem.prevTransform,
fontName: textContentItem.fontName,
hasEOL: false,
@ -2499,7 +2509,11 @@ class PartialEvaluator {
const advanceX = (posX - lastPosX) / textContentItem.textAdvanceScale;
const advanceY = posY - lastPosY;
if (advanceX < textContentItem.negativeSpaceMax) {
// When the total width of the current chunk is negative
// then we're writing from right to left.
const textOrientation = Math.sign(textContentItem.width);
if (advanceX < textOrientation * textContentItem.negativeSpaceMax) {
if (
Math.abs(advanceY) >
0.5 * textContentItem.height /* not the same line */
@ -2516,14 +2530,16 @@ class PartialEvaluator {
return;
}
if (advanceX <= textContentItem.trackingSpaceMin) {
if (advanceX <= textOrientation * textContentItem.trackingSpaceMin) {
textContentItem.width += advanceX;
} else if (!addFakeSpaces(advanceX, textContentItem.prevTransform)) {
} else if (
!addFakeSpaces(advanceX, textContentItem.prevTransform, textOrientation)
) {
if (textContentItem.str.length === 0) {
textContent.items.push({
str: " ",
dir: "ltr",
width: advanceX,
width: Math.abs(advanceX),
height: 0,
transform: textContentItem.prevTransform,
fontName: textContentItem.fontName,
@ -2652,10 +2668,10 @@ class PartialEvaluator {
}
}
function addFakeSpaces(width, transf) {
function addFakeSpaces(width, transf, textOrientation) {
if (
textContentItem.spaceInFlowMin <= width &&
width <= textContentItem.spaceInFlowMax
textOrientation * textContentItem.spaceInFlowMin <= width &&
width <= textOrientation * textContentItem.spaceInFlowMax
) {
if (textContentItem.initialized) {
textContentItem.str.push(" ");
@ -2677,8 +2693,8 @@ class PartialEvaluator {
// TODO: check if using the orientation from last chunk is
// better or not.
dir: "ltr",
width,
height,
width: Math.abs(width),
height: Math.abs(height),
transform: transf || getCurrentTextTransform(),
fontName,
hasEOL: false,

View File

@ -500,3 +500,4 @@
!poppler-937-0-fuzzed.pdf
!PDFBOX-3148-2-fuzzed.pdf
!poppler-90-0-fuzzed.pdf
!issue14415.pdf

BIN
test/pdfs/issue14415.pdf Normal file

Binary file not shown.

View File

@ -6191,5 +6191,10 @@
"link": true,
"rounds": 1,
"type": "eq"
}
},
{ "id": "issue14415",
"file": "pdfs/issue14415.pdf",
"md5": "fa306a250a3d37fe0e7a4b3bba51c91e",
"type": "text"
}
]