Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / core / SkGlyphRun.h
1 /*
2  * Copyright 2018 The Android Open Source Project
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 SkGlyphRun_DEFINED
9 #define SkGlyphRun_DEFINED
10
11 #include <functional>
12 #include <optional>
13 #include <vector>
14
15 #include "include/core/SkFont.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkPoint.h"
18 #include "include/core/SkRSXform.h"
19 #include "include/core/SkSpan.h"
20 #include "include/core/SkTypes.h"
21 #include "include/private/SkTemplates.h"
22 #include "src/core/SkGlyphBuffer.h"
23 #include "src/core/SkZip.h"
24
25 class SkBaseDevice;
26 class SkCanvas;
27 class SkGlyph;
28 class SkGlyphRunList;
29 class SkGlyphRunBuilder;
30 class SkTextBlob;
31 class SkTextBlobRunIterator;
32
33 class SkSubRunBuffers {
34 public:
35     class ScopedBuffers {
36     public:
37         ScopedBuffers(SkSubRunBuffers* painter, size_t size);
38         ~ScopedBuffers();
39         std::tuple<SkDrawableGlyphBuffer*, SkSourceGlyphBuffer*> buffers() {
40             return {&fBuffers->fAccepted, &fBuffers->fRejected};
41         }
42
43     private:
44         SkSubRunBuffers* const fBuffers;
45     };
46     static ScopedBuffers SK_WARN_UNUSED_RESULT EnsureBuffers(const SkGlyphRunList& glyphRunList);
47
48 private:
49     SkDrawableGlyphBuffer fAccepted;
50     SkSourceGlyphBuffer fRejected;
51 };
52
53 class SkGlyphRun {
54 public:
55     SkGlyphRun(const SkFont& font,
56                SkSpan<const SkPoint> positions,
57                SkSpan<const SkGlyphID> glyphIDs,
58                SkSpan<const char> text,
59                SkSpan<const uint32_t> clusters,
60                SkSpan<const SkVector> scaledRotations);
61
62     SkGlyphRun(const SkGlyphRun& glyphRun, const SkFont& font);
63
64     size_t runSize() const { return fSource.size(); }
65     SkSpan<const SkPoint> positions() const { return fSource.get<1>(); }
66     SkSpan<const SkGlyphID> glyphsIDs() const { return fSource.get<0>(); }
67     SkZip<const SkGlyphID, const SkPoint> source() const { return fSource; }
68     const SkFont& font() const { return fFont; }
69     SkSpan<const uint32_t> clusters() const { return fClusters; }
70     SkSpan<const char> text() const { return fText; }
71     SkSpan<const SkVector> scaledRotations() const { return fScaledRotations; }
72     SkRect sourceBounds(const SkPaint& paint) const;
73
74 private:
75     // GlyphIDs and positions.
76     const SkZip<const SkGlyphID, const SkPoint> fSource;
77     // Original text from SkTextBlob if present. Will be empty of not present.
78     const SkSpan<const char> fText;
79     // Original clusters from SkTextBlob if present. Will be empty if not present.
80     const SkSpan<const uint32_t>   fClusters;
81     // Possible RSXForm information
82     const SkSpan<const SkVector> fScaledRotations;
83     // Font for this run modified to have glyph encoding and left alignment.
84     SkFont fFont;
85 };
86
87 class SkGlyphRunList {
88     SkSpan<const SkGlyphRun> fGlyphRuns;
89
90 public:
91     // Blob maybe null.
92     SkGlyphRunList(
93             const SkTextBlob* blob,
94             SkRect bounds,
95             SkPoint origin,
96             SkSpan<const SkGlyphRun> glyphRunList,
97             SkGlyphRunBuilder* builder);
98
99     SkGlyphRunList(const SkGlyphRun& glyphRun,
100                    const SkRect& bounds,
101                    SkPoint origin,
102                    SkGlyphRunBuilder* builder);
103     uint64_t uniqueID() const;
104     bool anyRunsLCD() const;
105     void temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const;
106
107     bool canCache() const { return fOriginalTextBlob != nullptr; }
108     size_t runCount() const { return fGlyphRuns.size(); }
109     size_t totalGlyphCount() const {
110         size_t glyphCount = 0;
111         for (const SkGlyphRun& run : *this) {
112             glyphCount += run.runSize();
113         }
114         return glyphCount;
115     }
116
117     bool hasRSXForm() const {
118         for (const SkGlyphRun& run : *this) {
119             if (!run.scaledRotations().empty()) { return true; }
120         }
121         return false;
122     }
123
124     sk_sp<SkTextBlob> makeBlob() const;
125
126     SkPoint origin() const { return fOrigin; }
127     SkRect sourceBounds() const { return fSourceBounds; }
128     const SkTextBlob* blob() const { return fOriginalTextBlob; }
129     SkGlyphRunBuilder* builder() const { return fBuilder; }
130     SkSubRunBuffers* buffers() const;
131
132     auto begin() -> decltype(fGlyphRuns.begin())               { return fGlyphRuns.begin();      }
133     auto end()   -> decltype(fGlyphRuns.end())                 { return fGlyphRuns.end();        }
134     auto begin() const -> decltype(std::cbegin(fGlyphRuns))    { return std::cbegin(fGlyphRuns); }
135     auto end()   const -> decltype(std::cend(fGlyphRuns))      { return std::cend(fGlyphRuns);   }
136     auto size()  const -> decltype(fGlyphRuns.size())          { return fGlyphRuns.size();       }
137     auto empty() const -> decltype(fGlyphRuns.empty())         { return fGlyphRuns.empty();      }
138     auto operator [] (size_t i) const -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i];         }
139
140 private:
141     // The text blob is needed to hook up the call back that the SkTextBlob destructor calls. It
142     // should be used for nothing else.
143     const SkTextBlob* fOriginalTextBlob{nullptr};
144     const SkRect fSourceBounds{SkRect::MakeEmpty()};
145     const SkPoint fOrigin = {0, 0};
146     SkGlyphRunBuilder* const fBuilder;
147 };
148
149 class SkGlyphRunBuilder {
150 public:
151     SkGlyphRunList makeGlyphRunList(
152             const SkGlyphRun& run, SkRect bounds, SkPoint origin);
153     const SkGlyphRunList& textToGlyphRunList(const SkFont& font,
154                                              const SkPaint& paint,
155                                              const void* bytes,
156                                              size_t byteLength,
157                                              SkPoint origin,
158                                              SkTextEncoding encoding = SkTextEncoding::kUTF8);
159     const SkGlyphRunList& blobToGlyphRunList(const SkTextBlob& blob, SkPoint origin);
160     std::tuple<SkSpan<const SkPoint>, SkSpan<const SkVector>>
161             convertRSXForm(SkSpan<const SkRSXform> xforms);
162
163     bool empty() const { return fGlyphRunListStorage.empty(); }
164     SkSubRunBuffers* buffers() { return &fSubRunBuffers; }
165
166 private:
167     void initialize(const SkTextBlob& blob);
168     void prepareBuffers(int positionCount, int RSXFormCount);
169
170     SkSpan<const SkGlyphID> textToGlyphIDs(
171             const SkFont& font, const void* bytes, size_t byteLength, SkTextEncoding);
172
173     void makeGlyphRun(
174             const SkFont& font,
175             SkSpan<const SkGlyphID> glyphIDs,
176             SkSpan<const SkPoint> positions,
177             SkSpan<const char> text,
178             SkSpan<const uint32_t> clusters,
179             SkSpan<const SkVector> scaledRotations);
180
181     const SkGlyphRunList& setGlyphRunList(
182             const SkTextBlob* blob, const SkRect& bounds, SkPoint origin);
183
184     int fMaxTotalRunSize{0};
185     SkAutoTMalloc<SkPoint> fPositions;
186     int fMaxScaledRotations{0};
187     SkAutoTMalloc<SkVector> fScaledRotations;
188
189     std::vector<SkGlyphRun> fGlyphRunListStorage;
190     std::optional<SkGlyphRunList> fGlyphRunList;  // Defaults to no value;
191
192     // Used as a temporary for preparing using utfN text. This implies that only one run of
193     // glyph ids will ever be needed because blobs are already glyph based.
194     std::vector<SkGlyphID> fScratchGlyphIDs;
195
196     SkSubRunBuffers fSubRunBuffers;
197 };
198
199 inline SkSubRunBuffers* SkGlyphRunList::buffers() const { return fBuilder->buffers(); }
200
201 #endif  // SkGlyphRun_DEFINED