1 /*
2 * Copyright 2024 Google LLC
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 #ifndef SkShaperFactoryHelpers_DEFINED
8 #define SkShaperFactoryHelpers_DEFINED
9
10 #include "modules/skshaper/include/SkShaper.h"
11 #include "modules/skshaper/include/SkShaper_factory.h"
12
13 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
14 #include "modules/skshaper/include/SkShaper_harfbuzz.h"
15 #include "modules/skshaper/include/SkShaper_skunicode.h"
16 #include "modules/skunicode/include/SkUnicode.h"
17 #endif
18
19 #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
20 #include "modules/skshaper/include/SkShaper_coretext.h"
21 #endif
22
23 #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
24 #include "modules/skunicode/include/SkUnicode_icu.h"
25 #endif
26
27 #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
28 #include "modules/skunicode/include/SkUnicode_libgrapheme.h"
29 #endif
30
31 #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
32 #include "modules/skunicode/include/SkUnicode_icu4x.h"
33 #endif
34
35 namespace SkShapers {
36 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
37 class HarfbuzzFactory final : public Factory {
38 public:
HarfbuzzFactory()39 HarfbuzzFactory() {
40 #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
41 fUnicode = SkUnicodes::ICU::Make();
42 #endif
43 #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
44 if (!fUnicode) {
45 fUnicode = SkUnicodes::ICU4X::Make();
46 }
47 #endif
48 #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
49 if (!fUnicode) {
50 fUnicode = SkUnicodes::Libgrapheme::Make();
51 }
52 #endif
53 }
makeShaper(sk_sp<SkFontMgr> fallback)54 std::unique_ptr<SkShaper> makeShaper(sk_sp<SkFontMgr> fallback) override {
55 return SkShapers::HB::ShaperDrivenWrapper(fUnicode, fallback);
56 }
57
makeBidiRunIterator(const char * utf8,size_t utf8Bytes,uint8_t bidiLevel)58 std::unique_ptr<SkShaper::BiDiRunIterator> makeBidiRunIterator(const char* utf8,
59 size_t utf8Bytes,
60 uint8_t bidiLevel) override {
61 return SkShapers::unicode::BidiRunIterator(fUnicode, utf8, utf8Bytes, bidiLevel);
62 }
63
makeScriptRunIterator(const char * utf8,size_t utf8Bytes,SkFourByteTag script)64 std::unique_ptr<SkShaper::ScriptRunIterator> makeScriptRunIterator(const char* utf8,
65 size_t utf8Bytes,
66 SkFourByteTag script) override {
67 return SkShapers::HB::ScriptRunIterator(utf8, utf8Bytes, script);
68 }
69
getUnicode()70 SkUnicode* getUnicode() override { return fUnicode.get(); }
71
72 private:
73 sk_sp<SkUnicode> fUnicode;
74 };
75 #endif // defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
76
77 #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
78 class CoreTextFactory final : public Factory {
makeShaper(sk_sp<SkFontMgr>)79 std::unique_ptr<SkShaper> makeShaper(sk_sp<SkFontMgr>) override {
80 return SkShapers::CT::CoreText();
81 }
makeBidiRunIterator(const char * utf8,size_t utf8Bytes,uint8_t bidiLevel)82 std::unique_ptr<SkShaper::BiDiRunIterator> makeBidiRunIterator(const char* utf8,
83 size_t utf8Bytes,
84 uint8_t bidiLevel) override {
85 return std::make_unique<SkShaper::TrivialBiDiRunIterator>(0, 0);
86 }
makeScriptRunIterator(const char * utf8,size_t utf8Bytes,SkFourByteTag script)87 std::unique_ptr<SkShaper::ScriptRunIterator> makeScriptRunIterator(const char* utf8,
88 size_t utf8Bytes,
89 SkFourByteTag script) override {
90 return std::make_unique<SkShaper::TrivialScriptRunIterator>(0, 0);
91 }
getUnicode()92 SkUnicode* getUnicode() override { return nullptr; }
93 };
94 #endif // defined(SK_SHAPER_CORETEXT_AVAILABLE)
95
96 // This convenience function will return a set of callbacks that has the "best" text shaping
97 // depending on what parts of Skia the client has compiled in. For example, if the clients
98 // have compiled in SkShaper and a version of SkUnicode, callbacks which produce the
99 // appropriate types will be returned.
100 //
101 // This must be inline (and defined in this header) because the *client* has to compile this code
102 // with all defines set by *their* dependencies (which may include defines from SkShaper and
103 // SkUnicode modules).
BestAvailable()104 inline sk_sp<Factory> BestAvailable() {
105 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
106 return sk_make_sp<SkShapers::HarfbuzzFactory>();
107 #elif defined(SK_SHAPER_CORETEXT_AVAILABLE)
108 return sk_make_sp<SkShapers::CoreTextFactory>();
109 #else
110 return SkShapers::Primitive::Factory();
111 #endif
112 }
113
114 }; // namespace SkShapers
115
116 #endif // SkShaperFactoryHelpers_DEFINED
117