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 #ifdef ENABLE_DRAWING_ADAPTER 34 #include "modules/skparagraph/include/drawing.h" 35 #endif 36 37 #if !defined(SKSHAPER_IMPLEMENTATION) 38 #define SKSHAPER_IMPLEMENTATION 0 39 #endif 40 41 #if !defined(SKSHAPER_API) 42 #if defined(SKSHAPER_DLL) 43 #if defined(_MSC_VER) 44 #if SKSHAPER_IMPLEMENTATION 45 #define SKSHAPER_API __declspec(dllexport) 46 #else 47 #define SKSHAPER_API __declspec(dllimport) 48 #endif 49 #else 50 #define SKSHAPER_API __attribute__((visibility("default"))) 51 #endif 52 #else 53 #define SKSHAPER_API 54 #endif 55 #endif 56 #ifdef ENABLE_DRAWING_ADAPTER 57 namespace SkiaRsText { 58 #endif 59 class SKSHAPER_API SkShaper { 60 public: 61 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 62 static std::unique_ptr<SkShaper> MakePrimitive(); 63 64 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) 65 #ifdef ENABLE_DRAWING_ADAPTER 66 static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(std::shared_ptr<RSFontMgr> = nullptr); 67 static std::unique_ptr<SkShaper> MakeShapeThenWrap(std::shared_ptr<RSFontMgr> = nullptr); 68 #else 69 static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(sk_sp<SkFontMgr> fallback); 70 static std::unique_ptr<SkShaper> MakeShapeThenWrap(sk_sp<SkFontMgr> fallback); 71 #endif 72 static void PurgeHarfBuzzCache(); 73 #endif 74 75 #if defined(SK_SHAPER_CORETEXT_AVAILABLE) 76 static std::unique_ptr<SkShaper> MakeCoreText(); 77 #endif 78 79 #ifdef ENABLE_DRAWING_ADAPTER 80 static std::unique_ptr<SkShaper> Make(std::shared_ptr<RSFontMgr> = nullptr); 81 #else 82 static std::unique_ptr<SkShaper> Make(sk_sp<SkFontMgr> fallback = nullptr); 83 #endif 84 static void PurgeCaches(); 85 #endif // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 86 87 SkShaper(); 88 virtual ~SkShaper(); 89 90 class RunIterator { 91 public: 92 virtual ~RunIterator() = default; 93 /** Set state to that of current run and move iterator to end of that run. */ 94 virtual void consume() = 0; 95 /** Offset to one past the last (utf8) element in the current run. */ 96 virtual size_t endOfCurrentRun() const = 0; 97 /** Return true if consume should no longer be called. */ 98 virtual bool atEnd() const = 0; 99 }; 100 class FontRunIterator : public RunIterator { 101 public: 102 #ifdef ENABLE_DRAWING_ADAPTER 103 virtual const RSFont& currentFont() const = 0; 104 #else 105 virtual const SkFont& currentFont() const = 0; 106 #endif 107 }; 108 class BiDiRunIterator : public RunIterator { 109 public: 110 /** The unicode bidi embedding level (even ltr, odd rtl) */ 111 virtual uint8_t currentLevel() const = 0; 112 }; 113 class ScriptRunIterator : public RunIterator { 114 public: 115 /** Should be iso15924 codes. */ 116 virtual SkFourByteTag currentScript() const = 0; 117 }; 118 class LanguageRunIterator : public RunIterator { 119 public: 120 /** Should be BCP-47, c locale names may also work. */ 121 virtual const char* currentLanguage() const = 0; 122 }; 123 struct Feature { 124 SkFourByteTag tag; 125 uint32_t value; 126 size_t start; // Offset to the start (utf8) element of the run. 127 size_t end; // Offset to one past the last (utf8) element of the run. 128 }; 129 130 private: 131 template <typename RunIteratorSubclass> 132 class TrivialRunIterator : public RunIteratorSubclass { 133 public: 134 static_assert(std::is_base_of<RunIterator, RunIteratorSubclass>::value, ""); TrivialRunIterator(size_t utf8Bytes)135 TrivialRunIterator(size_t utf8Bytes) : fEnd(utf8Bytes), fAtEnd(fEnd == 0) {} consume()136 void consume() override { SkASSERT(!fAtEnd); fAtEnd = true; } endOfCurrentRun()137 size_t endOfCurrentRun() const override { return fAtEnd ? fEnd : 0; } atEnd()138 bool atEnd() const override { return fAtEnd; } 139 private: 140 size_t fEnd; 141 bool fAtEnd; 142 }; 143 144 public: 145 #ifdef ENABLE_DRAWING_ADAPTER 146 static std::unique_ptr<FontRunIterator> 147 MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes, 148 const RSFont& font, std::shared_ptr<RSFontMgr> fallback); 149 static std::unique_ptr<SkShaper::FontRunIterator> 150 MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes, 151 const RSFont& font, std::shared_ptr<RSFontMgr> fallback, 152 const char* requestName, RSFontStyle requestStyle, 153 const SkShaper::LanguageRunIterator*); 154 class TrivialFontRunIterator : public TrivialRunIterator<FontRunIterator> { 155 public: TrivialFontRunIterator(const RSFont & font,size_t utf8Bytes)156 TrivialFontRunIterator(const RSFont& font, size_t utf8Bytes) 157 : TrivialRunIterator(utf8Bytes), fFont(font) {} currentFont()158 const RSFont& currentFont() const override { return fFont; } 159 private: 160 RSFont fFont; 161 }; 162 #else 163 static std::unique_ptr<FontRunIterator> 164 MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes, 165 const SkFont& font, sk_sp<SkFontMgr> fallback); 166 static std::unique_ptr<SkShaper::FontRunIterator> 167 MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes, 168 const SkFont& font, sk_sp<SkFontMgr> fallback, 169 const char* requestName, SkFontStyle requestStyle, 170 const SkShaper::LanguageRunIterator*); 171 class TrivialFontRunIterator : public TrivialRunIterator<FontRunIterator> { 172 public: 173 TrivialFontRunIterator(const SkFont& font, size_t utf8Bytes) 174 : TrivialRunIterator(utf8Bytes), fFont(font) {} 175 const SkFont& currentFont() const override { return fFont; } 176 private: 177 SkFont fFont; 178 }; 179 #endif 180 181 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 182 static std::unique_ptr<BiDiRunIterator> 183 MakeBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel); 184 #if defined(SK_SHAPER_UNICODE_AVAILABLE) 185 static std::unique_ptr<BiDiRunIterator> 186 MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel); 187 #endif // defined(SK_SHAPER_UNICODE_AVAILABLE) 188 #endif // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 189 190 class TrivialBiDiRunIterator : public TrivialRunIterator<BiDiRunIterator> { 191 public: TrivialBiDiRunIterator(uint8_t bidiLevel,size_t utf8Bytes)192 TrivialBiDiRunIterator(uint8_t bidiLevel, size_t utf8Bytes) 193 : TrivialRunIterator(utf8Bytes), fBidiLevel(bidiLevel) {} currentLevel()194 uint8_t currentLevel() const override { return fBidiLevel; } 195 private: 196 uint8_t fBidiLevel; 197 }; 198 199 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 200 static std::unique_ptr<ScriptRunIterator> 201 MakeScriptRunIterator(const char* utf8, size_t utf8Bytes, SkFourByteTag script); 202 #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) 203 static std::unique_ptr<ScriptRunIterator> 204 MakeSkUnicodeHbScriptRunIterator(const char* utf8, size_t utf8Bytes); 205 static std::unique_ptr<ScriptRunIterator> 206 MakeSkUnicodeHbScriptRunIterator(const char* utf8, size_t utf8Bytes, SkFourByteTag script); 207 // Still used in some cases 208 static std::unique_ptr<ScriptRunIterator> 209 MakeHbIcuScriptRunIterator(const char* utf8, size_t utf8Bytes); 210 #endif // defined(SK_SHAPER_HARFBUZZ_AVAILABLE) 211 #endif // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 212 213 class TrivialScriptRunIterator : public TrivialRunIterator<ScriptRunIterator> { 214 public: TrivialScriptRunIterator(SkFourByteTag script,size_t utf8Bytes)215 TrivialScriptRunIterator(SkFourByteTag script, size_t utf8Bytes) 216 : TrivialRunIterator(utf8Bytes), fScript(script) {} currentScript()217 SkFourByteTag currentScript() const override { return fScript; } 218 private: 219 SkFourByteTag fScript; 220 }; 221 222 static std::unique_ptr<LanguageRunIterator> 223 MakeStdLanguageRunIterator(const char* utf8, size_t utf8Bytes); 224 class TrivialLanguageRunIterator : public TrivialRunIterator<LanguageRunIterator> { 225 public: TrivialLanguageRunIterator(const char * language,size_t utf8Bytes)226 TrivialLanguageRunIterator(const char* language, size_t utf8Bytes) 227 : TrivialRunIterator(utf8Bytes), fLanguage(language) {} currentLanguage()228 const char* currentLanguage() const override { return fLanguage.c_str(); } 229 private: 230 SkString fLanguage; 231 }; 232 233 class RunHandler { 234 public: 235 virtual ~RunHandler() = default; 236 237 struct Range { RangeRange238 constexpr Range() : fBegin(0), fSize(0) {} RangeRange239 constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {} 240 size_t fBegin; 241 size_t fSize; beginRange242 constexpr size_t begin() const { return fBegin; } endRange243 constexpr size_t end() const { return begin() + size(); } sizeRange244 constexpr size_t size() const { return fSize; } 245 }; 246 247 struct RunInfo { 248 #ifdef ENABLE_DRAWING_ADAPTER 249 const RSFont& fFont; 250 #else 251 const SkFont& fFont; 252 #endif 253 uint8_t fBidiLevel; 254 SkVector fAdvance; 255 size_t glyphCount; 256 Range utf8Range; 257 }; 258 259 struct Buffer { 260 SkGlyphID* glyphs; // required 261 SkPoint* positions; // required, if (!offsets) put glyphs[i] at positions[i] 262 // if ( offsets) positions[i+1]-positions[i] are advances 263 SkPoint* offsets; // optional, if ( offsets) put glyphs[i] at positions[i]+offsets[i] 264 uint32_t* clusters; // optional, utf8+clusters[i] starts run which produced glyphs[i] 265 SkPoint point; // offset to add to all positions 266 #ifdef ENABLE_TEXT_ENHANCE 267 SkPoint* advances; 268 #endif 269 }; 270 271 /** Called when beginning a line. */ 272 virtual void beginLine() = 0; 273 274 /** Called once for each run in a line. Can compute baselines and offsets. */ 275 virtual void runInfo(const RunInfo&) = 0; 276 277 /** Called after all runInfo calls for a line. */ 278 virtual void commitRunInfo() = 0; 279 280 /** Called for each run in a line after commitRunInfo. The buffer will be filled out. */ 281 virtual Buffer runBuffer(const RunInfo&) = 0; 282 283 /** Called after each runBuffer is filled out. */ 284 virtual void commitRunBuffer(const RunInfo&) = 0; 285 286 /** Called when ending a line. */ 287 virtual void commitLine() = 0; 288 }; 289 290 #if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS) 291 virtual void shape(const char* utf8, size_t utf8Bytes, 292 #ifdef ENABLE_DRAWING_ADAPTER 293 const RSFont& srcFont, 294 #else 295 const SkFont& srcFont, 296 #endif 297 bool leftToRight, 298 SkScalar width, 299 RunHandler*) const = 0; 300 301 virtual void shape(const char* utf8, size_t utf8Bytes, 302 FontRunIterator&, 303 BiDiRunIterator&, 304 ScriptRunIterator&, 305 LanguageRunIterator&, 306 SkScalar width, 307 RunHandler*) const = 0; 308 #endif 309 virtual void shape(const char* utf8, 310 size_t utf8Bytes, 311 FontRunIterator&, 312 BiDiRunIterator&, 313 ScriptRunIterator&, 314 LanguageRunIterator&, 315 const Feature* features, 316 size_t featuresSize, 317 SkScalar width, 318 RunHandler*) const = 0; 319 320 private: 321 SkShaper(const SkShaper&) = delete; 322 SkShaper& operator=(const SkShaper&) = delete; 323 }; 324 325 #ifndef ENABLE_DRAWING_ADAPTER 326 /** 327 * Helper for shaping text directly into a SkTextBlob. 328 */ 329 class SKSHAPER_API SkTextBlobBuilderRunHandler final : public SkShaper::RunHandler { 330 public: SkTextBlobBuilderRunHandler(const char * utf8Text,SkPoint offset)331 SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset) 332 : fUtf8Text(utf8Text) 333 , fOffset(offset) {} 334 sk_sp<SkTextBlob> makeBlob(); endPoint()335 SkPoint endPoint() { return fOffset; } 336 337 void beginLine() override; 338 void runInfo(const RunInfo&) override; 339 void commitRunInfo() override; 340 Buffer runBuffer(const RunInfo&) override; 341 void commitRunBuffer(const RunInfo&) override; 342 void commitLine() override; 343 344 private: 345 SkTextBlobBuilder fBuilder; 346 char const * const fUtf8Text; 347 uint32_t* fClusters; 348 int fClusterOffset; 349 int fGlyphCount; 350 SkScalar fMaxRunAscent; 351 SkScalar fMaxRunDescent; 352 SkScalar fMaxRunLeading; 353 SkPoint fCurrentPosition; 354 SkPoint fOffset; 355 }; 356 #endif 357 358 namespace SkShapers::Primitive { 359 SKSHAPER_API std::unique_ptr<SkShaper> PrimitiveText(); 360 361 SKSHAPER_API std::unique_ptr<SkShaper::BiDiRunIterator> TrivialBiDiRunIterator 362 (size_t utf8Bytes, uint8_t bidiLevel); 363 SKSHAPER_API std::unique_ptr<SkShaper::ScriptRunIterator> TrivialScriptRunIterator 364 (size_t utf8Bytes, SkFourByteTag scriptTag); 365 } // namespace SkShapers 366 #ifdef ENABLE_DRAWING_ADAPTER 367 } 368 using SkShaper = SkiaRsText::SkShaper; 369 // namespace SkShapers::Primitive = SkiaRsText::SkShapers::Primitive; 370 namespace SkShapers::Primitive{ 371 using namespace SkiaRsText::SkShapers::Primitive;; 372 } 373 #endif 374 #endif // SkShaper_DEFINED 375