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#ifndef SkSGText_DEFINED
9#define SkSGText_DEFINED
10
11#include "modules/sksg/include/SkSGGeometryNode.h"
12
13#include "include/core/SkFont.h"
14#include "include/core/SkPoint.h"
15#include "include/core/SkString.h"
16#include "include/core/SkTextBlob.h"
17#include "include/utils/SkTextUtils.h"
18
19class SkCanvas;
20class SkPaint;
21class SkTypeface;
22
23namespace sksg {
24
25/**
26 * Concrete Geometry node, wrapping a (shaped) SkTextBlob.
27 */
28class Text final : public GeometryNode {
29public:
30 static sk_sp<Text> Make(sk_sp<SkTypeface> tf, const SkString& text);
31 ~Text() override;
32
33 SG_ATTRIBUTE(Typeface, sk_sp<SkTypeface> , fTypeface)
34 SG_ATTRIBUTE(Text , SkString , fText )
35 SG_ATTRIBUTE(Position, SkPoint , fPosition)
36 SG_ATTRIBUTE(Size , SkScalar , fSize )
37 SG_ATTRIBUTE(ScaleX , SkScalar , fScaleX )
38 SG_ATTRIBUTE(SkewX , SkScalar , fSkewX )
39 SG_ATTRIBUTE(Align , SkTextUtils::Align, fAlign )
40 SG_ATTRIBUTE(Edging , SkFont::Edging , fEdging )
41 SG_ATTRIBUTE(Hinting , SkFontHinting , fHinting )
42
43 // TODO: add shaping functionality.
44
45protected:
46 void onClip(SkCanvas*, bool antiAlias) const override;
47 void onDraw(SkCanvas*, const SkPaint&) const override;
48 bool onContains(const SkPoint&) const override;
49
50 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
51 SkPath onAsPath() const override;
52
53private:
54 Text(sk_sp<SkTypeface>, const SkString&);
55
56 SkPoint alignedPosition(SkScalar advance) const;
57
58 sk_sp<SkTypeface> fTypeface;
59 SkString fText;
60 SkPoint fPosition = SkPoint::Make(0, 0);
61 SkScalar fSize = 12;
62 SkScalar fScaleX = 1;
63 SkScalar fSkewX = 0;
64 SkTextUtils::Align fAlign = SkTextUtils::kLeft_Align;
65 SkFont::Edging fEdging = SkFont::Edging::kAntiAlias;
66 SkFontHinting fHinting = SkFontHinting::kNormal;
67
68 sk_sp<SkTextBlob> fBlob; // cached text blob
69
70 using INHERITED = GeometryNode;
71};
72
73/**
74 * Concrete Geometry node, wrapping an external SkTextBlob.
75 */
76class TextBlob final : public GeometryNode {
77public:
78 static sk_sp<TextBlob> Make(sk_sp<SkTextBlob> = nullptr);
79 ~TextBlob() override;
80
81 SG_ATTRIBUTE(Blob , sk_sp<SkTextBlob>, fBlob )
82 SG_ATTRIBUTE(Position, SkPoint , fPosition)
83
84protected:
85 void onClip(SkCanvas*, bool antiAlias) const override;
86 void onDraw(SkCanvas*, const SkPaint&) const override;
87 bool onContains(const SkPoint&) const override;
88
89 SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
90 SkPath onAsPath() const override;
91
92private:
93 explicit TextBlob(sk_sp<SkTextBlob>);
94
95 sk_sp<SkTextBlob> fBlob;
96 SkPoint fPosition = SkPoint::Make(0, 0);
97
98 using INHERITED = GeometryNode;
99};
100} // namespace sksg
101
102#endif // SkSGText_DEFINED
103