| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkShaper_DEFINED |
| #define SkShaper_DEFINED |
| |
| #include "include/core/SkPoint.h" |
| #include "include/core/SkRefCnt.h" |
| #include "include/core/SkScalar.h" |
| #include "include/core/SkTextBlob.h" |
| #include "include/core/SkTypes.h" |
| |
| #include <memory> |
| |
| class SkFont; |
| class SkFontMgr; |
| |
| /** |
| Shapes text using HarfBuzz and places the shaped text into a |
| client-managed buffer. |
| |
| If compiled without HarfBuzz, fall back on SkPaint::textToGlyphs. |
| */ |
| class SkShaper { |
| public: |
| static std::unique_ptr<SkShaper> MakePrimitive(); |
| #ifdef SK_SHAPER_HARFBUZZ_AVAILABLE |
| static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(); |
| static std::unique_ptr<SkShaper> MakeShapeThenWrap(); |
| #endif |
| |
| static std::unique_ptr<SkShaper> Make(); |
| |
| SkShaper(); |
| virtual ~SkShaper(); |
| |
| class RunIterator { |
| public: |
| virtual ~RunIterator() = default; |
| /** Set state to that of current run and move iterator to end of that run. */ |
| virtual void consume() = 0; |
| /** Offset to one past the last (utf8) element in the current run. */ |
| virtual size_t endOfCurrentRun() const = 0; |
| /** Return true if consume should no longer be called. */ |
| virtual bool atEnd() const = 0; |
| }; |
| |
| class FontRunIterator : public RunIterator { |
| public: |
| virtual const SkFont& currentFont() const = 0; |
| }; |
| static std::unique_ptr<FontRunIterator> |
| MakeFontMgrRunIterator(const char* utf8, size_t utf8Bytes, |
| const SkFont& font, sk_sp<SkFontMgr> fallback); |
| |
| class BiDiRunIterator : public RunIterator { |
| public: |
| /** The unicode bidi embedding level (even ltr, odd rtl) */ |
| virtual uint8_t currentLevel() const = 0; |
| }; |
| #ifdef SK_SHAPER_HARFBUZZ_AVAILABLE |
| static std::unique_ptr<SkShaper::BiDiRunIterator> |
| MakeIcuBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel); |
| #endif |
| |
| class ScriptRunIterator : public RunIterator { |
| public: |
| /** Should be iso15924 codes. */ |
| virtual SkFourByteTag currentScript() const = 0; |
| }; |
| #ifdef SK_SHAPER_HARFBUZZ_AVAILABLE |
| static std::unique_ptr<SkShaper::ScriptRunIterator> |
| MakeHbIcuScriptRunIterator(const char* utf8, size_t utf8Bytes); |
| #endif |
| |
| class LanguageRunIterator : public RunIterator { |
| public: |
| /** Should be BCP-47, c locale names may also work. */ |
| virtual const char* currentLanguage() const = 0; |
| }; |
| static std::unique_ptr<SkShaper::LanguageRunIterator> |
| MakeStdLanguageRunIterator(const char* utf8, size_t utf8Bytes); |
| |
| class RunHandler { |
| public: |
| virtual ~RunHandler() = default; |
| |
| struct Range { |
| constexpr Range() : fBegin(0), fSize(0) {} |
| constexpr Range(size_t begin, size_t size) : fBegin(begin), fSize(size) {} |
| size_t fBegin; |
| size_t fSize; |
| constexpr size_t begin() const { return fBegin; } |
| constexpr size_t end() const { return begin() + size(); } |
| constexpr size_t size() const { return fSize; } |
| }; |
| |
| struct RunInfo { |
| const SkFont& fFont; |
| uint8_t fBidiLevel; |
| SkVector fAdvance; |
| size_t glyphCount; |
| Range utf8Range; |
| }; |
| |
| struct Buffer { |
| SkGlyphID* glyphs; // required |
| SkPoint* positions; // required |
| SkPoint* offsets; // optional |
| uint32_t* clusters; // optional |
| SkPoint point; |
| }; |
| |
| /** Called when beginning a line. */ |
| virtual void beginLine() = 0; |
| |
| /** Called once for each run in a line. Can compute baselines and offsets. */ |
| virtual void runInfo(const RunInfo&) = 0; |
| |
| /** Called after all runInfo calls for a line. */ |
| virtual void commitRunInfo() = 0; |
| |
| /** Called for each run in a line after commitRunInfo. The buffer will be filled out. */ |
| virtual Buffer runBuffer(const RunInfo&) = 0; |
| |
| /** Called after each runBuffer is filled out. */ |
| virtual void commitRunBuffer(const RunInfo&) = 0; |
| |
| /** Called when ending a line. */ |
| virtual void commitLine() = 0; |
| }; |
| |
| virtual void shape(const char* utf8, size_t utf8Bytes, |
| const SkFont& srcFont, |
| bool leftToRight, |
| SkScalar width, |
| RunHandler*) const = 0; |
| |
| virtual void shape(const char* utf8, size_t utf8Bytes, |
| FontRunIterator&, |
| BiDiRunIterator&, |
| ScriptRunIterator&, |
| LanguageRunIterator&, |
| SkScalar width, |
| RunHandler*) const = 0; |
| |
| private: |
| SkShaper(const SkShaper&) = delete; |
| SkShaper& operator=(const SkShaper&) = delete; |
| }; |
| |
| /** |
| * Helper for shaping text directly into a SkTextBlob. |
| */ |
| class SkTextBlobBuilderRunHandler final : public SkShaper::RunHandler { |
| public: |
| SkTextBlobBuilderRunHandler(const char* utf8Text, SkPoint offset) |
| : fUtf8Text(utf8Text) |
| , fOffset(offset) {} |
| sk_sp<SkTextBlob> makeBlob(); |
| SkPoint endPoint() { return fOffset; } |
| |
| void beginLine() override; |
| void runInfo(const RunInfo&) override; |
| void commitRunInfo() override; |
| Buffer runBuffer(const RunInfo&) override; |
| void commitRunBuffer(const RunInfo&) override; |
| void commitLine() override; |
| |
| private: |
| SkTextBlobBuilder fBuilder; |
| char const * const fUtf8Text; |
| uint32_t* fClusters; |
| int fClusterOffset; |
| int fGlyphCount; |
| SkScalar fMaxRunAscent; |
| SkScalar fMaxRunDescent; |
| SkScalar fMaxRunLeading; |
| SkPoint fCurrentPosition; |
| SkPoint fOffset; |
| }; |
| |
| #endif // SkShaper_DEFINED |