Coverage Report

Created: 2024-09-14 07:19

/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/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
1.50k
        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, "");
116
1.12k
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
116
376
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
116
376
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::TrivialRunIterator(unsigned long)
Line
Count
Source
116
376
        TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {}
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::FontRunIterator>::TrivialRunIterator(unsigned long)
117
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::FontRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::BiDiRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::ScriptRunIterator>::consume()
Unexecuted instantiation: SkShaper::TrivialRunIterator<SkShaper::LanguageRunIterator>::consume()
118
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
119
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
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:
136
        TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes)
137
0
            : TrivialRunIterator(utf8Bytes), fFont(font) {}
138
0
        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:
154
        TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes)
155
376
            : TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {}
156
0
        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:
177
        TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes)
178
376
            : TrivialRunIterator(utf8Bytes), fScript(script) {}
179
0
        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:
188
        TrivialLanguageRunIterator(const char* language, size_t utf8Bytes)
189
376
            : TrivialRunIterator(utf8Bytes), fLanguage(language) {}
190
0
        const char* currentLanguage() const override { return fLanguage.c_str(); }
191
    private:
192
        SkString fLanguage;
193
    };
194
195
    class RunHandler {
196
    public:
197
3.22k
        virtual ~RunHandler() = default;
198
199
        struct Range {
200
0
            constexpr Range() : fBegin(0), fSize(0) {}
201
376
            constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {}
202
            size_t fBegin;
203
            size_t fSize;
204
0
            constexpr size_t begin() const { return fBegin; }
205
0
            constexpr size_t end() const { return begin() + size(); }
206
0
            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:
281
    SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset)
282
        : fUtf8Text(utf8Text)
283
0
        , fOffset(offset) {}
284
    sk_sp<SkTextBlob> makeBlob();
285
0
    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