| // Copyright 2019 Google LLC | |
| #ifndef FontIterator_DEFINED | |
| #define FontIterator_DEFINED | |
| #include "include/core/SkSpan.h" | |
| #include "include/core/SkString.h" | |
| #include "include/core/SkTypes.h" | |
| #include "modules/skparagraph/include/TextStyle.h" | |
| #include "modules/skshaper/include/SkShaper.h" | |
| namespace skia { | |
| namespace textlayout { | |
| class LangIterator final : public SkShaper::LanguageRunIterator { | |
| public: | |
| LangIterator(SkSpan<const char> utf8, SkSpan<Block> styles, const TextStyle& defaultStyle) | |
| : fText(utf8) | |
| , fTextStyles(styles) | |
| , fCurrentChar(utf8.data()) | |
| , fCurrentStyle(fTextStyles.data()) | |
| , fCurrentLocale(defaultStyle.getLocale()) {} | |
| void consume() override { | |
| const char* textEnd = fText.data() + fText.size(); | |
| const Block* stylesEnd = fTextStyles.data() + fTextStyles.size(); | |
| SkASSERT(fCurrentChar < textEnd); | |
| if (fCurrentStyle == stylesEnd) { | |
| fCurrentChar = textEnd; | |
| return; | |
| } | |
| fCurrentChar = fText.data() + fCurrentStyle->fRange.end; | |
| fCurrentLocale = fCurrentStyle->fStyle.getLocale(); | |
| while (++fCurrentStyle != stylesEnd && !fCurrentStyle->fStyle.isPlaceholder()) { | |
| if (fCurrentStyle->fStyle.getLocale() != fCurrentLocale) { | |
| break; | |
| } | |
| fCurrentChar = fText.data() + fCurrentStyle->fRange.end; | |
| } | |
| } | |
| size_t endOfCurrentRun() const override { return fCurrentChar - fText.data(); } | |
| bool atEnd() const override { return fCurrentChar >= fText.data() + fText.size(); } | |
| const char* currentLanguage() const override { return fCurrentLocale.c_str(); } | |
| private: | |
| SkSpan<const char> fText; | |
| SkSpan<Block> fTextStyles; | |
| const char* fCurrentChar; | |
| Block* fCurrentStyle; | |
| SkString fCurrentLocale; | |
| }; | |
| } // namespace textlayout | |
| } // namespace skia | |
| #endif // FontIterator_DEFINED |