blob: 9aa72110dec7f392539b5aacbb9bba5e17a296d4 [file] [log] [blame]
Florin Malita51012ce2018-01-31 17:06:59 -05001/*
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 "SkSGText.h"
9
10#include "SkCanvas.h"
11#include "SkPaint.h"
12#include "SkPath.h"
13#include "SkTArray.h"
Florin Malita51012ce2018-01-31 17:06:59 -050014#include "SkTypeface.h"
15
16namespace sksg {
17
18sk_sp<Text> Text::Make(sk_sp<SkTypeface> tf, const SkString& text) {
19 return sk_sp<Text>(new Text(std::move(tf), text));
20}
21
22Text::Text(sk_sp<SkTypeface> tf, const SkString& text)
23 : fTypeface(std::move(tf))
24 , fText(text) {}
25
26Text::~Text() = default;
27
Florin Malita77af3862018-08-15 16:51:42 -040028SkPoint Text::alignedPosition(SkScalar advance) const {
29 auto aligned = fPosition;
30
31 switch (fAlign) {
Mike Reed3a42ec02018-10-30 12:53:21 -040032 case SkTextUtils::kLeft_Align:
Florin Malita77af3862018-08-15 16:51:42 -040033 break;
Mike Reed3a42ec02018-10-30 12:53:21 -040034 case SkTextUtils::kCenter_Align:
Florin Malita77af3862018-08-15 16:51:42 -040035 aligned.offset(-advance / 2, 0);
36 break;
Mike Reed3a42ec02018-10-30 12:53:21 -040037 case SkTextUtils::kRight_Align:
Florin Malita77af3862018-08-15 16:51:42 -040038 aligned.offset(-advance, 0);
39 break;
40 }
41
42 return aligned;
43}
44
Florin Malita51012ce2018-01-31 17:06:59 -050045SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) {
46 // TODO: we could potentially track invals which don't require rebuilding the blob.
47
Mike Reed2ed78202018-11-21 15:10:08 -050048 SkFont font;
Florin Malita51012ce2018-01-31 17:06:59 -050049 font.setTypeface(fTypeface);
Mike Reed2ed78202018-11-21 15:10:08 -050050 font.setSize(fSize);
51 font.setScaleX(fScaleX);
52 font.setSkewX(fSkewX);
Florin Malitaf7d6ac12018-11-21 16:03:58 -050053 font.setEdging(fEdging);
Florin Malita51012ce2018-01-31 17:06:59 -050054 font.setHinting(fHinting);
55
Florin Malita77af3862018-08-15 16:51:42 -040056 // 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
Mike Reed722dd612018-12-07 14:38:20 -050060 fBlob = SkTextBlob::MakeFromText(fText.c_str(), fText.size(), font, kUTF8_SkTextEncoding);
Florin Malita77af3862018-08-15 16:51:42 -040061 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());
Florin Malita51012ce2018-01-31 17:06:59 -050069}
70
71void Text::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
Florin Malita77af3862018-08-15 16:51:42 -040072 const auto aligned_pos = this->alignedPosition(this->bounds().width());
73 canvas->drawTextBlob(fBlob, aligned_pos.x(), aligned_pos.y(), paint);
Florin Malita51012ce2018-01-31 17:06:59 -050074}
75
Florin Malitaeb46bd82019-02-12 09:33:21 -050076bool Text::onContains(const SkPoint& p) const {
77 return this->asPath().contains(p.x(), p.y());
78}
79
Florin Malita51012ce2018-01-31 17:06:59 -050080SkPath Text::onAsPath() const {
81 // TODO
82 return SkPath();
83}
84
85void Text::onClip(SkCanvas* canvas, bool antiAlias) const {
86 canvas->clipPath(this->asPath(), antiAlias);
87}
88
Florin Malita0a8b4e12018-11-01 11:16:18 -040089sk_sp<TextBlob> TextBlob::Make(sk_sp<SkTextBlob> blob) {
90 return sk_sp<TextBlob>(new TextBlob(std::move(blob)));
91}
92
93TextBlob::TextBlob(sk_sp<SkTextBlob> blob)
94 : fBlob(std::move(blob)) {}
95
96TextBlob::~TextBlob() = default;
97
98SkRect TextBlob::onRevalidate(InvalidationController*, const SkMatrix&) {
99 return fBlob ? fBlob->bounds() : SkRect::MakeEmpty();
100}
101
102void TextBlob::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
103 canvas->drawTextBlob(fBlob, fPosition.x(), fPosition.y(), paint);
104}
105
Florin Malitaeb46bd82019-02-12 09:33:21 -0500106bool TextBlob::onContains(const SkPoint& p) const {
107 return this->asPath().contains(p.x(), p.y());
108}
109
Florin Malita0a8b4e12018-11-01 11:16:18 -0400110SkPath TextBlob::onAsPath() const {
111 // TODO
112 return SkPath();
113}
114
115void TextBlob::onClip(SkCanvas* canvas, bool antiAlias) const {
116 canvas->clipPath(this->asPath(), antiAlias);
117}
118
Florin Malita51012ce2018-01-31 17:06:59 -0500119} // namespace sksg