44
55#include " flutter/lib/ui/text/paragraph.h"
66
7- #include " flutter/common/settings.h"
87#include " flutter/common/threads.h"
98#include " flutter/sky/engine/core/rendering/PaintInfo.h"
10- #include " flutter/sky/engine/core/rendering/RenderParagraph.h"
119#include " flutter/sky/engine/core/rendering/RenderText.h"
10+ #include " flutter/sky/engine/core/rendering/RenderParagraph.h"
1211#include " flutter/sky/engine/core/rendering/style/RenderStyle.h"
1312#include " flutter/sky/engine/platform/fonts/FontCache.h"
1413#include " flutter/sky/engine/platform/graphics/GraphicsContext.h"
1514#include " flutter/sky/engine/platform/text/TextBoundaries.h"
16- #include " flutter/sky/engine/wtf/PassOwnPtr.h"
1715#include " lib/ftl/tasks/task_runner.h"
1816#include " lib/tonic/converter/dart_converter.h"
1917#include " lib/tonic/dart_args.h"
@@ -33,7 +31,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
3331 V (Paragraph, maxIntrinsicWidth) \
3432 V (Paragraph, alphabeticBaseline) \
3533 V (Paragraph, ideographicBaseline) \
36- V (Paragraph, didExceedMaxLines) \
34+ V (Paragraph, didExceedMaxLines) \
3735 V (Paragraph, layout) \
3836 V (Paragraph, paint) \
3937 V (Paragraph, getWordBoundary) \
@@ -43,65 +41,155 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
4341DART_BIND_ALL (Paragraph, FOR_EACH_BINDING)
4442
4543Paragraph::Paragraph (PassOwnPtr<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))) {}
44+ : m_renderView(renderView) {}
5145
5246Paragraph::~Paragraph () {
5347 if (m_renderView) {
5448 RenderView* renderView = m_renderView.leakPtr ();
55- Threads::UI ()->PostTask ([renderView]() { renderView->destroy (); });
49+ Threads::UI ()->PostTask (
50+ [renderView]() { renderView->destroy (); });
5651 }
5752}
5853
5954double Paragraph::width () {
60- return m_paragraphImpl ->width ();
55+ return firstChildBox () ->width ();
6156}
6257
6358double Paragraph::height () {
64- return m_paragraphImpl ->height ();
59+ return firstChildBox () ->height ();
6560}
6661
6762double Paragraph::minIntrinsicWidth () {
68- return m_paragraphImpl-> minIntrinsicWidth ();
63+ return firstChildBox ()-> minPreferredLogicalWidth ();
6964}
7065
7166double Paragraph::maxIntrinsicWidth () {
72- return m_paragraphImpl-> maxIntrinsicWidth ();
67+ return firstChildBox ()-> maxPreferredLogicalWidth ();
7368}
7469
7570double Paragraph::alphabeticBaseline () {
76- return m_paragraphImpl->alphabeticBaseline ();
71+ return firstChildBox ()->firstLineBoxBaseline (
72+ FontBaselineOrAuto (AlphabeticBaseline));
7773}
7874
7975double Paragraph::ideographicBaseline () {
80- return m_paragraphImpl->ideographicBaseline ();
76+ return firstChildBox ()->firstLineBoxBaseline (
77+ FontBaselineOrAuto (IdeographicBaseline));
8178}
8279
8380bool Paragraph::didExceedMaxLines () {
84- return m_paragraphImpl->didExceedMaxLines ();
81+ RenderBox* box = firstChildBox ();
82+ ASSERT (box->isRenderParagraph ());
83+ RenderParagraph* paragraph = static_cast <RenderParagraph*>(box);
84+ return paragraph->didExceedMaxLines ();
8585}
8686
8787void Paragraph::layout (double width) {
88- m_paragraphImpl->layout (width);
88+ FontCachePurgePreventer fontCachePurgePreventer;
89+
90+ int maxWidth = LayoutUnit (width); // Handles infinity properly.
91+ m_renderView->setFrameViewSize (IntSize (maxWidth, intMaxForLayoutUnit));
92+ m_renderView->layout ();
8993}
9094
9195void Paragraph::paint (Canvas* canvas, double x, double y) {
92- m_paragraphImpl->paint (canvas, x, 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);
93117}
94118
95119std::vector<TextBox> Paragraph::getRectsForRange (unsigned start, unsigned end) {
96- return m_paragraphImpl->getRectsForRange (start, 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 ;
97158}
98159
99160Dart_Handle Paragraph::getPositionForOffset (double dx, double dy) {
100- return m_paragraphImpl->getPositionForOffset (dx, 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;
101167}
102168
103169Dart_Handle Paragraph::getWordBoundary (unsigned offset) {
104- return m_paragraphImpl->getWordBoundary (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;
105193}
106194
107195} // namespace blink
0 commit comments