Skip to content

Commit

Permalink
Reland "Initial integration of libtxt with Flutter alongside Blink." (f…
Browse files Browse the repository at this point in the history
…lutter#3793)

* Transition to Hybrid lib/txt and blink text system.
  • Loading branch information
GaryQian authored Jun 19, 2017
1 parent 14f2ffa commit 3c04921
Show file tree
Hide file tree
Showing 20 changed files with 950 additions and 197 deletions.
3 changes: 3 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group("flutter") {
deps = [
"//flutter/lib/snapshot:generate_snapshot_bin",
"//flutter/sky",
"//lib/txt",
]

if (is_fuchsia) {
Expand All @@ -30,6 +31,8 @@ group("flutter") {
"//flutter/sky/engine/wtf:wtf_unittests",
"//flutter/synchronization:synchronization_unittests",
"//lib/ftl:ftl_unittests",
"//lib/txt/examples:txt_example($host_toolchain)",
"//lib/txt/tests($host_toolchain)", # txt_unittests
]
}
}
Expand Down
3 changes: 3 additions & 0 deletions DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ deps = {
'src/lib/zip':
Var('fuchsia_git') + '/zip' + '@' + '92dc87ca645fe8e9f5151ef6dac86d8311a7222f',

'src/lib/txt':
Var('fuchsia_git') + '/txt' + '@' + 'b44e28c2fd75d7d4b9dcc862bb2c01a090bb53e1',

'src/third_party/gtest':
Var('fuchsia_git') + '/third_party/gtest' + '@' + 'c00f82917331efbbd27124b537e4ccc915a02b72',

Expand Down
1 change: 1 addition & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct Settings {
bool use_test_fonts = false;
bool dart_non_checked_mode = false;
bool enable_software_rendering = false;
bool using_blink = true;
std::string aot_snapshot_path;
std::string aot_vm_snapshot_data_filename;
std::string aot_vm_snapshot_instr_filename;
Expand Down
8 changes: 8 additions & 0 deletions lib/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# found in the LICENSE file.

source_set("ui") {

sources = [
"compositing/scene.cc",
"compositing/scene.h",
Expand Down Expand Up @@ -55,6 +56,12 @@ source_set("ui") {
"text/paragraph.h",
"text/paragraph_builder.cc",
"text/paragraph_builder.h",
"text/paragraph_impl.cc",
"text/paragraph_impl.h",
"text/paragraph_impl_blink.cc",
"text/paragraph_impl_blink.h",
"text/paragraph_impl_txt.cc",
"text/paragraph_impl_txt.h",
"text/text_box.cc",
"text/text_box.h",
"ui_dart_state.cc",
Expand Down Expand Up @@ -83,5 +90,6 @@ source_set("ui") {
"//lib/tonic",
"//third_party/skia",
"//third_party/skia:gpu",
"//lib/txt",
]
}
132 changes: 22 additions & 110 deletions lib/ui/text/paragraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

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

#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/sky/engine/core/rendering/PaintInfo.h"
#include "flutter/sky/engine/core/rendering/RenderText.h"
#include "flutter/sky/engine/core/rendering/RenderParagraph.h"
#include "flutter/sky/engine/core/rendering/RenderText.h"
#include "flutter/sky/engine/core/rendering/style/RenderStyle.h"
#include "flutter/sky/engine/platform/fonts/FontCache.h"
#include "flutter/sky/engine/platform/graphics/GraphicsContext.h"
#include "flutter/sky/engine/platform/text/TextBoundaries.h"
#include "flutter/sky/engine/wtf/PassOwnPtr.h"
#include "lib/ftl/tasks/task_runner.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
Expand All @@ -31,7 +33,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
V(Paragraph, maxIntrinsicWidth) \
V(Paragraph, alphabeticBaseline) \
V(Paragraph, ideographicBaseline) \
V(Paragraph, didExceedMaxLines) \
V(Paragraph, didExceedMaxLines) \
V(Paragraph, layout) \
V(Paragraph, paint) \
V(Paragraph, getWordBoundary) \
Expand All @@ -41,155 +43,65 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Paragraph);
DART_BIND_ALL(Paragraph, FOR_EACH_BINDING)

Paragraph::Paragraph(PassOwnPtr<RenderView> renderView)
: m_renderView(renderView) {}
: m_paragraphImpl(std::make_unique<ParagraphImplBlink>(renderView)) {}

Paragraph::Paragraph(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraphImpl(
std::make_unique<ParagraphImplTxt>(std::move(paragraph))) {}

Paragraph::~Paragraph() {
if (m_renderView) {
RenderView* renderView = m_renderView.leakPtr();
Threads::UI()->PostTask(
[renderView]() { renderView->destroy(); });
Threads::UI()->PostTask([renderView]() { renderView->destroy(); });
}
}

double Paragraph::width() {
return firstChildBox()->width();
return m_paragraphImpl->width();
}

double Paragraph::height() {
return firstChildBox()->height();
return m_paragraphImpl->height();
}

double Paragraph::minIntrinsicWidth() {
return firstChildBox()->minPreferredLogicalWidth();
return m_paragraphImpl->minIntrinsicWidth();
}

double Paragraph::maxIntrinsicWidth() {
return firstChildBox()->maxPreferredLogicalWidth();
return m_paragraphImpl->maxIntrinsicWidth();
}

double Paragraph::alphabeticBaseline() {
return firstChildBox()->firstLineBoxBaseline(
FontBaselineOrAuto(AlphabeticBaseline));
return m_paragraphImpl->alphabeticBaseline();
}

double Paragraph::ideographicBaseline() {
return firstChildBox()->firstLineBoxBaseline(
FontBaselineOrAuto(IdeographicBaseline));
return m_paragraphImpl->ideographicBaseline();
}

bool Paragraph::didExceedMaxLines() {
RenderBox* box = firstChildBox();
ASSERT(box->isRenderParagraph());
RenderParagraph* paragraph = static_cast<RenderParagraph*>(box);
return paragraph->didExceedMaxLines();
return m_paragraphImpl->didExceedMaxLines();
}

void Paragraph::layout(double width) {
FontCachePurgePreventer fontCachePurgePreventer;

int maxWidth = LayoutUnit(width); // Handles infinity properly.
m_renderView->setFrameViewSize(IntSize(maxWidth, intMaxForLayoutUnit));
m_renderView->layout();
m_paragraphImpl->layout(width);
}

void Paragraph::paint(Canvas* canvas, double x, double y) {
SkCanvas* skCanvas = canvas->canvas();
if (!skCanvas)
return;

FontCachePurgePreventer fontCachePurgePreventer;

// Very simplified painting to allow painting an arbitrary (layer-less)
// subtree.
RenderBox* box = firstChildBox();
skCanvas->translate(x, y);

GraphicsContext context(skCanvas);
Vector<RenderBox*> layers;
LayoutRect bounds = box->absoluteBoundingBoxRect();
FTL_DCHECK(bounds.x() == 0 && bounds.y() == 0);
PaintInfo paintInfo(&context, enclosingIntRect(bounds), box);
box->paint(paintInfo, LayoutPoint(), layers);
// Note we're ignoring any layers encountered.
// TODO(abarth): Remove the concept of RenderLayers.

skCanvas->translate(-x, -y);
m_paragraphImpl->paint(canvas, x, y);
}

std::vector<TextBox> Paragraph::getRectsForRange(unsigned start, unsigned end) {
if (end <= start || start == end)
return std::vector<TextBox>();

unsigned offset = 0;
std::vector<TextBox> boxes;
for (RenderObject* object = m_renderView.get(); object;
object = object->nextInPreOrder()) {
if (!object->isText())
continue;
RenderText* text = toRenderText(object);
unsigned length = text->textLength();
if (offset + length > start) {
unsigned startOffset = offset > start ? 0 : start - offset;
unsigned endOffset = end - offset;
text->appendAbsoluteTextBoxesForRange(boxes, startOffset, endOffset);
}
offset += length;
if (offset >= end)
break;
}

return boxes;
}

int Paragraph::absoluteOffsetForPosition(const PositionWithAffinity& position) {
FTL_DCHECK(position.renderer());
unsigned offset = 0;
for (RenderObject* object = m_renderView.get(); object;
object = object->nextInPreOrder()) {
if (object == position.renderer())
return offset + position.offset();
if (object->isText()) {
RenderText* text = toRenderText(object);
offset += text->textLength();
}
}
FTL_DCHECK(false);
return 0;
return m_paragraphImpl->getRectsForRange(start, end);
}

Dart_Handle Paragraph::getPositionForOffset(double dx, double dy) {
LayoutPoint point(dx, dy);
PositionWithAffinity position = m_renderView->positionForPoint(point);
Dart_Handle result = Dart_NewList(2);
Dart_ListSetAt(result, 0, ToDart(absoluteOffsetForPosition(position)));
Dart_ListSetAt(result, 1, ToDart(static_cast<int>(position.affinity())));
return result;
return m_paragraphImpl->getPositionForOffset(dx, dy);
}

Dart_Handle Paragraph::getWordBoundary(unsigned offset) {
String text;
int start = 0, end = 0;

for (RenderObject* object = m_renderView.get(); object;
object = object->nextInPreOrder()) {
if (!object->isText())
continue;
RenderText* renderText = toRenderText(object);
text.append(renderText->text());
}

TextBreakIterator* it = wordBreakIterator(text, 0, text.length());
if (it) {
end = it->following(offset);
if (end < 0)
end = it->last();
start = it->previous();
}

Dart_Handle result = Dart_NewList(2);
Dart_ListSetAt(result, 0, ToDart(start));
Dart_ListSetAt(result, 1, ToDart(end));
return result;
return m_paragraphImpl->getWordBoundary(offset);
}

} // namespace blink
18 changes: 15 additions & 3 deletions lib/ui/text/paragraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_H_

#include "flutter/lib/ui/painting/canvas.h"
#include "flutter/lib/ui/text/paragraph_impl.h"
#include "flutter/lib/ui/text/paragraph_impl_blink.h"
#include "flutter/lib/ui/text/paragraph_impl_txt.h"
#include "flutter/lib/ui/text/text_box.h"
#include "flutter/sky/engine/core/rendering/RenderView.h"
#include "flutter/sky/engine/wtf/PassOwnPtr.h"
#include "lib/tonic/dart_wrappable.h"
#include "lib/txt/src/paragraph.h"

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

public:
static ftl::RefPtr<Paragraph> create(PassOwnPtr<RenderView> renderView) {
static ftl::RefPtr<Paragraph> Create(PassOwnPtr<RenderView> renderView) {
return ftl::MakeRefCounted<Paragraph>(renderView);
}

static ftl::RefPtr<Paragraph> Create(
std::unique_ptr<txt::Paragraph> paragraph) {
return ftl::MakeRefCounted<Paragraph>(std::move(paragraph));
}

~Paragraph() override;

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

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

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

explicit Paragraph(PassOwnPtr<RenderView> renderView);

explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);

OwnPtr<RenderView> m_renderView;
};

Expand Down
Loading

0 comments on commit 3c04921

Please sign in to comment.