Flutter Engine
The Flutter Engine
paragraph.cc
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#include "flutter/lib/ui/text/paragraph.h"
6
7#include "flutter/common/settings.h"
8#include "flutter/common/task_runners.h"
9#include "flutter/fml/logging.h"
10#include "flutter/fml/task_runner.h"
11#include "third_party/dart/runtime/include/dart_api.h"
19
20namespace flutter {
21
23
24Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
25 : m_paragraph_(std::move(paragraph)) {}
26
27Paragraph::~Paragraph() = default;
28
30 return m_paragraph_->GetMaxWidth();
31}
32
34 return m_paragraph_->GetHeight();
35}
36
37double Paragraph::longestLine() {
38 return m_paragraph_->GetLongestLine();
39}
40
41double Paragraph::minIntrinsicWidth() {
42 return m_paragraph_->GetMinIntrinsicWidth();
43}
44
45double Paragraph::maxIntrinsicWidth() {
46 return m_paragraph_->GetMaxIntrinsicWidth();
47}
48
49double Paragraph::alphabeticBaseline() {
50 return m_paragraph_->GetAlphabeticBaseline();
51}
52
53double Paragraph::ideographicBaseline() {
54 return m_paragraph_->GetIdeographicBaseline();
55}
56
57bool Paragraph::didExceedMaxLines() {
58 return m_paragraph_->DidExceedMaxLines();
59}
60
61void Paragraph::layout(double width) {
62 m_paragraph_->Layout(width);
63}
64
65void Paragraph::paint(Canvas* canvas, double x, double y) {
66 if (!m_paragraph_ || !canvas) {
67 // disposed.
68 return;
69 }
70
72 if (builder) {
73 m_paragraph_->Paint(builder, x, y);
74 }
75}
76
77static tonic::Float32List EncodeTextBoxes(
78 const std::vector<txt::Paragraph::TextBox>& boxes) {
79 // Layout:
80 // First value is the number of values.
81 // Then there are boxes.size() groups of 5 which are LTRBD, where D is the
82 // text direction index.
83 tonic::Float32List result(
85 uint64_t position = 0;
86 for (uint64_t i = 0; i < boxes.size(); i++) {
87 const txt::Paragraph::TextBox& box = boxes[i];
88 result[position++] = box.rect.fLeft;
89 result[position++] = box.rect.fTop;
90 result[position++] = box.rect.fRight;
91 result[position++] = box.rect.fBottom;
92 result[position++] = static_cast<float>(box.direction);
93 }
94 return result;
95}
96
97tonic::Float32List Paragraph::getRectsForRange(unsigned start,
98 unsigned end,
99 unsigned boxHeightStyle,
100 unsigned boxWidthStyle) {
101 std::vector<txt::Paragraph::TextBox> boxes = m_paragraph_->GetRectsForRange(
102 start, end, static_cast<txt::Paragraph::RectHeightStyle>(boxHeightStyle),
103 static_cast<txt::Paragraph::RectWidthStyle>(boxWidthStyle));
104 return EncodeTextBoxes(boxes);
105}
106
107tonic::Float32List Paragraph::getRectsForPlaceholders() {
108 std::vector<txt::Paragraph::TextBox> boxes =
109 m_paragraph_->GetRectsForPlaceholders();
110 return EncodeTextBoxes(boxes);
111}
112
113Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) {
115 m_paragraph_->GetGlyphPositionAtCoordinate(dx, dy);
116 std::vector<size_t> result = {
117 pos.position, // size_t already
118 static_cast<size_t>(pos.affinity) // affinity (enum)
119 };
120 return tonic::DartConverter<decltype(result)>::ToDart(result);
121}
122
124 Dart_Handle constructor,
126 std::array<Dart_Handle, 7> arguments = {
133 Dart_NewBoolean(glyphInfo.fDirection ==
135 };
136 return Dart_InvokeClosure(constructor, arguments.size(), arguments.data());
137}
138
139Dart_Handle Paragraph::getGlyphInfoAt(unsigned utf16Offset,
140 Dart_Handle constructor) const {
142 const bool found = m_paragraph_->GetGlyphInfoAt(utf16Offset, &glyphInfo);
143 if (!found) {
144 return Dart_Null();
145 }
146 Dart_Handle handle = glyphInfoFrom(constructor, glyphInfo);
148 return handle;
149}
150
151Dart_Handle Paragraph::getClosestGlyphInfo(double dx,
152 double dy,
153 Dart_Handle constructor) const {
155 const bool found =
156 m_paragraph_->GetClosestGlyphInfoAtCoordinate(dx, dy, &glyphInfo);
157 if (!found) {
158 return Dart_Null();
159 }
160 Dart_Handle handle = glyphInfoFrom(constructor, glyphInfo);
162 return handle;
163}
164
165Dart_Handle Paragraph::getWordBoundary(unsigned utf16Offset) {
167 m_paragraph_->GetWordBoundary(utf16Offset);
168 std::vector<size_t> result = {point.start, point.end};
169 return tonic::DartConverter<decltype(result)>::ToDart(result);
170}
171
172Dart_Handle Paragraph::getLineBoundary(unsigned utf16Offset) {
173 std::vector<txt::LineMetrics> metrics = m_paragraph_->GetLineMetrics();
174 int line_start = -1;
175 int line_end = -1;
176 for (txt::LineMetrics& line : metrics) {
177 if (utf16Offset >= line.start_index && utf16Offset <= line.end_index) {
178 line_start = line.start_index;
179 line_end = line.end_index;
180 break;
181 }
182 }
183 std::vector<int> result = {line_start, line_end};
184 return tonic::DartConverter<decltype(result)>::ToDart(result);
185}
186
187tonic::Float64List Paragraph::computeLineMetrics() const {
188 std::vector<txt::LineMetrics> metrics = m_paragraph_->GetLineMetrics();
189
190 // Layout:
191 // boxes.size() groups of 9 which are the line metrics
192 // properties
193 tonic::Float64List result(
194 Dart_NewTypedData(Dart_TypedData_kFloat64, metrics.size() * 9));
195 uint64_t position = 0;
196 for (uint64_t i = 0; i < metrics.size(); i++) {
197 const txt::LineMetrics& line = metrics[i];
198 result[position++] = static_cast<double>(line.hard_break);
199 result[position++] = line.ascent;
200 result[position++] = line.descent;
201 result[position++] = line.unscaled_ascent;
202 // We add then round to get the height. The
203 // definition of height here is different
204 // than the one in LibTxt.
205 result[position++] = round(line.ascent + line.descent);
206 result[position++] = line.width;
207 result[position++] = line.left;
208 result[position++] = line.baseline;
209 result[position++] = static_cast<double>(line.line_number);
210 }
211
212 return result;
213}
214
215Dart_Handle Paragraph::getLineMetricsAt(int lineNumber,
216 Dart_Handle constructor) const {
218 const bool found = m_paragraph_->GetLineMetricsAt(lineNumber, &line);
219 if (!found) {
220 return Dart_Null();
221 }
222 std::array<Dart_Handle, 9> arguments = {
223 Dart_NewBoolean(line.fHardBreak),
224 Dart_NewDouble(line.fAscent),
225 Dart_NewDouble(line.fDescent),
226 Dart_NewDouble(line.fUnscaledAscent),
227 // We add then round to get the height. The
228 // definition of height here is different
229 // than the one in LibTxt.
230 Dart_NewDouble(round(line.fAscent + line.fDescent)),
231 Dart_NewDouble(line.fWidth),
232 Dart_NewDouble(line.fLeft),
233 Dart_NewDouble(line.fBaseline),
234 Dart_NewInteger(line.fLineNumber),
235 };
236
237 Dart_Handle handle =
238 Dart_InvokeClosure(constructor, arguments.size(), arguments.data());
240 return handle;
241}
242
243size_t Paragraph::getNumberOfLines() const {
244 return m_paragraph_->GetNumberOfLines();
245}
246
247int Paragraph::getLineNumberAt(size_t utf16Offset) const {
248 return m_paragraph_->GetLineNumberAt(utf16Offset);
249}
250
251void Paragraph::dispose() {
252 m_paragraph_.reset();
253 ClearDartWrapper();
254}
255
256} // namespace flutter
static void round(SkPoint *p)
SkPoint pos
DisplayListBuilder * builder()
Definition: canvas.h:189
const Paint & paint
Definition: color_source.cc:38
DART_EXPORT Dart_Handle Dart_NewDouble(double value)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, int number_of_arguments, Dart_Handle *arguments)
@ Dart_TypedData_kFloat32
Definition: dart_api.h:2623
@ Dart_TypedData_kFloat64
Definition: dart_api.h:2624
DART_EXPORT Dart_Handle Dart_NewTypedData(Dart_TypedData_Type type, intptr_t length)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT Dart_Handle Dart_NewBoolean(bool value)
glong glong end
GAsyncResult * result
double y
double x
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, FlutterGpuTestClass)
static tonic::Float32List EncodeTextBoxes(const std::vector< txt::Paragraph::TextBox > &boxes)
Definition: paragraph.cc:77
Dart_Handle glyphInfoFrom(Dart_Handle constructor, const skia::textlayout::Paragraph::GlyphInfo &glyphInfo)
Definition: paragraph.cc:123
Definition: ref_ptr.h:256
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
Definition: dart_error.cc:33
int32_t height
int32_t width
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15
TextDirection direction
Definition: paragraph.h:85