Skip to content

Commit

Permalink
#482 #491 #483 Fix infinite loop bug with soft-hypen plus inserted hy…
Browse files Browse the repository at this point in the history
…phen overflowing line.

The core problem seems to be the under-reporting of width when we have a soft hyphen that is found to be unbreakable.
  • Loading branch information
danfickle committed May 26, 2020
1 parent ba8dc5c commit b885384
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,9 @@ public static LineBreakResult breakText(LayoutContext c,
context.setEnd(savedEnd);
continue LOOP;
} else {
if (context.getWidth() == 0) {
String calculatedSubstring = context.getCalculatedSubstring();
if (calculatedSubstring.chars().allMatch(ch -> ch == SOFT_HYPHEN)) {
// Consists only of soft hypen, we have to break here and skip all togheter. We do not
// need to try breaking on the charater level, this will not work.
tryToBreakAnywhere = true;
}
}
// Else, retry it on a new line.
// FIXME: This is very dangerous and has led to infinite
// loops. Needs review.
context.setEnd(savedEnd);
break LOOP;
}
Expand Down Expand Up @@ -501,15 +495,16 @@ public static LineBreakResult doBreakText(
context.setEnd(context.getStart() + current.left);
context.setUnbreakable(true);

if (current.left == currentString.length()) {
if (current.isSoftHyphenBreak) {
context.setWidth(current.withHyphenGraphicsLength);
} else if (current.left == currentString.length()) {
String text = context.getCalculatedSubstring();
float extraSpacing = text.length() * letterSpacing;
context.setWidth((int) (c.getTextRenderer().getWidth(
c.getFontContext(), font, text) + extraSpacing));
} else {
context.setWidth(current.graphicsLength);
}

return LineBreakResult.WORD_BREAKING_UNBREAKABLE;
}
}
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<html>
<head>
<style>
* {
font-family: 'Liberation Sans', sans-serif;
margin: 0;
padding: 0;
}

@page {
size: 30px 40px;
margin: 0;
padding: 0;
}
.content {
font-family: 'Liberation Sans', sans-serif;
word-wrap: break-word;
white-space:pre-wrap;
width: 10px;
}
</style>
</head>
<body>
<table class="content"><tbody><tr><td width="10">­</td></tr></tbody></table>
<div class="content">­</div>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,12 @@ public Reader getReader() {
})));
}

/**
* Tests another endless loop bug when the font reports a non-zero width
* for soft hyphen and this overflows the width of the box in break-word
* mode.
*/
@Test
@Ignore
public void testIssue482InfiniteLoopTable() throws IOException {
assertTrue(vt.runTest("issue-482-infinite-loop-table", builder -> {
builder.useFont(() -> VisualRegressionTest.class.getClassLoader().getResourceAsStream("org/apache/pdfbox/resources/ttf/LiberationSans-Regular.ttf"),
Expand Down

0 comments on commit b885384

Please sign in to comment.