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