SkShaper per-line callback

Tweak SkShaper to call out for each line, instead of bundling everything
as a text blob.

Change-Id: Ic522f88afcf31cefd873dc8b5cde1ac2e107c64f
Reviewed-on: https://skia-review.googlesource.com/c/176592
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/skshaper/src/SkShaper_primitive.cpp b/modules/skshaper/src/SkShaper_primitive.cpp
index 7b798e7..3d54262 100644
--- a/modules/skshaper/src/SkShaper_primitive.cpp
+++ b/modules/skshaper/src/SkShaper_primitive.cpp
@@ -8,7 +8,6 @@
 #include "SkShaper.h"
 
 #include "SkStream.h"
-#include "SkTextBlob.h"
 #include "SkTo.h"
 #include "SkTypeface.h"
 
@@ -32,7 +31,7 @@
     return (((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1;
 }
 
-SkPoint SkShaper::shape(SkTextBlobBuilder* builder,
+SkPoint SkShaper::shape(LineHandler* handler,
                         const SkFont& srcFont,
                         const char* utf8text,
                         size_t textBytes,
@@ -40,6 +39,7 @@
                         SkPoint point,
                         SkScalar width) const {
     sk_ignore_unused_variable(leftToRight);
+    sk_ignore_unused_variable(width);
 
     SkFont font(srcFont);
     font.setTypeface(fImpl->fTypeface);
@@ -47,32 +47,29 @@
     if (glyphCount <= 0) {
         return point;
     }
-    SkRect bounds;
+
     SkFontMetrics metrics;
     font.getMetrics(&metrics);
     point.fY -= metrics.fAscent;
-    (void)font.measureText(utf8text, textBytes, SkTextEncoding::kUTF8, &bounds);
-    const SkTextBlobBuilder::RunBuffer& runBuffer =
-        builder->allocRunTextPosH(font, glyphCount, point.y(), textBytes, SkString(), &bounds);
-    memcpy(runBuffer.utf8text, utf8text, textBytes);
-    const char* txtPtr = utf8text;
-    for (int i = 0; i < glyphCount; ++i) {
-        // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
-        runBuffer.clusters[i] = SkToU32(txtPtr - utf8text);
-        txtPtr += utf8_lead_byte_to_count(txtPtr);
-        SkASSERT(txtPtr <= utf8text + textBytes);
-    }
-    (void)font.textToGlyphs(utf8text, textBytes, SkTextEncoding::kUTF8,
-                            runBuffer.glyphs, glyphCount);
-    // replace with getPos()?
-    (void)font.getWidths(runBuffer.glyphs, glyphCount, runBuffer.pos);
-    SkScalar x = point.x();
-    for (int i = 0; i < glyphCount; ++i) {
-        SkScalar w = runBuffer.pos[i];
-        runBuffer.pos[i] = x;
-        x += w;
-    }
-    point.fY += metrics.fDescent + metrics.fLeading;
 
-    return point;
+    const auto buffer = handler->newLineBuffer(font, glyphCount, textBytes);
+    SkAssertResult(font.textToGlyphs(utf8text, textBytes, SkTextEncoding::kUTF8, buffer.glyphs,
+                                     glyphCount) == glyphCount);
+    font.getPos(buffer.glyphs, glyphCount, buffer.positions, point);
+
+    if (buffer.utf8text) {
+        memcpy(buffer.utf8text, utf8text, textBytes);
+    }
+
+    if (buffer.clusters) {
+        const char* txtPtr = utf8text;
+        for (int i = 0; i < glyphCount; ++i) {
+            // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
+            buffer.clusters[i] = SkToU32(txtPtr - utf8text);
+            txtPtr += utf8_lead_byte_to_count(txtPtr);
+            SkASSERT(txtPtr <= utf8text + textBytes);
+        }
+    }
+
+    return point + SkVector::Make(0, metrics.fDescent + metrics.fLeading);
 }