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 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, ""); TrivialRunIterator(size_t utf8Bytes)116 TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {} consume()117 void consume() override { SkASSERT(!fAtEnd); fAtEnd = true; } endOfCurrentRun()118 size_t endOfCurrentRun() const override { return fAtEnd ? fEnd : 0; } atEnd()119 bool atEnd() const override { return fAtEnd; } 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: TrivialFontRunIterator(const SkFont & font,size_t utf8Bytes)136 TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes) 137 : TrivialRunIterator(utf8Bytes), fFont(font) {} currentFont()138 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: TrivialBiDiRunIterator(uint8_t bidiLevel,size_t utf8Bytes)154 TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes) 155 : TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {} currentLevel()156 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: TrivialScriptRunIterator(SkFourByteTag script,size_t utf8Bytes)177 TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes) 178 : TrivialRunIterator(utf8Bytes), fScript(script) {} currentScript()179 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: TrivialLanguageRunIterator(const char * language,size_t utf8Bytes)188 TrivialLanguageRunIterator(const char* language, size_t utf8Bytes) 189 : TrivialRunIterator(utf8Bytes), fLanguage(language) {} currentLanguage()190 const char* currentLanguage() const override { return fLanguage.c_str(); } 191 private: 192 SkString fLanguage; 193 }; 194 195 class RunHandler { 196 public: 197 virtual ~RunHandler() = default; 198 199 struct Range { RangeRange200 constexpr Range() : fBegin(0), fSize(0) {} RangeRange201 constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {} 202 size_t fBegin; 203 size_t fSize; beginRange204 constexpr size_t begin() const { return fBegin; } endRange205 constexpr size_t end() const { return begin() + size(); } sizeRange206 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: SkTextBlobBuilderRunHandler(const char * utf8Text,SkPoint offset)281 SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset) 282 : fUtf8Text(utf8Text) 283 , fOffset(offset) {} 284 sk_sp<SkTextBlob> makeBlob(); endPoint()285 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 317