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