Commit e8996ed9 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[FragmentItem] Implement hit-testing text items

This patch implements hit-testing text items, that was not
implemented in the initial hit-test implementation in r720001
<crrev.com/c/1935773>.

The LayoutNG specific logic for |NodeForHitTest()| was moved
to |LayoutObject| in r720148 to share the logic with
|NGFragmentItem|.

8 failures, ~110 passes.

Bug: 982194
Change-Id: I4a1f3414cb1d299d4f1d6f57e64881f6aeddbff8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1943719Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720778}
parent 559210ed
......@@ -99,6 +99,7 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
return const_cast<LayoutObject*>(layout_object_);
}
Node* GetNode() const { return layout_object_->GetNode(); }
Node* NodeForHitTest() const { return layout_object_->NodeForHitTest(); }
bool HasSameParent(const NGFragmentItem& other) const;
wtf_size_t DeltaToNextForSameLayoutObject() const {
......
......@@ -70,12 +70,23 @@ inline bool IsVisibleToPaint(const NGFragmentItem& item,
style.Visibility() == EVisibility::kVisible;
}
inline bool IsVisibleToHitTest(const HitTestRequest& request,
const ComputedStyle& style) {
return request.IgnorePointerEventsNone() ||
style.PointerEvents() != EPointerEvents::kNone;
}
inline bool IsVisibleToHitTest(const NGFragmentItem& item,
const HitTestRequest& request) {
const ComputedStyle& style = item.Style();
return IsVisibleToPaint(item, style) && IsVisibleToHitTest(request, style);
}
bool FragmentVisibleToHitTestRequest(const NGPhysicalFragment& fragment,
const HitTestRequest& request) {
const ComputedStyle& style = fragment.Style();
return IsVisibleToPaint(fragment, style) &&
(request.IgnorePointerEventsNone() ||
style.PointerEvents() != EPointerEvents::kNone);
IsVisibleToHitTest(request, style);
}
// Hit tests inline ancestor elements of |fragment| who do not have their own
......@@ -1549,6 +1560,45 @@ bool NGBoxFragmentPainter::HitTestTextFragment(
return false;
}
bool NGBoxFragmentPainter::HitTestTextItem(
HitTestResult& result,
const NGFragmentItem& text_item,
const HitTestLocation& hit_test_location,
const PhysicalOffset& physical_offset,
HitTestAction action) {
DCHECK(text_item.IsText());
if (action != kHitTestForeground)
return false;
PhysicalRect border_rect(physical_offset, text_item.Size());
// TODO(layout-dev): Clip to line-top/bottom.
PhysicalRect rect(PixelSnappedIntRect(border_rect));
if (UNLIKELY(result.GetHitTestRequest().GetType() &
HitTestRequest::kHitTestVisualOverflow)) {
rect = text_item.SelfInkOverflow();
rect.Move(border_rect.offset);
}
if (IsVisibleToHitTest(text_item, result.GetHitTestRequest()) &&
hit_test_location.Intersects(rect)) {
Node* node = text_item.NodeForHitTest();
if (!result.InnerNode() && node) {
PhysicalOffset point =
hit_test_location.Point() - physical_offset + text_item.Offset();
result.SetNodeAndPosition(node, point);
}
if (result.AddNodeToListBasedTestResult(node, hit_test_location, rect) ==
kStopHitTesting) {
return true;
}
}
return false;
}
// Replicates logic in legacy InlineFlowBox::NodeAtPoint().
bool NGBoxFragmentPainter::HitTestLineBoxFragment(
HitTestResult& result,
......@@ -1768,7 +1818,9 @@ bool NGBoxFragmentPainter::HitTestItemsChildren(
const PhysicalOffset child_offset = item->Offset() + accumulated_offset;
if (item->IsText()) {
// TODO(kojii): Implement for a text item.
if (HitTestTextItem(result, *item, hit_test_location, child_offset,
action))
return true;
} else if (item->Type() == NGFragmentItem::kLine) {
const NGPhysicalLineBoxFragment* child_fragment = item->LineBoxFragment();
DCHECK(child_fragment);
......
......@@ -202,6 +202,11 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const HitTestLocation& hit_test_location,
const PhysicalOffset& physical_offset,
HitTestAction);
bool HitTestTextItem(HitTestResult& result,
const NGFragmentItem& text_item,
const HitTestLocation& hit_test_location,
const PhysicalOffset& physical_offset,
HitTestAction action);
// Hit tests the given line box fragment.
// @param physical_offset Physical offset of the line box fragment in paint
......
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