Coverage Report

Created: 2024-05-20 07:14

/src/skia/modules/skshaper/include/SkShaper.h
Line
Count
Source (jump to first uncovered line)
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
980
        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, "");
115
735
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
115
245
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
115
245
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
115
245
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::TrivialRunIterator(unsigned long)
116
0
        void consume() override { SkASSERT(!fAtEnd); fAtEnd = true; }
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::consume()
117
0
        size_t endOfCurrentRun() const override { return fAtEnd ? fEnd : 0; }
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::endOfCurrentRun() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::endOfCurrentRun() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::endOfCurrentRun() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::endOfCurrentRun() const
118
0
        bool atEnd() const override { return fAtEnd; }
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::atEnd() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::atEnd() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::atEnd() const
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::atEnd() const
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:
135
        TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes)
136
0
            : TrivialRunIterator(utf8Bytes), fFont(font) {}
137
0
        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:
153
        TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes)
154
245
            : TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {}
155
0
        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:
176
        TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes)
177
245
            : TrivialRunIterator(utf8Bytes), fScript(script) {}
178
0
        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:
187
        TrivialLanguageRunIterator(const char* language, size_t utf8Bytes)
188
245
            : TrivialRunIterator(utf8Bytes), fLanguage(language) {}
189
0
        const char* currentLanguage() const override { return fLanguage.c_str(); }
190
    private:
191
        SkString fLanguage;
192
    };
193
194
    class RunHandler {
195
    public:
196
106
        virtual ~RunHandler() = default;
197
198
        struct Range {
199
0
            constexpr Range() : fBegin(0), fSize(0) {}
200
245
            constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {}
201
            size_t fBegin;
202
            size_t fSize;
203
0
            constexpr size_t begin() const { return fBegin; }
204
0
            constexpr size_t end() const { return begin() + size(); }
205
0
            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:
280
    SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset)
281
        : fUtf8Text(utf8Text)
282
0
        , fOffset(offset) {}
283
    sk_sp<SkTextBlob> makeBlob();
284
0
    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