add textutils

These are meant to enable several things (eventually)

- fission Align off of paint
- fission TextEncoding off of paint
- fission SkFont of of paint

The first one is explicitly enabled here. The others will (I plan) follow later.

The final state of the world (the goal)
- paint has no font-ish parameters (no typeface or size)
- font has no paint-ish parameters (no aa or lcd)
- neither has alignment or encoding

Bug: skia:8493, skia:8501
Change-Id: I5fcb945b6bcab30ef5e7019dfccb682661f56230
Reviewed-on: https://skia-review.googlesource.com/c/165061
Auto-Submit: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/utils/SkTextUtils.cpp b/src/utils/SkTextUtils.cpp
new file mode 100644
index 0000000..784cf7d
--- /dev/null
+++ b/src/utils/SkTextUtils.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTextUtils.h"
+
+void SkTextUtils::DrawText(SkCanvas* canvas, const void* text, size_t size, SkScalar x, SkScalar y,
+                            const SkPaint& origPaint, SkPaint::Align align) {
+    int count = origPaint.countText(text, size);
+    if (!count) {
+        return;
+    }
+
+    SkPaint paint(origPaint);
+    SkAutoSTArray<32, uint16_t> glyphStorage;
+    const uint16_t* glyphs;
+
+    if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
+        glyphStorage.reset(count);
+        paint.textToGlyphs(text, size, glyphStorage.get());
+        glyphs = glyphStorage.get();
+        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    } else {
+        glyphs = static_cast<const uint16_t*>(text);
+    }
+
+    SkAutoSTArray<32, SkScalar> widthStorage(count);
+    SkScalar* widths = widthStorage.get();
+    paint.getTextWidths(glyphs, count * sizeof(uint16_t), widths);
+
+    if (align != SkPaint::kLeft_Align) {
+        SkScalar offset = 0;
+        for (int i = 0; i < count; ++i) {
+            offset += widths[i];
+        }
+        if (align == SkPaint::kCenter_Align) {
+            offset *= 0.5f;
+        }
+        x -= offset;
+    }
+
+    // Turn widths into h-positions
+    for (int i = 0; i < count; ++i) {
+        SkScalar w = widths[i];
+        widths[i] = x;
+        x += w;
+    }
+    canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), widths, y, paint);
+}
+