Restore line breaking in SkTextBox.
https://codereview.appspot.com/6500078/


git-svn-id: http://skia.googlecode.com/svn/trunk@5412 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/views/SkTextBox.cpp b/src/views/SkTextBox.cpp
index 355944a..78828b6 100644
--- a/src/views/SkTextBox.cpp
+++ b/src/views/SkTextBox.cpp
@@ -13,9 +13,86 @@
     return !((c - 1) >> 5);
 }
 
-static size_t linebreak(const char text[], const char stop[], const SkPaint& paint, SkScalar margin)
+static size_t linebreak(const char text[], const char stop[],
+                        const SkPaint& paint, SkScalar margin,
+                        size_t* trailing = NULL)
 {
-    return paint.breakText(text, stop - text, margin);
+    size_t lengthBreak = paint.breakText(text, stop - text, margin);
+
+    //Check for white space or line breakers before the lengthBreak
+    const char* start = text;
+    const char* word_start = text;
+    int prevWS = true;
+    if (trailing) {
+        *trailing = 0;
+    }
+
+    while (text < stop) {
+        const char* prevText = text;
+        SkUnichar uni = SkUTF8_NextUnichar(&text);
+        int currWS = is_ws(uni);
+
+        if (!currWS && prevWS) {
+            word_start = prevText;
+        }
+        prevWS = currWS;
+
+        if (text > start + lengthBreak) {
+            if (currWS) {
+                // eat the rest of the whitespace
+                while (text < stop && is_ws(SkUTF8_ToUnichar(text))) {
+                    text += SkUTF8_CountUTF8Bytes(text);
+                }
+                if (trailing) {
+                    *trailing = text - prevText;
+                }
+            } else {
+                // backup until a whitespace (or 1 char)
+                if (word_start == start) {
+                    if (prevText > start) {
+                        text = prevText;
+                    }
+                } else {
+                    text = word_start;
+                }
+            }
+            break;
+        }
+
+        if ('\n' == uni) {
+            size_t ret = text - start;
+            size_t lineBreakSize = 1;
+            if (text < stop) {
+                uni = SkUTF8_NextUnichar(&text);
+                if ('\r' == uni) {
+                    ret = text - start;
+                    ++lineBreakSize;
+                }
+            }
+            if (trailing) {
+                *trailing = lineBreakSize;
+            }
+            return ret;
+        }
+
+        if ('\r' == uni) {
+            size_t ret = text - start;
+            size_t lineBreakSize = 1;
+            if (text < stop) {
+                uni = SkUTF8_NextUnichar(&text);
+                if ('\n' == uni) {
+                    ret = text - start;
+                    ++lineBreakSize;
+                }
+            }
+            if (trailing) {
+                *trailing = lineBreakSize;
+            }
+            return ret;
+        }
+    }
+
+    return text - start;
 }
 
 int SkTextLineBreaker::CountLines(const char text[], size_t len, const SkPaint& paint, SkScalar width)
@@ -147,9 +224,10 @@
 
     for (;;)
     {
-        len = linebreak(text, textStop, paint, marginWidth);
+        size_t trailing;
+        len = linebreak(text, textStop, paint, marginWidth, &trailing);
         if (y + metrics.fDescent + metrics.fLeading > 0)
-            canvas->drawText(text, len, x, y, paint);
+            canvas->drawText(text, len - trailing, x, y, paint);
         text += len;
         if (text >= textStop)
             break;