Skip to content

Commit

Permalink
[sksg] Explicit text alignment
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
fmalita authored and Skia Commit-Bot committed Aug 15, 2018
1 parent d4c1d35 commit 77af386
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
2 changes: 2 additions & 0 deletions modules/sksg/include/SkSGText.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Text final : public GeometryNode {
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;
Expand Down
36 changes: 31 additions & 5 deletions modules/sksg/src/SkSGText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ Text::Text(sk_sp<SkTypeface> 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.

Expand All @@ -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;
Expand All @@ -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 {
Expand Down

0 comments on commit 77af386

Please sign in to comment.