提交 0fc962f0 编写于 作者: J Jason Simmons 提交者: GitHub

Rebase the libtxt integration by @GaryQian onto the current engine head (#4022)

See https://github.com/flutter/engine/pull/3964
上级 32447c72
......@@ -9,6 +9,7 @@ group("flutter") {
"//flutter/lib/snapshot:flutter_patched_sdk",
"//flutter/lib/snapshot:generate_snapshot_bin",
"//flutter/sky",
"//flutter/third_party/txt",
]
if (!is_fuchsia) {
......
......@@ -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;
......
......@@ -54,10 +54,18 @@ source_set("ui") {
"semantics/semantics_update.h",
"semantics/semantics_update_builder.cc",
"semantics/semantics_update_builder.h",
"text/font_collection_mgr.cc",
"text/font_collection_mgr.h",
"text/paragraph.cc",
"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",
......@@ -83,6 +91,7 @@ source_set("ui") {
"//flutter/flow",
"//flutter/glue",
"//flutter/sky/engine",
"//flutter/third_party/txt",
"//lib/tonic",
"//third_party/skia",
"//third_party/skia:gpu",
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This class creates and holds the txt::FontCollection that contains the
// Default and Custom fonts.
#include "flutter/lib/ui/text/font_collection_mgr.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/dart_library_natives.h"
using tonic::ToDart;
namespace blink {
IMPLEMENT_WRAPPERTYPEINFO(ui, FontCollectionMgr);
#define FOR_EACH_BINDING(V) \
V(FontCollectionMgr, initializeFontCollection) \
V(FontCollectionMgr, initializeFontCollectionSingle) \
V(FontCollectionMgr, initializeFontCollectionMultiple)
DART_BIND_ALL(FontCollectionMgr, FOR_EACH_BINDING)
txt::FontCollection* FontCollectionMgr::kFontCollection = nullptr;
void FontCollectionMgr::addFontDir(std::string font_dir) {
if (kFontCollection == nullptr)
initializeFontCollection();
kFontCollection->AddFontMgr(font_dir);
}
void FontCollectionMgr::initializeFontCollection() {
txt::FontCollection font_collection = txt::FontCollection();
kFontCollection = &font_collection;
}
void FontCollectionMgr::initializeFontCollectionSingle(std::string font_dir) {
txt::FontCollection font_collection = txt::FontCollection(font_dir);
kFontCollection = &font_collection;
}
void FontCollectionMgr::initializeFontCollectionMultiple(
std::vector<std::string> font_dirs) {
txt::FontCollection font_collection = txt::FontCollection(font_dirs);
kFontCollection = &font_collection;
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This class creates and holds the txt::FontCollection that contains the
// Default and Custom fonts.
#ifndef FLUTTER_LIB_UI_TEXT_FONT_COLLECTION_MGR_H_
#define FLUTTER_LIB_UI_TEXT_FONT_COLLECTION_MGR_H_
#include "flutter/sky/engine/wtf/PassOwnPtr.h"
#include "flutter/third_party/txt/src/txt/font_collection.h"
#include "lib/tonic/dart_wrappable.h"
namespace tonic {
class DartLibraryNatives;
} // namespace tonic
namespace blink {
class FontCollectionMgr : public ftl::RefCountedThreadSafe<FontCollectionMgr>,
public tonic::DartWrappable {
DEFINE_WRAPPERTYPEINFO();
FRIEND_MAKE_REF_COUNTED(FontCollectionMgr);
public:
static txt::FontCollection* kFontCollection;
static void addFontDir(std::string font_dir);
static void initializeFontCollection();
static void initializeFontCollectionSingle(std::string font_dir);
static void initializeFontCollectionMultiple(
std::vector<std::string> font_dirs);
static void RegisterNatives(tonic::DartLibraryNatives* natives);
};
} // namespace blink
#endif // FLUTTER_LIB_UI_TEXT_FONT_COLLECTION_MGR_H_
......@@ -4,14 +4,17 @@
#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/logging.h"
#include "lib/ftl/tasks/task_runner.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
......@@ -41,13 +44,16 @@ 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(); });
}
}
......@@ -59,144 +65,51 @@ size_t Paragraph::GetAllocationSize() {
}
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
......@@ -6,8 +6,13 @@
#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 "flutter/third_party/txt/src/txt/paragraph.h"
#include "lib/tonic/dart_wrappable.h"
namespace tonic {
......@@ -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();
......@@ -50,12 +60,12 @@ class Paragraph : public ftl::RefCountedThreadSafe<Paragraph>,
static void RegisterNatives(tonic::DartLibraryNatives* natives);
private:
RenderBox* firstChildBox() const { return m_renderView->firstChildBox(); }
int absoluteOffsetForPosition(const PositionWithAffinity& position);
std::unique_ptr<ParagraphImpl> m_paragraphImpl;
explicit Paragraph(PassOwnPtr<RenderView> renderView);
explicit Paragraph(std::unique_ptr<txt::Paragraph> paragraph);
OwnPtr<RenderView> m_renderView;
};
......
......@@ -4,6 +4,7 @@
#include "flutter/lib/ui/text/paragraph_builder.h"
#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/sky/engine/core/rendering/RenderInline.h"
......@@ -11,6 +12,12 @@
#include "flutter/sky/engine/core/rendering/RenderText.h"
#include "flutter/sky/engine/core/rendering/style/RenderStyle.h"
#include "flutter/sky/engine/platform/text/LocaleToScriptMapping.h"
#include "flutter/third_party/txt/src/txt/font_style.h"
#include "flutter/third_party/txt/src/txt/font_weight.h"
#include "flutter/third_party/txt/src/txt/paragraph_style.h"
#include "flutter/third_party/txt/src/txt/text_align.h"
#include "flutter/third_party/txt/src/txt/text_decoration.h"
#include "flutter/third_party/txt/src/txt/text_style.h"
#include "lib/ftl/tasks/task_runner.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
......@@ -95,8 +102,7 @@ void createFontForDocument(RenderStyle* style) {
style->font().update(UIDartState::Current()->font_selector());
}
PassRefPtr<RenderStyle> decodeParagraphStyle(
RenderStyle* parentStyle,
PassRefPtr<RenderStyle> decodeParagraphStyle(RenderStyle* parentStyle,
tonic::Int32List& encoded,
const std::string& fontFamily,
double fontSize,
......@@ -187,8 +193,8 @@ ftl::RefPtr<ParagraphBuilder> ParagraphBuilder::create(
double fontSize,
double lineHeight,
const std::string& ellipsis) {
return ftl::MakeRefCounted<ParagraphBuilder>(
encoded, fontFamily, fontSize, lineHeight, ellipsis);
return ftl::MakeRefCounted<ParagraphBuilder>(encoded, fontFamily, fontSize,
lineHeight, ellipsis);
}
ParagraphBuilder::ParagraphBuilder(tonic::Int32List& encoded,
......@@ -196,10 +202,46 @@ ParagraphBuilder::ParagraphBuilder(tonic::Int32List& encoded,
double fontSize,
double lineHeight,
const std::string& ellipsis) {
if (!Settings::Get().using_blink) {
int32_t mask = encoded[0];
txt::ParagraphStyle style;
if (mask & psTextAlignMask)
style.text_align = txt::TextAlign(encoded[psTextAlignIndex]);
if (mask & (psFontWeightMask | psFontStyleMask | psFontFamilyMask |
psFontSizeMask)) {
if (mask & psFontWeightMask)
style.font_weight =
static_cast<txt::FontWeight>(encoded[psFontWeightIndex]);
if (mask & psFontStyleMask)
style.font_style =
static_cast<txt::FontStyle>(encoded[psFontStyleIndex]);
if (mask & psFontFamilyMask)
style.font_family = fontFamily;
if (mask & psFontSizeMask)
style.font_size = fontSize;
}
if (mask & psLineHeightMask)
style.line_height = lineHeight;
if (mask & psMaxLinesMask)
style.max_lines = encoded[psMaxLinesIndex];
if (mask & psEllipsisMask)
style.ellipsis = ellipsis;
m_paragraphBuilder.SetParagraphStyle(style);
} else {
// Blink version.
createRenderView();
RefPtr<RenderStyle> paragraphStyle = decodeParagraphStyle(
m_renderView->style(), encoded, fontFamily, fontSize, lineHeight, ellipsis);
RefPtr<RenderStyle> paragraphStyle =
decodeParagraphStyle(m_renderView->style(), encoded, fontFamily,
fontSize, lineHeight, ellipsis);
encoded.Release();
m_renderParagraph = new RenderParagraph();
......@@ -207,13 +249,14 @@ ParagraphBuilder::ParagraphBuilder(tonic::Int32List& encoded,
m_currentRenderObject = m_renderParagraph;
m_renderView->addChild(m_currentRenderObject);
}
}
} // namespace blink
ParagraphBuilder::~ParagraphBuilder() {
if (m_renderView) {
RenderView* renderView = m_renderView.leakPtr();
Threads::UI()->PostTask(
[renderView]() { renderView->destroy(); });
Threads::UI()->PostTask([renderView]() { renderView->destroy(); });
}
}
......@@ -224,11 +267,67 @@ void ParagraphBuilder::pushStyle(tonic::Int32List& encoded,
double wordSpacing,
double height) {
FTL_DCHECK(encoded.num_elements() == 8);
RefPtr<RenderStyle> style = RenderStyle::create();
style->inheritFrom(m_currentRenderObject->style());
int32_t mask = encoded[0];
if (!Settings::Get().using_blink) {
// Set to use the properties of the previous style if the property is not
// explicitly given.
txt::TextStyle style = m_paragraphBuilder.PeekStyle();
if (mask & tsColorMask)
style.color = encoded[tsColorIndex];
if (mask & tsTextDecorationMask) {
style.decoration =
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
}
if (mask & tsTextDecorationColorMask)
style.decoration_color = encoded[tsTextDecorationColorIndex];
if (mask & tsTextDecorationStyleMask)
style.decoration_style = static_cast<txt::TextDecorationStyle>(
encoded[tsTextDecorationStyleIndex]);
if (mask & tsTextBaselineMask) {
// TODO(abarth): Implement TextBaseline. The CSS version of this
// property wasn't wired up either.
}
if (mask & (tsFontWeightMask | tsFontStyleMask | tsFontFamilyMask |
tsFontSizeMask | tsLetterSpacingMask | tsWordSpacingMask)) {
if (mask & tsFontWeightMask)
style.font_weight =
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
if (mask & tsFontStyleMask)
style.font_style =
static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
if (mask & tsFontFamilyMask)
style.font_family = fontFamily;
if (mask & tsFontSizeMask)
style.font_size = fontSize;
if (mask & tsLetterSpacingMask)
style.letter_spacing = letterSpacing;
if (mask & tsWordSpacingMask)
style.word_spacing = wordSpacing;
}
if (mask & tsHeightMask) {
style.height = height;
}
m_paragraphBuilder.PushStyle(style);
} else {
// Blink Version.
RefPtr<RenderStyle> style = RenderStyle::create();
style->inheritFrom(m_currentRenderObject->style());
if (mask & tsColorMask)
style->setColor(getColorFromARGB(encoded[tsColorIndex]));
......@@ -243,8 +342,8 @@ void ParagraphBuilder::pushStyle(tonic::Int32List& encoded,
StyleColor(getColorFromARGB(encoded[tsTextDecorationColorIndex])));
if (mask & tsTextDecorationStyleMask)
style->setTextDecorationStyle(
static_cast<TextDecorationStyle>(encoded[tsTextDecorationStyleIndex]));
style->setTextDecorationStyle(static_cast<TextDecorationStyle>(
encoded[tsTextDecorationStyleIndex]));
if (mask & tsTextBaselineMask) {
// TODO(abarth): Implement TextBaseline. The CSS version of this
......@@ -296,14 +395,24 @@ void ParagraphBuilder::pushStyle(tonic::Int32List& encoded,
span->setStyle(style.release());
m_currentRenderObject->addChild(span);
m_currentRenderObject = span;
}
}
void ParagraphBuilder::pop() {
if (!Settings::Get().using_blink) {
m_paragraphBuilder.Pop();
} else {
// Blink Version.
if (m_currentRenderObject)
m_currentRenderObject = m_currentRenderObject->parent();
}
}
void ParagraphBuilder::addText(const std::string& text) {
if (!Settings::Get().using_blink) {
m_paragraphBuilder.AddText(text);
} else {
// Blink Version.
if (!m_currentRenderObject)
return;
RenderText* renderText = new RenderText(String::fromUTF8(text).impl());
......@@ -311,11 +420,16 @@ void ParagraphBuilder::addText(const std::string& text) {
style->inheritFrom(m_currentRenderObject->style());
renderText->setStyle(style.release());
m_currentRenderObject->addChild(renderText);
}
}
ftl::RefPtr<Paragraph> ParagraphBuilder::build() {
m_currentRenderObject = nullptr;
return Paragraph::create(m_renderView.release());
if (!Settings::Get().using_blink) {
return Paragraph::Create(m_paragraphBuilder.Build());
} else {
return Paragraph::Create(m_renderView.release());
}
}
void ParagraphBuilder::createRenderView() {
......
......@@ -6,6 +6,9 @@
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_BUILDER_H_
#include "flutter/lib/ui/text/paragraph.h"
#include "flutter/sky/engine/core/rendering/RenderObject.h"
#include "flutter/sky/engine/wtf/OwnPtr.h"
#include "flutter/third_party/txt/src/txt/paragraph_builder.h"
#include "lib/tonic/dart_wrappable.h"
#include "lib/tonic/typed_data/int32_list.h"
......@@ -15,6 +18,8 @@ class DartLibraryNatives;
namespace blink {
class Paragraph;
class ParagraphBuilder : public ftl::RefCountedThreadSafe<ParagraphBuilder>,
public tonic::DartWrappable {
DEFINE_WRAPPERTYPEINFO();
......@@ -35,6 +40,7 @@ class ParagraphBuilder : public ftl::RefCountedThreadSafe<ParagraphBuilder>,
double letterSpacing,
double wordSpacing,
double height);
void pop();
void addText(const std::string& text);
......@@ -55,6 +61,7 @@ class ParagraphBuilder : public ftl::RefCountedThreadSafe<ParagraphBuilder>,
OwnPtr<RenderView> m_renderView;
RenderObject* m_renderParagraph;
RenderObject* m_currentRenderObject;
txt::ParagraphBuilder m_paragraphBuilder;
};
} // namespace blink
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/lib/ui/text/paragraph_impl.h"
namespace blink {} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_H_
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_H_
#include "flutter/lib/ui/painting/canvas.h"
#include "flutter/lib/ui/text/text_box.h"
namespace blink {
class ParagraphImpl {
public:
virtual ~ParagraphImpl(){};
virtual double width() = 0;
virtual double height() = 0;
virtual double minIntrinsicWidth() = 0;
virtual double maxIntrinsicWidth() = 0;
virtual double alphabeticBaseline() = 0;
virtual double ideographicBaseline() = 0;
virtual bool didExceedMaxLines() = 0;
virtual void layout(double width) = 0;
virtual void paint(Canvas* canvas, double x, double y) = 0;
virtual std::vector<TextBox> getRectsForRange(unsigned start,
unsigned end) = 0;
virtual Dart_Handle getPositionForOffset(double dx, double dy) = 0;
virtual Dart_Handle getWordBoundary(unsigned offset) = 0;
};
} // namespace blink
#endif // FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/lib/ui/text/paragraph_impl_blink.h"
#include "flutter/common/threads.h"
#include "flutter/lib/ui/text/paragraph.h"
#include "flutter/lib/ui/text/paragraph_impl.h"
#include "flutter/sky/engine/core/rendering/PaintInfo.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 "lib/ftl/tasks/task_runner.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/dart_library_natives.h"
using tonic::ToDart;
namespace blink {
ParagraphImplBlink::ParagraphImplBlink(PassOwnPtr<RenderView> renderView)
: m_renderView(renderView) {}
ParagraphImplBlink::~ParagraphImplBlink() {
if (m_renderView) {
RenderView* renderView = m_renderView.leakPtr();
Threads::UI()->PostTask([renderView]() { renderView->destroy(); });
}
}
double ParagraphImplBlink::width() {
return firstChildBox()->width();
}
double ParagraphImplBlink::height() {
return firstChildBox()->height();
}
double ParagraphImplBlink::minIntrinsicWidth() {
return firstChildBox()->minPreferredLogicalWidth();
}
double ParagraphImplBlink::maxIntrinsicWidth() {
return firstChildBox()->maxPreferredLogicalWidth();
}
double ParagraphImplBlink::alphabeticBaseline() {
return firstChildBox()->firstLineBoxBaseline(
FontBaselineOrAuto(AlphabeticBaseline));
}
double ParagraphImplBlink::ideographicBaseline() {
return firstChildBox()->firstLineBoxBaseline(
FontBaselineOrAuto(IdeographicBaseline));
}
bool ParagraphImplBlink::didExceedMaxLines() {
RenderBox* box = firstChildBox();
ASSERT(box->isRenderParagraph());
RenderParagraph* paragraph = static_cast<RenderParagraph*>(box);
return paragraph->didExceedMaxLines();
}
void ParagraphImplBlink::layout(double width) {
FontCachePurgePreventer fontCachePurgePreventer;
int maxWidth = LayoutUnit(width); // Handles infinity properly.
m_renderView->setFrameViewSize(IntSize(maxWidth, intMaxForLayoutUnit));
m_renderView->layout();
}
void ParagraphImplBlink::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);
}
std::vector<TextBox> ParagraphImplBlink::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 ParagraphImplBlink::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;
}
Dart_Handle ParagraphImplBlink::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;
}
Dart_Handle ParagraphImplBlink::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;
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_BLINK_H_
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_BLINK_H_
#include "flutter/lib/ui/painting/canvas.h"
#include "flutter/lib/ui/text/paragraph_impl.h"
#include "flutter/lib/ui/text/text_box.h"
#include "flutter/sky/engine/core/rendering/RenderView.h"
#include "flutter/third_party/txt/src/txt/paragraph.h"
namespace blink {
class ParagraphImplBlink : public ParagraphImpl {
public:
~ParagraphImplBlink() override;
explicit ParagraphImplBlink(PassOwnPtr<RenderView> renderView);
double width() override;
double height() override;
double minIntrinsicWidth() override;
double maxIntrinsicWidth() override;
double alphabeticBaseline() override;
double ideographicBaseline() override;
bool didExceedMaxLines() override;
void layout(double width) override;
void paint(Canvas* canvas, double x, double y) override;
std::vector<TextBox> getRectsForRange(unsigned start, unsigned end) override;
Dart_Handle getPositionForOffset(double dx, double dy) override;
Dart_Handle getWordBoundary(unsigned offset) override;
RenderView* renderView() const { return m_renderView.get(); }
private:
RenderBox* firstChildBox() const { return m_renderView->firstChildBox(); }
int absoluteOffsetForPosition(const PositionWithAffinity& position);
OwnPtr<RenderView> m_renderView;
};
} // namespace blink
#endif // FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_BLINK_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/lib/ui/text/paragraph_impl_txt.h"
#include "flutter/common/threads.h"
#include "flutter/lib/ui/text/paragraph.h"
#include "flutter/lib/ui/text/paragraph_impl.h"
#include "lib/ftl/logging.h"
#include "lib/ftl/tasks/task_runner.h"
#include "lib/tonic/converter/dart_converter.h"
#include "third_party/skia/include/core/SkPoint.h"
using tonic::ToDart;
namespace blink {
ParagraphImplTxt::ParagraphImplTxt(std::unique_ptr<txt::Paragraph> paragraph)
: m_paragraph(std::move(paragraph)) {}
ParagraphImplTxt::~ParagraphImplTxt() {}
double ParagraphImplTxt::width() {
return m_paragraph->GetMaxWidth();
}
double ParagraphImplTxt::height() {
return m_paragraph->GetHeight();
}
double ParagraphImplTxt::minIntrinsicWidth() {
return m_paragraph->GetMinIntrinsicWidth();
}
double ParagraphImplTxt::maxIntrinsicWidth() {
return m_paragraph->GetMaxIntrinsicWidth();
}
double ParagraphImplTxt::alphabeticBaseline() {
return m_paragraph->GetAlphabeticBaseline();
}
double ParagraphImplTxt::ideographicBaseline() {
return m_paragraph->GetIdeographicBaseline();
}
bool ParagraphImplTxt::didExceedMaxLines() {
return m_paragraph->DidExceedMaxLines();
}
void ParagraphImplTxt::layout(double width) {
m_width = width;
m_paragraph->Layout(width);
}
void ParagraphImplTxt::paint(Canvas* canvas, double x, double y) {
SkCanvas* sk_canvas = canvas->canvas();
if (!sk_canvas)
return;
m_paragraph->Paint(sk_canvas, x, y);
}
std::vector<TextBox> ParagraphImplTxt::getRectsForRange(unsigned start,
unsigned end) {
std::vector<TextBox> result;
std::vector<SkRect> rects = m_paragraph->GetRectsForRange(start, end);
for (size_t i = 0; i < rects.size(); ++i) {
result.push_back(TextBox(rects[i], m_paragraph->GetParagraphStyle().rtl
? TextDirection::RTL
: TextDirection::LTR));
}
return result;
}
Dart_Handle ParagraphImplTxt::getPositionForOffset(double dx, double dy) {
Dart_Handle result = Dart_NewList(2);
Dart_ListSetAt(
result, 0,
ToDart(m_paragraph->GetGlyphPositionAtCoordinate(dx, dy, true)));
Dart_ListSetAt(result, 1, ToDart(static_cast<int>(EAffinity::DOWNSTREAM)));
return result;
}
Dart_Handle ParagraphImplTxt::getWordBoundary(unsigned offset) {
SkIPoint point = m_paragraph->GetWordBoundary(offset);
Dart_Handle result = Dart_NewList(2);
Dart_ListSetAt(result, 0, ToDart(point.x()));
Dart_ListSetAt(result, 1, ToDart(point.y()));
return result;
}
} // namespace blink
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_TXT_H_
#define FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_TXT_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/text_box.h"
#include "flutter/third_party/txt/src/txt/paragraph.h"
namespace blink {
class ParagraphImplTxt : public ParagraphImpl {
public:
~ParagraphImplTxt() override;
explicit ParagraphImplTxt(std::unique_ptr<txt::Paragraph> paragraph);
double width() override;
double height() override;
double minIntrinsicWidth() override;
double maxIntrinsicWidth() override;
double alphabeticBaseline() override;
double ideographicBaseline() override;
bool didExceedMaxLines() override;
void layout(double width) override;
void paint(Canvas* canvas, double x, double y) override;
std::vector<TextBox> getRectsForRange(unsigned start, unsigned end) override;
Dart_Handle getPositionForOffset(double dx, double dy) override;
Dart_Handle getWordBoundary(unsigned offset) override;
private:
std::unique_ptr<txt::Paragraph> m_paragraph;
double m_width = -1.0;
};
} // namespace blink
#endif // FLUTTER_LIB_UI_TEXT_PARAGRAPH_IMPL_TXT_H_
......@@ -40,6 +40,7 @@ source_set("embedded_resources_cc") {
}
source_set("runtime") {
sources = [
"asset_font_selector.cc",
"asset_font_selector.h",
......@@ -82,6 +83,7 @@ source_set("runtime") {
"//lib/tonic",
"//third_party/rapidjson",
"//third_party/skia",
"//flutter/third_party/txt",
]
defines = []
......
......@@ -5,6 +5,7 @@
#include "flutter/runtime/asset_font_selector.h"
#include "flutter/assets/zip_asset_store.h"
#include "flutter/lib/ui/text/font_collection_mgr.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/sky/engine/platform/fonts/FontData.h"
#include "flutter/sky/engine/platform/fonts/FontFaceCreationParams.h"
......@@ -35,6 +36,7 @@ struct AssetFontSelector::TypefaceAsset {
};
namespace {
const char kFontManifestAssetPath[] = "FontManifest.json";
// Weight values corresponding to the members of the FontWeight enum.
......@@ -76,7 +78,8 @@ struct FontMatcher {
const FontDescription& description_;
int target_weight_;
};
}
} // namespace
void AssetFontSelector::Install(ftl::RefPtr<ZipAssetStore> asset_store) {
RefPtr<AssetFontSelector> font_selector =
......
......@@ -147,6 +147,9 @@ void Shell::InitStandalone(ftl::CommandLine command_line,
settings.enable_software_rendering =
command_line.HasOption(FlagForSwitch(Switch::EnableSoftwareRendering));
settings.using_blink =
!command_line.HasOption(FlagForSwitch(Switch::EnableTxt));
settings.endless_trace_buffer =
command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer));
......@@ -242,7 +245,8 @@ void Shell::GetRasterizers(std::vector<ftl::WeakPtr<Rasterizer>>* rasterizers) {
*rasterizers = rasterizers_;
}
void Shell::AddPlatformView(const std::shared_ptr<PlatformView>& platform_view) {
void Shell::AddPlatformView(
const std::shared_ptr<PlatformView>& platform_view) {
std::lock_guard<std::mutex> lk(platform_views_mutex_);
if (platform_view) {
platform_views_.push_back(platform_view);
......@@ -318,7 +322,8 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
for (auto it = platform_views_.begin(); it != platform_views_.end(); it++) {
std::shared_ptr<PlatformView> view = it->lock();
if (!view) continue;
if (!view)
continue;
if (reinterpret_cast<uintptr_t>(view.get()) == view_id) {
*view_existed = true;
view->RunFromSource(assets_directory, main, packages);
......
......@@ -65,6 +65,9 @@ DEF_SWITCH(EnableSoftwareRendering,
"Enable rendering using the Skia software backend. This is useful"
"when testing Flutter on emulators. By default, Flutter will"
"attempt to either use OpenGL or Vulkan.")
DEF_SWITCH(EnableTxt,
"enable-txt",
"Enable libtxt as the text shaping library instead of Blink.")
DEF_SWITCH(FLX, "flx", "Specify the the FLX path.")
DEF_SWITCH(Help, "help", "Display this help text.")
DEF_SWITCH(LogTag, "log-tag", "Tag associated with log messages.")
......
......@@ -9364,10 +9364,18 @@ FILE: ../../../flutter/lib/ui/painting/shader.cc
FILE: ../../../flutter/lib/ui/painting/shader.h
FILE: ../../../flutter/lib/ui/pointer.dart
FILE: ../../../flutter/lib/ui/text.dart
FILE: ../../../flutter/lib/ui/text/font_collection_mgr.cc
FILE: ../../../flutter/lib/ui/text/font_collection_mgr.h
FILE: ../../../flutter/lib/ui/text/paragraph.cc
FILE: ../../../flutter/lib/ui/text/paragraph.h
FILE: ../../../flutter/lib/ui/text/paragraph_builder.cc
FILE: ../../../flutter/lib/ui/text/paragraph_builder.h
FILE: ../../../flutter/lib/ui/text/paragraph_impl.cc
FILE: ../../../flutter/lib/ui/text/paragraph_impl.h
FILE: ../../../flutter/lib/ui/text/paragraph_impl_blink.cc
FILE: ../../../flutter/lib/ui/text/paragraph_impl_blink.h
FILE: ../../../flutter/lib/ui/text/paragraph_impl_txt.cc
FILE: ../../../flutter/lib/ui/text/paragraph_impl_txt.h
FILE: ../../../flutter/lib/ui/text/text_box.cc
FILE: ../../../flutter/lib/ui/ui.dart
FILE: ../../../flutter/lib/ui/ui_dart_state.cc
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册