mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reland "Initial integration of libtxt with Flutter alongside Blink." (flutter/engine#3793)
* Transition to Hybrid lib/txt and blink text system.
This commit is contained in:
parent
ec07bed91f
commit
d9bc2f5604
3
DEPS
3
DEPS
@ -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',
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ group("flutter") {
|
||||
deps = [
|
||||
"//flutter/lib/snapshot:generate_snapshot_bin",
|
||||
"//flutter/sky",
|
||||
"//lib/txt",
|
||||
]
|
||||
|
||||
if (is_fuchsia) {
|
||||
@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
source_set("ui") {
|
||||
|
||||
sources = [
|
||||
"compositing/scene.cc",
|
||||
"compositing/scene.h",
|
||||
@ -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",
|
||||
@ -83,5 +90,6 @@ source_set("ui") {
|
||||
"//lib/tonic",
|
||||
"//third_party/skia",
|
||||
"//third_party/skia:gpu",
|
||||
"//lib/txt",
|
||||
]
|
||||
}
|
||||
|
||||
@ -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"
|
||||
@ -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) \
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
@ -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();
|
||||
@ -48,12 +58,14 @@ class Paragraph : public ftl::RefCountedThreadSafe<Paragraph>,
|
||||
static void RegisterNatives(tonic::DartLibraryNatives* natives);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ParagraphImpl> m_paragraphImpl;
|
||||
|
||||
RenderBox* firstChildBox() const { return m_renderView->firstChildBox(); }
|
||||
|
||||
int absoluteOffsetForPosition(const PositionWithAffinity& position);
|
||||
|
||||
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"
|
||||
@ -16,6 +17,12 @@
|
||||
#include "lib/tonic/dart_args.h"
|
||||
#include "lib/tonic/dart_binding_macros.h"
|
||||
#include "lib/tonic/dart_library_natives.h"
|
||||
#include "lib/txt/src/font_style.h"
|
||||
#include "lib/txt/src/font_weight.h"
|
||||
#include "lib/txt/src/paragraph_style.h"
|
||||
#include "lib/txt/src/text_align.h"
|
||||
#include "lib/txt/src/text_decoration.h"
|
||||
#include "lib/txt/src/text_style.h"
|
||||
|
||||
namespace blink {
|
||||
namespace {
|
||||
@ -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,167 @@ 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) {
|
||||
txt::TextStyle tstyle;
|
||||
|
||||
if (mask & tsTextDecorationMask) {
|
||||
style->setTextDecoration(
|
||||
static_cast<TextDecoration>(encoded[tsTextDecorationIndex]));
|
||||
style->applyTextDecorations();
|
||||
}
|
||||
if (mask & tsColorMask)
|
||||
tstyle.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) {
|
||||
tstyle.decoration =
|
||||
static_cast<txt::TextDecoration>(encoded[tsTextDecorationIndex]);
|
||||
}
|
||||
|
||||
if (mask & tsFontSizeMask) {
|
||||
fontDescription.setSpecifiedSize(fontSize);
|
||||
fontDescription.setIsAbsoluteSize(true);
|
||||
fontDescription.setComputedSize(
|
||||
getComputedSizeFromSpecifiedSize(fontSize));
|
||||
if (mask & tsTextDecorationColorMask)
|
||||
tstyle.decoration_color = encoded[tsTextDecorationColorIndex];
|
||||
|
||||
if (mask & tsTextDecorationStyleMask)
|
||||
tstyle.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)
|
||||
tstyle.font_weight =
|
||||
static_cast<txt::FontWeight>(encoded[tsFontWeightIndex]);
|
||||
|
||||
if (mask & tsWordSpacingMask)
|
||||
fontDescription.setWordSpacing(wordSpacing);
|
||||
if (mask & tsFontStyleMask)
|
||||
tstyle.font_style =
|
||||
static_cast<txt::FontStyle>(encoded[tsFontStyleIndex]);
|
||||
|
||||
style->setFontDescription(fontDescription);
|
||||
style->font().update(UIDartState::Current()->font_selector());
|
||||
if (mask & tsFontFamilyMask)
|
||||
tstyle.font_family = fontFamily;
|
||||
|
||||
if (mask & tsFontSizeMask)
|
||||
tstyle.font_size = fontSize;
|
||||
|
||||
if (mask & tsLetterSpacingMask)
|
||||
tstyle.letter_spacing = letterSpacing;
|
||||
|
||||
if (mask & tsWordSpacingMask)
|
||||
tstyle.word_spacing = wordSpacing;
|
||||
}
|
||||
|
||||
if (mask & tsHeightMask) {
|
||||
tstyle.height = height;
|
||||
}
|
||||
|
||||
m_paragraphBuilder.PushStyle(tstyle);
|
||||
} 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,8 +6,11 @@
|
||||
#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 "lib/tonic/dart_wrappable.h"
|
||||
#include "lib/tonic/typed_data/int32_list.h"
|
||||
#include "lib/txt/src/paragraph_builder.h"
|
||||
|
||||
namespace tonic {
|
||||
class DartLibraryNatives;
|
||||
@ -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
engine/src/flutter/lib/ui/text/paragraph_impl.cc
Normal file
7
engine/src/flutter/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
engine/src/flutter/lib/ui/text/paragraph_impl.h
Normal file
45
engine/src/flutter/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
engine/src/flutter/lib/ui/text/paragraph_impl_blink.cc
Normal file
180
engine/src/flutter/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
engine/src/flutter/lib/ui/text/paragraph_impl_blink.h
Normal file
49
engine/src/flutter/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 "lib/txt/src/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_
|
||||
75
engine/src/flutter/lib/ui/text/paragraph_impl_txt.cc
Normal file
75
engine/src/flutter/lib/ui/text/paragraph_impl_txt.cc
Normal file
@ -0,0 +1,75 @@
|
||||
// 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/tasks/task_runner.h"
|
||||
#include "lib/txt/src/paragraph_constraints.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
ParagraphImplTxt::ParagraphImplTxt(std::unique_ptr<txt::Paragraph> paragraph)
|
||||
: m_paragraph(std::move(paragraph)) {}
|
||||
|
||||
ParagraphImplTxt::~ParagraphImplTxt() {}
|
||||
|
||||
double ParagraphImplTxt::width() {
|
||||
return m_width;
|
||||
}
|
||||
|
||||
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(txt::ParagraphConstraints{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) {
|
||||
return std::vector<TextBox>{0ull};
|
||||
}
|
||||
|
||||
Dart_Handle ParagraphImplTxt::getPositionForOffset(double dx, double dy) {
|
||||
// TODO(garyq): Implement in the library.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Dart_Handle ParagraphImplTxt::getWordBoundary(unsigned offset) {
|
||||
// TODO(garyq): Implement in the library.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
44
engine/src/flutter/lib/ui/text/paragraph_impl_txt.h
Normal file
44
engine/src/flutter/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 "lib/txt/src/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_
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -63,6 +63,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.")
|
||||
|
||||
@ -245,6 +245,9 @@ public final class FlutterActivityDelegate
|
||||
if (intent.getBooleanExtra("enable-software-rendering", false)) {
|
||||
args.add("--enable-software-rendering");
|
||||
}
|
||||
if (intent.getBooleanExtra("enable-txt", false)) {
|
||||
args.add("--enable-txt");
|
||||
}
|
||||
if (!args.isEmpty()) {
|
||||
String[] argsArray = new String[args.size()];
|
||||
return args.toArray(argsArray);
|
||||
|
||||
@ -9162,6 +9162,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--------------------------------------------------------------------------------
|
||||
etc1
|
||||
lib
|
||||
observatory_pub_packages
|
||||
skia
|
||||
vulkan
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user