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