• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "modules/sksg/include/SkSGText.h"
9 
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPath.h"
13 #include "include/core/SkTypeface.h"
14 #include "include/private/SkTArray.h"
15 
16 namespace sksg {
17 
Make(sk_sp<SkTypeface> tf,const SkString & text)18 sk_sp<Text> Text::Make(sk_sp<SkTypeface> tf, const SkString& text) {
19     return sk_sp<Text>(new Text(std::move(tf), text));
20 }
21 
Text(sk_sp<SkTypeface> tf,const SkString & text)22 Text::Text(sk_sp<SkTypeface> tf, const SkString& text)
23     : fTypeface(std::move(tf))
24     , fText(text) {}
25 
26 Text::~Text() = default;
27 
alignedPosition(SkScalar advance) const28 SkPoint Text::alignedPosition(SkScalar advance) const {
29     auto aligned = fPosition;
30 
31     switch (fAlign) {
32     case SkTextUtils::kLeft_Align:
33         break;
34     case SkTextUtils::kCenter_Align:
35         aligned.offset(-advance / 2, 0);
36         break;
37     case SkTextUtils::kRight_Align:
38         aligned.offset(-advance, 0);
39         break;
40     }
41 
42     return aligned;
43 }
44 
onRevalidate(InvalidationController *,const SkMatrix &)45 SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) {
46     // TODO: we could potentially track invals which don't require rebuilding the blob.
47 
48     SkFont font;
49     font.setTypeface(fTypeface);
50     font.setSize(fSize);
51     font.setScaleX(fScaleX);
52     font.setSkewX(fSkewX);
53     font.setEdging(fEdging);
54     font.setHinting(fHinting);
55 
56     // N.B.: fAlign is applied externally (in alignedPosition()), because
57     //  1) SkTextBlob has some trouble computing accurate bounds with alignment.
58     //  2) SkPaint::Align is slated for deprecation.
59 
60     fBlob = SkTextBlob::MakeFromText(fText.c_str(), fText.size(), font, SkTextEncoding::kUTF8);
61     if (!fBlob) {
62         return SkRect::MakeEmpty();
63     }
64 
65     const auto& bounds = fBlob->bounds();
66     const auto aligned_pos = this->alignedPosition(bounds.width());
67 
68     return bounds.makeOffset(aligned_pos.x(), aligned_pos.y());
69 }
70 
onDraw(SkCanvas * canvas,const SkPaint & paint) const71 void Text::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
72     const auto aligned_pos = this->alignedPosition(this->bounds().width());
73     canvas->drawTextBlob(fBlob, aligned_pos.x(), aligned_pos.y(), paint);
74 }
75 
onContains(const SkPoint & p) const76 bool Text::onContains(const SkPoint& p) const {
77     return this->asPath().contains(p.x(), p.y());
78 }
79 
onAsPath() const80 SkPath Text::onAsPath() const {
81     // TODO
82     return SkPath();
83 }
84 
onClip(SkCanvas * canvas,bool antiAlias) const85 void Text::onClip(SkCanvas* canvas, bool antiAlias) const {
86     canvas->clipPath(this->asPath(), antiAlias);
87 }
88 
Make(sk_sp<SkTextBlob> blob)89 sk_sp<TextBlob> TextBlob::Make(sk_sp<SkTextBlob> blob) {
90     return sk_sp<TextBlob>(new TextBlob(std::move(blob)));
91 }
92 
TextBlob(sk_sp<SkTextBlob> blob)93 TextBlob::TextBlob(sk_sp<SkTextBlob> blob)
94     : fBlob(std::move(blob)) {}
95 
96 TextBlob::~TextBlob() = default;
97 
onRevalidate(InvalidationController *,const SkMatrix &)98 SkRect TextBlob::onRevalidate(InvalidationController*, const SkMatrix&) {
99     return fBlob ? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y())
100                  : SkRect::MakeEmpty();
101 }
102 
onDraw(SkCanvas * canvas,const SkPaint & paint) const103 void TextBlob::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
104     canvas->drawTextBlob(fBlob, fPosition.x(), fPosition.y(), paint);
105 }
106 
onContains(const SkPoint & p) const107 bool TextBlob::onContains(const SkPoint& p) const {
108     return this->asPath().contains(p.x(), p.y());
109 }
110 
onAsPath() const111 SkPath TextBlob::onAsPath() const {
112     // TODO
113     return SkPath();
114 }
115 
onClip(SkCanvas * canvas,bool antiAlias) const116 void TextBlob::onClip(SkCanvas* canvas, bool antiAlias) const {
117     canvas->clipPath(this->asPath(), antiAlias);
118 }
119 
120 } // namespace sksg
121