Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ParagraphImpl.h
Go to the documentation of this file.
1// Copyright 2019 Google LLC.
2#ifndef ParagraphImpl_DEFINED
3#define ParagraphImpl_DEFINED
4
12#include "include/core/SkSpan.h"
29#include "src/core/SkTHash.h"
30
31#include <memory>
32#include <string>
33#include <vector>
34
35class SkCanvas;
36
37namespace skia {
38namespace textlayout {
39
40class LineMetrics;
41class TextLine;
42
43template <typename T> bool operator==(const SkSpan<T>& a, const SkSpan<T>& b) {
44 return a.size() == b.size() && a.begin() == b.begin();
45}
46
47template <typename T> bool operator<=(const SkSpan<T>& a, const SkSpan<T>& b) {
48 return a.begin() >= b.begin() && a.end() <= b.end();
49}
50
51template <typename TStyle>
52struct StyleBlock {
54 StyleBlock(size_t start, size_t end, const TStyle& style) : fRange(start, end), fStyle(style) {}
55 StyleBlock(TextRange textRange, const TStyle& style) : fRange(textRange), fStyle(style) {}
56 void add(TextRange tail) {
57 SkASSERT(fRange.end == tail.start);
58 fRange = TextRange(fRange.start, fRange.start + fRange.width() + tail.width());
59 }
61 TStyle fStyle;
62};
63
70
73 kIndexed = 1, // Text is indexed
74 kShaped = 2, // Text is shaped
77 kDrawn = 7
78};
79
80/*
81struct BidiRegion {
82 BidiRegion(size_t start, size_t end, uint8_t dir)
83 : text(start, end), direction(dir) { }
84 TextRange text;
85 uint8_t direction;
86};
87*/
88class ParagraphImpl final : public Paragraph {
89
90public:
91
93 ParagraphStyle style,
97 sk_sp<SkUnicode> unicode);
98
99 ParagraphImpl(const std::u16string& utf16text,
100 ParagraphStyle style,
104 sk_sp<SkUnicode> unicode);
105
106 ~ParagraphImpl() override;
107
108 void layout(SkScalar width) override;
109 void paint(SkCanvas* canvas, SkScalar x, SkScalar y) override;
110 void paint(ParagraphPainter* canvas, SkScalar x, SkScalar y) override;
111 std::vector<TextBox> getRectsForRange(unsigned start,
112 unsigned end,
113 RectHeightStyle rectHeightStyle,
114 RectWidthStyle rectWidthStyle) override;
115 std::vector<TextBox> getRectsForPlaceholders() override;
116 void getLineMetrics(std::vector<LineMetrics>&) override;
118 SkRange<size_t> getWordBoundary(unsigned offset) override;
119
121
122 size_t lineNumber() override { return fLines.size(); }
123
125 TextRange textExcludingSpaces, TextRange text, TextRange textIncludingNewlines,
126 ClusterRange clusters, ClusterRange clustersWithGhosts, SkScalar widthWithSpaces,
127 InternalLineMetrics sizes);
128
129 SkSpan<const char> text() const { return SkSpan<const char>(fText.c_str(), fText.size()); }
130 InternalState state() const { return fState; }
131 SkSpan<Run> runs() { return SkSpan<Run>(fRuns.data(), fRuns.size()); }
133 return SkSpan<Block>(fTextStyles.data(), fTextStyles.size());
134 }
136 return SkSpan<Placeholder>(fPlaceholders.data(), fPlaceholders.size());
137 }
138 SkSpan<TextLine> lines() { return SkSpan<TextLine>(fLines.data(), fLines.size()); }
140 SkSpan<Cluster> clusters() { return SkSpan<Cluster>(fClusters.begin(), fClusters.size()); }
142 void formatLines(SkScalar maxWidth);
143 void ensureUTF16Mapping();
149 size_t getUTF16Index(TextIndex index) const {
150 return fUTF16IndexForUTF8Index[index];
151 }
152
154 bool strutForceHeight() const {
156 }
160 InternalLineMetrics strutMetrics() const { return fStrutMetrics; }
161
162 SkString getEllipsis() const;
163
168 auto clusterIndex = this->fClustersIndexFromCodeUnit[textIndex];
170 return clusterIndex;
171 }
172 Run& run(RunIndex runIndex) {
173 SkASSERT(runIndex < SkToSizeT(fRuns.size()));
174 return fRuns[runIndex];
175 }
176
178 SkSpan<Block> blocks(BlockRange blockRange);
179 Block& block(BlockIndex blockIndex);
181
182 void markDirty() override {
183 if (fState > kIndexed) {
184 fState = kIndexed;
185 }
186 }
187
188 int32_t unresolvedGlyphs() override;
189 std::unordered_set<SkUnichar> unresolvedCodepoints() override;
190 void addUnresolvedCodepoints(TextRange textRange);
191
193 sk_sp<SkPicture> getPicture() { return fPicture; }
194
195 SkScalar widthWithTrailingSpaces() { return fMaxWidthWithTrailingSpaces; }
196
197 void resetContext();
198 void resolveStrut();
199
202 void buildClusterTable();
204 void breakShapedTextIntoLines(SkScalar maxWidth);
205
206 void updateTextAlign(TextAlign textAlign) override;
207 void updateFontSize(size_t from, size_t to, SkScalar fontSize) override;
208 void updateForegroundPaint(size_t from, size_t to, SkPaint paint) override;
209 void updateBackgroundPaint(size_t from, size_t to, SkPaint paint) override;
210
211 void visit(const Visitor&) override;
212 void extendedVisit(const ExtendedVisitor&) override;
213 int getPath(int lineNumber, SkPath* dest) override;
214 bool containsColorFontOrBitmap(SkTextBlob* textBlob) override;
215 bool containsEmoji(SkTextBlob* textBlob) override;
216
217 int getLineNumberAt(TextIndex codeUnitIndex) const override;
218 int getLineNumberAtUTF16Offset(size_t codeUnitIndex) override;
219 bool getLineMetricsAt(int lineNumber, LineMetrics* lineMetrics) const override;
220 TextRange getActualTextRange(int lineNumber, bool includeSpaces) const override;
221 bool getGlyphClusterAt(TextIndex codeUnitIndex, GlyphClusterInfo* glyphInfo) override;
223 SkScalar dy,
224 GlyphClusterInfo* glyphInfo) override;
225
226 bool getGlyphInfoAtUTF16Offset(size_t codeUnitIndex, GlyphInfo* graphemeInfo) override;
227 bool getClosestUTF16GlyphInfoAt(SkScalar dx, SkScalar dy, GlyphInfo* graphemeInfo) override;
228 SkFont getFontAt(TextIndex codeUnitIndex) const override;
229 SkFont getFontAtUTF16Offset(size_t codeUnitIndex) override;
230 std::vector<FontInfo> getFonts() const override;
231
232 InternalLineMetrics getEmptyMetrics() const { return fEmptyMetrics; }
233 InternalLineMetrics getStrutMetrics() const { return fStrutMetrics; }
234
236
237 void resetShifts() {
238 for (auto& run : fRuns) {
239 run.resetJustificationShifts();
240 }
241 }
242
243 bool codeUnitHasProperty(size_t index, SkUnicode::CodeUnitFlags property) const {
244 return (fCodeUnitProperties[index] & property) == property;
245 }
246
247 sk_sp<SkUnicode> getUnicode() { return fUnicode; }
248
249private:
250 friend class ParagraphBuilder;
251 friend class ParagraphCacheKey;
253 friend class ParagraphCache;
254
255 friend class TextWrapper;
256 friend class OneLineShaper;
257
258 void computeEmptyMetrics();
259
260 // Input
267 skia_private::TArray<Block, true> fTextStyles; // TODO: take out only the font stuff
269 SkString fText;
270
271 // Internal structures
272 InternalState fState;
273 skia_private::TArray<Run, false> fRuns; // kShaped
274 skia_private::TArray<Cluster, true> fClusters; // kClusterized (cached: text, word spacing, letter spacing, resolved fonts)
276 skia_private::TArray<size_t, true> fClustersIndexFromCodeUnit;
277 std::vector<size_t> fWords;
278 std::vector<SkUnicode::BidiRegion> fBidiRegions;
279 // These two arrays are used in measuring methods (getRectsForRange, getGlyphPositionAtCoordinate)
280 // They are filled lazily whenever they need and cached
281 skia_private::TArray<TextIndex, true> fUTF8IndexForUTF16Index;
282 skia_private::TArray<size_t, true> fUTF16IndexForUTF8Index;
283 SkOnce fillUTF16MappingOnce;
284 size_t fUnresolvedGlyphs;
285 std::unordered_set<SkUnichar> fUnresolvedCodepoints;
286
287 skia_private::TArray<TextLine, false> fLines; // kFormatted (cached: width, max lines, ellipsis, text align)
288 sk_sp<SkPicture> fPicture; // kRecorded (cached: text styles)
289
291
292 InternalLineMetrics fEmptyMetrics;
293 InternalLineMetrics fStrutMetrics;
294
295 SkScalar fOldWidth;
296 SkScalar fOldHeight;
297 SkScalar fMaxWidthWithTrailingSpaces;
298
299 sk_sp<SkUnicode> fUnicode;
300 bool fHasLineBreaks;
301 bool fHasWhitespacesInside;
302 TextIndex fTrailingSpaces;
303};
304} // namespace textlayout
305} // namespace skia
306
307
308#endif // ParagraphImpl_DEFINED
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
size_t size() const
Definition SkString.h:131
const char * c_str() const
Definition SkString.h:133
Run & run(RunIndex runIndex)
PositionWithAffinity getGlyphPositionAtCoordinate(SkScalar dx, SkScalar dy) override
TextLine & addLine(SkVector offset, SkVector advance, TextRange textExcludingSpaces, TextRange text, TextRange textIncludingNewlines, ClusterRange clusters, ClusterRange clustersWithGhosts, SkScalar widthWithSpaces, InternalLineMetrics sizes)
void updateFontSize(size_t from, size_t to, SkScalar fontSize) override
InternalLineMetrics getStrutMetrics() const
InternalLineMetrics getEmptyMetrics() const
SkFont getFontAtUTF16Offset(size_t codeUnitIndex) override
skia_private::TArray< ResolvedFontDescriptor > resolvedFonts() const
InternalLineMetrics strutMetrics() const
int getLineNumberAt(TextIndex codeUnitIndex) const override
void extendedVisit(const ExtendedVisitor &) override
ClusterIndex clusterIndex(TextIndex textIndex)
bool codeUnitHasProperty(size_t index, SkUnicode::CodeUnitFlags property) const
sk_sp< FontCollection > fontCollection() const
bool getGlyphClusterAt(TextIndex codeUnitIndex, GlyphClusterInfo *glyphInfo) override
TextIndex findNextGlyphClusterBoundary(TextIndex utf8) const
void visit(const Visitor &) override
Cluster & cluster(ClusterIndex clusterIndex)
std::vector< TextBox > getRectsForPlaceholders() override
SkSpan< const char > text() const
skia_private::TArray< TextIndex > countSurroundingGraphemes(TextRange textRange) const
std::vector< FontInfo > getFonts() const override
bool getClosestUTF16GlyphInfoAt(SkScalar dx, SkScalar dy, GlyphInfo *graphemeInfo) override
const ParagraphStyle & paragraphStyle() const
int getPath(int lineNumber, SkPath *dest) override
std::unordered_set< SkUnichar > unresolvedCodepoints() override
void getLineMetrics(std::vector< LineMetrics > &) override
InternalState state() const
bool containsColorFontOrBitmap(SkTextBlob *textBlob) override
bool getLineMetricsAt(int lineNumber, LineMetrics *lineMetrics) const override
SkRange< size_t > getWordBoundary(unsigned offset) override
bool getClosestGlyphClusterAt(SkScalar dx, SkScalar dy, GlyphClusterInfo *glyphInfo) override
Run & runByCluster(ClusterIndex clusterIndex)
SkSpan< Placeholder > placeholders()
bool containsEmoji(SkTextBlob *textBlob) override
TextIndex findPreviousGlyphClusterBoundary(TextIndex utf8) const
size_t getUTF16Index(TextIndex index) const
void breakShapedTextIntoLines(SkScalar maxWidth)
SkSpan< Block > blocks(BlockRange blockRange)
sk_sp< SkPicture > getPicture()
void updateTextAlign(TextAlign textAlign) override
void layout(SkScalar width) override
void updateBackgroundPaint(size_t from, size_t to, SkPaint paint) override
bool getGlyphInfoAtUTF16Offset(size_t codeUnitIndex, GlyphInfo *graphemeInfo) override
Block & block(BlockIndex blockIndex)
void addUnresolvedCodepoints(TextRange textRange)
void setState(InternalState state)
BlockRange findAllBlocks(TextRange textRange)
void updateForegroundPaint(size_t from, size_t to, SkPaint paint) override
void formatLines(SkScalar maxWidth)
SkFont getFontAt(TextIndex codeUnitIndex) const override
std::vector< TextBox > getRectsForRange(unsigned start, unsigned end, RectHeightStyle rectHeightStyle, RectWidthStyle rectWidthStyle) override
TextIndex findPreviousGraphemeBoundary(TextIndex utf8) const
TextIndex findNextGraphemeBoundary(TextIndex utf8) const
int getLineNumberAtUTF16Offset(size_t codeUnitIndex) override
TextRange getActualTextRange(int lineNumber, bool includeSpaces) const override
sk_sp< SkUnicode > getUnicode()
ParagraphStyle fParagraphStyle
Definition Paragraph.h:274
sk_sp< FontCollection > fFontCollection
Definition Paragraph.h:273
std::function< void(int lineNumber, const ExtendedVisitorInfo *)> ExtendedVisitor
Definition Paragraph.h:112
std::function< void(int lineNumber, const VisitorInfo *)> Visitor
Definition Paragraph.h:98
const Paint & paint
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
glong glong end
double y
double x
Definition run.py:1
const size_t EMPTY_INDEX
Definition DartTypes.h:91
bool operator==(const FontArguments &a, const FontArguments &b)
const SkRange< size_t > EMPTY_RANGE
Definition DartTypes.h:128
SkRange< size_t > TextRange
Definition TextStyle.h:337
size_t ClusterIndex
Definition Run.h:35
bool operator<=(const SkSpan< T > &a, const SkSpan< T > &b)
size_t RunIndex
Definition Run.h:32
Definition ref_ptr.h:256
int32_t width
Point offset
const StrutStyle & getStrutStyle() const
ResolvedFontDescriptor(TextIndex index, SkFont font)
StyleBlock(TextRange textRange, const TStyle &style)
StyleBlock(size_t start, size_t end, const TStyle &style)
void add(TextRange tail)