Commit 85aaee32 authored by Yoichi Osato's avatar Yoichi Osato Committed by Commit Bot

[LayoutNG] Update LayoutSelectionStartEndForNG signature

This patch updates LayoutSelectionStartEndForNG signature by
1. Introducing LayoutSelectionStatus structure for return type consisting of
start/end.
2. Change argument type from NGPhysicalTextFragment to NGPaintFragment.

This is a preparation for line break selection painting:
crbug.com/c/896780

Bug: 708452
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_layout_ng;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: Idca785e841a577b1a591ae10cf3d9771d21c6ce1
Reviewed-on: https://chromium-review.googlesource.com/1029563
Commit-Queue: Yoichi Osato <yoichio@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553962}
parent b6230f92
...@@ -1220,9 +1220,9 @@ void FrameSelection::ClearLayoutSelection() { ...@@ -1220,9 +1220,9 @@ void FrameSelection::ClearLayoutSelection() {
layout_selection_->ClearSelection(); layout_selection_->ClearSelection();
} }
std::pair<unsigned, unsigned> FrameSelection::LayoutSelectionStartEndForNG( LayoutSelectionStatus FrameSelection::ComputeLayoutSelectionStatus(
const NGPhysicalTextFragment& text_fragment) const { const NGPaintFragment& text_fragment) const {
return layout_selection_->SelectionStartEndForNG(text_fragment); return layout_selection_->ComputeSelectionStatus(text_fragment);
} }
bool FrameSelection::IsDirectional() const { bool FrameSelection::IsDirectional() const {
......
...@@ -49,12 +49,13 @@ class LocalFrame; ...@@ -49,12 +49,13 @@ class LocalFrame;
class FrameCaret; class FrameCaret;
class GranularityStrategy; class GranularityStrategy;
class GraphicsContext; class GraphicsContext;
class NGPhysicalTextFragment; class NGPaintFragment;
class Range; class Range;
class SelectionEditor; class SelectionEditor;
class LayoutSelection; class LayoutSelection;
enum class SelectionModifyAlteration; enum class SelectionModifyAlteration;
enum class SelectionModifyDirection; enum class SelectionModifyDirection;
enum class SelectionState;
class TextIteratorBehavior; class TextIteratorBehavior;
struct PaintInvalidatorContext; struct PaintInvalidatorContext;
...@@ -64,6 +65,27 @@ enum class CaretVisibility; ...@@ -64,6 +65,27 @@ enum class CaretVisibility;
enum class HandleVisibility { kNotVisible, kVisible }; enum class HandleVisibility { kNotVisible, kVisible };
// This is return type of ComputeLayoutSelectionStatus(paintfragment).
// This structure represents how the fragment is selected.
// |start|, |end| : Selection start/end offset. This offset is based on
// the text of NGInlineNode of a parent block thus
// |fragemnt.StartOffset <= start <= end <= fragment.EndOffset|.
// |start| == |end| means this fragment is not selected.
struct LayoutSelectionStatus {
STACK_ALLOCATED();
LayoutSelectionStatus(unsigned passed_start, unsigned passed_end)
: start(passed_start), end(passed_end) {
DCHECK_LE(start, end);
}
bool operator==(const LayoutSelectionStatus& other) const {
return start == other.start && end == other.end;
}
unsigned start;
unsigned end;
};
class CORE_EXPORT FrameSelection final class CORE_EXPORT FrameSelection final
: public GarbageCollectedFinalized<FrameSelection>, : public GarbageCollectedFinalized<FrameSelection>,
public SynchronousMutationObserver { public SynchronousMutationObserver {
...@@ -220,8 +242,8 @@ class CORE_EXPORT FrameSelection final ...@@ -220,8 +242,8 @@ class CORE_EXPORT FrameSelection final
base::Optional<unsigned> LayoutSelectionStart() const; base::Optional<unsigned> LayoutSelectionStart() const;
base::Optional<unsigned> LayoutSelectionEnd() const; base::Optional<unsigned> LayoutSelectionEnd() const;
void ClearLayoutSelection(); void ClearLayoutSelection();
std::pair<unsigned, unsigned> LayoutSelectionStartEndForNG( LayoutSelectionStatus ComputeLayoutSelectionStatus(
const NGPhysicalTextFragment&) const; const NGPaintFragment&) const;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer.h"
namespace blink { namespace blink {
...@@ -657,8 +658,10 @@ static unsigned ClampOffset(unsigned offset, ...@@ -657,8 +658,10 @@ static unsigned ClampOffset(unsigned offset,
text_fragment.EndOffset()); text_fragment.EndOffset());
} }
std::pair<unsigned, unsigned> LayoutSelection::SelectionStartEndForNG( LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
const NGPhysicalTextFragment& text_fragment) const { const NGPaintFragment& fragment) const {
const NGPhysicalTextFragment& text_fragment =
ToNGPhysicalTextFragmentOrDie(fragment.PhysicalFragment());
// FrameSelection holds selection offsets in layout block flow at // FrameSelection holds selection offsets in layout block flow at
// LayoutSelection::Commit() if selection starts/ends within Text that // LayoutSelection::Commit() if selection starts/ends within Text that
// each LayoutObject::SelectionState indicates. // each LayoutObject::SelectionState indicates.
......
...@@ -31,9 +31,9 @@ namespace blink { ...@@ -31,9 +31,9 @@ namespace blink {
class IntRect; class IntRect;
class LayoutObject; class LayoutObject;
class NGPhysicalTextFragment; class NGPaintFragment;
class FrameSelection; class FrameSelection;
struct LayoutSelectionStatus;
// This class represents a selection range in layout tree for painting and // This class represents a selection range in layout tree for painting and
// paint invalidation. // paint invalidation.
// The current selection to be painted is represented as 2 pairs of // The current selection to be painted is represented as 2 pairs of
...@@ -105,12 +105,7 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> { ...@@ -105,12 +105,7 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> {
void ClearSelection(); void ClearSelection();
base::Optional<unsigned> SelectionStart() const; base::Optional<unsigned> SelectionStart() const;
base::Optional<unsigned> SelectionEnd() const; base::Optional<unsigned> SelectionEnd() const;
// This function returns selected part of |text_fragment|. LayoutSelectionStatus ComputeSelectionStatus(const NGPaintFragment&) const;
// Returned pair is a partial range of
// (text_fragment.StartOffset(), text_fragment.EndOffset()).
// If first equals second, it indicates "no selection in fragment".
std::pair<unsigned, unsigned> SelectionStartEndForNG(
const NGPhysicalTextFragment&) const;
void OnDocumentShutdown(); void OnDocumentShutdown();
......
...@@ -696,6 +696,11 @@ class NGLayoutSelectionTest ...@@ -696,6 +696,11 @@ class NGLayoutSelectionTest
ScopedPaintUnderInvalidationCheckingForTest(true) {} ScopedPaintUnderInvalidationCheckingForTest(true) {}
}; };
std::ostream& operator<<(std::ostream& ostream,
const LayoutSelectionStatus& status) {
return ostream << status.start << ", " << status.end;
}
static const NGPaintFragment* FindNGPaintFragmentInternal( static const NGPaintFragment* FindNGPaintFragmentInternal(
const NGPaintFragment* paint, const NGPaintFragment* paint,
const LayoutObject* layout_object) { const LayoutObject* layout_object) {
...@@ -709,7 +714,7 @@ static const NGPaintFragment* FindNGPaintFragmentInternal( ...@@ -709,7 +714,7 @@ static const NGPaintFragment* FindNGPaintFragmentInternal(
return nullptr; return nullptr;
} }
static const NGPhysicalTextFragment& GetNGPhysicalTextFragment( static const NGPaintFragment& GetNGPaintFragment(
const LayoutObject* layout_object) { const LayoutObject* layout_object) {
DCHECK(layout_object->IsText()); DCHECK(layout_object->IsText());
LayoutBlockFlow* block_flow = layout_object->EnclosingNGBlockFlow(); LayoutBlockFlow* block_flow = layout_object->EnclosingNGBlockFlow();
...@@ -718,9 +723,8 @@ static const NGPhysicalTextFragment& GetNGPhysicalTextFragment( ...@@ -718,9 +723,8 @@ static const NGPhysicalTextFragment& GetNGPhysicalTextFragment(
LayoutNGBlockFlow* layout_ng = ToLayoutNGBlockFlow(block_flow); LayoutNGBlockFlow* layout_ng = ToLayoutNGBlockFlow(block_flow);
const NGPaintFragment* paint_fragment = const NGPaintFragment* paint_fragment =
FindNGPaintFragmentInternal(layout_ng->PaintFragment(), layout_object); FindNGPaintFragmentInternal(layout_ng->PaintFragment(), layout_object);
const NGPhysicalFragment& physical_fragment = DCHECK(paint_fragment);
paint_fragment->PhysicalFragment(); return *paint_fragment;
return ToNGPhysicalTextFragment(physical_fragment);
} }
TEST_F(NGLayoutSelectionTest, SelectOnOneText) { TEST_F(NGLayoutSelectionTest, SelectOnOneText) {
...@@ -740,16 +744,16 @@ TEST_F(NGLayoutSelectionTest, SelectOnOneText) { ...@@ -740,16 +744,16 @@ TEST_F(NGLayoutSelectionTest, SelectOnOneText) {
LayoutObject* const foo = LayoutObject* const foo =
GetDocument().body()->firstChild()->GetLayoutObject(); GetDocument().body()->firstChild()->GetLayoutObject();
EXPECT_EQ(std::make_pair(0u, 0u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(0u, 0u),
GetNGPhysicalTextFragment(foo))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo)));
LayoutObject* const bar = GetDocument() LayoutObject* const bar = GetDocument()
.body() .body()
->firstChild() ->firstChild()
->nextSibling() ->nextSibling()
->firstChild() ->firstChild()
->GetLayoutObject(); ->GetLayoutObject();
EXPECT_EQ(std::make_pair(4u, 5u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(4u, 5u),
GetNGPhysicalTextFragment(bar))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(bar)));
} }
TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) { TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) {
...@@ -765,12 +769,14 @@ TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) { ...@@ -765,12 +769,14 @@ TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) {
Node* const foo = GetDocument().body()->firstChild()->nextSibling(); Node* const foo = GetDocument().body()->firstChild()->nextSibling();
const LayoutTextFragment* const foo_f = const LayoutTextFragment* const foo_f =
ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 0)); ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 0));
EXPECT_EQ(std::make_pair(0u, 1u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(
GetNGPhysicalTextFragment(foo_f))); LayoutSelectionStatus(0u, 1u),
Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_f)));
const LayoutTextFragment* const foo_oo = const LayoutTextFragment* const foo_oo =
ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 1)); ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 1));
EXPECT_EQ(std::make_pair(1u, 2u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(
GetNGPhysicalTextFragment(foo_oo))); LayoutSelectionStatus(1u, 2u),
Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_oo)));
} }
TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) { TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) {
...@@ -786,16 +792,16 @@ TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) { ...@@ -786,16 +792,16 @@ TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) {
TEST_NO_NEXT_LAYOUT_OBJECT(); TEST_NO_NEXT_LAYOUT_OBJECT();
LayoutObject* const foo = LayoutObject* const foo =
GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); GetDocument().body()->firstChild()->firstChild()->GetLayoutObject();
EXPECT_EQ(std::make_pair(1u, 3u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(1u, 3u),
GetNGPhysicalTextFragment(foo))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo)));
LayoutObject* const bar = GetDocument() LayoutObject* const bar = GetDocument()
.body() .body()
->firstChild() ->firstChild()
->nextSibling() ->nextSibling()
->firstChild() ->firstChild()
->GetLayoutObject(); ->GetLayoutObject();
EXPECT_EQ(std::make_pair(0u, 2u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(0u, 2u),
GetNGPhysicalTextFragment(bar))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(bar)));
} }
TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) { TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) {
...@@ -812,8 +818,8 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) { ...@@ -812,8 +818,8 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) {
TEST_NO_NEXT_LAYOUT_OBJECT(); TEST_NO_NEXT_LAYOUT_OBJECT();
LayoutObject* const foo = LayoutObject* const foo =
GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); GetDocument().body()->firstChild()->firstChild()->GetLayoutObject();
EXPECT_EQ(std::make_pair(1u, 3u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(1u, 3u),
GetNGPhysicalTextFragment(foo))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo)));
EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value()); EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value());
} }
...@@ -849,8 +855,8 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsDecendant) { ...@@ -849,8 +855,8 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsDecendant) {
TEST_NO_NEXT_LAYOUT_OBJECT(); TEST_NO_NEXT_LAYOUT_OBJECT();
LayoutObject* const foo = LayoutObject* const foo =
GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); GetDocument().body()->firstChild()->firstChild()->GetLayoutObject();
EXPECT_EQ(std::make_pair(1u, 3u), Selection().LayoutSelectionStartEndForNG( EXPECT_EQ(LayoutSelectionStatus(1u, 3u),
GetNGPhysicalTextFragment(foo))); Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo)));
EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value()); EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value());
} }
......
...@@ -79,13 +79,14 @@ NGTextFragmentPainter::NGTextFragmentPainter( ...@@ -79,13 +79,14 @@ NGTextFragmentPainter::NGTextFragmentPainter(
// |selection_start| and |selection_end| should be between // |selection_start| and |selection_end| should be between
// [text_fragment.StartOffset(), text_fragment.EndOffset()]. // [text_fragment.StartOffset(), text_fragment.EndOffset()].
static void PaintSelection(GraphicsContext& context, static void PaintSelection(GraphicsContext& context,
const NGPhysicalTextFragment& text_fragment, const NGPaintFragment& paint_fragment,
const Document& document, const Document& document,
const ComputedStyle& style, const ComputedStyle& style,
Color text_color, Color text_color,
const LayoutRect& box_rect, const LayoutRect& box_rect,
unsigned int selection_start, const LayoutSelectionStatus& selection_status) {
unsigned int selection_end) { const NGPhysicalTextFragment& text_fragment =
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()) if (!color.Alpha())
...@@ -93,14 +94,15 @@ static void PaintSelection(GraphicsContext& context, ...@@ -93,14 +94,15 @@ static void PaintSelection(GraphicsContext& context,
GraphicsContextStateSaver state_saver(context); GraphicsContextStateSaver state_saver(context);
DCHECK_LE(text_fragment.StartOffset(), selection_start); DCHECK_LE(text_fragment.StartOffset(), selection_status.start);
DCHECK_LE(text_fragment.StartOffset(), selection_end); DCHECK_LE(text_fragment.StartOffset(), selection_status.end);
DCHECK_GE(text_fragment.EndOffset(), selection_start); DCHECK_GE(text_fragment.EndOffset(), selection_status.start);
DCHECK_GE(text_fragment.EndOffset(), selection_end); DCHECK_GE(text_fragment.EndOffset(), selection_status.end);
const ShapeResult* shape_result = text_fragment.TextShapeResult(); const ShapeResult* shape_result = text_fragment.TextShapeResult();
DCHECK(shape_result);
const CharacterRange& range = shape_result->GetCharacterRange( const CharacterRange& range = shape_result->GetCharacterRange(
selection_start - text_fragment.StartOffset(), selection_status.start - text_fragment.StartOffset(),
selection_end - text_fragment.StartOffset()); selection_status.end - text_fragment.StartOffset());
const FloatRect& selection_rect = PixelSnappedSelectionRect( const FloatRect& selection_rect = PixelSnappedSelectionRect(
FloatRect(box_rect.Location().X() + range.start, box_rect.Location().Y(), FloatRect(box_rect.Location().X() + range.start, box_rect.Location().Y(),
range.Width(), box_rect.Height().ToFloat())); range.Width(), box_rect.Height().ToFloat()));
...@@ -135,13 +137,10 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -135,13 +137,10 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
bool is_printing = paint_info.IsPrinting(); bool is_printing = paint_info.IsPrinting();
// Determine whether or not we're selected. // Determine whether or not we're selected.
int selection_start; const LayoutSelectionStatus& selection_status =
int selection_end; document.GetFrame()->Selection().ComputeLayoutSelectionStatus(fragment_);
std::tie(selection_start, selection_end) = DCHECK_LE(selection_status.start, selection_status.end);
document.GetFrame()->Selection().LayoutSelectionStartEndForNG( const bool have_selection = selection_status.start < selection_status.end;
text_fragment);
DCHECK_LE(selection_start, selection_end);
const bool have_selection = selection_start < selection_end;
if (!have_selection && paint_info.phase == PaintPhase::kSelection) { if (!have_selection && paint_info.phase == PaintPhase::kSelection) {
// When only painting the selection, don't bother to paint if there is none. // When only painting the selection, don't bother to paint if there is none.
return; return;
...@@ -182,9 +181,8 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -182,9 +181,8 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
if (have_selection && paint_info.phase != PaintPhase::kSelection && if (have_selection && paint_info.phase != PaintPhase::kSelection &&
paint_info.phase != PaintPhase::kTextClip && !is_printing) { paint_info.phase != PaintPhase::kTextClip && !is_printing) {
// TODO(yoichio): Implement composition highlights. // TODO(yoichio): Implement composition highlights.
PaintSelection(context, text_fragment, document, style, PaintSelection(context, fragment_, document, style,
selection_style.fill_color, box_rect, selection_start, selection_style.fill_color, box_rect, selection_status);
selection_end);
} }
// 2. Now paint the foreground, including text and decorations. // 2. Now paint the foreground, including text and decorations.
...@@ -227,15 +225,19 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -227,15 +225,19 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
&has_line_through_decoration); &has_line_through_decoration);
} }
int start_offset = text_fragment.StartOffset(); unsigned start_offset = text_fragment.StartOffset();
int end_offset = start_offset + length; unsigned end_offset = start_offset + length;
if (have_selection && paint_selected_text_separately) { if (have_selection && paint_selected_text_separately) {
// Paint only the text that is not selected. // Paint only the text that is not selected.
if (start_offset < selection_start) if (start_offset < selection_status.start) {
text_painter.Paint(start_offset, selection_start, length, text_style); text_painter.Paint(start_offset, selection_status.start, length,
if (selection_end < end_offset) text_style);
text_painter.Paint(selection_end, end_offset, length, text_style); }
if (selection_status.end < end_offset) {
text_painter.Paint(selection_status.end, end_offset, length,
text_style);
}
} else { } else {
text_painter.Paint(start_offset, end_offset, length, text_style); text_painter.Paint(start_offset, end_offset, length, text_style);
} }
...@@ -251,7 +253,8 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info, ...@@ -251,7 +253,8 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
if (have_selection && if (have_selection &&
(paint_selected_text_only || paint_selected_text_separately)) { (paint_selected_text_only || paint_selected_text_separately)) {
// Paint only the text that is selected. // Paint only the text that is selected.
text_painter.Paint(selection_start, selection_end, length, selection_style); text_painter.Paint(selection_status.start, selection_status.end, length,
selection_style);
} }
} }
......
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