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