Flutter Engine
 
Loading...
Searching...
No Matches
paragraph.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_TXT_SRC_TXT_PARAGRAPH_H_
6#define FLUTTER_TXT_SRC_TXT_PARAGRAPH_H_
7
9#include "line_metrics.h"
10#include "paragraph_style.h"
11#include "third_party/skia/include/core/SkFont.h"
12#include "third_party/skia/include/core/SkRect.h"
13#include "third_party/skia/modules/skparagraph/include/Metrics.h"
14#include "third_party/skia/modules/skparagraph/include/Paragraph.h"
15
16class SkCanvas;
17
18namespace txt {
19
20// Interface for text layout engines. The current implementation is based on
21// Skia's SkShaper/SkParagraph text layout module.
22class Paragraph {
23 public:
24 // NOLINTNEXTLINE(readability-identifier-naming)
26
27 // Options for various types of bounding boxes provided by
28 // GetRectsForRange(...).
29 enum class RectHeightStyle {
30 // Provide tight bounding boxes that fit heights per run.
31 kTight,
32
33 // The height of the boxes will be the maximum height of all runs in the
34 // line. All rects in the same line will be the same height.
35 kMax,
36
37 // Extends the top and/or bottom edge of the bounds to fully cover any line
38 // spacing. The top edge of each line should be the same as the bottom edge
39 // of the line above. There should be no gaps in vertical coverage given any
40 // ParagraphStyle line_height.
41 //
42 // The top and bottom of each rect will cover half of the
43 // space above and half of the space below the line.
44 kIncludeLineSpacingMiddle,
45 // The line spacing will be added to the top of the rect.
46 kIncludeLineSpacingTop,
47 // The line spacing will be added to the bottom of the rect.
48 kIncludeLineSpacingBottom,
49
50 // Calculate boxes based on the strut's metrics.
51 kStrut
52 };
53
54 enum class RectWidthStyle {
55 // Provide tight bounding boxes that fit widths to the runs of each line
56 // independently.
57 kTight,
58
59 // Extends the width of the last rect of each line to match the position of
60 // the widest rect over all the lines.
61 kMax
62 };
63
65 const size_t position;
67
69 };
70
71 struct TextBox {
72 SkRect rect;
74
75 TextBox(SkRect r, TextDirection d) : rect(r), direction(d) {}
76 };
77
78 template <typename T>
79 struct Range {
80 Range() : start(), end() {}
81 Range(T s, T e) : start(s), end(e) {}
82
84
85 bool operator==(const Range<T>& other) const {
86 return start == other.start && end == other.end;
87 }
88
89 T width() const { return end - start; }
90
91 void Shift(T delta) {
92 start += delta;
93 end += delta;
94 }
95 };
96
97 virtual ~Paragraph() = default;
98
99 // Returns the width provided in the Layout() method. This is the maximum
100 // width any line in the laid out paragraph can occupy. We expect that
101 // GetMaxWidth() >= GetLayoutWidth().
102 virtual double GetMaxWidth() = 0;
103
104 // Returns the height of the laid out paragraph. NOTE this is not a tight
105 // bounding height of the glyphs, as some glyphs do not reach as low as they
106 // can.
107 virtual double GetHeight() = 0;
108
109 // Returns the width of the longest line as found in Layout(), which is
110 // defined as the horizontal distance from the left edge of the leftmost glyph
111 // to the right edge of the rightmost glyph. We expect that
112 // GetLongestLine() <= GetMaxWidth().
113 virtual double GetLongestLine() = 0;
114
115 // Returns the actual max width of the longest line after Layout().
116 virtual double GetMinIntrinsicWidth() = 0;
117
118 // Returns the total width covered by the paragraph without linebreaking.
119 virtual double GetMaxIntrinsicWidth() = 0;
120
121 // Distance from top of paragraph to the Alphabetic baseline of the first
122 // line. Used for alphabetic fonts (A-Z, a-z, greek, etc.)
123 virtual double GetAlphabeticBaseline() = 0;
124
125 // Distance from top of paragraph to the Ideographic baseline of the first
126 // line. Used for ideographic fonts (Chinese, Japanese, Korean, etc.)
127 virtual double GetIdeographicBaseline() = 0;
128
129 // Checks if the layout extends past the maximum lines and had to be
130 // truncated.
131 virtual bool DidExceedMaxLines() = 0;
132
133 // Layout calculates the positioning of all the glyphs. Must call this method
134 // before Painting and getting any statistics from this class.
135 virtual void Layout(double width) = 0;
136
137 // Paints the laid out text onto the supplied DisplayListBuilder at
138 // (x, y) offset from the origin. Only valid after Layout() is called.
139 virtual bool Paint(flutter::DisplayListBuilder* builder,
140 double x,
141 double y) = 0;
142
143 // Returns a vector of bounding boxes that enclose all text between start and
144 // end glyph indexes, including start and excluding end.
145 virtual std::vector<TextBox> GetRectsForRange(
146 size_t start,
147 size_t end,
148 RectHeightStyle rect_height_style,
149 RectWidthStyle rect_width_style) = 0;
150
151 // Returns a vector of bounding boxes that bound all inline placeholders in
152 // the paragraph.
153 //
154 // There will be one box for each inline placeholder. The boxes will be in the
155 // same order as they were added to the paragraph. The bounds will always be
156 // tight and should fully enclose the area where the placeholder should be.
157 //
158 // More granular boxes may be obtained through GetRectsForRange, which will
159 // return bounds on both text as well as inline placeholders.
160 virtual std::vector<TextBox> GetRectsForPlaceholders() = 0;
161
162 // Returns the index of the glyph that corresponds to the provided coordinate,
163 // with the top left corner as the origin, and +y direction as down.
165 double dy) = 0;
166
167 virtual bool GetGlyphInfoAt(
168 unsigned offset,
169 skia::textlayout::Paragraph::GlyphInfo* glyphInfo) const = 0;
170
172 double dx,
173 double dy,
174 skia::textlayout::Paragraph::GlyphInfo* glyphInfo) const = 0;
175
176 // Finds the first and last glyphs that define a word containing the glyph at
177 // index offset.
178 virtual Range<size_t> GetWordBoundary(size_t offset) = 0;
179
180 virtual std::vector<LineMetrics>& GetLineMetrics() = 0;
181
182 virtual bool GetLineMetricsAt(
183 int lineNumber,
184 skia::textlayout::LineMetrics* lineMetrics) const = 0;
185
186 // Returns the total number of visible lines in the paragraph.
187 virtual size_t GetNumberOfLines() const = 0;
188
189 // Returns the zero-indexed line number that contains the given code unit
190 // offset. Returns -1 if the given offset is out of bounds, or points to a
191 // codepoint that is logically after the last visible codepoint.
192 //
193 // If the offset points to a hard line break, this method returns the line
194 // number of the line this hard line break breaks, intead of the new line it
195 // creates.
196 virtual int GetLineNumberAt(size_t utf16Offset) const = 0;
197};
198
199} // namespace txt
200
201#endif // FLUTTER_TXT_SRC_TXT_PARAGRAPH_H_
virtual double GetLongestLine()=0
virtual ~Paragraph()=default
virtual std::vector< TextBox > GetRectsForRange(size_t start, size_t end, RectHeightStyle rect_height_style, RectWidthStyle rect_width_style)=0
virtual void Layout(double width)=0
virtual bool GetGlyphInfoAt(unsigned offset, skia::textlayout::Paragraph::GlyphInfo *glyphInfo) const =0
virtual std::vector< LineMetrics > & GetLineMetrics()=0
virtual size_t GetNumberOfLines() const =0
virtual bool GetClosestGlyphInfoAtCoordinate(double dx, double dy, skia::textlayout::Paragraph::GlyphInfo *glyphInfo) const =0
virtual bool DidExceedMaxLines()=0
virtual double GetHeight()=0
virtual bool GetLineMetricsAt(int lineNumber, skia::textlayout::LineMetrics *lineMetrics) const =0
virtual double GetMinIntrinsicWidth()=0
virtual double GetAlphabeticBaseline()=0
virtual int GetLineNumberAt(size_t utf16Offset) const =0
virtual bool Paint(flutter::DisplayListBuilder *builder, double x, double y)=0
virtual PositionWithAffinity GetGlyphPositionAtCoordinate(double dx, double dy)=0
virtual Range< size_t > GetWordBoundary(size_t offset)=0
virtual double GetMaxIntrinsicWidth()=0
virtual double GetIdeographicBaseline()=0
virtual std::vector< TextBox > GetRectsForPlaceholders()=0
virtual double GetMaxWidth()=0
int32_t x
auto & d
Definition main.cc:28
double y
PositionWithAffinity(size_t p, Affinity a)
Definition paragraph.h:68
void Shift(T delta)
Definition paragraph.h:91
bool operator==(const Range< T > &other) const
Definition paragraph.h:85
TextBox(SkRect r, TextDirection d)
Definition paragraph.h:75
TextDirection direction
Definition paragraph.h:73
const size_t end