Skip to content

Commit

Permalink
#429 Tests and fixes break-word with centered or justified text.
Browse files Browse the repository at this point in the history
I had taken care of breaking itself, but measurement (required for non-left aligned text) was previously forgotten. Now fixed.
  • Loading branch information
danfickle committed Feb 1, 2020
1 parent 6241417 commit 913c196
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,51 +119,74 @@ public static LineBreakResult breakText(LayoutContext c,
return doBreakText(c, context, avail, style, tryToBreakAnywhere);
} else {
int originalStart = context.getStart();
int totalWidth = 0;

// The idea is we only break a word if it will not fit on a line by itself.

LineBreakResult result;
LOOP:
while (true) {
int savedEnd = context.getEnd();
result = doBreakText(c, context, avail, style, tryToBreakAnywhere);

switch (result) {
case WORD_BREAKING_FINISHED:
case CHAR_BREAKING_FINISHED:
case CHAR_BREAKING_UNBREAKABLE:
case CHAR_BREAKING_NEED_NEW_LINE:
totalWidth += context.getWidth();
break LOOP;


case CHAR_BREAKING_UNBREAKABLE:
if (totalWidth == 0 &&
avail == lineWidth) {
// We are at the start of the line but could not fit a single character!
totalWidth += context.getWidth();
break LOOP;
} else {
// We may be at the end of the line, so pick up at next line.
context.setEnd(savedEnd);
break LOOP;
}

case CHAR_BREAKING_FOUND_WORD_BREAK:
// We found a word break so resume normal word wrapping.
tryToBreakAnywhere = false;
break;

case WORD_BREAKING_NEED_NEW_LINE: {
if (context.getNextWidth() >= lineWidth) {
// If the next word is too great to fit on a line by itself, start wrapping
// here in character breaking mode.
tryToBreakAnywhere = true;
break;
} else {
// Else, finish so it can be put on a new line.
totalWidth += context.getWidth();
break LOOP;
}
}
case WORD_BREAKING_UNBREAKABLE: {
if (context.getWidth() >= lineWidth) {
// If the word is too long to fit on a line by itself, retry it in
// character breaking mode.
tryToBreakAnywhere = true;
context.resetEnd();
context.setEnd(savedEnd);
continue LOOP;
} else {
// Else, retry it on a new line.
context.setEnd(savedEnd);
break LOOP;
}
}

default:
break LOOP;
}

context.setStart(context.getEnd());
avail -= context.getWidth();
totalWidth += context.getWidth();
}

context.setStart(originalStart);
context.setWidth(totalWidth);

// We need to know this for the next line.
context.setFinishedInCharBreakingMode(tryToBreakAnywhere);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ private static void startNewInlineLine(LayoutContext c, BlockBox box, int breakA
MarkerData markerData, List<FloatLayoutResult> pendingFloats, boolean hasFirstLinePEs,
List<Layer> pendingInlineLayers, int lineOffset, InlineBox inlineBox, LineBreakContext lbContext) {

if (inlineBox.getStyle().isTextJustify()) {
IdentValue align = inlineBox.getStyle().getIdent(CSSName.TEXT_ALIGN);
if (align == IdentValue.JUSTIFY ||
(align != IdentValue.LEFT && inlineBox.getStyle().getWordWrap() == IdentValue.BREAK_WORD)) {
current.line.trimTrailingSpace(c);
}

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<html>
<head>
<style>
@page {
margin: 10mm;
size: 100mm 25cm;
}
body, td {
margin:5mm;
width: 68mm;
text-align: center;
border: 1px solid black;
}
table, .wrap {
word-wrap: break-word;
}
</style>
</head>
<body style="font-family: serif;">

<div class="wrap">
FirstWordTooLongForLineSoItShouldWrap MiddleWordTooLongForLineSoItShouldWrap LastWordTooLongForLineSoItShouldWrap
</div><br/>

<div class="wrap">
First Word Too Long For Line So It Should MiddleWordTooLongForLineSoItShouldWrap LastWordTooLongForLineSoItShouldWrap
</div><br/>

<div class="wrap">
First Word Too Long For Line So It Should MiddleWordTooLongForLineSoItShouldWrap Last Word Too Long For Line So It Should
</div><br/>

<div class="wrap">
FirstWordNotTooLongForLineSoIt FirstWordNotTooLongForLineSoIt FirstWordNotTooLongForLineSoIt FirstWordNotTooLongForLineSoIt
</div><br/>

<div class="wrap">
FirstWordNotTooLongForLine <b>FirstWordNotTooLongForLine</b> <b><i>FirstWordNotTooLongForLineSoIt FirstWordNotTooLongForLineSoIt</i></b>
</div><br/>

<div class="wrap">
One two three FirstWordNotTooLongForLineSoIt four five FirstWordNotTooLongForLineSoIt six seven FirstWordNotTooLongForLineSoIt eight FirstWordNotTooLongForLineSoIt
</div><br/>

<table>
<tr><td>OneTwoThreeFour</td><td>Five six seven</td><td>Eight nine</td></tr>
<tr><td>One Two Three Four</td><td>Fivesixseven</td><td>Eight nine</td></tr>
<tr><td>One Two Three Four</td><td>Five six seven</td><td>Eightnine</td></tr>
<tr><td>OneTwoThreeFour</td><td>Fivesixseven</td><td>Eightnine</td></tr>
</table>

</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,14 @@ public void testIssue429BreakWordNested() throws IOException {
public void testIssue429BreakWordExtra() throws IOException {
assertTrue(vt.runTest("issue-429-break-word-extra"));
}

/**
* Similar to break word extra but with with text-align: center enabled.
*/
@Test
public void testIssue429BreakWordExtraCentered() throws IOException {
assertTrue(vt.runTest("issue-429-break-word-extra-centered"));
}

/**
* Tests break-word in the presence of floats.
Expand Down

0 comments on commit 913c196

Please sign in to comment.