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