mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Rebase the libtxt integration by @GaryQian onto the current engine head (#4022)
See https://github.com/flutter/engine/pull/3964
This commit is contained in:
parent
32447c72fc
commit
0fc962f0dc
1
BUILD.gn
1
BUILD.gn
@ -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) {
|
||||
|
||||
2
DEPS
2
DEPS
@ -130,7 +130,7 @@ deps = {
|
||||
'src/lib/zip':
|
||||
Var('fuchsia_git') + '/zip' + '@' + '92dc87ca645fe8e9f5151ef6dac86d8311a7222f',
|
||||
|
||||
'src/third_party/benchmark':
|
||||
'src/third_party/benchmark':
|
||||
Var('fuchsia_git') + '/third_party/benchmark' + '@' + '296537bc48d380adf21567c5d736ab79f5363d22',
|
||||
|
||||
'src/third_party/gtest':
|
||||
|
||||
@ -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",
|
||||
|
||||
52
lib/ui/text/font_collection_mgr.cc
Normal file
52
lib/ui/text/font_collection_mgr.cc
Normal file
@ -0,0 +1,52 @@
|
||||
// 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
|
||||
44
lib/ui/text/font_collection_mgr.h
Normal file
44
lib/ui/text/font_collection_mgr.h
Normal file
@ -0,0 +1,44 @@
|
||||
// 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"
|
||||
@ -31,7 +34,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) \
|
||||
@ -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,13 +102,12 @@ void createFontForDocument(RenderStyle* style) {
|
||||
style->font().update(UIDartState::Current()->font_selector());
|
||||
}
|
||||
|
||||
PassRefPtr<RenderStyle> decodeParagraphStyle(
|
||||
RenderStyle* parentStyle,
|
||||
tonic::Int32List& encoded,
|
||||
const std::string& fontFamily,
|
||||
double fontSize,
|
||||
double lineHeight,
|
||||
const std::string& ellipsis) {
|
||||
PassRefPtr<RenderStyle> decodeParagraphStyle(RenderStyle* parentStyle,
|
||||
tonic::Int32List& encoded,
|
||||
const std::string& fontFamily,
|
||||
double fontSize,
|
||||
double lineHeight,
|
||||
const std::string& ellipsis) {
|
||||
FTL_DCHECK(encoded.num_elements() == 5);
|
||||
|
||||
RefPtr<RenderStyle> style = RenderStyle::create();
|
||||
@ -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,24 +202,61 @@ ParagraphBuilder::ParagraphBuilder(tonic::Int32List& encoded,
|
||||
double fontSize,
|
||||
double lineHeight,
|
||||
const std::string& ellipsis) {
|
||||
createRenderView();
|
||||
if (!Settings::Get().using_blink) {
|
||||
int32_t mask = encoded[0];
|
||||
txt::ParagraphStyle style;
|
||||
if (mask & psTextAlignMask)
|
||||
style.text_align = txt::TextAlign(encoded[psTextAlignIndex]);
|
||||
|
||||
RefPtr<RenderStyle> paragraphStyle = decodeParagraphStyle(
|
||||
m_renderView->style(), encoded, fontFamily, fontSize, lineHeight, ellipsis);
|
||||
encoded.Release();
|
||||
if (mask & (psFontWeightMask | psFontStyleMask | psFontFamilyMask |
|
||||
psFontSizeMask)) {
|
||||
if (mask & psFontWeightMask)
|
||||
style.font_weight =
|
||||
static_cast<txt::FontWeight>(encoded[psFontWeightIndex]);
|
||||
|
||||
m_renderParagraph = new RenderParagraph();
|
||||
m_renderParagraph->setStyle(paragraphStyle.release());
|
||||
if (mask & psFontStyleMask)
|
||||
style.font_style =
|
||||
static_cast<txt::FontStyle>(encoded[psFontStyleIndex]);
|
||||
|
||||
m_currentRenderObject = m_renderParagraph;
|
||||
m_renderView->addChild(m_currentRenderObject);
|
||||
}
|
||||
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);
|
||||
encoded.Release();
|
||||
|
||||
m_renderParagraph = new RenderParagraph();
|
||||
m_renderParagraph->setStyle(paragraphStyle.release());
|
||||
|
||||
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,98 +267,169 @@ 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 (mask & tsColorMask)
|
||||
style->setColor(getColorFromARGB(encoded[tsColorIndex]));
|
||||
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 & tsTextDecorationMask) {
|
||||
style->setTextDecoration(
|
||||
static_cast<TextDecoration>(encoded[tsTextDecorationIndex]));
|
||||
style->applyTextDecorations();
|
||||
}
|
||||
if (mask & tsColorMask)
|
||||
style.color = encoded[tsColorIndex];
|
||||
|
||||
if (mask & tsTextDecorationColorMask)
|
||||
style->setTextDecorationColor(
|
||||
StyleColor(getColorFromARGB(encoded[tsTextDecorationColorIndex])));
|
||||
|
||||
if (mask & tsTextDecorationStyleMask)
|
||||
style->setTextDecorationStyle(
|
||||
static_cast<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)) {
|
||||
FontDescription fontDescription = style->fontDescription();
|
||||
|
||||
if (mask & tsFontWeightMask)
|
||||
fontDescription.setWeight(
|
||||
static_cast<FontWeight>(encoded[tsFontWeightIndex]));
|
||||
|
||||
if (mask & tsFontStyleMask)
|
||||
fontDescription.setStyle(
|
||||
static_cast<FontStyle>(encoded[tsFontStyleIndex]));
|
||||
|
||||
if (mask & tsFontFamilyMask) {
|
||||
FontFamily family;
|
||||
family.setFamily(String::fromUTF8(fontFamily));
|
||||
fontDescription.setFamily(family);
|
||||
if (mask & tsTextDecorationMask) {
|
||||
style.decoration =
|
||||
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
|
||||
}
|
||||
|
||||
if (mask & tsFontSizeMask) {
|
||||
fontDescription.setSpecifiedSize(fontSize);
|
||||
fontDescription.setIsAbsoluteSize(true);
|
||||
fontDescription.setComputedSize(
|
||||
getComputedSizeFromSpecifiedSize(fontSize));
|
||||
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 & tsLetterSpacingMask)
|
||||
fontDescription.setLetterSpacing(letterSpacing);
|
||||
if (mask & (tsFontWeightMask | tsFontStyleMask | tsFontFamilyMask |
|
||||
tsFontSizeMask | tsLetterSpacingMask | tsWordSpacingMask)) {
|
||||
if (mask & tsFontWeightMask)
|
||||
style.font_weight =
|
||||
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
|
||||
|
||||
if (mask & tsWordSpacingMask)
|
||||
fontDescription.setWordSpacing(wordSpacing);
|
||||
if (mask & tsFontStyleMask)
|
||||
style.font_style =
|
||||
static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
|
||||
|
||||
style->setFontDescription(fontDescription);
|
||||
style->font().update(UIDartState::Current()->font_selector());
|
||||
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]));
|
||||
|
||||
if (mask & tsTextDecorationMask) {
|
||||
style->setTextDecoration(
|
||||
static_cast<TextDecoration>(encoded[tsTextDecorationIndex]));
|
||||
style->applyTextDecorations();
|
||||
}
|
||||
|
||||
if (mask & tsTextDecorationColorMask)
|
||||
style->setTextDecorationColor(
|
||||
StyleColor(getColorFromARGB(encoded[tsTextDecorationColorIndex])));
|
||||
|
||||
if (mask & tsTextDecorationStyleMask)
|
||||
style->setTextDecorationStyle(static_cast<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)) {
|
||||
FontDescription fontDescription = style->fontDescription();
|
||||
|
||||
if (mask & tsFontWeightMask)
|
||||
fontDescription.setWeight(
|
||||
static_cast<FontWeight>(encoded[tsFontWeightIndex]));
|
||||
|
||||
if (mask & tsFontStyleMask)
|
||||
fontDescription.setStyle(
|
||||
static_cast<FontStyle>(encoded[tsFontStyleIndex]));
|
||||
|
||||
if (mask & tsFontFamilyMask) {
|
||||
FontFamily family;
|
||||
family.setFamily(String::fromUTF8(fontFamily));
|
||||
fontDescription.setFamily(family);
|
||||
}
|
||||
|
||||
if (mask & tsFontSizeMask) {
|
||||
fontDescription.setSpecifiedSize(fontSize);
|
||||
fontDescription.setIsAbsoluteSize(true);
|
||||
fontDescription.setComputedSize(
|
||||
getComputedSizeFromSpecifiedSize(fontSize));
|
||||
}
|
||||
|
||||
if (mask & tsLetterSpacingMask)
|
||||
fontDescription.setLetterSpacing(letterSpacing);
|
||||
|
||||
if (mask & tsWordSpacingMask)
|
||||
fontDescription.setWordSpacing(wordSpacing);
|
||||
|
||||
style->setFontDescription(fontDescription);
|
||||
style->font().update(UIDartState::Current()->font_selector());
|
||||
}
|
||||
|
||||
if (mask & tsHeightMask) {
|
||||
style->setLineHeight(Length(height * 100.0, Percent));
|
||||
}
|
||||
|
||||
encoded.Release();
|
||||
|
||||
RenderObject* span = new RenderInline();
|
||||
span->setStyle(style.release());
|
||||
m_currentRenderObject->addChild(span);
|
||||
m_currentRenderObject = span;
|
||||
}
|
||||
|
||||
if (mask & tsHeightMask) {
|
||||
style->setLineHeight(Length(height * 100.0, Percent));
|
||||
}
|
||||
|
||||
encoded.Release();
|
||||
|
||||
RenderObject* span = new RenderInline();
|
||||
span->setStyle(style.release());
|
||||
m_currentRenderObject->addChild(span);
|
||||
m_currentRenderObject = span;
|
||||
}
|
||||
|
||||
void ParagraphBuilder::pop() {
|
||||
if (m_currentRenderObject)
|
||||
m_currentRenderObject = m_currentRenderObject->parent();
|
||||
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 (!m_currentRenderObject)
|
||||
return;
|
||||
RenderText* renderText = new RenderText(String::fromUTF8(text).impl());
|
||||
RefPtr<RenderStyle> style = RenderStyle::create();
|
||||
style->inheritFrom(m_currentRenderObject->style());
|
||||
renderText->setStyle(style.release());
|
||||
m_currentRenderObject->addChild(renderText);
|
||||
if (!Settings::Get().using_blink) {
|
||||
m_paragraphBuilder.AddText(text);
|
||||
} else {
|
||||
// Blink Version.
|
||||
if (!m_currentRenderObject)
|
||||
return;
|
||||
RenderText* renderText = new RenderText(String::fromUTF8(text).impl());
|
||||
RefPtr<RenderStyle> style = RenderStyle::create();
|
||||
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
|
||||
|
||||
7
lib/ui/text/paragraph_impl.cc
Normal file
7
lib/ui/text/paragraph_impl.cc
Normal file
@ -0,0 +1,7 @@
|
||||
// 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
|
||||
45
lib/ui/text/paragraph_impl.h
Normal file
45
lib/ui/text/paragraph_impl.h
Normal file
@ -0,0 +1,45 @@
|
||||
// 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_
|
||||
180
lib/ui/text/paragraph_impl_blink.cc
Normal file
180
lib/ui/text/paragraph_impl_blink.cc
Normal file
@ -0,0 +1,180 @@
|
||||
// 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
|
||||
49
lib/ui/text/paragraph_impl_blink.h
Normal file
49
lib/ui/text/paragraph_impl_blink.h
Normal file
@ -0,0 +1,49 @@
|
||||
// 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_
|
||||
93
lib/ui/text/paragraph_impl_txt.cc
Normal file
93
lib/ui/text/paragraph_impl_txt.cc
Normal file
@ -0,0 +1,93 @@
|
||||
// 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
|
||||
44
lib/ui/text/paragraph_impl_txt.h
Normal file
44
lib/ui/text/paragraph_impl_txt.h
Normal file
@ -0,0 +1,44 @@
|
||||
// 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user