From 77af386c13cb241b4afd8dab9dc8ca5f64acd628 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Wed, 15 Aug 2018 16:51:42 -0400 Subject: [PATCH] [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 Reviewed-by: Mike Reed --- modules/sksg/include/SkSGText.h | 2 ++ modules/sksg/src/SkSGText.cpp | 36 ++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/modules/sksg/include/SkSGText.h b/modules/sksg/include/SkSGText.h index eb43337a104e2..c1df888605da2 100644 --- a/modules/sksg/include/SkSGText.h +++ b/modules/sksg/include/SkSGText.h @@ -49,6 +49,8 @@ class Text final : public GeometryNode { private: explicit Text(sk_sp, const SkString&); + SkPoint alignedPosition(SkScalar advance) const; + const sk_sp fTypeface; SkString fText; uint32_t fFlags = SkPaintDefaults_Flags; diff --git a/modules/sksg/src/SkSGText.cpp b/modules/sksg/src/SkSGText.cpp index c149390023283..1451c38e47de4 100644 --- a/modules/sksg/src/SkSGText.cpp +++ b/modules/sksg/src/SkSGText.cpp @@ -26,6 +26,23 @@ Text::Text(sk_sp tf, const SkString& text) 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 @@ SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) { 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 @@ SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) { 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 {