xref: /aosp_15_r20/external/skia/modules/skshaper/include/SkShaper.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2016 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 SkShaper_DEFINED
9 #define SkShaper_DEFINED
10 
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFourByteTag.h"
13 #include "include/core/SkPoint.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkString.h"
17 #include "include/core/SkTextBlob.h"
18 #include "include/core/SkTypes.h"
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <memory>
23 #include <type_traits>
24 
25 class SkFontStyle;
26 
27 #if defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
28 class SkFontMgr;
29 #else
30 #include "include/core/SkFontMgr.h"
31 #endif
32 
33 #if !defined(SKSHAPER_IMPLEMENTATION)
34     #define SKSHAPER_IMPLEMENTATION 0
35 #endif
36 
37 #if !defined(SKSHAPER_API)
38     #if defined(SKSHAPER_DLL)
39         #if defined(_MSC_VER)
40             #if SKSHAPER_IMPLEMENTATION
41                 #define SKSHAPER_API __declspec(dllexport)
42             #else
43                 #define SKSHAPER_API __declspec(dllimport)
44             #endif
45         #else
46             #define SKSHAPER_API __attribute__((visibility("default")))
47         #endif
48     #else
49         #define SKSHAPER_API
50     #endif
51 #endif
52 
53 class SKSHAPER_API SkShaper {
54 public:
55 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
56     static std::unique_ptr<SkShaper> MakePrimitive();
57 
58 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE)
59     static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(sk_sp<SkFontMgr> fallback);
60     static std::unique_ptr<SkShaper> MakeShapeThenWrap(sk_sp<SkFontMgr> fallback);
61     static void PurgeHarfBuzzCache();
62 #endif
63 
64 #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
65     static std::unique_ptr<SkShaper> MakeCoreText();
66 #endif
67 
68     static std::unique_ptr<SkShaper> Make(sk_sp<SkFontMgr> fallback = nullptr);
69     static void PurgeCaches();
70 #endif  // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
71 
72     SkShaper();
73     virtual ~SkShaper();
74 
75     class RunIterator {
76     public:
77         virtual ~RunIterator() = default;
78         /** Set state to that of current run and move iterator to end of that run. */
79         virtual void consume() = 0;
80         /** Offset to one past the last (utf8) element in the current run. */
81         virtual size_t endOfCurrentRun() const = 0;
82         /** Return true if consume should no longer be called. */
83         virtual bool atEnd() const = 0;
84     };
85     class FontRunIterator : public RunIterator {
86     public:
87         virtual const SkFont& currentFont() const = 0;
88     };
89     class BiDiRunIterator : public RunIterator {
90     public:
91         /** The unicode bidi embedding level (even ltr, odd rtl) */
92         virtual uint8_t currentLevel() const = 0;
93     };
94     class ScriptRunIterator : public RunIterator {
95     public:
96         /** Should be iso15924 codes. */
97         virtual SkFourByteTag currentScript() const = 0;
98     };
99     class LanguageRunIterator : public RunIterator {
100     public:
101         /** Should be BCP-47, c locale names may also work. */
102         virtual const char* currentLanguage() const = 0;
103     };
104     struct Feature {
105         SkFourByteTag tag;
106         uint32_t value;
107         size_t start; // Offset to the start (utf8) element of the run.
108         size_t end;   // Offset to one past the last (utf8) element of the run.
109     };
110 
111 private:
112     template <typename RunIteratorSubclass>
113     class TrivialRunIterator : public RunIteratorSubclass {
114     public:
115         static_assert(std::is_base_of<RunIterator, RunIteratorSubclass>::value, "");
TrivialRunIterator(size_t utf8Bytes)116         TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
consume()117         void consume() override { SkASSERT(!fAtEnd); fAtEnd = true; }
endOfCurrentRun()118         size_t endOfCurrentRun() const override { return fAtEnd ? fEnd : 0; }
atEnd()119         bool atEnd() const override { return fAtEnd; }
120     private:
121         size_t fEnd;
122         bool fAtEnd;
123     };
124 
125 public:
126     static std::unique_ptr<FontRunIterator>
127     MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes,
128                            const SkFont& font, sk_sp<SkFontMgr> fallback);
129     static std::unique_ptr<SkShaper::FontRunIterator>
130     MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes,
131                            const SkFont& font, sk_sp<SkFontMgr> fallback,
132                            const char* requestName, SkFontStyle requestStyle,
133                            const SkShaper::LanguageRunIterator*);
134     class TrivialFontRunIterator : public TrivialRunIterator<FontRunIterator> {
135     public:
TrivialFontRunIterator(const SkFont & font,size_t utf8Bytes)136         TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes)
137             : TrivialRunIterator(utf8Bytes), fFont(font) {}
currentFont()138         const SkFont& currentFont() const override { return fFont; }
139     private:
140         SkFont fFont;
141     };
142 
143 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
144     static std::unique_ptr<BiDiRunIterator>
145     MakeBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
146 #if defined(SK_SHAPER_UNICODE_AVAILABLE)
147     static std::unique_ptr<BiDiRunIterator>
148     MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel);
149 #endif  // defined(SK_SHAPER_UNICODE_AVAILABLE)
150 #endif  // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
151 
152     class TrivialBiDiRunIterator : public TrivialRunIterator<BiDiRunIterator> {
153     public:
TrivialBiDiRunIterator(uint8_t bidiLevel,size_t utf8Bytes)154         TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes)
155             : TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {}
currentLevel()156         uint8_t currentLevel() const override { return fBidiLevel; }
157     private:
158         uint8_t fBidiLevel;
159     };
160 
161 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
162     static std::unique_ptr<ScriptRunIterator>
163     MakeScriptRunIterator(const char* utf8, size_t utf8Bytes, SkFourByteTag script);
164 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE)
165     static std::unique_ptr<ScriptRunIterator>
166     MakeSkUnicodeHbScriptRunIterator(const char* utf8, size_t utf8Bytes);
167     static std::unique_ptr<ScriptRunIterator>
168     MakeSkUnicodeHbScriptRunIterator(const char* utf8, size_t utf8Bytes, SkFourByteTag script);
169     // Still used in some cases
170     static std::unique_ptr<ScriptRunIterator>
171     MakeHbIcuScriptRunIterator(const char* utf8, size_t utf8Bytes);
172 #endif  // defined(SK_SHAPER_HARFBUZZ_AVAILABLE)
173 #endif  // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
174 
175     class TrivialScriptRunIterator : public TrivialRunIterator<ScriptRunIterator> {
176     public:
TrivialScriptRunIterator(SkFourByteTag script,size_t utf8Bytes)177         TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes)
178             : TrivialRunIterator(utf8Bytes), fScript(script) {}
currentScript()179         SkFourByteTag currentScript() const override { return fScript; }
180     private:
181         SkFourByteTag fScript;
182     };
183 
184     static std::unique_ptr<LanguageRunIterator>
185     MakeStdLanguageRunIterator(const char* utf8, size_t utf8Bytes);
186     class TrivialLanguageRunIterator : public TrivialRunIterator<LanguageRunIterator> {
187     public:
TrivialLanguageRunIterator(const char * language,size_t utf8Bytes)188         TrivialLanguageRunIterator(const char* language, size_t utf8Bytes)
189             : TrivialRunIterator(utf8Bytes), fLanguage(language) {}
currentLanguage()190         const char* currentLanguage() const override { return fLanguage.c_str(); }
191     private:
192         SkString fLanguage;
193     };
194 
195     class RunHandler {
196     public:
197         virtual ~RunHandler() = default;
198 
199         struct Range {
RangeRange200             constexpr Range() : fBegin(0), fSize(0) {}
RangeRange201             constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {}
202             size_t fBegin;
203             size_t fSize;
beginRange204             constexpr size_t begin() const { return fBegin; }
endRange205             constexpr size_t end() const { return begin() + size(); }
sizeRange206             constexpr size_t size() const { return fSize; }
207         };
208 
209         struct RunInfo {
210             const SkFont& fFont;
211             uint8_t fBidiLevel;
212             SkVector fAdvance;
213             size_t glyphCount;
214             Range utf8Range;
215         };
216 
217         struct Buffer {
218             SkGlyphID* glyphs;  // required
219             SkPoint* positions; // required, if (!offsets) put glyphs[i] at positions[i]
220                                 //           if ( offsets) positions[i+1]-positions[i] are advances
221             SkPoint* offsets;   // optional, if ( offsets) put glyphs[i] at positions[i]+offsets[i]
222             uint32_t* clusters; // optional, utf8+clusters[i] starts run which produced glyphs[i]
223             SkPoint point;      // offset to add to all positions
224         };
225 
226         /** Called when beginning a line. */
227         virtual void beginLine() = 0;
228 
229         /** Called once for each run in a line. Can compute baselines and offsets. */
230         virtual void runInfo(const RunInfo&) = 0;
231 
232         /** Called after all runInfo calls for a line. */
233         virtual void commitRunInfo() = 0;
234 
235         /** Called for each run in a line after commitRunInfo. The buffer will be filled out. */
236         virtual Buffer runBuffer(const RunInfo&) = 0;
237 
238         /** Called after each runBuffer is filled out. */
239         virtual void commitRunBuffer(const RunInfo&) = 0;
240 
241         /** Called when ending a line. */
242         virtual void commitLine() = 0;
243     };
244 
245 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
246     virtual void shape(const char* utf8, size_t utf8Bytes,
247                        const SkFont& srcFont,
248                        bool leftToRight,
249                        SkScalar width,
250                        RunHandler*) const = 0;
251 
252     virtual void shape(const char* utf8, size_t utf8Bytes,
253                        FontRunIterator&,
254                        BiDiRunIterator&,
255                        ScriptRunIterator&,
256                        LanguageRunIterator&,
257                        SkScalar width,
258                        RunHandler*) const = 0;
259 #endif
260     virtual void shape(const char* utf8,
261                        size_t utf8Bytes,
262                        FontRunIterator&,
263                        BiDiRunIterator&,
264                        ScriptRunIterator&,
265                        LanguageRunIterator&,
266                        const Feature* features,
267                        size_t featuresSize,
268                        SkScalar width,
269                        RunHandler*) const = 0;
270 
271 private:
272     SkShaper(const SkShaper&) = delete;
273     SkShaper& operator=(const SkShaper&) = delete;
274 };
275 
276 /**
277  * Helper for shaping text directly into a SkTextBlob.
278  */
279 class SKSHAPER_API SkTextBlobBuilderRunHandler final : public SkShaper::RunHandler {
280 public:
SkTextBlobBuilderRunHandler(const char * utf8Text,SkPoint offset)281     SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset)
282         : fUtf8Text(utf8Text)
283         , fOffset(offset) {}
284     sk_sp<SkTextBlob> makeBlob();
endPoint()285     SkPoint endPoint() { return fOffset; }
286 
287     void beginLine() override;
288     void runInfo(const RunInfo&) override;
289     void commitRunInfo() override;
290     Buffer runBuffer(const RunInfo&) override;
291     void commitRunBuffer(const RunInfo&) override;
292     void commitLine() override;
293 
294 private:
295     SkTextBlobBuilder fBuilder;
296     char const * const fUtf8Text;
297     uint32_t* fClusters;
298     int fClusterOffset;
299     int fGlyphCount;
300     SkScalar fMaxRunAscent;
301     SkScalar fMaxRunDescent;
302     SkScalar fMaxRunLeading;
303     SkPoint fCurrentPosition;
304     SkPoint fOffset;
305 };
306 
307 namespace SkShapers::Primitive {
308 SKSHAPER_API std::unique_ptr<SkShaper> PrimitiveText();
309 
310 SKSHAPER_API std::unique_ptr<SkShaper::BiDiRunIterator> TrivialBiDiRunIterator
311                                               (size_t utf8Bytes,  uint8_t bidiLevel);
312 SKSHAPER_API std::unique_ptr<SkShaper::ScriptRunIterator> TrivialScriptRunIterator
313                                               (size_t utf8Bytes, SkFourByteTag scriptTag);
314 }  // namespace SkShapers
315 
316 #endif  // SkShaper_DEFINED
317