LayoutTests:

        Reviewed by Hyatt.

        - test for http://bugs.webkit.org/show_bug.cgi?id=13438 <rdar://problem/5153030>
                   Run rounding makes word-break:break-all/word not functional

        * fast/text/word-break-run-rounding-expected.checksum: Added.
        * fast/text/word-break-run-rounding-expected.png: Added.
        * fast/text/word-break-run-rounding-expected.txt: Added.
        * fast/text/word-break-run-rounding.html: Added.

WebCore:

        Reviewed by Hyatt.

        - fix http://bugs.webkit.org/show_bug.cgi?id=13438 <rdar://problem/5153030>
              Run rounding makes word-break:break-all/word not functional

        Test: fast/text/word-break-run-rounding.html

        * rendering/RenderText.cpp:
        (WebCore::RenderText::calcPrefWidths): Update the maximum width only on word
        boundaries to avoid rounding errors.
        * rendering/bidi.cpp:
        (WebCore::RenderBlock::findNextLineBreak): Integrated breakAll with the
        midWordBreak/wrapW mechanism. Also made the wrapW upper bound more accurate
        by resetting it when tmpW is committed.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@24278 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index 782c585..1d28b2a 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -2275,6 +2275,7 @@
             bool appliedStartWidth = pos > 0; // If the span originated on a previous line,
                                               // then assume the start width has been applied.
             int wrapW = tmpW + inlineWidth(o, !appliedStartWidth, true);
+            int charWidth = 0;
             int nextBreakable = -1;
             bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
             // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
@@ -2330,14 +2331,15 @@
                 
                 currentCharacterIsWS = currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
 
-                if (breakAll || (breakWords && !midWordBreak)) {
-                    wrapW += t->width(pos, 1, f, w + wrapW);
-                    midWordBreak = w + wrapW > width;
+                if ((breakAll || breakWords) && !midWordBreak) {
+                    wrapW += charWidth;
+                    charWidth = t->width(pos, 1, f, w + wrapW);
+                    midWordBreak = w + wrapW + charWidth > width;
                 }
 
                 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(str, pos, strlen, nextBreakable, breakNBSP));
     
-                if (betweenWords || midWordBreak || breakAll) {
+                if (betweenWords || midWordBreak) {
                     bool stoppedIgnoringSpaces = false;
                     if (ignoringSpaces) {
                         if (!currentCharacterIsSpace) {
@@ -2422,7 +2424,7 @@
                             }
                             goto end; // Didn't fit. Jump to the end.
                         } else {
-                            if (midWordBreak)
+                            if (!betweenWords || (midWordBreak && !autoWrap))
                                 tmpW -= additionalTmpW;
                             if (pos > 0 && str[pos-1] == softHyphen)
                                 // Subtract the width of the soft hyphen out since we fit on a line.
@@ -2446,6 +2448,7 @@
 
                     if (autoWrap && betweenWords) {
                         w += tmpW;
+                        wrapW = 0;
                         tmpW = 0;
                         lBreak.obj = o;
                         lBreak.pos = pos;
@@ -2459,8 +2462,10 @@
                         // adding the end width forces a break.
                         lBreak.obj = o;
                         lBreak.pos = pos;
-                        midWordBreak &= breakWords;
-                    } else {
+                        midWordBreak &= (breakWords || breakAll);
+                    }
+
+                    if (betweenWords) {
                         lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
                         lastSpace = pos;
                     }