Flutter Engine
The Flutter Engine
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) {}
57 SkASSERT(fRange.end == tail.start);
59 }
61 TStyle fStyle;
62};
63
66 : fFont(std::move(font)), fTextStart(index) {}
69};
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,
98
99 ParagraphImpl(const std::u16string& utf16text,
100 ParagraphStyle style,
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 }
157 bool strutHeightOverride() const {
159 }
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
Definition: SkFont.h:35
Definition: SkOnce.h:22
Definition: SkPath.h:59
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
SkSpan< TextLine > lines()
InternalLineMetrics getStrutMetrics() const
void paint(SkCanvas *canvas, SkScalar x, SkScalar y) override
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)
SkSpan< Cluster > clusters()
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
ParagraphImpl(const SkString &text, ParagraphStyle style, skia_private::TArray< Block, true > blocks, skia_private::TArray< Placeholder, true > placeholders, sk_sp< FontCollection > fonts, sk_sp< SkUnicode > unicode)
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)
int32_t unresolvedGlyphs() override
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
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
glong glong end
double y
double x
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
it will be possible to load the file into Perfetto s trace viewer disable asset fonts
Definition: switches.h:213
font
Font Metadata and Metrics.
Definition: run.py:1
size_t BlockIndex
Definition: TextStyle.h:355
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
size_t TextIndex
Definition: TextStyle.h:336
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)
Definition: ParagraphImpl.h:47
size_t RunIndex
Definition: Run.h:32
Definition: DartTypes.h:13
Definition: ref_ptr.h:256
dest
Definition: zip.py:79
int32_t width
SeparatedVector2 offset
const StrutStyle & getStrutStyle() const
ResolvedFontDescriptor(TextIndex index, SkFont font)
Definition: ParagraphImpl.h:65
StyleBlock(TextRange textRange, const TStyle &style)
Definition: ParagraphImpl.h:55
StyleBlock(size_t start, size_t end, const TStyle &style)
Definition: ParagraphImpl.h:54
void add(TextRange tail)
Definition: ParagraphImpl.h:56