diff options
author | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-22 18:57:44 +0000 |
---|---|---|
committer | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-22 18:59:19 +0000 |
commit | 6ef948738e7140efb20570caebedf30aa1bc0332 (patch) | |
tree | 80059706e359ee2fc6289dfb8aa6c77f9b83f019 /cc | |
parent | c7bab312051cb4e8dbe13f1cc347841a2e76176a (diff) | |
download | chromium_src-6ef948738e7140efb20570caebedf30aa1bc0332.zip chromium_src-6ef948738e7140efb20570caebedf30aa1bc0332.tar.gz chromium_src-6ef948738e7140efb20570caebedf30aa1bc0332.tar.bz2 |
Plumb selection edge points through the compositor
Previously, a rect was used to convey selection bound edge geometry. This
proved confusing and problematic, particularly for non-axis-aligned text.
Instead, start using the bound edge points provided by Blink.
This depends on the Blink change http://codereview.chromium.org/495673003/.
BUG=405666
Review URL: https://codereview.chromium.org/494823002
Cr-Commit-Position: refs/heads/master@{#291460}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291460 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/input/layer_selection_bound.cc | 2 | ||||
-rw-r--r-- | cc/input/layer_selection_bound.h | 5 | ||||
-rw-r--r-- | cc/output/viewport_selection_bound.cc | 2 | ||||
-rw-r--r-- | cc/output/viewport_selection_bound.h | 5 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 10 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.cc | 53 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl_unittest.cc | 80 |
7 files changed, 104 insertions, 53 deletions
diff --git a/cc/input/layer_selection_bound.cc b/cc/input/layer_selection_bound.cc index c8054c4..2761e9e2 100644 --- a/cc/input/layer_selection_bound.cc +++ b/cc/input/layer_selection_bound.cc @@ -16,7 +16,7 @@ LayerSelectionBound::~LayerSelectionBound() { bool operator==(const LayerSelectionBound& lhs, const LayerSelectionBound& rhs) { return lhs.type == rhs.type && lhs.layer_id == rhs.layer_id && - lhs.layer_rect == rhs.layer_rect; + lhs.edge_top == rhs.edge_top && lhs.edge_bottom == rhs.edge_bottom; } bool operator!=(const LayerSelectionBound& lhs, diff --git a/cc/input/layer_selection_bound.h b/cc/input/layer_selection_bound.h index 30b2c80..21d5284 100644 --- a/cc/input/layer_selection_bound.h +++ b/cc/input/layer_selection_bound.h @@ -7,7 +7,7 @@ #include "cc/base/cc_export.h" #include "cc/input/selection_bound_type.h" -#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry/point_f.h" namespace cc { @@ -17,7 +17,8 @@ struct CC_EXPORT LayerSelectionBound { ~LayerSelectionBound(); SelectionBoundType type; - gfx::RectF layer_rect; + gfx::PointF edge_top; + gfx::PointF edge_bottom; int layer_id; }; diff --git a/cc/output/viewport_selection_bound.cc b/cc/output/viewport_selection_bound.cc index cfcb829..75a38d6 100644 --- a/cc/output/viewport_selection_bound.cc +++ b/cc/output/viewport_selection_bound.cc @@ -16,7 +16,7 @@ ViewportSelectionBound::~ViewportSelectionBound() { bool operator==(const ViewportSelectionBound& lhs, const ViewportSelectionBound& rhs) { return lhs.type == rhs.type && lhs.visible == rhs.visible && - lhs.viewport_rect == rhs.viewport_rect; + lhs.edge_top == rhs.edge_top && lhs.edge_bottom == rhs.edge_bottom; } bool operator!=(const ViewportSelectionBound& lhs, diff --git a/cc/output/viewport_selection_bound.h b/cc/output/viewport_selection_bound.h index bb4ed12..77298e7 100644 --- a/cc/output/viewport_selection_bound.h +++ b/cc/output/viewport_selection_bound.h @@ -7,7 +7,7 @@ #include "cc/base/cc_export.h" #include "cc/input/selection_bound_type.h" -#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry/point_f.h" namespace cc { @@ -17,7 +17,8 @@ struct CC_EXPORT ViewportSelectionBound { ~ViewportSelectionBound(); SelectionBoundType type; - gfx::RectF viewport_rect; + gfx::PointF edge_top; + gfx::PointF edge_bottom; bool visible; }; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index f9f3a90..fa30193 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -6307,11 +6307,13 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { EXPECT_EQ(ViewportSelectionBound(), selection_end_before); // Plumb the layer-local selection bounds. - gfx::Rect selection_rect(5, 0, 0, 5); + gfx::PointF selection_top(5, 0); + gfx::PointF selection_bottom(5, 5); LayerSelectionBound start, end; start.type = SELECTION_BOUND_CENTER; start.layer_id = root_layer_id; - start.layer_rect = selection_rect; + start.edge_bottom = selection_bottom; + start.edge_top = selection_top; end = start; host_impl_->active_tree()->RegisterSelection(start, end); @@ -6332,8 +6334,8 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { fake_output_surface->last_sent_frame().metadata.selection_end; EXPECT_EQ(start.type, selection_start_after.type); EXPECT_EQ(end.type, selection_end_after.type); - EXPECT_EQ(selection_rect, selection_start_after.viewport_rect); - EXPECT_EQ(selection_rect, selection_start_after.viewport_rect); + EXPECT_EQ(selection_bottom, selection_start_after.edge_bottom); + EXPECT_EQ(selection_top, selection_start_after.edge_top); EXPECT_TRUE(selection_start_after.visible); EXPECT_TRUE(selection_start_after.visible); } diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 0b9b880..26dd3d8 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -1334,31 +1334,50 @@ void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& start, } static ViewportSelectionBound ComputeViewportSelection( - const LayerSelectionBound& bound, + const LayerSelectionBound& layer_bound, LayerImpl* layer, float device_scale_factor) { - ViewportSelectionBound result; - result.type = bound.type; + ViewportSelectionBound viewport_bound; + viewport_bound.type = layer_bound.type; - if (!layer || bound.type == SELECTION_BOUND_EMPTY) - return result; + if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY) + return viewport_bound; - gfx::RectF layer_scaled_rect = gfx::ScaleRect( - bound.layer_rect, layer->contents_scale_x(), layer->contents_scale_y()); - gfx::RectF screen_rect = MathUtil::ProjectClippedRect( - layer->screen_space_transform(), layer_scaled_rect); + gfx::PointF layer_scaled_top = gfx::ScalePoint(layer_bound.edge_top, + layer->contents_scale_x(), + layer->contents_scale_y()); + gfx::PointF layer_scaled_bottom = gfx::ScalePoint(layer_bound.edge_bottom, + layer->contents_scale_x(), + layer->contents_scale_y()); - // The bottom left of the bound is used for visibility because 1) the bound - // edge rect is one-dimensional (no width), and 2) the bottom is the logical + bool clipped = false; + gfx::PointF screen_top = MathUtil::MapPoint( + layer->screen_space_transform(), layer_scaled_top, &clipped); + gfx::PointF screen_bottom = MathUtil::MapPoint( + layer->screen_space_transform(), layer_scaled_bottom, &clipped); + + const float inv_scale = 1.f / device_scale_factor; + viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale); + viewport_bound.edge_bottom = gfx::ScalePoint(screen_bottom, inv_scale); + + // The bottom edge point is used for visibility testing as it is the logical // focal point for bound selection handles (this may change in the future). - const gfx::PointF& visibility_point = screen_rect.bottom_left(); - float intersect_distance = 0.f; - result.visible = PointHitsLayer(layer, visibility_point, &intersect_distance); + // Shifting the visibility point fractionally inward ensures that neighboring + // or logically coincident layers aligned to integral DPI coordinates will not + // spuriously occlude the bound. + gfx::Vector2dF visibility_offset = layer_scaled_top - layer_scaled_bottom; + visibility_offset.Scale(device_scale_factor / visibility_offset.Length()); + gfx::PointF visibility_point = layer_scaled_bottom + visibility_offset; + if (visibility_point.x() <= 0) + visibility_point.set_x(visibility_point.x() + device_scale_factor); + visibility_point = MathUtil::MapPoint( + layer->screen_space_transform(), visibility_point, &clipped); - screen_rect.Scale(1.f / device_scale_factor); - result.viewport_rect = screen_rect; + float intersect_distance = 0.f; + viewport_bound.visible = + PointHitsLayer(layer, visibility_point, &intersect_distance); - return result; + return viewport_bound; } void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* start, diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 7c917e0..a0dd11a 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc @@ -2098,12 +2098,14 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { LayerSelectionBound left_input; left_input.type = SELECTION_BOUND_LEFT; - left_input.layer_rect = gfx::RectF(10, 10, 5, 20); + left_input.edge_top = gfx::PointF(10, 10); + left_input.edge_bottom = gfx::PointF(10, 20); left_input.layer_id = root_layer_id; LayerSelectionBound right_input; right_input.type = SELECTION_BOUND_RIGHT; - right_input.layer_rect = gfx::RectF(50, 10, 5, 20); + right_input.edge_top = gfx::PointF(50, 10); + right_input.edge_bottom = gfx::PointF(50, 30); right_input.layer_id = root_layer_id; ViewportSelectionBound left_output, right_output; @@ -2117,22 +2119,26 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { host_impl().active_tree()->RegisterSelection(left_input, right_input); host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_EQ(left_input.type, left_output.type); - EXPECT_EQ(left_input.layer_rect, left_output.viewport_rect); + EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom); + EXPECT_EQ(left_input.edge_top, left_output.edge_top); EXPECT_TRUE(left_output.visible); EXPECT_EQ(right_input.type, right_output.type); - EXPECT_EQ(right_input.layer_rect, right_output.viewport_rect); + EXPECT_EQ(right_input.edge_bottom, right_output.edge_bottom); + EXPECT_EQ(right_input.edge_top, right_output.edge_top); EXPECT_TRUE(right_output.visible); // Insertion bounds should produce identical left and right bounds. LayerSelectionBound insertion_input; insertion_input.type = SELECTION_BOUND_CENTER; - insertion_input.layer_rect = gfx::RectF(10, 10, 5, 20); + insertion_input.edge_top = gfx::PointF(15, 10); + insertion_input.edge_bottom = gfx::PointF(15, 30); insertion_input.layer_id = root_layer_id; host_impl().active_tree()->RegisterSelection(insertion_input, LayerSelectionBound()); host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_EQ(insertion_input.type, left_output.type); - EXPECT_EQ(insertion_input.layer_rect, left_output.viewport_rect); + EXPECT_EQ(insertion_input.edge_bottom, left_output.edge_bottom); + EXPECT_EQ(insertion_input.edge_top, left_output.edge_top); EXPECT_TRUE(left_output.visible); EXPECT_EQ(left_output, right_output); } @@ -2198,12 +2204,14 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { LayerSelectionBound left_input; left_input.type = SELECTION_BOUND_LEFT; - left_input.layer_rect = gfx::RectF(25, 10, 5, 20); + left_input.edge_top = gfx::PointF(25, 10); + left_input.edge_bottom = gfx::PointF(25, 30); left_input.layer_id = clipped_layer_id; LayerSelectionBound right_input; right_input.type = SELECTION_BOUND_RIGHT; - right_input.layer_rect = gfx::RectF(75, 10, 5, 20); + right_input.edge_top = gfx::PointF(75, 10); + right_input.edge_bottom = gfx::PointF(75, 30); right_input.layer_id = clipped_layer_id; host_impl().active_tree()->RegisterSelection(left_input, right_input); @@ -2211,29 +2219,38 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { ViewportSelectionBound left_output, right_output; host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_EQ(left_input.type, left_output.type); - gfx::RectF expected_left_output_rect = left_input.layer_rect; - expected_left_output_rect.Offset(clipping_offset); - EXPECT_EQ(expected_left_output_rect, left_output.viewport_rect); + gfx::PointF expected_left_output_top = left_input.edge_top; + gfx::PointF expected_left_output_bottom = left_input.edge_bottom; + expected_left_output_top.Offset(clipping_offset.x(), clipping_offset.y()); + expected_left_output_bottom.Offset(clipping_offset.x(), clipping_offset.y()); + EXPECT_EQ(expected_left_output_top, left_output.edge_top); + EXPECT_EQ(expected_left_output_bottom, left_output.edge_bottom); EXPECT_TRUE(left_output.visible); EXPECT_EQ(right_input.type, right_output.type); - gfx::RectF expected_right_output_rect = right_input.layer_rect; - expected_right_output_rect.Offset(clipping_offset); - EXPECT_EQ(expected_right_output_rect, right_output.viewport_rect); + gfx::PointF expected_right_output_top = right_input.edge_top; + gfx::PointF expected_right_output_bottom = right_input.edge_bottom; + expected_right_output_bottom.Offset(clipping_offset.x(), clipping_offset.y()); + expected_right_output_top.Offset(clipping_offset.x(), clipping_offset.y()); + EXPECT_EQ(expected_right_output_top, right_output.edge_top); + EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom); EXPECT_FALSE(right_output.visible); // Handles outside the viewport bounds should be marked invisible. - left_input.layer_rect = gfx::RectF(-25, 0, 5, 20); + left_input.edge_top = gfx::PointF(-25, 0); + left_input.edge_bottom = gfx::PointF(-25, 20); host_impl().active_tree()->RegisterSelection(left_input, right_input); host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_FALSE(left_output.visible); - left_input.layer_rect = gfx::RectF(0, -25, 5, 20); + left_input.edge_top = gfx::PointF(0, -25); + left_input.edge_bottom = gfx::PointF(0, -5); host_impl().active_tree()->RegisterSelection(left_input, right_input); host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_FALSE(left_output.visible); // If the handle bottom is partially visible, the handle is marked visible. - left_input.layer_rect = gfx::RectF(0, -20, 5, 21); + left_input.edge_top = gfx::PointF(0, -20); + left_input.edge_bottom = gfx::PointF(0, 1); host_impl().active_tree()->RegisterSelection(left_input, right_input); host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_TRUE(left_output.visible); @@ -2293,12 +2310,14 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { LayerSelectionBound left_input; left_input.type = SELECTION_BOUND_LEFT; - left_input.layer_rect = gfx::RectF(10, 10, 5, 20); + left_input.edge_top = gfx::PointF(10, 10); + left_input.edge_bottom = gfx::PointF(10, 30); left_input.layer_id = root_layer_id; LayerSelectionBound right_input; right_input.type = SELECTION_BOUND_RIGHT; - right_input.layer_rect = gfx::RectF(0, 0, 5, 20); + right_input.edge_top = gfx::PointF(0, 0); + right_input.edge_bottom = gfx::PointF(0, 20); right_input.layer_id = sub_layer_id; host_impl().active_tree()->RegisterSelection(left_input, right_input); @@ -2307,15 +2326,24 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { ViewportSelectionBound left_output, right_output; host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); EXPECT_EQ(left_input.type, left_output.type); - gfx::RectF expected_left_output_rect = left_input.layer_rect; - expected_left_output_rect.Scale(page_scale_factor); - EXPECT_EQ(left_input.layer_rect, left_output.viewport_rect); + gfx::PointF expected_left_output_top = left_input.edge_top; + gfx::PointF expected_left_output_bottom = left_input.edge_bottom; + expected_left_output_top.Scale(page_scale_factor); + expected_left_output_bottom.Scale(page_scale_factor); + EXPECT_EQ(left_input.edge_top, left_output.edge_top); + EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom); EXPECT_TRUE(left_output.visible); EXPECT_EQ(right_input.type, right_output.type); - gfx::RectF expected_right_output_rect = right_input.layer_rect; - expected_right_output_rect.Offset(sub_layer_offset); - expected_right_output_rect.Scale(page_scale_factor); - EXPECT_EQ(expected_right_output_rect, right_output.viewport_rect); + + gfx::PointF expected_right_output_top = right_input.edge_top; + gfx::PointF expected_right_output_bottom = right_input.edge_bottom; + expected_right_output_top.Offset(sub_layer_offset.x(), sub_layer_offset.y()); + expected_right_output_bottom.Offset(sub_layer_offset.x(), + sub_layer_offset.y()); + expected_right_output_top.Scale(page_scale_factor); + expected_right_output_bottom.Scale(page_scale_factor); + EXPECT_EQ(expected_right_output_top, right_output.edge_top); + EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom); EXPECT_TRUE(right_output.visible); } |