aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/views/SkTextBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/views/SkTextBox.cpp')
-rw-r--r--src/views/SkTextBox.cpp86
1 files changed, 82 insertions, 4 deletions
diff --git a/src/views/SkTextBox.cpp b/src/views/SkTextBox.cpp
index 355944aef1..78828b6d85 100644
--- a/src/views/SkTextBox.cpp
+++ b/src/views/SkTextBox.cpp
@@ -13,9 +13,86 @@ static inline int is_ws(int c)
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 @@ void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPa
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;