• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC.
2 #ifndef LineBreaker_DEFINED
3 #define LineBreaker_DEFINED
4 
5 #include <functional>  // std::function
6 #include <queue>
7 #include "include/core/SkSpan.h"
8 #include "modules/skparagraph/include/TextStyle.h"
9 #include "modules/skparagraph/src/ParagraphImpl.h"
10 #include "modules/skparagraph/src/Run.h"
11 
12 namespace skia {
13 namespace textlayout {
14 
15 class ParagraphImpl;
16 class OneLineShaper : public SkShaper::RunHandler {
17 public:
OneLineShaper(ParagraphImpl * paragraph)18     explicit OneLineShaper(ParagraphImpl* paragraph)
19         : fParagraph(paragraph)
20         , fHeight(0.0f)
21         , fUseHalfLeading(false)
22         , fAdvance(SkPoint::Make(0.0f, 0.0f))
23         , fUnresolvedGlyphs(0)
24         , fUniqueRunId(paragraph->fRuns.size()){ }
25 
26     bool shape();
27 
unresolvedGlyphs()28     size_t unresolvedGlyphs() { return fUnresolvedGlyphs; }
29 
30 private:
31 
32     struct RunBlock {
RunBlockRunBlock33         RunBlock() : fRun(nullptr) { }
34 
35         // First unresolved block
RunBlockRunBlock36         explicit RunBlock(TextRange text) : fRun(nullptr), fText(text) { }
37 
RunBlockRunBlock38         RunBlock(std::shared_ptr<Run> run, TextRange text, GlyphRange glyphs, size_t score)
39             : fRun(std::move(run))
40             , fText(text)
41             , fGlyphs(glyphs) { }
42 
43         // Entire run comes as one block fully resolved
RunBlockRunBlock44         explicit RunBlock(std::shared_ptr<Run> run)
45             : fRun(std::move(run))
46             , fText(fRun->fTextRange)
47             , fGlyphs(GlyphRange(0, fRun->size())) { }
48 
49         std::shared_ptr<Run> fRun;
50         TextRange fText;
51         GlyphRange fGlyphs;
isFullyResolvedRunBlock52         bool isFullyResolved() { return fRun != nullptr && fGlyphs.width() == fRun->size(); }
53     };
54 
55     using ShapeVisitor =
56             std::function<SkScalar(TextRange textRange, SkSpan<Block>, SkScalar&, TextIndex, uint8_t)>;
57     bool iterateThroughShapingRegions(const ShapeVisitor& shape);
58 
59     using ShapeSingleFontVisitor = std::function<void(Block, SkTArray<SkShaper::Feature>)>;
60     void iterateThroughFontStyles(TextRange textRange, SkSpan<Block> styleSpan, const ShapeSingleFontVisitor& visitor);
61 
62     enum Resolved {
63         Nothing,
64         Something,
65         Everything
66     };
67 
68     using TypefaceVisitor = std::function<Resolved(sk_sp<SkTypeface> typeface)>;
69     void matchResolvedFonts(const TextStyle& textStyle, const TypefaceVisitor& visitor);
70 #ifdef SK_DEBUG
71     void printState();
72 #endif
73     void finish(const Block& block, SkScalar height, SkScalar& advanceX);
74 
beginLine()75     void beginLine() override {}
runInfo(const RunInfo &)76     void runInfo(const RunInfo&) override {}
commitRunInfo()77     void commitRunInfo() override {}
commitLine()78     void commitLine() override {}
79 
runBuffer(const RunInfo & info)80     Buffer runBuffer(const RunInfo& info) override {
81         fCurrentRun = std::make_shared<Run>(fParagraph,
82                                            info,
83                                            fCurrentText.start,
84                                            fHeight,
85                                            fUseHalfLeading,
86                                            ++fUniqueRunId,
87                                            fAdvance.fX);
88         return fCurrentRun->newRunBuffer();
89     }
90 
91     void commitRunBuffer(const RunInfo&) override;
92 
93     TextRange clusteredText(GlyphRange& glyphs);
clusterIndex(GlyphIndex glyph)94     ClusterIndex clusterIndex(GlyphIndex glyph) {
95         return fCurrentText.start + fCurrentRun->fClusterIndexes[glyph];
96     }
97     void addFullyResolved();
98     void addUnresolvedWithRun(GlyphRange glyphRange);
99     void sortOutGlyphs(std::function<void(GlyphRange)>&& sortOutUnresolvedBLock);
100     ClusterRange normalizeTextRange(GlyphRange glyphRange);
101     void fillGaps(size_t);
102 
103     ParagraphImpl* fParagraph;
104     TextRange fCurrentText;
105     SkScalar fHeight;
106     bool fUseHalfLeading;
107     SkVector fAdvance;
108     size_t fUnresolvedGlyphs;
109     size_t fUniqueRunId;
110 
111     // TODO: Something that is not thead-safe since we don't need it
112     std::shared_ptr<Run> fCurrentRun;
113     std::deque<RunBlock> fUnresolvedBlocks;
114     std::vector<RunBlock> fResolvedBlocks;
115 
116     // Keeping all resolved typefaces
117     struct FontKey {
118 
FontKeyFontKey119         FontKey() {}
120 
FontKeyFontKey121         FontKey(SkUnichar unicode, SkFontStyle fontStyle, SkString locale)
122             : fUnicode(unicode), fFontStyle(fontStyle), fLocale(locale) { }
123         SkUnichar fUnicode;
124         SkFontStyle fFontStyle;
125         SkString fLocale;
126 
127         bool operator==(const FontKey& other) const;
128 
129         struct Hasher {
130             size_t operator()(const FontKey& key) const;
131         };
132     };
133     SkTHashMap<FontKey, sk_sp<SkTypeface>, FontKey::Hasher> fFallbackFonts;
134 };
135 
136 }  // namespace textlayout
137 }  // namespace skia
138 #endif
139