diff --git a/third_party/blink/renderer/core/paint/applied_decoration_painter.cc b/third_party/blink/renderer/core/paint/applied_decoration_painter.cc index 3a8f28e1aeab0..a35f8bb988fb8 100644 --- a/third_party/blink/renderer/core/paint/applied_decoration_painter.cc +++ b/third_party/blink/renderer/core/paint/applied_decoration_painter.cc @@ -10,7 +10,7 @@ namespace blink { -void AppliedDecorationPainter::Paint(const cc::PaintFlags* flags) { +void AppliedDecorationPainter::Paint() { context_.SetStrokeStyle(decoration_info_.StrokeStyle()); context_.SetStrokeColor(decoration_info_.LineColor()); @@ -19,7 +19,7 @@ void AppliedDecorationPainter::Paint(const cc::PaintFlags* flags) { DarkModeFilter::ElementRole::kForeground)); switch (decoration_info_.DecorationStyle()) { case ETextDecorationStyle::kWavy: - PaintWavyTextDecoration(flags); + PaintWavyTextDecoration(); break; case ETextDecorationStyle::kDotted: case ETextDecorationStyle::kDashed: @@ -27,22 +27,20 @@ void AppliedDecorationPainter::Paint(const cc::PaintFlags* flags) { [[fallthrough]]; default: context_.DrawLineForText(decoration_info_.StartPoint(), - decoration_info_.Width(), auto_dark_mode, flags); + decoration_info_.Width(), auto_dark_mode, + decoration_info_.SvgPaintFlags()); if (decoration_info_.DecorationStyle() == ETextDecorationStyle::kDouble) { context_.DrawLineForText( decoration_info_.StartPoint() + gfx::Vector2dF(0, decoration_info_.DoubleOffset()), - decoration_info_.Width(), auto_dark_mode, flags); + decoration_info_.Width(), auto_dark_mode, + decoration_info_.SvgPaintFlags()); } } } -void AppliedDecorationPainter::PaintWavyTextDecoration( - const cc::PaintFlags* unused) { - // FIXME we need to use our own PaintFlags for the shader? - (void)unused; - +void AppliedDecorationPainter::PaintWavyTextDecoration() { // We need this because of the clipping we're doing below, as we paint both // overlines and underlines here. That clip would hide the overlines, when // painting the underlines. diff --git a/third_party/blink/renderer/core/paint/applied_decoration_painter.h b/third_party/blink/renderer/core/paint/applied_decoration_painter.h index e3c3c3853b81b..a37ba4c805e50 100644 --- a/third_party/blink/renderer/core/paint/applied_decoration_painter.h +++ b/third_party/blink/renderer/core/paint/applied_decoration_painter.h @@ -23,10 +23,10 @@ class AppliedDecorationPainter final { const TextDecorationInfo& decoration_info) : context_(context), decoration_info_(decoration_info) {} - void Paint(const cc::PaintFlags* flags = nullptr); + void Paint(); private: - void PaintWavyTextDecoration(const cc::PaintFlags*); + void PaintWavyTextDecoration(); GraphicsContext& context_; const TextDecorationInfo& decoration_info_; diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.cc b/third_party/blink/renderer/core/paint/text_decoration_info.cc index 6469c7101b602..96d6d3c372ddd 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.cc +++ b/third_party/blink/renderer/core/paint/text_decoration_info.cc @@ -313,7 +313,7 @@ void TextDecorationInfo::SetLineData(TextDecorationLine line, Path stroke_path = PrepareWavyStrokePath(); gfx::RectF pattern_rect = ComputeWavyPatternRect(stroke_path); sk_sp tile_record = - PrepareWavyTileRecord(stroke_path, pattern_rect); + PrepareWavyTileRecord(stroke_path, pattern_rect, svg_paint_flags_); wavy_cache = WavyCache{ stroke_path, pattern_rect, tile_record, ResolvedThickness(), LineColor(), IsSpellingOrGrammarError(), @@ -404,16 +404,19 @@ void TextDecorationInfo::SetSpellingOrGrammarErrorLineData( } ETextDecorationStyle TextDecorationInfo::DecorationStyle() const { - if (IsSpellingOrGrammarError()) { -#if BUILDFLAG(IS_MAC) - return ETextDecorationStyle::kDotted; -#else - return ETextDecorationStyle::kWavy; -#endif - } + return ETextDecorationStyle::kWavy; + // return ETextDecorationStyle::kDashed; - DCHECK(applied_text_decoration_); - return applied_text_decoration_->Style(); + // if (IsSpellingOrGrammarError()) { + // #if BUILDFLAG(IS_MAC) + // return ETextDecorationStyle::kDotted; + // #else + // return ETextDecorationStyle::kWavy; + // #endif + // } + + // DCHECK(applied_text_decoration_); + // return applied_text_decoration_->Style(); } Color TextDecorationInfo::LineColor() const { @@ -706,12 +709,20 @@ Path TextDecorationInfo::PrepareWavyStrokePath() const { sk_sp TextDecorationInfo::PrepareWavyTileRecord( const Path& stroke_path, - const gfx::RectF& pattern_rect) const { - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setColor(LineColor().Rgb()); - flags.setStyle(cc::PaintFlags::kStroke_Style); - flags.setStrokeWidth(ResolvedThickness()); + const gfx::RectF& pattern_rect, + const cc::PaintFlags* svg_paint_flags) const { + cc::PaintFlags local_flags; + const cc::PaintFlags* flags; + + if (svg_paint_flags) { + flags = svg_paint_flags; + } else { + local_flags.setAntiAlias(true); + local_flags.setColor(LineColor().Rgb()); + local_flags.setStyle(cc::PaintFlags::kStroke_Style); + local_flags.setStrokeWidth(ResolvedThickness()); + flags = &local_flags; + } // Create a canvas with origin (0,0) and size of the wavy pattern rect. PaintRecorder recorder; @@ -720,7 +731,14 @@ sk_sp TextDecorationInfo::PrepareWavyTileRecord( // Translate the wavy pattern so that nothing is painted at y<0. cc::RecordPaintCanvas* canvas = recorder.getRecordingCanvas(); canvas->translate(-pattern_rect.x(), -pattern_rect.y()); - canvas->cc::PaintCanvas::drawPath(stroke_path.GetSkPath(), flags); + if (svg_paint_flags) { + StrokeData stroke_data; + stroke_data.SetThickness(ResolvedThickness()); + canvas->cc::PaintCanvas::drawPath( + stroke_path.StrokePath(stroke_data, AffineTransform{}), *flags); + } else { + canvas->cc::PaintCanvas::drawPath(stroke_path.GetSkPath(), *flags); + } return recorder.finishRecordingAsPicture(); } diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.h b/third_party/blink/renderer/core/paint/text_decoration_info.h index 57594cb4a6282..bf34de168086b 100644 --- a/third_party/blink/renderer/core/paint/text_decoration_info.h +++ b/third_party/blink/renderer/core/paint/text_decoration_info.h @@ -99,6 +99,12 @@ class CORE_EXPORT TextDecorationInfo { // the style passed at construction. void SetDecorationIndex(int decoration_index); + // The svg paint flags (if any) should be set before calling |SetLineData|. + void SetSvgPaintFlags(const cc::PaintFlags* flags) { + svg_paint_flags_ = flags; + } + const cc::PaintFlags* SvgPaintFlags() const { return svg_paint_flags_; } + // Set data for one of the text decoration lines: over, under or // through. Must be called before trying to paint or compute bounds // for a line. @@ -167,8 +173,10 @@ class CORE_EXPORT TextDecorationInfo { float StepFromResolvedThickness() const; Path PrepareDottedOrDashedStrokePath() const; Path PrepareWavyStrokePath() const; - sk_sp PrepareWavyTileRecord(const Path&, - const gfx::RectF&) const; + sk_sp PrepareWavyTileRecord( + const Path&, + const gfx::RectF&, + const cc::PaintFlags* svg_paint_flags) const; bool IsSpellingOrGrammarError() const { return line_data_.line == TextDecorationLine::kSpellingError || line_data_.line == TextDecorationLine::kGrammarError; @@ -242,6 +250,7 @@ class CORE_EXPORT TextDecorationInfo { }; LineData line_data_; absl::optional highlight_override_; + const cc::PaintFlags* svg_paint_flags_ = nullptr; struct WavyCache { // Cache value: diff --git a/third_party/blink/renderer/core/paint/text_painter_base.cc b/third_party/blink/renderer/core/paint/text_painter_base.cc index 8fcb1d9f35759..8d8f3921355d8 100644 --- a/third_party/blink/renderer/core/paint/text_painter_base.cc +++ b/third_party/blink/renderer/core/paint/text_painter_base.cc @@ -242,6 +242,7 @@ void TextPainterBase::PaintDecorationsExceptLineThrough( applied_decoration_index < decorations.size(); ++applied_decoration_index) { decoration_info.SetDecorationIndex(applied_decoration_index); + decoration_info.SetSvgPaintFlags(flags); context.SetStrokeThickness(decoration_info.ResolvedThickness()); if (decoration_info.HasSpellingOrGrammerError() && @@ -251,7 +252,7 @@ void TextPainterBase::PaintDecorationsExceptLineThrough( // We ignore "text-decoration-skip-ink: auto" for spelling and grammar // error markers. AppliedDecorationPainter decoration_painter(context, decoration_info); - decoration_painter.Paint(flags); + decoration_painter.Paint(); continue; } @@ -294,6 +295,7 @@ void TextPainterBase::PaintDecorationsOnlyLineThrough( TextDecorationLine lines = decoration.Lines(); if (EnumHasFlags(lines, TextDecorationLine::kLineThrough)) { decoration_info.SetDecorationIndex(applied_decoration_index); + decoration_info.SetSvgPaintFlags(flags); const float resolved_thickness = decoration_info.ResolvedThickness(); context.SetStrokeThickness(resolved_thickness); @@ -301,7 +303,7 @@ void TextPainterBase::PaintDecorationsOnlyLineThrough( AppliedDecorationPainter decoration_painter(context, decoration_info); // No skip: ink for line-through, // compare https://github.com/w3c/csswg-drafts/issues/711 - decoration_painter.Paint(flags); + decoration_painter.Paint(); } } } @@ -323,7 +325,7 @@ void TextPainterBase::PaintDecorationUnderOrOverLine( std::min(decoration_info.ResolvedThickness(), kDecorationClipMaxDilation)); } - decoration_painter.Paint(flags); + decoration_painter.Paint(); } void TextPainterBase::PaintEmphasisMarkForCombinedText( diff --git a/third_party/blink/web_tests/fast/css3-text/css3-text-decoration/text-decoration-style-wavy-font-size.html b/third_party/blink/web_tests/fast/css3-text/css3-text-decoration/text-decoration-style-wavy-font-size.html index 28536b0ecc7b6..464b8be69ba34 100644 --- a/third_party/blink/web_tests/fast/css3-text/css3-text-decoration/text-decoration-style-wavy-font-size.html +++ b/third_party/blink/web_tests/fast/css3-text/css3-text-decoration/text-decoration-style-wavy-font-size.html @@ -1,7 +1,9 @@