[sksg] Explicit text alignment

Work around for https://bugs.chromium.org/p/skia/issues/detail?id=8252

Change-Id: Icae3f69f07a2c95302cfbb3833185517f43d326e
Reviewed-on: https://skia-review.googlesource.com/147218
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/modules/sksg/include/SkSGText.h b/modules/sksg/include/SkSGText.h
index eb43337..c1df888 100644
--- a/modules/sksg/include/SkSGText.h
+++ b/modules/sksg/include/SkSGText.h
@@ -49,6 +49,8 @@
 private:
     explicit Text(sk_sp<SkTypeface>, const SkString&);
 
+    SkPoint alignedPosition(SkScalar advance) const;
+
     const sk_sp<SkTypeface> fTypeface;
     SkString                fText;
     uint32_t                fFlags    = SkPaintDefaults_Flags;
diff --git a/modules/sksg/src/SkSGText.cpp b/modules/sksg/src/SkSGText.cpp
index c149390..1451c38 100644
--- a/modules/sksg/src/SkSGText.cpp
+++ b/modules/sksg/src/SkSGText.cpp
@@ -26,6 +26,23 @@
 
 Text::~Text() = default;
 
+SkPoint Text::alignedPosition(SkScalar advance) const {
+    auto aligned = fPosition;
+
+    switch (fAlign) {
+    case SkPaint::kLeft_Align:
+        break;
+    case SkPaint::kCenter_Align:
+        aligned.offset(-advance / 2, 0);
+        break;
+    case SkPaint::kRight_Align:
+        aligned.offset(-advance, 0);
+        break;
+    }
+
+    return aligned;
+}
+
 SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) {
     // TODO: we could potentially track invals which don't require rebuilding the blob.
 
@@ -35,9 +52,12 @@
     font.setTextSize(fSize);
     font.setTextScaleX(fScaleX);
     font.setTextSkewX(fSkewX);
-    font.setTextAlign(fAlign);
     font.setHinting(fHinting);
 
+    // N.B.: fAlign is applied externally (in alignedPosition()), because
+    //  1) SkTextBlob has some trouble computing accurate bounds with alignment.
+    //  2) SkPaint::Align is slated for deprecation.
+
     // First, convert to glyphIDs.
     font.setTextEncoding(SkPaint::kUTF8_TextEncoding);
     SkSTArray<256, SkGlyphID, true> glyphs;
@@ -56,13 +76,19 @@
     memcpy(buf.glyphs, glyphs.begin(), glyphs.count() * sizeof(SkGlyphID));
 
     fBlob = builder.make();
-    return fBlob
-        ? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y())
-        : SkRect::MakeEmpty();
+    if (!fBlob) {
+        return SkRect::MakeEmpty();
+    }
+
+    const auto& bounds = fBlob->bounds();
+    const auto aligned_pos = this->alignedPosition(bounds.width());
+
+    return bounds.makeOffset(aligned_pos.x(), aligned_pos.y());
 }
 
 void Text::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
-    canvas->drawTextBlob(fBlob, fPosition.x(), fPosition.y(), paint);
+    const auto aligned_pos = this->alignedPosition(this->bounds().width());
+    canvas->drawTextBlob(fBlob, aligned_pos.x(), aligned_pos.y(), paint);
 }
 
 SkPath Text::onAsPath() const {