Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c548c65

Browse files
authored
Initial integration of libtxt with Flutter alongside Blink. (#3771)
1 parent e5b79ba commit c548c65

File tree

20 files changed

+950
-197
lines changed

20 files changed

+950
-197
lines changed

BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ group("flutter") {
88
deps = [
99
"//flutter/lib/snapshot:generate_snapshot_bin",
1010
"//flutter/sky",
11+
"//lib/txt",
1112
]
1213

1314
if (is_fuchsia) {
@@ -30,6 +31,8 @@ group("flutter") {
3031
"//flutter/sky/engine/wtf:wtf_unittests",
3132
"//flutter/synchronization:synchronization_unittests",
3233
"//lib/ftl:ftl_unittests",
34+
"//lib/txt/examples:txt_example($host_toolchain)",
35+
"//lib/txt/tests($host_toolchain)", # txt_unittests
3336
]
3437
}
3538
}

DEPS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ deps = {
7171
'src/lib/zip':
7272
Var('fuchsia_git') + '/zip' + '@' + '92dc87ca645fe8e9f5151ef6dac86d8311a7222f',
7373

74+
'src/lib/txt':
75+
Var('fuchsia_git') + '/txt' + '@' + 'b44e28c2fd75d7d4b9dcc862bb2c01a090bb53e1',
76+
7477
'src/third_party/gtest':
7578
Var('fuchsia_git') + '/third_party/gtest' + '@' + 'c00f82917331efbbd27124b537e4ccc915a02b72',
7679

common/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct Settings {
2727
bool use_test_fonts = false;
2828
bool dart_non_checked_mode = false;
2929
bool enable_software_rendering = false;
30+
bool using_blink = true;
3031
std::string aot_snapshot_path;
3132
std::string aot_vm_snapshot_data_filename;
3233
std::string aot_vm_snapshot_instr_filename;

lib/ui/BUILD.gn

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# found in the LICENSE file.
44

55
source_set("ui") {
6+
67
sources = [
78
"compositing/scene.cc",
89
"compositing/scene.h",
@@ -55,6 +56,12 @@ source_set("ui") {
5556
"text/paragraph.h",
5657
"text/paragraph_builder.cc",
5758
"text/paragraph_builder.h",
59+
"text/paragraph_impl.cc",
60+
"text/paragraph_impl.h",
61+
"text/paragraph_impl_blink.cc",
62+
"text/paragraph_impl_blink.h",
63+
"text/paragraph_impl_txt.cc",
64+
"text/paragraph_impl_txt.h",
5865
"text/text_box.cc",
5966
"text/text_box.h",
6067
"ui_dart_state.cc",
@@ -83,5 +90,6 @@ source_set("ui") {
8390
"//lib/tonic",
8491
"//third_party/skia",
8592
"//third_party/skia:gpu",
93+
"//lib/txt",
8694
]
8795
}

lib/ui/text/paragraph.cc

Lines changed: 22 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44

55
#include "flutter/lib/ui/text/paragraph.h"
66

7+
#include "flutter/common/settings.h"
78
#include "flutter/common/threads.h"
89
#include "flutter/sky/engine/core/rendering/PaintInfo.h"
9-
#include "flutter/sky/engine/core/rendering/RenderText.h"
1010
#include "flutter/sky/engine/core/rendering/RenderParagraph.h"
11+
#include "flutter/sky/engine/core/rendering/RenderText.h"
1112
#include "flutter/sky/engine/core/rendering/style/RenderStyle.h"
1213
#include "flutter/sky/engine/platform/fonts/FontCache.h"
1314
#include "flutter/sky/engine/platform/graphics/GraphicsContext.h"
1415
#include "flutter/sky/engine/platform/text/TextBoundaries.h"
16+
#include "flutter/sky/engine/wtf/PassOwnPtr.h"
1517
#include "lib/ftl/tasks/task_runner.h"
1618
#include "lib/tonic/converter/dart_converter.h"
1719
#include "lib/tonic/dart_args.h"
@@ -31,7 +33,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
3133
V(Paragraph, maxIntrinsicWidth) \
3234
V(Paragraph, alphabeticBaseline) \
3335
V(Paragraph, ideographicBaseline) \
34-
V(Paragraph, didExceedMaxLines) \
36+
V(Paragraph, didExceedMaxLines) \
3537
V(Paragraph, layout) \
3638
V(Paragraph, paint) \
3739
V(Paragraph, getWordBoundary) \
@@ -41,155 +43,65 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
4143
DART_BIND_ALL(Paragraph, FOR_EACH_BINDING)
4244

4345
Paragraph::Paragraph(PassOwnPtr<RenderView> renderView)
44-
: m_renderView(renderView) {}
46+
: m_paragraphImpl(std::make_unique<ParagraphImplBlink>(renderView)) {}
47+
48+
Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
49+
: m_paragraphImpl(
50+
std::make_unique<ParagraphImplTxt>(std::move(paragraph))) {}
4551

4652
Paragraph::~Paragraph() {
4753
if (m_renderView) {
4854
RenderView* renderView = m_renderView.leakPtr();
49-
Threads::UI()->PostTask(
50-
[renderView]() { renderView->destroy(); });
55+
Threads::UI()->PostTask([renderView]() { renderView->destroy(); });
5156
}
5257
}
5358

5459
double Paragraph::width() {
55-
return firstChildBox()->width();
60+
return m_paragraphImpl->width();
5661
}
5762

5863
double Paragraph::height() {
59-
return firstChildBox()->height();
64+
return m_paragraphImpl->height();
6065
}
6166

6267
double Paragraph::minIntrinsicWidth() {
63-
return firstChildBox()->minPreferredLogicalWidth();
68+
return m_paragraphImpl->minIntrinsicWidth();
6469
}
6570

6671
double Paragraph::maxIntrinsicWidth() {
67-
return firstChildBox()->maxPreferredLogicalWidth();
72+
return m_paragraphImpl->maxIntrinsicWidth();
6873
}
6974

7075
double Paragraph::alphabeticBaseline() {
71-
return firstChildBox()->firstLineBoxBaseline(
72-
FontBaselineOrAuto(AlphabeticBaseline));
76+
return m_paragraphImpl->alphabeticBaseline();
7377
}
7478

7579
double Paragraph::ideographicBaseline() {
76-
return firstChildBox()->firstLineBoxBaseline(
77-
FontBaselineOrAuto(IdeographicBaseline));
80+
return m_paragraphImpl->ideographicBaseline();
7881
}
7982

8083
bool Paragraph::didExceedMaxLines() {
81-
RenderBox* box = firstChildBox();
82-
ASSERT(box->isRenderParagraph());
83-
RenderParagraph* paragraph = static_cast<RenderParagraph*>(box);
84-
return paragraph->didExceedMaxLines();
84+
return m_paragraphImpl->didExceedMaxLines();
8585
}
8686

8787
void Paragraph::layout(double width) {
88-
FontCachePurgePreventer fontCachePurgePreventer;
89-
90-
int maxWidth = LayoutUnit(width); // Handles infinity properly.
91-
m_renderView->setFrameViewSize(IntSize(maxWidth, intMaxForLayoutUnit));
92-
m_renderView->layout();
88+
m_paragraphImpl->layout(width);
9389
}
9490

9591
void Paragraph::paint(Canvas* canvas, double x, double y) {
96-
SkCanvas* skCanvas = canvas->canvas();
97-
if (!skCanvas)
98-
return;
99-
100-
FontCachePurgePreventer fontCachePurgePreventer;
101-
102-
// Very simplified painting to allow painting an arbitrary (layer-less)
103-
// subtree.
104-
RenderBox* box = firstChildBox();
105-
skCanvas->translate(x, y);
106-
107-
GraphicsContext context(skCanvas);
108-
Vector<RenderBox*> layers;
109-
LayoutRect bounds = box->absoluteBoundingBoxRect();
110-
FTL_DCHECK(bounds.x() == 0 && bounds.y() == 0);
111-
PaintInfo paintInfo(&context, enclosingIntRect(bounds), box);
112-
box->paint(paintInfo, LayoutPoint(), layers);
113-
// Note we're ignoring any layers encountered.
114-
// TODO(abarth): Remove the concept of RenderLayers.
115-
116-
skCanvas->translate(-x, -y);
92+
m_paragraphImpl->paint(canvas, x, y);
11793
}
11894

11995
std::vector<TextBox> Paragraph::getRectsForRange(unsigned start, unsigned end) {
120-
if (end <= start || start == end)
121-
return std::vector<TextBox>();
122-
123-
unsigned offset = 0;
124-
std::vector<TextBox> boxes;
125-
for (RenderObject* object = m_renderView.get(); object;
126-
object = object->nextInPreOrder()) {
127-
if (!object->isText())
128-
continue;
129-
RenderText* text = toRenderText(object);
130-
unsigned length = text->textLength();
131-
if (offset + length > start) {
132-
unsigned startOffset = offset > start ? 0 : start - offset;
133-
unsigned endOffset = end - offset;
134-
text->appendAbsoluteTextBoxesForRange(boxes, startOffset, endOffset);
135-
}
136-
offset += length;
137-
if (offset >= end)
138-
break;
139-
}
140-
141-
return boxes;
142-
}
143-
144-
int Paragraph::absoluteOffsetForPosition(const PositionWithAffinity& position) {
145-
FTL_DCHECK(position.renderer());
146-
unsigned offset = 0;
147-
for (RenderObject* object = m_renderView.get(); object;
148-
object = object->nextInPreOrder()) {
149-
if (object == position.renderer())
150-
return offset + position.offset();
151-
if (object->isText()) {
152-
RenderText* text = toRenderText(object);
153-
offset += text->textLength();
154-
}
155-
}
156-
FTL_DCHECK(false);
157-
return 0;
96+
return m_paragraphImpl->getRectsForRange(start, end);
15897
}
15998

16099
Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) {
161-
LayoutPoint point(dx, dy);
162-
PositionWithAffinity position = m_renderView->positionForPoint(point);
163-
Dart_Handle result = Dart_NewList(2);
164-
Dart_ListSetAt(result, 0, ToDart(absoluteOffsetForPosition(position)));
165-
Dart_ListSetAt(result, 1, ToDart(static_cast<int>(position.affinity())));
166-
return result;
100+
return m_paragraphImpl->getPositionForOffset(dx, dy);
167101
}
168102

169103
Dart_Handle Paragraph::getWordBoundary(unsigned offset) {
170-
String text;
171-
int start = 0, end = 0;
172-
173-
for (RenderObject* object = m_renderView.get(); object;
174-
object = object->nextInPreOrder()) {
175-
if (!object->isText())
176-
continue;
177-
RenderText* renderText = toRenderText(object);
178-
text.append(renderText->text());
179-
}
180-
181-
TextBreakIterator* it = wordBreakIterator(text, 0, text.length());
182-
if (it) {
183-
end = it->following(offset);
184-
if (end < 0)
185-
end = it->last();
186-
start = it->previous();
187-
}
188-
189-
Dart_Handle result = Dart_NewList(2);
190-
Dart_ListSetAt(result, 0, ToDart(start));
191-
Dart_ListSetAt(result, 1, ToDart(end));
192-
return result;
104+
return m_paragraphImpl->getWordBoundary(offset);
193105
}
194106

195107
} // namespace blink

lib/ui/text/paragraph.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_H_
77

88
#include "flutter/lib/ui/painting/canvas.h"
9+
#include "flutter/lib/ui/text/paragraph_impl.h"
10+
#include "flutter/lib/ui/text/paragraph_impl_blink.h"
11+
#include "flutter/lib/ui/text/paragraph_impl_txt.h"
912
#include "flutter/lib/ui/text/text_box.h"
1013
#include "flutter/sky/engine/core/rendering/RenderView.h"
14+
#include "flutter/sky/engine/wtf/PassOwnPtr.h"
1115
#include "lib/tonic/dart_wrappable.h"
16+
#include "lib/txt/src/paragraph.h"
1217

1318
namespace tonic {
1419
class DartLibraryNatives;
@@ -22,10 +27,15 @@ class Paragraph : public ftl::RefCountedThreadSafe<Paragraph>,
2227
FRIEND_MAKE_REF_COUNTED(Paragraph);
2328

2429
public:
25-
static ftl::RefPtr<Paragraph> create(PassOwnPtr<RenderView> renderView) {
30+
static ftl::RefPtr<Paragraph> Create(PassOwnPtr<RenderView> renderView) {
2631
return ftl::MakeRefCounted<Paragraph>(renderView);
2732
}
2833

34+
static ftl::RefPtr<Paragraph> Create(
35+
std::unique_ptr<txt::Paragraph> paragraph) {
36+
return ftl::MakeRefCounted<Paragraph>(std::move(paragraph));
37+
}
38+
2939
~Paragraph() override;
3040

3141
double width();
@@ -48,12 +58,14 @@ class Paragraph : public ftl::RefCountedThreadSafe<Paragraph>,
4858
static void RegisterNatives(tonic::DartLibraryNatives* natives);
4959

5060
private:
51-
RenderBox* firstChildBox() const { return m_renderView->firstChildBox(); }
61+
std::unique_ptr<ParagraphImpl> m_paragraphImpl;
5262

53-
int absoluteOffsetForPosition(const PositionWithAffinity& position);
63+
RenderBox* firstChildBox() const { return m_renderView->firstChildBox(); }
5464

5565
explicit Paragraph(PassOwnPtr<RenderView> renderView);
5666

67+
explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);
68+
5769
OwnPtr<RenderView> m_renderView;
5870
};
5971

0 commit comments

Comments
 (0)