[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 {