diff --git a/display_list/display_list_builder.cc b/display_list/display_list_builder.cc index ccef2769aeaaf..81c06b08b1be0 100644 --- a/display_list/display_list_builder.cc +++ b/display_list/display_list_builder.cc @@ -1071,6 +1071,13 @@ void DisplayListBuilder::drawTextBlob(const sk_sp blob, Push(0, 1, blob, x, y); CheckLayerOpacityCompatibility(); } +void DisplayListBuilder::drawTextBlob(const sk_sp& blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) { + setAttributesFromDlPaint(paint, DisplayListOpFlags::kDrawTextBlobFlags); + drawTextBlob(blob, x, y); +} void DisplayListBuilder::drawShadow(const SkPath& path, const DlColor color, const SkScalar elevation, diff --git a/display_list/display_list_builder.h b/display_list/display_list_builder.h index 8bcc3ffa56db6..5be4146b14e45 100644 --- a/display_list/display_list_builder.h +++ b/display_list/display_list_builder.h @@ -334,6 +334,10 @@ class DisplayListBuilder final : public virtual Dispatcher, void drawTextBlob(const sk_sp blob, SkScalar x, SkScalar y) override; + void drawTextBlob(const sk_sp& blob, + SkScalar x, + SkScalar y, + const DlPaint& paint); void drawShadow(const SkPath& path, const DlColor color, const SkScalar elevation, @@ -503,7 +507,6 @@ class DisplayListBuilder final : public virtual Dispatcher, void onSetColorFilter(const DlColorFilter* filter); void onSetPathEffect(const DlPathEffect* effect); void onSetMaskFilter(const DlMaskFilter* filter); - void onSetMaskBlurFilter(SkBlurStyle style, SkScalar sigma); DlPaint current_; // If |current_blender_| is set then ignore |current_.getBlendMode()| diff --git a/display_list/display_list_mask_filter.h b/display_list/display_list_mask_filter.h index 56233421a9638..336d7c58e74fd 100644 --- a/display_list/display_list_mask_filter.h +++ b/display_list/display_list_mask_filter.h @@ -58,12 +58,13 @@ class DlMaskFilter // filter is then used to combine those colors. class DlBlurMaskFilter final : public DlMaskFilter { public: - DlBlurMaskFilter(SkBlurStyle style, SkScalar sigma) - : style_(style), sigma_(sigma) {} + DlBlurMaskFilter(SkBlurStyle style, SkScalar sigma, bool respect_ctm = true) + : style_(style), sigma_(sigma), respect_ctm_(respect_ctm) {} DlBlurMaskFilter(const DlBlurMaskFilter& filter) - : DlBlurMaskFilter(filter.style_, filter.sigma_) {} + : DlBlurMaskFilter(filter.style_, filter.sigma_, filter.respect_ctm_) {} DlBlurMaskFilter(const DlBlurMaskFilter* filter) - : DlBlurMaskFilter(filter->style_, filter->sigma_) {} + : DlBlurMaskFilter(filter->style_, filter->sigma_, filter->respect_ctm_) { + } DlMaskFilterType type() const override { return DlMaskFilterType::kBlur; } size_t size() const override { return sizeof(*this); } @@ -73,24 +74,29 @@ class DlBlurMaskFilter final : public DlMaskFilter { } sk_sp skia_object() const override { - return SkMaskFilter::MakeBlur(style_, sigma_); + return SkMaskFilter::MakeBlur(style_, sigma_, respect_ctm_); } const DlBlurMaskFilter* asBlur() const override { return this; } SkBlurStyle style() const { return style_; } SkScalar sigma() const { return sigma_; } + bool respectCTM() const { return respect_ctm_; } protected: bool equals_(DlMaskFilter const& other) const override { FML_DCHECK(other.type() == DlMaskFilterType::kBlur); auto that = static_cast(&other); - return style_ == that->style_ && sigma_ == that->sigma_; + return style_ == that->style_ && sigma_ == that->sigma_ && + respect_ctm_ == that->respect_ctm_; } private: SkBlurStyle style_; SkScalar sigma_; + // Added for backward compatibility with Flutter text shadow rendering which + // uses Skia blur filters with this flag set to false. + bool respect_ctm_; }; // A wrapper class for a Skia MaskFilter of unknown type. The above 4 types diff --git a/display_list/display_list_test_utils.cc b/display_list/display_list_test_utils.cc index 74e9c9ed4ee2e..144fe140d7490 100644 --- a/display_list/display_list_test_utils.cc +++ b/display_list/display_list_test_utils.cc @@ -284,15 +284,15 @@ std::vector CreateAllAttributesOps() { }}, {"SetMaskFilter", { - {0, 24, 0, 0, + {0, 32, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter1); }}, - {0, 24, 0, 0, + {0, 32, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter2); }}, - {0, 24, 0, 0, + {0, 32, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter3); }}, - {0, 24, 0, 0, + {0, 32, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter4); }}, - {0, 24, 0, 0, + {0, 32, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter5); }}, {0, 0, 0, 0, [](DisplayListBuilder& b) { b.setMaskFilter(nullptr); }}, diff --git a/lib/ui/painting/canvas.h b/lib/ui/painting/canvas.h index 22ef44315ca09..0855c52c20f8c 100644 --- a/lib/ui/painting/canvas.h +++ b/lib/ui/painting/canvas.h @@ -190,6 +190,11 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { SkCanvas* canvas() const { return canvas_; } void Invalidate(); + DisplayListBuilder* builder() { + return display_list_recorder_ ? display_list_recorder_->builder().get() + : nullptr; + } + private: explicit Canvas(SkCanvas* canvas); @@ -205,9 +210,6 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { // paint attributes from an SkPaint and an operation type as well as access // to the raw DisplayListBuilder for emitting custom rendering operations. sk_sp display_list_recorder_; - DisplayListBuilder* builder() { - return display_list_recorder_->builder().get(); - } }; } // namespace flutter diff --git a/lib/ui/text/paragraph.cc b/lib/ui/text/paragraph.cc index 6b4bb3610bc50..4b3df6439186d 100644 --- a/lib/ui/text/paragraph.cc +++ b/lib/ui/text/paragraph.cc @@ -64,11 +64,15 @@ void Paragraph::paint(Canvas* canvas, double x, double y) { return; } - SkCanvas* sk_canvas = canvas->canvas(); - if (!sk_canvas) { + DisplayListBuilder* builder = canvas->builder(); + if (builder && m_paragraph->Paint(builder, x, y)) { return; } - m_paragraph->Paint(sk_canvas, x, y); + // Fall back to SkCanvas if painting to DisplayListBuilder is not supported. + SkCanvas* sk_canvas = canvas->canvas(); + if (sk_canvas) { + m_paragraph->Paint(sk_canvas, x, y); + } } static tonic::Float32List EncodeTextBoxes( diff --git a/lib/ui/text/paragraph_builder.cc b/lib/ui/text/paragraph_builder.cc index 03daf9358452c..82881ede24eda 100644 --- a/lib/ui/text/paragraph_builder.cc +++ b/lib/ui/text/paragraph_builder.cc @@ -472,6 +472,9 @@ void ParagraphBuilder::pushStyle(const tonic::Int32List& encoded, SkPaint sk_paint; style.has_background = true; style.background = *background.paint(sk_paint); + DlPaint dl_paint; + background.toDlPaint(dl_paint); + style.background_dl = dl_paint; } } @@ -481,6 +484,9 @@ void ParagraphBuilder::pushStyle(const tonic::Int32List& encoded, SkPaint sk_paint; style.has_foreground = true; style.foreground = *foreground.paint(sk_paint); + DlPaint dl_paint; + foreground.toDlPaint(dl_paint); + style.foreground_dl = dl_paint; } } diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index 98327626ec2aa..3060859fe4773 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -143,6 +143,7 @@ source_set("txt") { configs += [ ":define_skshaper" ] public_deps = [ + "//flutter/display_list", "//flutter/fml", "//third_party/harfbuzz", "//third_party/icu", diff --git a/third_party/txt/src/skia/paragraph_builder_skia.cc b/third_party/txt/src/skia/paragraph_builder_skia.cc index 79b7a65adb413..272b6e09cb21e 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.cc +++ b/third_party/txt/src/skia/paragraph_builder_skia.cc @@ -42,10 +42,68 @@ SkFontStyle MakeSkFontStyle(txt::FontWeight font_weight, : SkFontStyle::Slant::kItalic_Slant); } -skt::ParagraphStyle TxtToSkia(const ParagraphStyle& txt) { +} // anonymous namespace + +ParagraphBuilderSkia::ParagraphBuilderSkia( + const ParagraphStyle& style, + std::shared_ptr font_collection) + : base_style_(style.GetTextStyle()) { + builder_ = skt::ParagraphBuilder::make( + TxtToSkia(style), font_collection->CreateSktFontCollection()); +} + +ParagraphBuilderSkia::~ParagraphBuilderSkia() = default; + +void ParagraphBuilderSkia::PushStyle(const TextStyle& style) { + builder_->pushStyle(TxtToSkia(style)); + txt_style_stack_.push(style); +} + +void ParagraphBuilderSkia::Pop() { + builder_->pop(); + txt_style_stack_.pop(); +} + +const TextStyle& ParagraphBuilderSkia::PeekStyle() { + return txt_style_stack_.empty() ? base_style_ : txt_style_stack_.top(); +} + +void ParagraphBuilderSkia::AddText(const std::u16string& text) { + builder_->addText(text); +} + +void ParagraphBuilderSkia::AddPlaceholder(PlaceholderRun& span) { + skt::PlaceholderStyle placeholder_style; + placeholder_style.fHeight = span.height; + placeholder_style.fWidth = span.width; + placeholder_style.fBaseline = static_cast(span.baseline); + placeholder_style.fBaselineOffset = span.baseline_offset; + placeholder_style.fAlignment = + static_cast(span.alignment); + + builder_->addPlaceholder(placeholder_style); +} + +std::unique_ptr ParagraphBuilderSkia::Build() { + return std::make_unique(builder_->Build(), + std::move(dl_paints_)); +} + +skt::ParagraphPainter::PaintID ParagraphBuilderSkia::CreatePaintID( + const flutter::DlPaint& dl_paint) { + dl_paints_.push_back(dl_paint); + return dl_paints_.size() - 1; +} + +skt::ParagraphStyle ParagraphBuilderSkia::TxtToSkia(const ParagraphStyle& txt) { skt::ParagraphStyle skia; skt::TextStyle text_style; + // Convert the default color of an SkParagraph text style into a DlPaint. + flutter::DlPaint dl_paint; + dl_paint.setColor(text_style.getColor()); + text_style.setForegroundPaintID(CreatePaintID(dl_paint)); + text_style.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style)); text_style.setFontSize(SkDoubleToScalar(txt.font_size)); text_style.setHeight(SkDoubleToScalar(txt.height)); @@ -84,7 +142,7 @@ skt::ParagraphStyle TxtToSkia(const ParagraphStyle& txt) { return skia; } -skt::TextStyle TxtToSkia(const TextStyle& txt) { +skt::TextStyle ParagraphBuilderSkia::TxtToSkia(const TextStyle& txt) { skt::TextStyle skia; skia.setColor(txt.color); @@ -112,10 +170,14 @@ skt::TextStyle TxtToSkia(const TextStyle& txt) { skia.setLocale(SkString(txt.locale.c_str())); if (txt.has_background) { - skia.setBackgroundColor(txt.background); + skia.setBackgroundPaintID(CreatePaintID(txt.background_dl)); } if (txt.has_foreground) { - skia.setForegroundColor(txt.foreground); + skia.setForegroundPaintID(CreatePaintID(txt.foreground_dl)); + } else { + flutter::DlPaint dl_paint; + dl_paint.setColor(txt.color); + skia.setForegroundPaintID(CreatePaintID(dl_paint)); } skia.resetFontFeatures(); @@ -153,50 +215,4 @@ skt::TextStyle TxtToSkia(const TextStyle& txt) { return skia; } -} // anonymous namespace - -ParagraphBuilderSkia::ParagraphBuilderSkia( - const ParagraphStyle& style, - std::shared_ptr font_collection) - : builder_(skt::ParagraphBuilder::make( - TxtToSkia(style), - font_collection->CreateSktFontCollection())), - base_style_(style.GetTextStyle()) {} - -ParagraphBuilderSkia::~ParagraphBuilderSkia() = default; - -void ParagraphBuilderSkia::PushStyle(const TextStyle& style) { - builder_->pushStyle(TxtToSkia(style)); - txt_style_stack_.push(style); -} - -void ParagraphBuilderSkia::Pop() { - builder_->pop(); - txt_style_stack_.pop(); -} - -const TextStyle& ParagraphBuilderSkia::PeekStyle() { - return txt_style_stack_.empty() ? base_style_ : txt_style_stack_.top(); -} - -void ParagraphBuilderSkia::AddText(const std::u16string& text) { - builder_->addText(text); -} - -void ParagraphBuilderSkia::AddPlaceholder(PlaceholderRun& span) { - skt::PlaceholderStyle placeholder_style; - placeholder_style.fHeight = span.height; - placeholder_style.fWidth = span.width; - placeholder_style.fBaseline = static_cast(span.baseline); - placeholder_style.fBaselineOffset = span.baseline_offset; - placeholder_style.fAlignment = - static_cast(span.alignment); - - builder_->addPlaceholder(placeholder_style); -} - -std::unique_ptr ParagraphBuilderSkia::Build() { - return std::make_unique(builder_->Build()); -} - } // namespace txt diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h index 06b00caf43c52..58869cfa0a58b 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.h +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -19,6 +19,7 @@ #include "txt/paragraph_builder.h" +#include "flutter/display_list/display_list_paint.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" namespace txt { @@ -39,9 +40,15 @@ class ParagraphBuilderSkia : public ParagraphBuilder { virtual std::unique_ptr Build() override; private: + skia::textlayout::ParagraphPainter::PaintID CreatePaintID( + const flutter::DlPaint& dl_paint); + skia::textlayout::ParagraphStyle TxtToSkia(const ParagraphStyle& txt); + skia::textlayout::TextStyle TxtToSkia(const TextStyle& txt); + std::shared_ptr builder_; TextStyle base_style_; std::stack txt_style_stack_; + std::vector dl_paints_; }; } // namespace txt diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index 2bf3fbeead623..359a0880de218 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -22,6 +22,9 @@ namespace txt { namespace skt = skia::textlayout; +using PaintID = skt::ParagraphPainter::PaintID; + +using namespace flutter; namespace { @@ -40,54 +43,108 @@ txt::FontStyle GetTxtFontStyle(SkFontStyle::Slant font_slant) { : txt::FontStyle::italic; } -TextStyle SkiaToTxt(const skt::TextStyle& skia) { - TextStyle txt; +class DisplayListParagraphPainter : public skt::ParagraphPainter { + public: + DisplayListParagraphPainter(DisplayListBuilder* builder, + const std::vector& dl_paints) + : builder_(builder), dl_paints_(dl_paints) {} + + DlPaint toDlPaint(const DecorationStyle& decor_style, + DlDrawStyle draw_style = DlDrawStyle::kStroke) { + DlPaint paint; + paint.setDrawStyle(draw_style); + paint.setAntiAlias(true); + paint.setColor(decor_style.getColor()); + paint.setStrokeWidth(decor_style.getStrokeWidth()); + std::optional dash_path_effect = + decor_style.getDashPathEffect(); + if (dash_path_effect) { + std::array intervals{dash_path_effect->fOnLength, + dash_path_effect->fOffLength}; + paint.setPathEffect( + DlDashPathEffect::Make(intervals.data(), intervals.size(), 0)); + } + return paint; + } - txt.color = skia.getColor(); - txt.decoration = static_cast(skia.getDecorationType()); - txt.decoration_color = skia.getDecorationColor(); - txt.decoration_style = - static_cast(skia.getDecorationStyle()); - txt.decoration_thickness_multiplier = - SkScalarToDouble(skia.getDecorationThicknessMultiplier()); - txt.font_weight = GetTxtFontWeight(skia.getFontStyle().weight()); - txt.font_style = GetTxtFontStyle(skia.getFontStyle().slant()); + void drawTextBlob(const sk_sp& blob, + SkScalar x, + SkScalar y, + const SkPaintOrID& paint) override { + if (!blob) { + return; + } + size_t paint_id = std::get(paint); + FML_DCHECK(paint_id < dl_paints_.size()); + builder_->drawTextBlob(blob, x, y, dl_paints_[paint_id]); + } - txt.text_baseline = static_cast(skia.getTextBaseline()); + void drawTextShadow(const sk_sp& blob, + SkScalar x, + SkScalar y, + SkColor color, + SkScalar blur_sigma) override { + if (!blob) { + return; + } + DlPaint paint; + paint.setColor(color); + if (blur_sigma > 0.0) { + DlBlurMaskFilter filter(SkBlurStyle::kNormal_SkBlurStyle, blur_sigma, + false); + paint.setMaskFilter(&filter); + } + builder_->drawTextBlob(blob, x, y, paint); + } - for (const SkString& font_family : skia.getFontFamilies()) { - txt.font_families.emplace_back(font_family.c_str()); + void drawRect(const SkRect& rect, const SkPaintOrID& paint) override { + size_t paint_id = std::get(paint); + FML_DCHECK(paint_id < dl_paints_.size()); + builder_->drawRect(rect, dl_paints_[paint_id]); } - txt.font_size = SkScalarToDouble(skia.getFontSize()); - txt.letter_spacing = SkScalarToDouble(skia.getLetterSpacing()); - txt.word_spacing = SkScalarToDouble(skia.getWordSpacing()); - txt.height = SkScalarToDouble(skia.getHeight()); + void drawFilledRect(const SkRect& rect, + const DecorationStyle& decor_style) override { + DlPaint paint = toDlPaint(decor_style, DlDrawStyle::kFill); + builder_->drawRect(rect, paint); + } - txt.locale = skia.getLocale().c_str(); - if (skia.hasBackground()) { - txt.background = skia.getBackground(); + void drawPath(const SkPath& path, + const DecorationStyle& decor_style) override { + builder_->drawPath(path, toDlPaint(decor_style)); } - if (skia.hasForeground()) { - txt.foreground = skia.getForeground(); + + void drawLine(SkScalar x0, + SkScalar y0, + SkScalar x1, + SkScalar y1, + const DecorationStyle& decor_style) override { + builder_->drawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), + toDlPaint(decor_style)); } - txt.text_shadows.clear(); - for (const skt::TextShadow& skia_shadow : skia.getShadows()) { - txt::TextShadow shadow; - shadow.offset = skia_shadow.fOffset; - shadow.blur_sigma = skia_shadow.fBlurSigma; - shadow.color = skia_shadow.fColor; - txt.text_shadows.emplace_back(shadow); + void clipRect(const SkRect& rect) override { + builder_->clipRect(rect, SkClipOp::kIntersect, false); } - return txt; -} + void translate(SkScalar dx, SkScalar dy) override { + builder_->translate(dx, dy); + } + + void save() override { builder_->save(); } + + void restore() override { builder_->restore(); } + + private: + DisplayListBuilder* builder_; + const std::vector& dl_paints_; +}; } // anonymous namespace -ParagraphSkia::ParagraphSkia(std::unique_ptr paragraph) - : paragraph_(std::move(paragraph)) {} +ParagraphSkia::ParagraphSkia(std::unique_ptr paragraph, + std::vector&& dl_paints) + : paragraph_(std::move(paragraph)), dl_paints_(dl_paints) {} double ParagraphSkia::GetMaxWidth() { return SkScalarToDouble(paragraph_->getMaxWidth()); @@ -170,6 +227,12 @@ void ParagraphSkia::Paint(SkCanvas* canvas, double x, double y) { paragraph_->paint(canvas, x, y); } +bool ParagraphSkia::Paint(DisplayListBuilder* builder, double x, double y) { + DisplayListParagraphPainter painter(builder, dl_paints_); + paragraph_->paint(&painter, x, y); + return true; +} + std::vector ParagraphSkia::GetRectsForRange( size_t start, size_t end, @@ -215,4 +278,60 @@ Paragraph::Range ParagraphSkia::GetWordBoundary(size_t offset) { return Paragraph::Range(range.start, range.end); } +TextStyle ParagraphSkia::SkiaToTxt(const skt::TextStyle& skia) { + TextStyle txt; + + txt.color = skia.getColor(); + txt.decoration = static_cast(skia.getDecorationType()); + txt.decoration_color = skia.getDecorationColor(); + txt.decoration_style = + static_cast(skia.getDecorationStyle()); + txt.decoration_thickness_multiplier = + SkScalarToDouble(skia.getDecorationThicknessMultiplier()); + txt.font_weight = GetTxtFontWeight(skia.getFontStyle().weight()); + txt.font_style = GetTxtFontStyle(skia.getFontStyle().slant()); + + txt.text_baseline = static_cast(skia.getTextBaseline()); + + for (const SkString& font_family : skia.getFontFamilies()) { + txt.font_families.emplace_back(font_family.c_str()); + } + + txt.font_size = SkScalarToDouble(skia.getFontSize()); + txt.letter_spacing = SkScalarToDouble(skia.getLetterSpacing()); + txt.word_spacing = SkScalarToDouble(skia.getWordSpacing()); + txt.height = SkScalarToDouble(skia.getHeight()); + + txt.locale = skia.getLocale().c_str(); + if (skia.hasBackground()) { + skt::ParagraphPainter::SkPaintOrID background = + skia.getBackgroundPaintOrID(); + if (std::holds_alternative(background)) { + txt.background = std::get(background); + } else if (std::holds_alternative(background)) { + txt.background_dl = dl_paints_[std::get(background)]; + } + } + if (skia.hasForeground()) { + skt::ParagraphPainter::SkPaintOrID foreground = + skia.getForegroundPaintOrID(); + if (std::holds_alternative(foreground)) { + txt.foreground = std::get(foreground); + } else if (std::holds_alternative(foreground)) { + txt.foreground_dl = dl_paints_[std::get(foreground)]; + } + } + + txt.text_shadows.clear(); + for (const skt::TextShadow& skia_shadow : skia.getShadows()) { + txt::TextShadow shadow; + shadow.offset = skia_shadow.fOffset; + shadow.blur_sigma = skia_shadow.fBlurSigma; + shadow.color = skia_shadow.fColor; + txt.text_shadows.emplace_back(shadow); + } + + return txt; +} + } // namespace txt diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index 286fbe47ca09c..640ab479d41f7 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -28,7 +28,8 @@ namespace txt { // Implementation of Paragraph based on Skia's text layout module. class ParagraphSkia : public Paragraph { public: - ParagraphSkia(std::unique_ptr paragraph); + ParagraphSkia(std::unique_ptr paragraph, + std::vector&& dl_paints); virtual ~ParagraphSkia() = default; @@ -53,6 +54,7 @@ class ParagraphSkia : public Paragraph { void Layout(double width) override; void Paint(SkCanvas* canvas, double x, double y) override; + bool Paint(flutter::DisplayListBuilder* builder, double x, double y) override; std::vector GetRectsForRange( size_t start, @@ -68,7 +70,10 @@ class ParagraphSkia : public Paragraph { Range GetWordBoundary(size_t offset) override; private: + TextStyle SkiaToTxt(const skia::textlayout::TextStyle& skia); + std::unique_ptr paragraph_; + std::vector dl_paints_; std::optional> line_metrics_; std::vector line_metrics_styles_; }; diff --git a/third_party/txt/src/txt/paragraph.h b/third_party/txt/src/txt/paragraph.h index 2065a2d1cbd17..db713241d5936 100644 --- a/third_party/txt/src/txt/paragraph.h +++ b/third_party/txt/src/txt/paragraph.h @@ -18,6 +18,7 @@ #ifndef LIB_TXT_SRC_PARAGRAPH_H_ #define LIB_TXT_SRC_PARAGRAPH_H_ +#include "flutter/display_list/display_list_builder.h" #include "line_metrics.h" #include "paragraph_style.h" #include "third_party/skia/include/core/SkRect.h" @@ -146,6 +147,9 @@ class Paragraph { // Paints the laid out text onto the supplied SkCanvas at (x, y) offset from // the origin. Only valid after Layout() is called. virtual void Paint(SkCanvas* canvas, double x, double y) = 0; + virtual bool Paint(flutter::DisplayListBuilder* builder, + double x, + double y) = 0; // Returns a vector of bounding boxes that enclose all text between start and // end glyph indexes, including start and excluding end. diff --git a/third_party/txt/src/txt/paragraph_txt.h b/third_party/txt/src/txt/paragraph_txt.h index b536b40ef9a4f..989fc058bed37 100644 --- a/third_party/txt/src/txt/paragraph_txt.h +++ b/third_party/txt/src/txt/paragraph_txt.h @@ -74,6 +74,11 @@ class ParagraphTxt : public Paragraph { virtual void Layout(double width) override; virtual void Paint(SkCanvas* canvas, double x, double y) override; + virtual bool Paint(flutter::DisplayListBuilder* builder, + double x, + double y) override { + return false; + } // Getter for paragraph_style_. const ParagraphStyle& GetParagraphStyle() const; diff --git a/third_party/txt/src/txt/text_style.h b/third_party/txt/src/txt/text_style.h index 2a63c685c81d2..7fcb30a26117f 100644 --- a/third_party/txt/src/txt/text_style.h +++ b/third_party/txt/src/txt/text_style.h @@ -20,6 +20,7 @@ #include #include +#include "flutter/display_list/display_list_paint.h" #include "font_features.h" #include "font_style.h" #include "font_weight.h" @@ -56,8 +57,10 @@ class TextStyle { std::string locale; bool has_background = false; SkPaint background; + flutter::DlPaint background_dl; bool has_foreground = false; SkPaint foreground; + flutter::DlPaint foreground_dl; // An ordered list of shadows where the first shadow will be drawn first (at // the bottom). std::vector text_shadows;