Commit d5fc99d9 authored by Yoichi Osato's avatar Yoichi Osato Committed by Commit Bot

[LayoutNG] Paint text match markers

This patch implements painting text match markers.
Logic is copied from inline_text_box_painter.cc, which is very simple:
1 paint background rect with a given color
2 paint foreground text with a given color

This patch fixes:
paint/invalidation/text-match-pre-wrapped-text.html
paint/invalidation/text-match-transparent-text.html
paint/invalidation/text-match.html
paint/markers/first-letter.html

Bug: 850448
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng;luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ic09ef1748620d5d353f89fc5c8ebced768d5a5ed
Reviewed-on: https://chromium-review.googlesource.com/1103990Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Yoichi Osato <yoichio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567969}
parent a5adc873
...@@ -15,6 +15,7 @@ class FloatRect; ...@@ -15,6 +15,7 @@ class FloatRect;
class GraphicsContext; class GraphicsContext;
class LayoutPoint; class LayoutPoint;
class StyleableMarker; class StyleableMarker;
struct TextPaintStyle;
// Document marker painter for both LayoutNG and legacy layout. // Document marker painter for both LayoutNG and legacy layout.
// This paints text decorations for spell/grammer check, find-in-page, and // This paints text decorations for spell/grammer check, find-in-page, and
...@@ -34,6 +35,9 @@ class DocumentMarkerPainter { ...@@ -34,6 +35,9 @@ class DocumentMarkerPainter {
const ComputedStyle& style, const ComputedStyle& style,
DocumentMarker::MarkerType marker_type, DocumentMarker::MarkerType marker_type,
const LayoutRect& local_rect); const LayoutRect& local_rect);
static TextPaintStyle ComputeTextPaintStyleFrom(
const ComputedStyle& style,
const TextMatchMarker& marker);
}; };
} // namespace blink } // namespace blink
......
...@@ -1084,6 +1084,23 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline( ...@@ -1084,6 +1084,23 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
width); width);
} }
// TODO(yoichio): Move this to document_marker_controller.cc
TextPaintStyle DocumentMarkerPainter::ComputeTextPaintStyleFrom(
const ComputedStyle& style,
const TextMatchMarker& marker) {
const Color text_color =
LayoutTheme::GetTheme().PlatformTextSearchColor(marker.IsActiveMatch());
if (style.VisitedDependentColor(GetCSSPropertyColor()) == text_color)
return {};
TextPaintStyle text_style;
text_style.current_color = text_style.fill_color = text_style.stroke_color =
text_style.emphasis_mark_color = text_color;
text_style.stroke_width = style.TextStrokeWidth();
text_style.shadow = nullptr;
return text_style;
}
void InlineTextBoxPainter::PaintTextMatchMarkerForeground( void InlineTextBoxPainter::PaintTextMatchMarkerForeground(
const PaintInfo& paint_info, const PaintInfo& paint_info,
const LayoutPoint& box_origin, const LayoutPoint& box_origin,
...@@ -1100,21 +1117,15 @@ void InlineTextBoxPainter::PaintTextMatchMarkerForeground( ...@@ -1100,21 +1117,15 @@ void InlineTextBoxPainter::PaintTextMatchMarkerForeground(
GetTextMatchMarkerPaintOffsets(marker, inline_text_box_); GetTextMatchMarkerPaintOffsets(marker, inline_text_box_);
TextRun run = inline_text_box_.ConstructTextRun(style); TextRun run = inline_text_box_.ConstructTextRun(style);
Color text_color =
LayoutTheme::GetTheme().PlatformTextSearchColor(marker.IsActiveMatch());
if (style.VisitedDependentColor(GetCSSPropertyColor()) == text_color)
return;
const SimpleFontData* font_data = font.PrimaryFont(); const SimpleFontData* font_data = font.PrimaryFont();
DCHECK(font_data); DCHECK(font_data);
if (!font_data) if (!font_data)
return; return;
TextPaintStyle text_style; const TextPaintStyle text_style =
text_style.current_color = text_style.fill_color = text_style.stroke_color = DocumentMarkerPainter::ComputeTextPaintStyleFrom(style, marker);
text_style.emphasis_mark_color = text_color; if (text_style.current_color == Color::kTransparent)
text_style.stroke_width = style.TextStrokeWidth(); return;
text_style.shadow = nullptr;
LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(), LayoutRect box_rect(box_origin, LayoutSize(inline_text_box_.LogicalWidth(),
inline_text_box_.LogicalHeight())); inline_text_box_.LogicalHeight()));
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/markers/composition_marker.h" #include "third_party/blink/renderer/core/editing/markers/composition_marker.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h" #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
...@@ -77,18 +78,6 @@ DocumentMarkerVector ComputeMarkersToPaint( ...@@ -77,18 +78,6 @@ DocumentMarkerVector ComputeMarkersToPaint(
return document_marker_controller.ComputeMarkersToPaint(*node); return document_marker_controller.ComputeMarkersToPaint(*node);
} }
void PaintSingleMarkerBackgroundRun(GraphicsContext& context,
const LayoutPoint& box_origin,
Color background_color,
const NGPhysicalOffsetRect& local_rect) {
if (background_color == Color::kTransparent)
return;
GraphicsContextStateSaver state_saver(context);
const NGPhysicalOffsetRect global_rect(
local_rect.offset + NGPhysicalOffset(box_origin), local_rect.size);
context.FillRect(global_rect.ToFloatRect(), background_color);
}
void PaintStyleableMarkerUnderline(GraphicsContext& context, void PaintStyleableMarkerUnderline(GraphicsContext& context,
const LayoutPoint& box_origin, const LayoutPoint& box_origin,
const StyleableMarker& marker, const StyleableMarker& marker,
...@@ -129,13 +118,26 @@ unsigned ClampOffset(unsigned offset, ...@@ -129,13 +118,26 @@ unsigned ClampOffset(unsigned offset,
text_fragment.EndOffset()); text_fragment.EndOffset());
} }
void PaintRect(GraphicsContext& context,
const NGPhysicalOffset& location,
const NGPhysicalOffsetRect& rect,
const Color color) {
if (!color.Alpha())
return;
if (rect.size.IsEmpty())
return;
const NGPhysicalOffsetRect global_rect(rect.offset + location, rect.size);
context.FillRect(global_rect.ToFloatRect(), color);
}
// Copied from InlineTextBoxPainter // Copied from InlineTextBoxPainter
void PaintDocumentMarkers(GraphicsContext& context, void PaintDocumentMarkers(GraphicsContext& context,
const NGPaintFragment& paint_fragment, const NGPaintFragment& paint_fragment,
const DocumentMarkerVector& markers_to_paint, const DocumentMarkerVector& markers_to_paint,
const LayoutPoint& box_origin, const LayoutPoint& box_origin,
const ComputedStyle& style, const ComputedStyle& style,
DocumentMarkerPaintPhase marker_paint_phase) { DocumentMarkerPaintPhase marker_paint_phase,
NGTextPainter* text_painter) {
if (markers_to_paint.IsEmpty()) if (markers_to_paint.IsEmpty())
return; return;
...@@ -156,11 +158,10 @@ void PaintDocumentMarkers(GraphicsContext& context, ...@@ -156,11 +158,10 @@ void PaintDocumentMarkers(GraphicsContext& context,
continue; continue;
switch (marker->GetType()) { switch (marker->GetType()) {
// TODO(yoichio): Implement following cases
case DocumentMarker::kSpelling: case DocumentMarker::kSpelling:
case DocumentMarker::kGrammar: { case DocumentMarker::kGrammar: {
if (context.Printing()) if (context.Printing())
return; break;
if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground)
continue; continue;
DocumentMarkerPainter::PaintDocumentMarker( DocumentMarkerPainter::PaintDocumentMarker(
...@@ -168,26 +169,57 @@ void PaintDocumentMarkers(GraphicsContext& context, ...@@ -168,26 +169,57 @@ void PaintDocumentMarkers(GraphicsContext& context,
text_fragment.LocalRect(paint_start_offset, paint_end_offset) text_fragment.LocalRect(paint_start_offset, paint_end_offset)
.ToLayoutRect()); .ToLayoutRect());
} break; } break;
// case DocumentMarker::kTextMatch:
case DocumentMarker::kTextMatch: {
if (!text_fragment.GetNode()
->GetDocument()
.GetFrame()
->GetEditor()
.MarkedTextMatchesAreHighlighted())
break;
const TextMatchMarker& text_match_marker =
ToTextMatchMarkerOrDie(*marker);
if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) {
const Color color =
LayoutTheme::GetTheme().PlatformTextSearchHighlightColor(
text_match_marker.IsActiveMatch());
PaintRect(
context, NGPhysicalOffset(box_origin),
text_fragment.LocalRect(paint_start_offset, paint_end_offset),
color);
break;
}
const TextPaintStyle text_style =
DocumentMarkerPainter::ComputeTextPaintStyleFrom(style,
text_match_marker);
if (text_style.current_color == Color::kTransparent)
break;
text_painter->Paint(paint_start_offset, paint_end_offset,
paint_end_offset - paint_start_offset, text_style);
} break;
case DocumentMarker::kComposition: case DocumentMarker::kComposition:
case DocumentMarker::kActiveSuggestion: case DocumentMarker::kActiveSuggestion:
case DocumentMarker::kSuggestion: { case DocumentMarker::kSuggestion: {
const StyleableMarker& styleable_marker = ToStyleableMarker(*marker); const StyleableMarker& styleable_marker = ToStyleableMarker(*marker);
if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) { if (marker_paint_phase == DocumentMarkerPaintPhase::kBackground) {
PaintSingleMarkerBackgroundRun( PaintRect(
context, box_origin, styleable_marker.BackgroundColor(), context, NGPhysicalOffset(box_origin),
text_fragment.LocalRect(paint_start_offset, paint_end_offset)); text_fragment.LocalRect(paint_start_offset, paint_end_offset),
} else { styleable_marker.BackgroundColor());
// TODO(yoichio) We call this on vertical/horizontal flipped context. break;
// Since NGPhysicalTextFragment::LocalRect returns physical rect,
// we need to adapt it.
PaintStyleableMarkerUnderline(
context, box_origin, styleable_marker, style,
text_fragment.LocalRect(paint_start_offset, paint_end_offset));
} }
// TODO(yoichio) We call this on vertical/horizontal flipped context.
// Since NGPhysicalTextFragment::LocalRect returns physical rect,
// we need to adapt it.
PaintStyleableMarkerUnderline(
context, box_origin, styleable_marker, style,
text_fragment.LocalRect(paint_start_offset, paint_end_offset));
} break; } break;
default: default:
// Marker is not painted, or painting code has not been added yet NOTREACHED();
break; break;
} }
} }
...@@ -215,17 +247,10 @@ static void PaintSelection(GraphicsContext& context, ...@@ -215,17 +247,10 @@ static void PaintSelection(GraphicsContext& context,
ToNGPhysicalTextFragment(paint_fragment.PhysicalFragment()); ToNGPhysicalTextFragment(paint_fragment.PhysicalFragment());
const Color color = const Color color =
SelectionBackgroundColor(document, style, text_fragment, text_color); SelectionBackgroundColor(document, style, text_fragment, text_color);
if (!color.Alpha())
return;
const NGPhysicalOffsetRect selection_rect = const NGPhysicalOffsetRect selection_rect =
paint_fragment.ComputeLocalSelectionRect(selection_status); paint_fragment.ComputeLocalSelectionRect(selection_status);
if (selection_rect.size.IsEmpty()) PaintRect(context, NGPhysicalOffset(box_rect.Location()), selection_rect,
return; color);
const NGPhysicalOffsetRect global_rect(
selection_rect.offset + NGPhysicalOffset(box_rect.Location()),
selection_rect.size);
context.FillRect(global_rect.ToFloatRect(), color);
} }
// This is copied from InlineTextBoxPainter::PaintSelection() but lacks of // This is copied from InlineTextBoxPainter::PaintSelection() but lacks of
...@@ -296,7 +321,7 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -296,7 +321,7 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
if (paint_info.phase != PaintPhase::kSelection && if (paint_info.phase != PaintPhase::kSelection &&
paint_info.phase != PaintPhase::kTextClip && !is_printing) { paint_info.phase != PaintPhase::kTextClip && !is_printing) {
PaintDocumentMarkers(context, fragment_, markers_to_paint, box_origin, PaintDocumentMarkers(context, fragment_, markers_to_paint, box_origin,
style, DocumentMarkerPaintPhase::kBackground); style, DocumentMarkerPaintPhase::kBackground, nullptr);
if (have_selection) { if (have_selection) {
PaintSelection(context, fragment_, document, style, PaintSelection(context, fragment_, document, style,
...@@ -391,7 +416,7 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -391,7 +416,7 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
if (paint_info.phase != PaintPhase::kForeground) if (paint_info.phase != PaintPhase::kForeground)
return; return;
PaintDocumentMarkers(context, fragment_, markers_to_paint, box_origin, style, PaintDocumentMarkers(context, fragment_, markers_to_paint, box_origin, style,
DocumentMarkerPaintPhase::kForeground); DocumentMarkerPaintPhase::kForeground, &text_painter);
} }
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment