Remove SkTextBox

Change-Id: I697135475fa9c1b7e803500b743f10c3877c1e10
Reviewed-on: https://skia-review.googlesource.com/129560
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index d59cea6..f0faae3 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1579,6 +1579,7 @@
         "src/utils/SkLuaCanvas.cpp",
       ]
       deps = [
+        ":skshaper",
         "//third_party/lua",
       ]
     }
diff --git a/gn/utils.gni b/gn/utils.gni
index 920924b..01d3136 100644
--- a/gn/utils.gni
+++ b/gn/utils.gni
@@ -21,7 +21,6 @@
   "$_include/utils/SkParsePath.h",
   "$_include/utils/SkRandom.h",
   "$_include/utils/SkShadowUtils.h",
-  "$_include/utils/SkTextBox.h",
 
   "$_src/utils/SkBase64.cpp",
   "$_src/utils/SkBase64.h",
@@ -58,7 +57,6 @@
   "$_src/utils/SkShadowTessellator.cpp",
   "$_src/utils/SkShadowTessellator.h",
   "$_src/utils/SkShadowUtils.cpp",
-  "$_src/utils/SkTextBox.cpp",
   "$_src/utils/SkThreadUtils_pthread.cpp",
   "$_src/utils/SkThreadUtils_win.cpp",
   "$_src/utils/SkWhitelistTypefaces.cpp",
diff --git a/include/utils/SkTextBox.h b/include/utils/SkTextBox.h
deleted file mode 100644
index 885800c..0000000
--- a/include/utils/SkTextBox.h
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkTextBox_DEFINED
-#define SkTextBox_DEFINED
-
-#include "SkCanvas.h"
-
-/** \class SkTextBox
-
-    SkTextBox is a helper class for drawing 1 or more lines of text
-    within a rectangle. The textbox is positioned and clipped by its Frame.
-    The Margin rectangle controls where the text is drawn relative to
-    the Frame. Line-breaks occur inside the Margin rectangle.
-
-    Spacing is a linear equation used to compute the distance between lines
-    of text. Spacing consists of two scalars: mul and add, and the spacing
-    between lines is computed as: spacing = paint.getTextSize() * mul + add
-*/
-class SkTextBox {
-public:
-    SkTextBox();
-
-    enum Mode {
-        kOneLine_Mode,
-        kLineBreak_Mode,
-
-        kModeCount
-    };
-    Mode    getMode() const { return (Mode)fMode; }
-    void    setMode(Mode);
-
-    enum SpacingAlign {
-        kStart_SpacingAlign,
-        kCenter_SpacingAlign,
-        kEnd_SpacingAlign,
-
-        kSpacingAlignCount
-    };
-    SpacingAlign    getSpacingAlign() const { return (SpacingAlign)fSpacingAlign; }
-    void            setSpacingAlign(SpacingAlign);
-
-    void    getBox(SkRect*) const;
-    void    setBox(const SkRect&);
-    void    setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
-
-    void    getSpacing(SkScalar* mul, SkScalar* add) const;
-    void    setSpacing(SkScalar mul, SkScalar add);
-
-    void    draw(SkCanvas*, const char text[], size_t len, const SkPaint&);
-
-    void    setText(const char text[], size_t len, const SkPaint&);
-    void    draw(SkCanvas*);
-    int     countLines() const;
-    SkScalar getTextHeight() const;
-
-    sk_sp<SkTextBlob> snapshotTextBlob(SkScalar* computedBottom) const;
-
-    class Visitor {
-    public:
-        virtual ~Visitor() {}
-        virtual void operator()(const char*, size_t, SkScalar x, SkScalar y, const SkPaint&) = 0;
-    };
-
-private:
-    SkRect      fBox;
-    SkScalar    fSpacingMul, fSpacingAdd;
-    uint8_t     fMode, fSpacingAlign;
-    const char* fText;
-    size_t      fLen;
-    const SkPaint* fPaint;
-
-    SkScalar visit(Visitor&, const char text[], size_t len, const SkPaint&) const;
-};
-
-class SkTextLineBreaker {
-public:
-    static int CountLines(const char text[], size_t len, const SkPaint&, SkScalar width);
-};
-
-#endif
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index c90c13a..36bd0b2 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -26,6 +26,7 @@
 #include "SkPictureRecorder.h"
 #include "SkPixelRef.h"
 #include "SkRRect.h"
+#include "SkShaper.h"
 #include "SkString.h"
 #include "SkSurface.h"
 #include "SkTextBlob.h"
@@ -1960,7 +1961,6 @@
     return 1;
 }
 
-#include "SkTextBox.h"
 // Sk.newTextBlob(text, rect, paint)
 static int lsk_newTextBlob(lua_State* L) {
     const char* text = lua_tolstring(L, 1, nullptr);
@@ -1968,14 +1968,14 @@
     lua2rect(L, 2, &bounds);
     const SkPaint& paint = *get_obj<SkPaint>(L, 3);
 
-    SkTextBox box;
-    box.setMode(SkTextBox::kLineBreak_Mode);
-    box.setBox(bounds);
-    box.setText(text, strlen(text), paint);
+    SkShaper shaper(nullptr);
 
-    SkScalar newBottom;
-    push_ref<SkTextBlob>(L, box.snapshotTextBlob(&newBottom));
-    SkLua(L).pushScalar(newBottom);
+    SkTextBlobBuilder builder;
+    SkPoint end = shaper.shape(&builder, paint, text, strlen(text), true,
+                               { bounds.left(), bounds.top() }, bounds.width());
+
+    push_ref<SkTextBlob>(L, builder.make());
+    SkLua(L).pushScalar(end.fY);
     return 2;
 }
 
diff --git a/src/utils/SkTextBox.cpp b/src/utils/SkTextBox.cpp
deleted file mode 100644
index 9b26a9f..0000000
--- a/src/utils/SkTextBox.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkTextBox.h"
-#include "SkUtils.h"
-
-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,
-                        size_t* trailing = nullptr)
-{
-    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)
-{
-    const char* stop = text + len;
-    int         count = 0;
-
-    if (width > 0)
-    {
-        do {
-            count += 1;
-            text += linebreak(text, stop, paint, width);
-        } while (text < stop);
-    }
-    return count;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-SkTextBox::SkTextBox()
-{
-    fBox.setEmpty();
-    fSpacingMul = SK_Scalar1;
-    fSpacingAdd = 0;
-    fMode = kLineBreak_Mode;
-    fSpacingAlign = kStart_SpacingAlign;
-}
-
-void SkTextBox::setMode(Mode mode)
-{
-    SkASSERT((unsigned)mode < kModeCount);
-    fMode = SkToU8(mode);
-}
-
-void SkTextBox::setSpacingAlign(SpacingAlign align)
-{
-    SkASSERT((unsigned)align < kSpacingAlignCount);
-    fSpacingAlign = SkToU8(align);
-}
-
-void SkTextBox::getBox(SkRect* box) const
-{
-    if (box)
-        *box = fBox;
-}
-
-void SkTextBox::setBox(const SkRect& box)
-{
-    fBox = box;
-}
-
-void SkTextBox::setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
-{
-    fBox.set(left, top, right, bottom);
-}
-
-void SkTextBox::getSpacing(SkScalar* mul, SkScalar* add) const
-{
-    if (mul)
-        *mul = fSpacingMul;
-    if (add)
-        *add = fSpacingAdd;
-}
-
-void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
-{
-    fSpacingMul = mul;
-    fSpacingAdd = add;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-SkScalar SkTextBox::visit(Visitor& visitor, const char text[], size_t len,
-                          const SkPaint& paint) const {
-    SkScalar marginWidth = fBox.width();
-
-    if (marginWidth <= 0 || len == 0) {
-        return fBox.top();
-    }
-
-    const char* textStop = text + len;
-
-    SkScalar                x, y, scaledSpacing, height, fontHeight;
-    SkPaint::FontMetrics    metrics;
-
-    switch (paint.getTextAlign()) {
-    case SkPaint::kLeft_Align:
-        x = 0;
-        break;
-    case SkPaint::kCenter_Align:
-        x = SkScalarHalf(marginWidth);
-        break;
-    default:
-        x = marginWidth;
-        break;
-    }
-    x += fBox.fLeft;
-
-    fontHeight = paint.getFontMetrics(&metrics);
-    scaledSpacing = fontHeight * fSpacingMul + fSpacingAdd;
-    height = fBox.height();
-
-    //  compute Y position for first line
-    {
-        SkScalar textHeight = fontHeight;
-
-        if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign) {
-            int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
-            SkASSERT(count > 0);
-            textHeight += scaledSpacing * (count - 1);
-        }
-
-        switch (fSpacingAlign) {
-        case kStart_SpacingAlign:
-            y = 0;
-            break;
-        case kCenter_SpacingAlign:
-            y = SkScalarHalf(height - textHeight);
-            break;
-        default:
-            SkASSERT(fSpacingAlign == kEnd_SpacingAlign);
-            y = height - textHeight;
-            break;
-        }
-        y += fBox.fTop - metrics.fAscent;
-    }
-
-    for (;;) {
-        size_t trailing;
-        len = linebreak(text, textStop, paint, marginWidth, &trailing);
-        if (y + metrics.fDescent + metrics.fLeading > 0) {
-            visitor(text, len - trailing, x, y, paint);
-        }
-        text += len;
-        if (text >= textStop) {
-            break;
-        }
-        y += scaledSpacing;
-        if (y + metrics.fAscent >= fBox.fBottom) {
-            break;
-        }
-    }
-    return y + metrics.fDescent + metrics.fLeading;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-class CanvasVisitor : public SkTextBox::Visitor {
-    SkCanvas* fCanvas;
-public:
-    CanvasVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
-
-    void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
-                    const SkPaint& paint) override {
-        fCanvas->drawText(text, length, x, y, paint);
-    }
-};
-
-void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
-    fText = text;
-    fLen = len;
-    fPaint = &paint;
-}
-
-void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint) {
-    CanvasVisitor sink(canvas);
-    this->visit(sink, text, len, paint);
-}
-
-void SkTextBox::draw(SkCanvas* canvas) {
-    this->draw(canvas, fText, fLen, *fPaint);
-}
-
-int SkTextBox::countLines() const {
-    return SkTextLineBreaker::CountLines(fText, fLen, *fPaint, fBox.width());
-}
-
-SkScalar SkTextBox::getTextHeight() const {
-    SkScalar spacing = fPaint->getTextSize() * fSpacingMul + fSpacingAdd;
-    return this->countLines() * spacing;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkTextBlob.h"
-
-class TextBlobVisitor : public SkTextBox::Visitor {
-public:
-    SkTextBlobBuilder fBuilder;
-
-    void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
-                    const SkPaint& paint) override {
-        SkPaint p(paint);
-        p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        const int count = paint.countText(text, length);
-        paint.textToGlyphs(text, length, fBuilder.allocRun(p, count, x, y).glyphs);
-    }
-};
-
-sk_sp<SkTextBlob> SkTextBox::snapshotTextBlob(SkScalar* computedBottom) const {
-    TextBlobVisitor visitor;
-    SkScalar newB = this->visit(visitor, fText, fLen, *fPaint);
-    if (computedBottom) {
-        *computedBottom = newB;
-    }
-    return visitor.fBuilder.make();
-}