Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 1 | // Copyright 2019 Google LLC. |
| 2 | #include "modules/skparagraph/src/FontIterator.h" |
| 3 | #include <unicode/brkiter.h> |
| 4 | #include <unicode/ubidi.h> |
| 5 | #include "include/core/SkBlurTypes.h" |
| 6 | #include "include/core/SkCanvas.h" |
| 7 | #include "include/core/SkFontMgr.h" |
| 8 | #include "include/core/SkPictureRecorder.h" |
| 9 | #include "modules/skparagraph/src/ParagraphImpl.h" |
| 10 | #include "src/core/SkSpan.h" |
| 11 | #include "src/utils/SkUTF.h" |
| 12 | |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 13 | // TODO: FontCollection and FontIterator have common functionality |
| 14 | namespace skia { |
| 15 | namespace textlayout { |
| 16 | |
| 17 | FontIterator::FontIterator(SkSpan<const char> utf8, |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 18 | SkSpan<TextBlock> styles, |
| 19 | sk_sp<FontCollection> fonts) |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 20 | : fText(utf8) |
| 21 | , fStyles(styles) |
| 22 | , fCurrentChar(utf8.begin()) |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 23 | , fFontResolver(std::move(fonts)) { |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 24 | findAllFontsForAllStyledBlocks(); |
| 25 | } |
| 26 | |
| 27 | void FontIterator::consume() { |
| 28 | SkASSERT(fCurrentChar < fText.end()); |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 29 | auto found = fFontResolver.findFirst(fCurrentChar, &fFont, &fLineHeight); |
| 30 | SkASSERT(found); |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 31 | |
| 32 | // Move until we find the first character that cannot be resolved with the current font |
| 33 | while (++fCurrentChar != fText.end()) { |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 34 | SkFont font; |
| 35 | SkScalar height; |
| 36 | found = fFontResolver.findNext(fCurrentChar, &font, &height); |
| 37 | if (found) { |
| 38 | if (fFont == font && fLineHeight == height) { |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 39 | continue; |
| 40 | } |
| 41 | break; |
| 42 | } |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | void FontIterator::findAllFontsForAllStyledBlocks() { |
| 47 | TextBlock combined; |
| 48 | for (auto& block : fStyles) { |
| 49 | SkASSERT(combined.text().begin() == nullptr || |
| 50 | combined.text().end() == block.text().begin()); |
| 51 | |
| 52 | if (combined.text().begin() != nullptr && |
| 53 | block.style().matchOneAttribute(StyleType::kFont, combined.style())) { |
| 54 | combined.add(block.text()); |
| 55 | continue; |
| 56 | } |
| 57 | |
| 58 | if (!combined.text().empty()) { |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 59 | fFontResolver.findAllFontsForStyledBlock(combined.style(), combined.text()); |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | combined = block; |
| 63 | } |
Julia Lavrova | 6e6333f | 2019-06-17 10:34:10 -0400 | [diff] [blame^] | 64 | fFontResolver.findAllFontsForStyledBlock(combined.style(), combined.text()); |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 65 | } |
| 66 | |
Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 67 | } // namespace textlayout |
| 68 | } // namespace skia |