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