• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC.
2 #ifndef FontIterator_DEFINED
3 #define FontIterator_DEFINED
4 
5 #include <unicode/brkiter.h>
6 #include <unicode/ubidi.h>
7 #include "include/core/SkBlurTypes.h"
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkFontMgr.h"
10 #include "include/core/SkPictureRecorder.h"
11 #include "modules/skparagraph/src/FontResolver.h"
12 #include "modules/skparagraph/src/ParagraphImpl.h"
13 #include "src/core/SkSpan.h"
14 #include "src/utils/SkUTF.h"
15 
16 namespace skia {
17 namespace textlayout {
18 
19 class FontIterator final : public SkShaper::FontRunIterator {
20 public:
FontIterator(SkSpan<const char> utf8,FontResolver * fontResolver)21     FontIterator(SkSpan<const char> utf8, FontResolver* fontResolver)
22         : fText(utf8), fCurrentChar(utf8.begin()), fFontResolver(fontResolver) {
23     }
24 
consume()25     void consume() override {
26         SkASSERT(fCurrentChar < fText.end());
27         auto found = fFontResolver->findNext(fCurrentChar, &fFont, &fLineHeight);
28         SkASSERT(found);
29         if (!found) {
30             fCurrentChar = fText.end();
31             return;
32         }
33         // Move until we find the first character that cannot be resolved with the current font
34         while (++fCurrentChar != fText.end()) {
35             SkFont font;
36             SkScalar height;
37             if (fFontResolver->findNext(fCurrentChar, &font, &height)) {
38                   if (fFont == font && fLineHeight == height) {
39                       continue;
40                   }
41               break;
42             }
43         }
44     }
45 
endOfCurrentRun()46     size_t endOfCurrentRun() const override { return fCurrentChar - fText.begin(); }
atEnd()47     bool atEnd() const override { return fCurrentChar == fText.end(); }
currentFont()48     const SkFont& currentFont() const override { return fFont; }
currentLineHeight()49     SkScalar currentLineHeight() const { return fLineHeight; }
50 
51 private:
52 
53     SkSpan<const char> fText;
54     const char* fCurrentChar;
55     SkFont fFont;
56     SkScalar fLineHeight;
57     FontResolver* fFontResolver;
58 };
59 
60 class LangIterator final : public SkShaper::LanguageRunIterator {
61 public:
LangIterator(SkSpan<const char> utf8,SkSpan<Block> styles,const TextStyle & defaultStyle)62     LangIterator(SkSpan<const char> utf8, SkSpan<Block> styles, const TextStyle& defaultStyle)
63             : fText(utf8)
64             , fTextStyles(styles)
65             , fCurrentChar(utf8.begin())
66             , fCurrentStyle(fTextStyles.begin())
67             , fCurrentLocale(defaultStyle.getLocale()) {}
68 
consume()69     void consume() override {
70         SkASSERT(fCurrentChar < fText.end());
71 
72         if (fCurrentStyle == fTextStyles.end()) {
73             fCurrentChar = fText.end();
74             return;
75         }
76 
77         fCurrentChar = fText.begin() + fCurrentStyle->fRange.end;
78         fCurrentLocale = fCurrentStyle->fStyle.getLocale();
79         while (++fCurrentStyle != fTextStyles.end()) {
80             if (fCurrentStyle->fStyle.getLocale() != fCurrentLocale) {
81                 break;
82             }
83             fCurrentChar = fText.begin() + fCurrentStyle->fRange.end;
84         }
85     }
86 
endOfCurrentRun()87     size_t endOfCurrentRun() const override { return fCurrentChar - fText.begin(); }
atEnd()88     bool atEnd() const override { return fCurrentChar == fText.end(); }
currentLanguage()89     const char* currentLanguage() const override { return fCurrentLocale.c_str(); }
90 
91 private:
92     SkSpan<const char> fText;
93     SkSpan<Block> fTextStyles;
94     const char* fCurrentChar;
95     Block* fCurrentStyle;
96     SkString fCurrentLocale;
97 };
98 }  // namespace textlayout
99 }  // namespace skia
100 
101 #endif  // FontIterator_DEFINED
102