Commit 1b5ef063 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

[CI] Cleanup some SVG hit-testing code

...mostly by de-indenting it by reversing the visibility-check. Also
reuse ComputedStyle locals and switch to using a ComputedStyle&.
In LayoutSVGShape::NodeAtFloatPointInternal, the large-ish condition is
split into three slightly smaller.

Change-Id: I275081391a3b399f9887215f4fe3075884de103c
Reviewed-on: https://chromium-review.googlesource.com/995674Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#548154}
parent 52d613e7
...@@ -155,27 +155,27 @@ bool LayoutSVGImage::NodeAtFloatPoint(HitTestResult& result, ...@@ -155,27 +155,27 @@ bool LayoutSVGImage::NodeAtFloatPoint(HitTestResult& result,
if (hit_test_action != kHitTestForeground) if (hit_test_action != kHitTestForeground)
return false; return false;
const ComputedStyle& style = StyleRef();
PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_IMAGE_HITTESTING,
result.GetHitTestRequest(), result.GetHitTestRequest(),
Style()->PointerEvents()); style.PointerEvents());
bool is_visible = (Style()->Visibility() == EVisibility::kVisible); if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
if (is_visible || !hit_rules.require_visible) { return false;
FloatPoint local_point;
if (!SVGLayoutSupport::TransformToUserSpaceAndCheckClipping( FloatPoint local_point;
*this, LocalToSVGParentTransform(), point_in_parent, local_point)) if (!SVGLayoutSupport::TransformToUserSpaceAndCheckClipping(
return false; *this, LocalToSVGParentTransform(), point_in_parent, local_point))
return false;
if (hit_rules.can_hit_fill || hit_rules.can_hit_bounding_box) {
if (object_bounding_box_.Contains(local_point)) { if (hit_rules.can_hit_fill || hit_rules.can_hit_bounding_box) {
const LayoutPoint& local_layout_point = LayoutPoint(local_point); if (object_bounding_box_.Contains(local_point)) {
UpdateHitTestResult(result, local_layout_point); const LayoutPoint& local_layout_point = LayoutPoint(local_point);
if (result.AddNodeToListBasedTestResult( UpdateHitTestResult(result, local_layout_point);
GetElement(), local_layout_point) == kStopHitTesting) if (result.AddNodeToListBasedTestResult(
return true; GetElement(), local_layout_point) == kStopHitTesting)
} return true;
} }
} }
return false; return false;
} }
......
...@@ -366,22 +366,24 @@ bool LayoutSVGShape::NodeAtFloatPoint(HitTestResult& result, ...@@ -366,22 +366,24 @@ bool LayoutSVGShape::NodeAtFloatPoint(HitTestResult& result,
bool LayoutSVGShape::NodeAtFloatPointInternal(const HitTestRequest& request, bool LayoutSVGShape::NodeAtFloatPointInternal(const HitTestRequest& request,
const FloatPoint& local_point, const FloatPoint& local_point,
PointerEventsHitRules hit_rules) { PointerEventsHitRules hit_rules) {
bool is_visible = (Style()->Visibility() == EVisibility::kVisible); const ComputedStyle& style = StyleRef();
if (is_visible || !hit_rules.require_visible) { if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
const SVGComputedStyle& svg_style = Style()->SvgStyle(); return false;
WindRule fill_rule = svg_style.FillRule(); if (hit_rules.can_hit_bounding_box &&
if (request.SvgClipContent()) ObjectBoundingBox().Contains(local_point))
fill_rule = svg_style.ClipRule(); return true;
if ((hit_rules.can_hit_bounding_box && const SVGComputedStyle& svg_style = style.SvgStyle();
ObjectBoundingBox().Contains(local_point)) || if (hit_rules.can_hit_stroke &&
(hit_rules.can_hit_stroke && (svg_style.HasStroke() || !hit_rules.require_stroke) &&
(svg_style.HasStroke() || !hit_rules.require_stroke) && StrokeContains(local_point, hit_rules.require_stroke))
StrokeContains(local_point, hit_rules.require_stroke)) || return true;
(hit_rules.can_hit_fill && WindRule fill_rule = svg_style.FillRule();
(svg_style.HasFill() || !hit_rules.require_fill) && if (request.SvgClipContent())
FillContains(local_point, hit_rules.require_fill, fill_rule))) fill_rule = svg_style.ClipRule();
return true; if (hit_rules.can_hit_fill &&
} (svg_style.HasFill() || !hit_rules.require_fill) &&
FillContains(local_point, hit_rules.require_fill, fill_rule))
return true;
return false; return false;
} }
......
...@@ -305,38 +305,39 @@ bool LayoutSVGText::NodeAtFloatPoint(HitTestResult& result, ...@@ -305,38 +305,39 @@ bool LayoutSVGText::NodeAtFloatPoint(HitTestResult& result,
if (hit_test_action != kHitTestForeground) if (hit_test_action != kHitTestForeground)
return false; return false;
const ComputedStyle& style = StyleRef();
PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING, PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING,
result.GetHitTestRequest(), result.GetHitTestRequest(),
Style()->PointerEvents()); style.PointerEvents());
bool is_visible = (Style()->Visibility() == EVisibility::kVisible);
if (is_visible || !hit_rules.require_visible) { if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
if ((hit_rules.can_hit_bounding_box && !ObjectBoundingBox().IsEmpty()) || return false;
(hit_rules.can_hit_stroke &&
(Style()->SvgStyle().HasStroke() || !hit_rules.require_stroke)) ||
(hit_rules.can_hit_fill &&
(Style()->SvgStyle().HasFill() || !hit_rules.require_fill))) {
FloatPoint local_point;
if (!SVGLayoutSupport::TransformToUserSpaceAndCheckClipping(
*this, LocalToSVGParentTransform(), point_in_parent, local_point))
return false;
HitTestLocation hit_test_location(local_point);
if (LayoutBlock::NodeAtPoint(result, hit_test_location, LayoutPoint(),
hit_test_action))
return true;
// Consider the bounding box if requested. if ((hit_rules.can_hit_bounding_box && !ObjectBoundingBox().IsEmpty()) ||
if (hit_rules.can_hit_bounding_box && (hit_rules.can_hit_stroke &&
ObjectBoundingBox().Contains(local_point)) { (style.SvgStyle().HasStroke() || !hit_rules.require_stroke)) ||
const LayoutPoint& local_layout_point = LayoutPoint(local_point); (hit_rules.can_hit_fill &&
UpdateHitTestResult(result, local_layout_point); (style.SvgStyle().HasFill() || !hit_rules.require_fill))) {
if (result.AddNodeToListBasedTestResult( FloatPoint local_point;
GetElement(), local_layout_point) == kStopHitTesting) if (!SVGLayoutSupport::TransformToUserSpaceAndCheckClipping(
return true; *this, LocalToSVGParentTransform(), point_in_parent, local_point))
} return false;
HitTestLocation hit_test_location(local_point);
if (LayoutBlock::NodeAtPoint(result, hit_test_location, LayoutPoint(),
hit_test_action))
return true;
// Consider the bounding box if requested.
if (hit_rules.can_hit_bounding_box &&
ObjectBoundingBox().Contains(local_point)) {
const LayoutPoint& local_layout_point = LayoutPoint(local_point);
UpdateHitTestResult(result, local_layout_point);
if (result.AddNodeToListBasedTestResult(
GetElement(), local_layout_point) == kStopHitTesting)
return true;
} }
} }
return false; return false;
} }
......
...@@ -283,45 +283,41 @@ bool SVGInlineTextBox::NodeAtPoint(HitTestResult& result, ...@@ -283,45 +283,41 @@ bool SVGInlineTextBox::NodeAtPoint(HitTestResult& result,
// FIXME: integrate with InlineTextBox::nodeAtPoint better. // FIXME: integrate with InlineTextBox::nodeAtPoint better.
DCHECK(!IsLineBreak()); DCHECK(!IsLineBreak());
auto line_layout_item = LineLayoutSVGInlineText(GetLineLayoutItem());
const ComputedStyle& style = line_layout_item.StyleRef();
PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING, PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING,
result.GetHitTestRequest(), result.GetHitTestRequest(),
GetLineLayoutItem().Style()->PointerEvents()); style.PointerEvents());
bool is_visible = if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
GetLineLayoutItem().Style()->Visibility() == EVisibility::kVisible; return false;
if (is_visible || !hit_rules.require_visible) { if (hit_rules.can_hit_bounding_box ||
if (hit_rules.can_hit_bounding_box || (hit_rules.can_hit_stroke &&
(hit_rules.can_hit_stroke && (style.SvgStyle().HasStroke() || !hit_rules.require_stroke)) ||
(GetLineLayoutItem().Style()->SvgStyle().HasStroke() || (hit_rules.can_hit_fill &&
!hit_rules.require_stroke)) || (style.SvgStyle().HasFill() || !hit_rules.require_fill))) {
(hit_rules.can_hit_fill && LayoutRect rect(Location(), Size());
(GetLineLayoutItem().Style()->SvgStyle().HasFill() || rect.MoveBy(accumulated_offset);
!hit_rules.require_fill))) { if (location_in_container.Intersects(rect)) {
LayoutRect rect(Location(), Size()); const SimpleFontData* font_data =
rect.MoveBy(accumulated_offset); line_layout_item.ScaledFont().PrimaryFont();
if (location_in_container.Intersects(rect)) { DCHECK(font_data);
LineLayoutSVGInlineText line_layout_item = if (!font_data)
LineLayoutSVGInlineText(GetLineLayoutItem()); return false;
const SimpleFontData* font_data =
line_layout_item.ScaledFont().PrimaryFont(); DCHECK(line_layout_item.ScalingFactor());
DCHECK(font_data); float baseline = font_data->GetFontMetrics().FloatAscent() /
if (!font_data) line_layout_item.ScalingFactor();
return false; FloatPoint float_location = FloatPoint(location_in_container.Point());
for (const SVGTextFragment& fragment : text_fragments_) {
DCHECK(line_layout_item.ScalingFactor()); FloatQuad fragment_quad = fragment.BoundingQuad(baseline);
float baseline = font_data->GetFontMetrics().FloatAscent() / if (fragment_quad.ContainsPoint(float_location)) {
line_layout_item.ScalingFactor(); line_layout_item.UpdateHitTestResult(
FloatPoint float_location = FloatPoint(location_in_container.Point()); result,
for (const SVGTextFragment& fragment : text_fragments_) { location_in_container.Point() - ToLayoutSize(accumulated_offset));
FloatQuad fragment_quad = fragment.BoundingQuad(baseline); if (result.AddNodeToListBasedTestResult(line_layout_item.GetNode(),
if (fragment_quad.ContainsPoint(float_location)) { location_in_container,
line_layout_item.UpdateHitTestResult( rect) == kStopHitTesting)
result, location_in_container.Point() - return true;
ToLayoutSize(accumulated_offset));
if (result.AddNodeToListBasedTestResult(line_layout_item.GetNode(),
location_in_container,
rect) == kStopHitTesting)
return true;
}
} }
} }
} }
......
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