• 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 "modules/skparagraph/include/TextStyle.h"
8 #include "modules/skparagraph/src/ParagraphImpl.h"
9 #include "modules/skparagraph/src/Run.h"
10 #include "src/core/SkSpan.h"
11 
12 namespace skia {
13 namespace textlayout {
14 
15 typedef size_t GlyphIndex;
16 typedef SkRange<GlyphIndex> GlyphRange;
17 
18 class ParagraphImpl;
19 class OneLineShaper : public SkShaper::RunHandler {
20 public:
OneLineShaper(ParagraphImpl * paragraph)21     explicit OneLineShaper(ParagraphImpl* paragraph)
22         : fParagraph(paragraph)
23         , fHeight(0.0f)
24         , fAdvance(SkPoint::Make(0.0f, 0.0f))
25         , fUnresolvedGlyphs(0) { }
26 
27     bool shape();
28 
unresolvedGlyphs()29     size_t unresolvedGlyphs() { return fUnresolvedGlyphs; }
30 
31 private:
32 
33     struct RunBlock {
RunBlockRunBlock34         RunBlock() : fRun(nullptr) { }
35 
36         // First unresolved block
RunBlockRunBlock37         explicit RunBlock(TextRange text) : fRun(nullptr), fText(text) { }
38 
RunBlockRunBlock39         RunBlock(std::shared_ptr<Run> run, TextRange text, GlyphRange glyphs, size_t score)
40             : fRun(std::move(run))
41             , fText(text)
42             , fGlyphs(glyphs) { }
43 
44         // Entire run comes as one block fully resolved
RunBlockRunBlock45         explicit RunBlock(std::shared_ptr<Run> run)
46             : fRun(std::move(run))
47             , fText(run->fTextRange)
48             , fGlyphs(GlyphRange(0, run->size())) { }
49 
50         std::shared_ptr<Run> fRun;
51         TextRange fText;
52         GlyphRange fGlyphs;
isFullyResolvedRunBlock53         bool isFullyResolved() { return fRun != nullptr && fGlyphs.width() == fRun->size(); }
54     };
55 
56     using ShapeVisitor =
57             std::function<SkScalar(TextRange textRange, SkSpan<Block>, SkScalar&, TextIndex, uint8_t)>;
58     bool iterateThroughShapingRegions(const ShapeVisitor& shape);
59 
60     using ShapeSingleFontVisitor = std::function<void(Block, SkTArray<SkShaper::Feature>)>;
61     void iterateThroughFontStyles(TextRange textRange, SkSpan<Block> styleSpan, const ShapeSingleFontVisitor& visitor);
62 
63     using TypefaceVisitor = std::function<bool(sk_sp<SkTypeface> typeface)>;
64     void matchResolvedFonts(const TextStyle& textStyle, const TypefaceVisitor& visitor);
65 #ifdef SK_DEBUG
66     void printState();
67 #endif
68     void dropUnresolved();
69     void finish(TextRange text, SkScalar height, SkScalar& advanceX);
70 
beginLine()71     void beginLine() override {}
runInfo(const RunInfo &)72     void runInfo(const RunInfo&) override {}
commitRunInfo()73     void commitRunInfo() override {}
commitLine()74     void commitLine() override {}
75 
runBuffer(const RunInfo & info)76     Buffer runBuffer(const RunInfo& info) override {
77         auto index = fUnresolvedBlocks.size() + fResolvedBlocks.size();
78         fCurrentRun = std::make_shared<Run>(fParagraph,
79                                            info,
80                                            fCurrentText.start,
81                                            fHeight,
82                                            index,
83                                            fAdvance.fX);
84         return fCurrentRun->newRunBuffer();
85     }
86 
87     void commitRunBuffer(const RunInfo&) override;
88 
89     TextRange clusteredText(GlyphRange glyphs);
clusterIndex(GlyphIndex glyph)90     ClusterIndex clusterIndex(GlyphIndex glyph) {
91         return fCurrentText.start + fCurrentRun->fClusterIndexes[glyph];
92     }
93     void addFullyResolved();
94     void addUnresolvedWithRun(GlyphRange glyphRange);
95     void sortOutGlyphs(std::function<void(GlyphRange)>&& sortOutUnresolvedBLock);
96     ClusterRange normalizeTextRange(GlyphRange glyphRange);
97     void increment(TextIndex& index);
98     void fillGaps(size_t);
99 
100     ParagraphImpl* fParagraph;
101     TextRange fCurrentText;
102     SkScalar fHeight;
103     SkVector fAdvance;
104     size_t fUnresolvedGlyphs;
105 
106     // TODO: Something that is not thead-safe since we don't need it
107     std::shared_ptr<Run> fCurrentRun;
108     std::queue<RunBlock> fUnresolvedBlocks;
109     std::vector<RunBlock> fResolvedBlocks;
110 };
111 
112 }
113 }
114 #endif
115