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