Reland "SkParagraph"

This is a reland of 10ad0b9b01e4b8a4721ae2ec1adee9ca7d0fe534

Original change's description:
> SkParagraph
>
> Change-Id: I0a4be75fd0c18021c201bcc1edfdfad8556edeff
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/192100
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>

Change-Id: I46cf43eae693edf68e45345acd0eb39e04e02bfc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/219863
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.cpp b/modules/skparagraph/src/ParagraphBuilderImpl.cpp
new file mode 100644
index 0000000..0a97527
--- /dev/null
+++ b/modules/skparagraph/src/ParagraphBuilderImpl.cpp
@@ -0,0 +1,106 @@
+// Copyright 2019 Google LLC.
+#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
+#include "include/core/SkPaint.h"
+#include "modules/skparagraph/include/ParagraphStyle.h"
+#include "modules/skparagraph/src/ParagraphImpl.h"
+#include "src/core/SkMakeUnique.h"
+#include "src/core/SkSpan.h"
+#include "unicode/unistr.h"
+
+namespace skia {
+namespace textlayout {
+
+std::shared_ptr<ParagraphBuilder> ParagraphBuilder::make(
+        ParagraphStyle style, sk_sp<FontCollection> fontCollection) {
+    return std::make_shared<ParagraphBuilderImpl>(style, fontCollection);
+}
+
+ParagraphBuilderImpl::ParagraphBuilderImpl(
+        ParagraphStyle style, sk_sp<FontCollection> fontCollection)
+        : ParagraphBuilder(style, fontCollection), fFontCollection(std::move(fontCollection)) {
+    this->setParagraphStyle(style);
+}
+
+ParagraphBuilderImpl::~ParagraphBuilderImpl() = default;
+
+void ParagraphBuilderImpl::setParagraphStyle(const ParagraphStyle& style) {
+    fParagraphStyle = style;
+    fTextStyles.push(fParagraphStyle.getTextStyle());
+    fStyledBlocks.emplace_back(fUtf8.size(), fUtf8.size(), fParagraphStyle.getTextStyle());
+}
+
+void ParagraphBuilderImpl::pushStyle(const TextStyle& style) {
+    this->endRunIfNeeded();
+
+    fTextStyles.push(style);
+    if (!fStyledBlocks.empty() && fStyledBlocks.back().fEnd == fUtf8.size() &&
+        fStyledBlocks.back().fStyle == style) {
+        // Just continue with the same style
+    } else {
+        // Go with the new style
+        fStyledBlocks.emplace_back(fUtf8.size(), fUtf8.size(), fTextStyles.top());
+    }
+}
+
+void ParagraphBuilderImpl::pop() {
+    this->endRunIfNeeded();
+
+    if (fTextStyles.size() > 1) {
+        fTextStyles.pop();
+    } else {
+        // In this case we use paragraph style and skip Pop operation
+        SkDebugf("SkParagraphBuilder.Pop() called too many times.\n");
+    }
+
+    auto top = fTextStyles.top();
+    fStyledBlocks.emplace_back(fUtf8.size(), fUtf8.size(), top);
+}
+
+TextStyle ParagraphBuilderImpl::peekStyle() {
+    this->endRunIfNeeded();
+
+    if (!fTextStyles.empty()) {
+        return fTextStyles.top();
+    } else {
+        SkDebugf("SkParagraphBuilder._styles is empty.\n");
+        return fParagraphStyle.getTextStyle();
+    }
+}
+
+void ParagraphBuilderImpl::addText(const std::u16string& text) {
+    icu::UnicodeString unicode;
+    unicode.setTo((UChar*)text.data());
+    std::string str;
+    unicode.toUTF8String(str);
+    // SkDebugf("Layout text16: '%s'\n", str.c_str());
+    fUtf8.insert(fUtf8.size(), str.c_str());
+}
+
+void ParagraphBuilderImpl::addText(const char* text) {
+    // SkDebugf("Layout text8: '%s'\n", text);
+    fUtf8.insert(fUtf8.size(), text);
+}
+
+void ParagraphBuilderImpl::endRunIfNeeded() {
+    if (fStyledBlocks.empty()) {
+        return;
+    }
+
+    auto& last = fStyledBlocks.back();
+    if (last.fStart == fUtf8.size()) {
+        fStyledBlocks.pop_back();
+    } else {
+        last.fEnd = fUtf8.size();
+    }
+}
+
+std::unique_ptr<Paragraph> ParagraphBuilderImpl::Build() {
+    if (!fUtf8.isEmpty()) {
+        this->endRunIfNeeded();
+    }
+    return skstd::make_unique<ParagraphImpl>(
+            fUtf8, fParagraphStyle, fStyledBlocks, fFontCollection);
+}
+
+}  // namespace textlayout
+}  // namespace skia