• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC.
2 #ifndef Paragraph_DEFINED
3 #define Paragraph_DEFINED
4 
5 #include "modules/skparagraph/include/FontCollection.h"
6 #include "modules/skparagraph/include/Metrics.h"
7 #include "modules/skparagraph/include/ParagraphStyle.h"
8 #include "modules/skparagraph/include/TextLineBase.h"
9 #include "modules/skparagraph/include/TextStyle.h"
10 #include <unordered_set>
11 #include "drawing.h"
12 
13 class SkCanvas;
14 
15 namespace skia {
16 namespace textlayout {
17 
18 class ParagraphPainter;
19 
20 class Paragraph {
21 
22 public:
23     Paragraph() = default;
24 
25     Paragraph(ParagraphStyle style, sk_sp<FontCollection> fonts);
26 
27     virtual ~Paragraph() = default;
28 
getMaxWidth()29     SkScalar getMaxWidth() { return fWidth; }
30 
getHeight()31     SkScalar getHeight() { return fHeight; }
32 
getMinIntrinsicWidth()33     SkScalar getMinIntrinsicWidth() { return fMinIntrinsicWidth; }
34 
getMaxIntrinsicWidth()35     SkScalar getMaxIntrinsicWidth() { return fMaxIntrinsicWidth; }
36 
getAlphabeticBaseline()37     SkScalar getAlphabeticBaseline() { return fAlphabeticBaseline; }
38 
getIdeographicBaseline()39     SkScalar getIdeographicBaseline() { return fIdeographicBaseline; }
40 
getLongestLine()41     SkScalar getLongestLine() { return fLongestLine; }
42 
getLongestLineWithIndent()43     SkScalar getLongestLineWithIndent() { return fLongestLineWithIndent; }
44 
setLongestLineWithIndent(SkScalar longestLineWithIndent)45     void setLongestLineWithIndent(SkScalar longestLineWithIndent)
46     {
47         fLongestLineWithIndent = longestLineWithIndent;
48     }
49 
getGlyphsBoundsTop()50     SkScalar getGlyphsBoundsTop() { return fGlyphsBoundsTop; }
51 
getGlyphsBoundsBottom()52     SkScalar getGlyphsBoundsBottom() { return fGlyphsBoundsBottom; }
53 
getGlyphsBoundsLeft()54     SkScalar getGlyphsBoundsLeft() { return fGlyphsBoundsLeft; }
55 
getGlyphsBoundsRight()56     SkScalar getGlyphsBoundsRight() { return fGlyphsBoundsRight; }
57 
didExceedMaxLines()58     bool didExceedMaxLines() { return fExceededMaxLines; }
59 
60     virtual void layout(SkScalar width) = 0;
61 
62     virtual void paint(SkCanvas* canvas, SkScalar x, SkScalar y) = 0;
63 
64     virtual void paint(ParagraphPainter* painter, SkScalar x, SkScalar y) = 0;
65 #ifdef USE_SKIA_TXT
66     virtual void paint(ParagraphPainter* painter, RSPath* path, SkScalar hOffset, SkScalar vOffset) = 0;
67 #endif
68     // Returns a vector of bounding boxes that enclose all text between
69     // start and end glyph indexes, including start and excluding end
70     virtual std::vector<TextBox> getRectsForRange(unsigned start,
71                                                   unsigned end,
72                                                   RectHeightStyle rectHeightStyle,
73                                                   RectWidthStyle rectWidthStyle) = 0;
74 
75     virtual std::vector<TextBox> getRectsForPlaceholders() = 0;
76 
77     // Returns the index of the glyph that corresponds to the provided coordinate,
78     // with the top left corner as the origin, and +y direction as down
79     virtual PositionWithAffinity getGlyphPositionAtCoordinate(SkScalar dx, SkScalar dy) = 0;
80 
81     // Finds the first and last glyphs that define a word containing
82     // the glyph at index offset
83     virtual SkRange<size_t> getWordBoundary(unsigned offset) = 0;
84 
85     virtual void getLineMetrics(std::vector<LineMetrics>&) = 0;
86 
87     virtual size_t lineNumber() = 0;
88 
89     virtual void markDirty() = 0;
90 
91     // This function will return the number of unresolved glyphs or
92     // -1 if not applicable (has not been shaped yet - valid case)
93     virtual int32_t unresolvedGlyphs() = 0;
94     virtual std::unordered_set<SkUnichar> unresolvedCodepoints() = 0;
95 
96     // Experimental API that allows fast way to update some of "immutable" paragraph attributes
97     // but not the text itself
98     virtual void updateTextAlign(TextAlign textAlign) = 0;
99     virtual void updateFontSize(size_t from, size_t to, SkScalar fontSize) = 0;
100     virtual void updateForegroundPaint(size_t from, size_t to, SkPaint paint) = 0;
101     virtual void updateBackgroundPaint(size_t from, size_t to, SkPaint paint) = 0;
102     virtual std::vector<ParagraphPainter::PaintID> updateColor(size_t from, size_t to, SkColor color) = 0;
103 
104     enum VisitorFlags {
105         kWhiteSpace_VisitorFlag = 1 << 0,
106     };
107     struct VisitorInfo {
108         const SkFont&   font;
109         SkPoint         origin;
110         SkScalar        advanceX;
111         int             count;
112         const uint16_t* glyphs;     // count values
113         const SkPoint*  positions;  // count values
114         const uint32_t* utf8Starts; // count+1 values
115         unsigned        flags;
116     };
117 
118     // lineNumber begins at 0. If info is null, this signals the end of that line.
119     using Visitor = std::function<void(int lineNumber, const VisitorInfo*)>;
120     virtual void visit(const Visitor&) = 0;
121 
122     // Editing API
123     virtual int getLineNumberAt(TextIndex codeUnitIndex) const = 0;
124 
125     /* Returns line metrics info for the line
126      *
127      * @param lineNumber    a line number
128      * @param lineMetrics   an address to return the info (in case of null just skipped)
129      * @return              true if the line is found; false if not
130      */
131     virtual bool getLineMetricsAt(int lineNumber, LineMetrics* lineMetrics) const = 0;
132 
133     /* Returns the visible text on the line (excluding a possible ellipsis)
134      *
135      * @param lineNumber    a line number
136      * @param includeSpaces indicates if the whitespaces should be included
137      * @return              the range of the text that is shown in the line
138      */
139     virtual TextRange getActualTextRange(int lineNumber, bool includeSpaces) const = 0;
140 
141     struct GlyphClusterInfo {
142         SkRect fBounds;
143         TextRange fClusterTextRange;
144         TextDirection fGlyphClusterPosition;
145     };
146 
147     /** Finds a glyph cluster for text index
148      *
149      * @param codeUnitIndex   a text index
150      * @param glyphInfo       a glyph cluster info filled if not null
151      * @return                true if glyph cluster was found; false if not
152      */
153     virtual bool getGlyphClusterAt(TextIndex codeUnitIndex, GlyphClusterInfo* glyphInfo) = 0;
154 
155     /** Finds the closest glyph cluster for a visual text position
156      *
157      * @param dx              x coordinate
158      * @param dy              y coordinate
159      * @param glyphInfo       a glyph cluster info filled if not null
160      * @return
161      */
162     virtual bool getClosestGlyphClusterAt(SkScalar dx,
163                                           SkScalar dy,
164                                           GlyphClusterInfo* glyphInfo) = 0;
165 
166 #ifndef USE_SKIA_TXT
167     struct FontInfo {
FontInfoFontInfo168         FontInfo(const SkFont font, const TextRange textRange)
169             : fFont(font), fTextRange(textRange) { }
170         virtual ~FontInfo() = default;
171         FontInfo(const FontInfo& ) = default;
172         SkFont fFont;
173         TextRange fTextRange;
174     };
175 #else
176     struct FontInfo {
FontInfoFontInfo177         FontInfo(const RSFont font, const TextRange textRange)
178             : fFont(font), fTextRange(textRange) { }
179         virtual ~FontInfo() = default;
180         FontInfo(const FontInfo& ) = default;
181         RSFont fFont;
182         TextRange fTextRange;
183     };
184 #endif
185 
186     struct TextCutRecord {
187         size_t charbegin;
188         size_t charOver;
189         SkScalar phraseWidth;
190     };
191 
192     /** Returns the font that is used to shape the text at the position
193      *
194      * @param codeUnitIndex   text index
195      * @return                font info or an empty font info if the text is not found
196      */
197 #ifndef USE_SKIA_TXT
198     virtual SkFont getFontAt(TextIndex codeUnitIndex) const = 0;
199 #else
200     virtual RSFont getFontAt(TextIndex codeUnitIndex) const = 0;
201 #endif
202 
203     /** Returns the information about all the fonts used to shape the paragraph text
204      *
205      * @return                a list of fonts and text ranges
206      */
207     virtual std::vector<FontInfo> getFonts() const = 0;
208 
209     virtual void setIndents(const std::vector<SkScalar>& indents) = 0;
210 
211     virtual SkScalar detectIndents(size_t index) = 0;
212 
213     virtual SkScalar getTextSplitRatio() const = 0;
214 
215 #ifndef USE_SKIA_TXT
216     virtual SkFontMetrics measureText() = 0;
217 #else
218     virtual RSFontMetrics measureText() = 0;
219 #endif
220 
221 #ifndef USE_SKIA_TXT
222     virtual bool GetLineFontMetrics(const size_t lineNumber, size_t& charNumber,
223         std::vector<SkFontMetrics>& fontMetrics) = 0;
224 #else
225     virtual bool GetLineFontMetrics(const size_t lineNumber, size_t& charNumber,
226         std::vector<RSFontMetrics>& fontMetrics) = 0;
227 #endif
228     virtual std::vector<std::unique_ptr<TextLineBase>> GetTextLines() = 0;
229     virtual std::unique_ptr<Paragraph> CloneSelf() = 0;
230 
231 #ifdef OHOS_SUPPORT
232     virtual SkIRect generatePaintRegion(SkScalar x, SkScalar y) = 0;
233     virtual size_t GetMaxLines() const = 0;
234 #endif
235 
236 protected:
237     sk_sp<FontCollection> fFontCollection;
238     ParagraphStyle fParagraphStyle;
239 
240     // Things for Flutter
241     SkScalar fAlphabeticBaseline;
242     SkScalar fIdeographicBaseline;
243     SkScalar fGlyphsBoundsTop;
244     SkScalar fGlyphsBoundsBottom;
245     SkScalar fGlyphsBoundsLeft;
246     SkScalar fGlyphsBoundsRight;
247     SkScalar fHeight;
248     SkScalar fWidth;
249     SkScalar fMaxIntrinsicWidth;
250     SkScalar fMinIntrinsicWidth;
251     SkScalar fLongestLine;
252     SkScalar fLongestLineWithIndent;
253     bool fExceededMaxLines;
254 };
255 }  // namespace textlayout
256 }  // namespace skia
257 
258 #endif  // Paragraph_DEFINED
259