• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Google LLC.
2 #ifndef LogicalRun_DEFINED
3 #define LogicalRun_DEFINED
4 
5 #include "experimental/sktext/include/Types.h"
6 #include "experimental/sktext/src/Line.h"
7 #include "modules/skshaper/include/SkShaper.h"
8 
9 namespace skia {
10 namespace text {
11 
12 class LogicalRun {
13     public:
14     LogicalRun(const SkShaper::RunHandler::RunInfo& info, TextIndex textStart, SkScalar glyphOffset);
newRunBuffer()15     SkShaper::RunHandler::Buffer newRunBuffer() {
16         return {fGlyphs.data(), fPositions.data(), fOffsets.data(), fClusters.data(), {0.0f, 0.0f} };
17     }
commit()18     void commit() {
19         fFont.getBounds(fGlyphs.data(), fGlyphs.size(), fBounds.data(), nullptr);
20         fPositions[fGlyphs.size()] = fAdvance;
21         fClusters[fGlyphs.size()] = this->leftToRight() ? fUtf8Range.end() : fUtf8Range.begin();
22     }
23 
getTextRange()24     TextRange getTextRange() const { return fUtf16Range; }
25 
calculateWidth(GlyphRange glyphRange)26     SkScalar calculateWidth(GlyphRange glyphRange) const {
27         SkASSERT(glyphRange.fStart <= glyphRange.fEnd &&
28                  glyphRange.fEnd < SkToSizeT(fPositions.size()));
29         return fPositions[glyphRange.fEnd].fX - fPositions[glyphRange.fStart].fX;
30     }
calculateWidth(GlyphIndex start,GlyphIndex end)31     SkScalar calculateWidth(GlyphIndex start, GlyphIndex end) const {
32       return calculateWidth(GlyphRange(start, end));
33     }
width()34     SkScalar width() const { return fAdvance.fX; }
firstGlyphPosition()35     SkScalar firstGlyphPosition() const { return fPositions[0].fX; }
36 
leftToRight()37     bool leftToRight() const { return fBidiLevel % 2 == 0; }
bidiLevel()38     uint8_t bidiLevel() const { return fBidiLevel; }
size()39     size_t size() const { return fGlyphs.size(); }
40 
getRunType()41     LogicalRunType getRunType() const { return fRunType; }
setRunType(LogicalRunType runType)42     void setRunType(LogicalRunType runType) { fRunType = runType; }
43 
44     template <typename Callback>
forEachCluster(Callback && callback)45     void forEachCluster(Callback&& callback) {
46         for(int glyph = 0; glyph < fClusters.size(); ++glyph) {
47             callback(glyph, fRunStart + fClusters[glyph]);
48         }
49     }
50 
51     template <typename Callback>
convertUtf16Range(Callback && callback)52     void convertUtf16Range(Callback&& callback) {
53         this->fUtf16Range.fStart = callback(this->fUtf8Range.begin());
54         this->fUtf16Range.fEnd = callback(this->fUtf8Range.end());
55     }
56 
57     // Convert indexes into utf16 and also shift them to be on the entire text scale
58     template <typename Callback>
convertClusterIndexes(Callback && callback)59     void convertClusterIndexes(Callback&& callback) {
60         for (int glyph = 0; glyph < fClusters.size(); ++glyph) {
61             fClusters[glyph] = callback(fClusters[glyph]);
62         }
63     }
64 
65     private:
66     friend class ShapedText;
67     friend class WrappedText;
68     SkFont fFont;
69     TextMetrics fTextMetrics;
70 
71     LogicalRunType fRunType;
72     SkVector fAdvance;
73     SkShaper::RunHandler::Range fUtf8Range;
74     TextRange fUtf16Range;
75     TextIndex fRunStart;
76     SkScalar  fRunOffset;
77     SkSTArray<128, SkGlyphID, true> fGlyphs;
78     SkSTArray<128, SkPoint, true> fPositions;
79     SkSTArray<128, SkPoint, true> fOffsets;
80     SkSTArray<128, uint32_t, true> fClusters;
81     SkSTArray<128, SkRect, true> fBounds;
82 
83     uint8_t fBidiLevel;
84 };
85 
86 } // namespace text
87 } // namespace skia
88 #endif
89