Commit cf4cb88a authored by Daniel Libby's avatar Daniel Libby Committed by Chromium LUCI CQ

Refactor SelectionBoundsRecorder for future re-use

After crrev.com/c/2586450 removed NGPaintFragment and templates, this
class is much easier to reuse in upcoming changes for selection
recording for non-NG text, replaced, and SVG text. Remove dependencies
on NGInlineCursor, force the caller to provide the selection rect, and
factor out the early out checks so callers can compute the rect only
when necessary.

Bug: 1065049
Change-Id: If4bcc660c5e5b288fec0e0432d377d4d6289a878
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2598097Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Daniel Libby <dlibby@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#839174}
parent dbeda302
...@@ -200,6 +200,8 @@ blink_core_sources_paint = [ ...@@ -200,6 +200,8 @@ blink_core_sources_paint = [
"scoped_svg_paint_state.h", "scoped_svg_paint_state.h",
"scrollable_area_painter.cc", "scrollable_area_painter.cc",
"scrollable_area_painter.h", "scrollable_area_painter.h",
"selection_bounds_recorder.cc",
"selection_bounds_recorder.h",
"svg_container_painter.cc", "svg_container_painter.cc",
"svg_container_painter.h", "svg_container_painter.h",
"svg_foreign_object_painter.cc", "svg_foreign_object_painter.cc",
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/paint/list_marker_painter.h" #include "third_party/blink/renderer/core/paint/list_marker_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_text_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_text_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/selection_bounds_recorder.h"
#include "third_party/blink/renderer/core/paint/text_painter_base.h" #include "third_party/blink/renderer/core/paint/text_painter_base.h"
#include "third_party/blink/renderer/core/style/applied_text_decoration.h" #include "third_party/blink/renderer/core/style/applied_text_decoration.h"
#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/computed_style.h"
...@@ -374,69 +375,6 @@ class SelectionPaintState { ...@@ -374,69 +375,6 @@ class SelectionPaintState {
bool paint_selected_text_separately_; bool paint_selected_text_separately_;
}; };
class SelectionBoundsRecorder {
STACK_ALLOCATED();
public:
SelectionBoundsRecorder(const NGInlineCursor& cursor,
SelectionPaintState& selection,
PaintController& paint_controller,
const PhysicalOffset& box_rect_offset)
: cursor_(cursor),
selection_(selection),
paint_controller_(paint_controller),
box_rect_offset_(box_rect_offset) {}
~SelectionBoundsRecorder();
private:
const NGInlineCursor& cursor_;
SelectionPaintState& selection_;
PaintController& paint_controller_;
const PhysicalOffset& box_rect_offset_;
};
SelectionBoundsRecorder::~SelectionBoundsRecorder() {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
const FrameSelection& frame_selection =
cursor_.Current().GetLayoutObject()->GetFrame()->Selection();
if (!frame_selection.IsHandleVisible() || frame_selection.IsHidden())
return;
SelectionState state = selection_.State();
if (state == SelectionState::kInside || state == SelectionState::kNone)
return;
// TODO(crbug.com/1065049) Handle RTL (i.e. IsTextDirectionRTL) to adjust
// the type and edges appropriately (i.e. the right edge of the selection rect
// should be used for start's edges).
base::Optional<PaintedSelectionBound> start;
base::Optional<PaintedSelectionBound> end;
auto selection_rect =
PixelSnappedIntRect(selection_.ComputeSelectionRect(box_rect_offset_));
if (state == SelectionState::kStart ||
state == SelectionState::kStartAndEnd) {
start.emplace();
start->type = gfx::SelectionBound::Type::LEFT;
start->edge_start = selection_rect.MinXMinYCorner();
start->edge_end = selection_rect.MinXMaxYCorner();
// TODO(crbug.com/1065049) Handle the case where selection within input
// text is clipped out.
start->hidden = false;
}
if (state == SelectionState::kStartAndEnd || state == SelectionState::kEnd) {
end.emplace();
end->type = gfx::SelectionBound::Type::RIGHT;
end->edge_start = selection_rect.MaxXMinYCorner();
end->edge_end = selection_rect.MaxXMaxYCorner();
end->hidden = false;
}
paint_controller_.RecordSelection(start, end);
}
// Check if text-emphasis and ruby annotation text are on different sides. // Check if text-emphasis and ruby annotation text are on different sides.
// See InlineTextBox::GetEmphasisMarkPosition(). // See InlineTextBox::GetEmphasisMarkPosition().
// //
...@@ -541,12 +479,16 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -541,12 +479,16 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
// whether the diplay item that contains the actual selection painting is // whether the diplay item that contains the actual selection painting is
// reused. // reused.
base::Optional<SelectionBoundsRecorder> selection_recorder; base::Optional<SelectionBoundsRecorder> selection_recorder;
if (UNLIKELY(RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && if (UNLIKELY(selection && paint_info.phase == PaintPhase::kForeground &&
selection && paint_info.phase == PaintPhase::kForeground &&
!is_printing)) { !is_printing)) {
selection_recorder.emplace(cursor_, *selection, if (SelectionBoundsRecorder::ShouldRecordSelection(
paint_info.context.GetPaintController(), cursor_.Current().GetLayoutObject()->GetFrame()->Selection(),
box_rect.offset); selection->State())) {
PhysicalRect selection_rect =
selection->ComputeSelectionRect(box_rect.offset);
selection_recorder.emplace(selection->State(), selection_rect,
paint_info.context.GetPaintController());
}
} }
if (paint_info.phase != PaintPhase::kTextClip) { if (paint_info.phase != PaintPhase::kTextClip) {
......
// Copyright 2020 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 "third_party/blink/renderer/core/paint/selection_bounds_recorder.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
namespace blink {
SelectionBoundsRecorder::SelectionBoundsRecorder(
SelectionState state,
PhysicalRect selection_rect,
PaintController& paint_controller)
: state_(state),
selection_rect_(selection_rect),
paint_controller_(paint_controller) {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
}
SelectionBoundsRecorder::~SelectionBoundsRecorder() {
// TODO(crbug.com/1065049) Handle RTL (i.e. IsTextDirectionRTL) to adjust
// the type and edges appropriately (i.e. the right edge of the selection rect
// should be used for start's edges).
base::Optional<PaintedSelectionBound> start;
base::Optional<PaintedSelectionBound> end;
auto selection_rect = PixelSnappedIntRect(selection_rect_);
if (state_ == SelectionState::kStart ||
state_ == SelectionState::kStartAndEnd) {
start.emplace();
start->type = gfx::SelectionBound::Type::LEFT;
start->edge_start = selection_rect.MinXMinYCorner();
start->edge_end = selection_rect.MinXMaxYCorner();
// TODO(crbug.com/1065049) Handle the case where selection within input
// text is clipped out.
start->hidden = false;
}
if (state_ == SelectionState::kStartAndEnd ||
state_ == SelectionState::kEnd) {
end.emplace();
end->type = gfx::SelectionBound::Type::RIGHT;
end->edge_start = selection_rect.MaxXMinYCorner();
end->edge_end = selection_rect.MaxXMaxYCorner();
end->hidden = false;
}
paint_controller_.RecordSelection(start, end);
}
bool SelectionBoundsRecorder::ShouldRecordSelection(
const FrameSelection& frame_selection,
SelectionState state) {
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return false;
if (!frame_selection.IsHandleVisible() || frame_selection.IsHidden())
return false;
if (state == SelectionState::kInside || state == SelectionState::kNone)
return false;
return true;
}
} // namespace blink
// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SELECTION_BOUNDS_RECORDER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SELECTION_BOUNDS_RECORDER_H_
#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class FrameSelection;
class PaintController;
// This class is used for recording painted selection bounds when
// CompositeAfterPaint is enabled. Based on the SelectionState and provided
// |selection_rect|, records the appropriate bounds via the paint controller.
// These bounds are consumed at composition time by PaintArtifactCompositor and
// pushed to the LayerTreeHost. All of the work happens in the destructor to
// ensure this information recorded after any painting is completed, even if
// a cached drawing is re-used.
class SelectionBoundsRecorder {
STACK_ALLOCATED();
public:
SelectionBoundsRecorder(SelectionState state,
PhysicalRect selection_rect,
PaintController& paint_controller);
~SelectionBoundsRecorder();
static bool ShouldRecordSelection(const FrameSelection&, SelectionState);
private:
const SelectionState state_;
PhysicalRect selection_rect_;
PaintController& paint_controller_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SELECTION_BOUNDS_RECORDER_H_
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