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 | |
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
-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 | ||||
-rw-r--r-- | content/browser/renderer_host/input/touch_selection_controller.cc | 89 | ||||
-rw-r--r-- | content/browser/renderer_host/input/touch_selection_controller.h | 23 | ||||
-rw-r--r-- | content/browser/renderer_host/input/touch_selection_controller_unittest.cc | 52 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_android.cc | 50 | ||||
-rw-r--r-- | content/common/cc_messages.h | 3 | ||||
-rw-r--r-- | content/renderer/gpu/render_widget_compositor.cc | 21 |
13 files changed, 217 insertions, 178 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); } diff --git a/content/browser/renderer_host/input/touch_selection_controller.cc b/content/browser/renderer_host/input/touch_selection_controller.cc index ea0e7e7..f27d690 100644 --- a/content/browser/renderer_host/input/touch_selection_controller.cc +++ b/content/browser/renderer_host/input/touch_selection_controller.cc @@ -9,15 +9,31 @@ #include "third_party/WebKit/public/web/WebInputEvent.h" namespace content { +namespace { + +TouchHandleOrientation ToTouchHandleOrientation(cc::SelectionBoundType type) { + switch (type) { + case cc::SELECTION_BOUND_LEFT: + return TOUCH_HANDLE_LEFT; + case cc::SELECTION_BOUND_RIGHT: + return TOUCH_HANDLE_RIGHT; + case cc::SELECTION_BOUND_CENTER: + return TOUCH_HANDLE_CENTER; + case cc::SELECTION_BOUND_EMPTY: + return TOUCH_HANDLE_ORIENTATION_UNDEFINED; + } + NOTREACHED() << "Invalid selection bound type: " << type; + return TOUCH_HANDLE_ORIENTATION_UNDEFINED; +} + +} // namespace TouchSelectionController::TouchSelectionController( TouchSelectionControllerClient* client) : client_(client), response_pending_input_event_(INPUT_EVENT_TYPE_NONE), start_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED), - start_visible_(false), end_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED), - end_visible_(false), is_insertion_active_(false), activate_insertion_automatically_(false), is_selection_active_(false), @@ -33,30 +49,21 @@ TouchSelectionController::~TouchSelectionController() { } void TouchSelectionController::OnSelectionBoundsChanged( - const gfx::RectF& start_rect, - TouchHandleOrientation start_orientation, - bool start_visible, - const gfx::RectF& end_rect, - TouchHandleOrientation end_orientation, - bool end_visible) { + const cc::ViewportSelectionBound& start, + const cc::ViewportSelectionBound& end) { if (!activate_selection_automatically_ && !activate_insertion_automatically_) { DCHECK_EQ(INPUT_EVENT_TYPE_NONE, response_pending_input_event_); return; } - if (start_rect_ == start_rect && end_rect_ == end_rect && - start_orientation_ == start_orientation && - end_orientation_ == end_orientation && start_visible_ == start_visible && - end_visible_ == end_visible) + if (start == start_ && end_ == end) return; - start_rect_ = start_rect; - start_orientation_ = start_orientation; - start_visible_ = start_visible; - end_rect_ = end_rect; - end_orientation_ = end_orientation; - end_visible_ = end_visible; + start_ = start; + end_ = end; + start_orientation_ = ToTouchHandleOrientation(start_.type); + end_orientation_ = ToTouchHandleOrientation(end_.type); // Ensure that |response_pending_input_event_| is cleared after the method // completes, while also making its current value available for the duration @@ -83,9 +90,7 @@ void TouchSelectionController::OnSelectionBoundsChanged( end_orientation_ = end_selection_handle_->orientation(); } - const gfx::PointF start = GetStartPosition(); - const gfx::PointF end = GetEndPosition(); - if (start != end || + if (GetStartPosition() != GetEndPosition() || (is_selection_dragging && start_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED && end_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED)) { @@ -201,11 +206,11 @@ void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) { } if (&handle == start_selection_handle_.get()) { - fixed_handle_position_ = end_selection_handle_->position() - - gfx::Vector2dF(0, GetEndLineHeight() / 2.f); + fixed_handle_position_ = + end_selection_handle_->position() + GetEndLineOffset(); } else { - fixed_handle_position_ = start_selection_handle_->position() - - gfx::Vector2dF(0, GetStartLineHeight() / 2.f); + fixed_handle_position_ = + start_selection_handle_->position() + GetStartLineOffset(); } client_->OnSelectionEvent(SELECTION_DRAG_STARTED, handle.position()); } @@ -214,10 +219,10 @@ void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle, const gfx::PointF& position) { // As the position corresponds to the bottom left point of the selection // bound, offset it by half the corresponding line height. - float half_line_height = &handle == end_selection_handle_.get() - ? GetEndLineHeight() / 2.f - : GetStartLineHeight() / 2.f; - gfx::PointF line_position = position - gfx::Vector2dF(0, half_line_height); + gfx::Vector2dF line_offset = &handle == end_selection_handle_.get() + ? GetStartLineOffset() + : GetEndLineOffset(); + gfx::PointF line_position = position + line_offset; if (&handle == insertion_handle_.get()) { client_->MoveCaret(line_position); } else { @@ -360,36 +365,34 @@ void TouchSelectionController::DeactivateSelection() { void TouchSelectionController::ResetCachedValuesIfInactive() { if (is_selection_active_ || is_insertion_active_) return; - start_rect_ = gfx::RectF(); - end_rect_ = gfx::RectF(); + start_ = cc::ViewportSelectionBound(); + end_ = cc::ViewportSelectionBound(); start_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED; end_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED; - start_visible_ = false; - end_visible_ = false; } -gfx::PointF TouchSelectionController::GetStartPosition() const { - return start_rect_.bottom_left(); +const gfx::PointF& TouchSelectionController::GetStartPosition() const { + return start_.edge_bottom; } -gfx::PointF TouchSelectionController::GetEndPosition() const { - return end_rect_.bottom_left(); +const gfx::PointF& TouchSelectionController::GetEndPosition() const { + return end_.edge_bottom; } -float TouchSelectionController::GetStartLineHeight() const { - return start_rect_.height(); +gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const { + return gfx::ScaleVector2d(start_.edge_top - start_.edge_bottom, 0.5f); } -float TouchSelectionController::GetEndLineHeight() const { - return end_rect_.height(); +gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const { + return gfx::ScaleVector2d(end_.edge_top - end_.edge_bottom, 0.5f); } bool TouchSelectionController::GetStartVisible() const { - return start_visible_ && !temporarily_hidden_; + return start_.visible && !temporarily_hidden_; } bool TouchSelectionController::GetEndVisible() const { - return end_visible_ && !temporarily_hidden_; + return end_.visible && !temporarily_hidden_; } TouchHandle::AnimationStyle TouchSelectionController::GetAnimationStyle( diff --git a/content/browser/renderer_host/input/touch_selection_controller.h b/content/browser/renderer_host/input/touch_selection_controller.h index c2b2059..20a1f8e 100644 --- a/content/browser/renderer_host/input/touch_selection_controller.h +++ b/content/browser/renderer_host/input/touch_selection_controller.h @@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_SELECTION_CONTROLLER_H_ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_SELECTION_CONTROLLER_H_ +#include "cc/output/viewport_selection_bound.h" #include "content/browser/renderer_host/input/selection_event_type.h" #include "content/browser/renderer_host/input/touch_handle.h" #include "content/common/content_export.h" @@ -46,12 +47,8 @@ class CONTENT_EXPORT TouchSelectionController : public TouchHandleClient { // To be called when the selection bounds have changed. // Note that such updates will trigger handle updates only if preceded // by an appropriate call to allow automatic showing. - void OnSelectionBoundsChanged(const gfx::RectF& start_rect, - TouchHandleOrientation start_orientation, - bool start_visible, - const gfx::RectF& end_rect, - TouchHandleOrientation end_orientation, - bool end_visible); + void OnSelectionBoundsChanged(const cc::ViewportSelectionBound& start, + const cc::ViewportSelectionBound& end); // Allows touch-dragging of the handle. // Returns true iff the event was consumed, in which case the caller should @@ -107,10 +104,10 @@ class CONTENT_EXPORT TouchSelectionController : public TouchHandleClient { void DeactivateSelection(); void ResetCachedValuesIfInactive(); - gfx::PointF GetStartPosition() const; - gfx::PointF GetEndPosition() const; - float GetStartLineHeight() const; - float GetEndLineHeight() const; + const gfx::PointF& GetStartPosition() const; + const gfx::PointF& GetEndPosition() const; + gfx::Vector2dF GetStartLineOffset() const; + gfx::Vector2dF GetEndLineOffset() const; bool GetStartVisible() const; bool GetEndVisible() const; TouchHandle::AnimationStyle GetAnimationStyle(bool was_active) const; @@ -119,12 +116,10 @@ class CONTENT_EXPORT TouchSelectionController : public TouchHandleClient { InputEventType response_pending_input_event_; - gfx::RectF start_rect_; + cc::ViewportSelectionBound start_; + cc::ViewportSelectionBound end_; TouchHandleOrientation start_orientation_; - bool start_visible_; - gfx::RectF end_rect_; TouchHandleOrientation end_orientation_; - bool end_visible_; scoped_ptr<TouchHandle> insertion_handle_; bool is_insertion_active_; diff --git a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc index cfbd48e..460ed20 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc @@ -85,51 +85,35 @@ class TouchSelectionControllerTest : public testing::Test, void SetDraggingEnabled(bool enabled) { dragging_enabled_ = enabled; } void ClearSelection() { - controller_->OnSelectionBoundsChanged(gfx::RectF(), - TOUCH_HANDLE_ORIENTATION_UNDEFINED, - false, - gfx::RectF(), - TOUCH_HANDLE_ORIENTATION_UNDEFINED, - false); + controller_->OnSelectionBoundsChanged(cc::ViewportSelectionBound(), + cc::ViewportSelectionBound()); } void ClearInsertion() { ClearSelection(); } - void ChangeInsertion(const gfx::RectF& rect, - TouchHandleOrientation orientation, - bool visible) { - controller_->OnSelectionBoundsChanged( - rect, orientation, visible, rect, orientation, visible); - } - void ChangeInsertion(const gfx::RectF& rect, bool visible) { - ChangeInsertion(rect, TOUCH_HANDLE_CENTER, visible); - } - - void ChangeSelection(const gfx::RectF& start_rect, - TouchHandleOrientation start_orientation, - bool start_visible, - const gfx::RectF& end_rect, - TouchHandleOrientation end_orientation, - bool end_visible) { - controller_->OnSelectionBoundsChanged(start_rect, - start_orientation, - start_visible, - end_rect, - end_orientation, - end_visible); + cc::ViewportSelectionBound bound; + bound.type = cc::SELECTION_BOUND_CENTER; + bound.edge_top = rect.origin(); + bound.edge_bottom = rect.bottom_left(); + bound.visible = visible; + controller_->OnSelectionBoundsChanged(bound, bound); } void ChangeSelection(const gfx::RectF& start_rect, bool start_visible, const gfx::RectF& end_rect, bool end_visible) { - ChangeSelection(start_rect, - TOUCH_HANDLE_LEFT, - start_visible, - end_rect, - TOUCH_HANDLE_RIGHT, - end_visible); + cc::ViewportSelectionBound start_bound, end_bound; + start_bound.type = cc::SELECTION_BOUND_LEFT; + end_bound.type = cc::SELECTION_BOUND_RIGHT; + start_bound.edge_top = start_rect.origin(); + start_bound.edge_bottom = start_rect.bottom_left(); + end_bound.edge_top = end_rect.origin(); + end_bound.edge_bottom = end_rect.bottom_left(); + start_bound.visible = start_visible; + end_bound.visible = end_visible; + controller_->OnSelectionBoundsChanged(start_bound, end_bound); } void Animate() { diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 7c8d13d..659db53 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -25,6 +25,7 @@ #include "cc/output/compositor_frame_ack.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" +#include "cc/output/viewport_selection_bound.h" #include "cc/resources/single_release_callback.h" #include "cc/trees/layer_tree_host.h" #include "content/browser/accessibility/browser_accessibility_manager_android.h" @@ -770,31 +771,32 @@ void RenderWidgetHostViewAndroid::SelectionBoundsChanged( if (!selection_controller_) return; - gfx::RectF anchor_rect(params.anchor_rect); - gfx::RectF focus_rect(params.focus_rect); + gfx::RectF start_rect(params.anchor_rect); + gfx::RectF end_rect(params.focus_rect); if (params.is_anchor_first) - std::swap(anchor_rect, focus_rect); + std::swap(start_rect, end_rect); + + cc::ViewportSelectionBound start_bound, end_bound; + start_bound.visible = true; + end_bound.visible = true; + start_bound.edge_top = start_rect.origin(); + start_bound.edge_bottom = start_rect.bottom_left(); + end_bound.edge_top = end_rect.origin(); + end_bound.edge_bottom = end_rect.bottom_left(); - TouchHandleOrientation anchor_orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED); - TouchHandleOrientation focus_orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED); if (params.anchor_rect == params.focus_rect) { if (params.anchor_rect.x() && params.anchor_rect.y()) - anchor_orientation = focus_orientation = TOUCH_HANDLE_CENTER; + start_bound.type = end_bound.type = cc::SELECTION_BOUND_CENTER; } else { - anchor_orientation = params.anchor_dir == blink::WebTextDirectionRightToLeft - ? TOUCH_HANDLE_LEFT - : TOUCH_HANDLE_RIGHT; - focus_orientation = params.focus_dir == blink::WebTextDirectionRightToLeft - ? TOUCH_HANDLE_RIGHT - : TOUCH_HANDLE_LEFT; + start_bound.type = params.anchor_dir == blink::WebTextDirectionRightToLeft + ? cc::SELECTION_BOUND_LEFT + : cc::SELECTION_BOUND_RIGHT; + end_bound.type = params.focus_dir == blink::WebTextDirectionRightToLeft + ? cc::SELECTION_BOUND_RIGHT + : cc::SELECTION_BOUND_LEFT; } - selection_controller_->OnSelectionBoundsChanged(anchor_rect, - anchor_orientation, - true, - focus_rect, - focus_orientation, - true); + selection_controller_->OnSelectionBoundsChanged(start_bound, end_bound); } void RenderWidgetHostViewAndroid::SetBackgroundOpaque(bool opaque) { @@ -1539,15 +1541,17 @@ void RenderWidgetHostViewAndroid::OnShowingPastePopup( // of the region have been updated, explicitly set the properties now. // TODO(jdduke): Remove this workaround when auxiliary paste popup // notifications are no longer required, crbug.com/398170. - gfx::RectF rect(point, gfx::SizeF()); - TouchHandleOrientation orientation = TOUCH_HANDLE_CENTER; - const bool visible = true; + cc::ViewportSelectionBound insertion_bound; + insertion_bound.type = cc::SELECTION_BOUND_LEFT; + insertion_bound.visible = true; + insertion_bound.edge_top = point; + insertion_bound.edge_bottom = point; HideTextHandles(); ShowSelectionHandlesAutomatically(); selection_controller_->OnSelectionEditable(true); selection_controller_->OnSelectionEmpty(true); - selection_controller_->OnSelectionBoundsChanged( - rect, orientation, visible, rect, orientation, visible); + selection_controller_->OnSelectionBoundsChanged(insertion_bound, + insertion_bound); } SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h index 8cb3cc2..d51f7af 100644 --- a/content/common/cc_messages.h +++ b/content/common/cc_messages.h @@ -263,7 +263,8 @@ IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(cc::ViewportSelectionBound) IPC_STRUCT_TRAITS_MEMBER(type) - IPC_STRUCT_TRAITS_MEMBER(viewport_rect) + IPC_STRUCT_TRAITS_MEMBER(edge_top) + IPC_STRUCT_TRAITS_MEMBER(edge_bottom) IPC_STRUCT_TRAITS_MEMBER(visible) IPC_STRUCT_TRAITS_END() diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index e4335ab..b9d7a01 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc @@ -85,24 +85,25 @@ bool GetSwitchValueAsInt( } cc::LayerSelectionBound ConvertWebSelectionBound( - const WebSelectionBound& bound) { - DCHECK(bound.layerId); + const WebSelectionBound& web_bound) { + DCHECK(web_bound.layerId); - cc::LayerSelectionBound result; - switch (bound.type) { + cc::LayerSelectionBound cc_bound; + switch (web_bound.type) { case blink::WebSelectionBound::Caret: - result.type = cc::SELECTION_BOUND_CENTER; + cc_bound.type = cc::SELECTION_BOUND_CENTER; break; case blink::WebSelectionBound::SelectionLeft: - result.type = cc::SELECTION_BOUND_LEFT; + cc_bound.type = cc::SELECTION_BOUND_LEFT; break; case blink::WebSelectionBound::SelectionRight: - result.type = cc::SELECTION_BOUND_RIGHT; + cc_bound.type = cc::SELECTION_BOUND_RIGHT; break; } - result.layer_id = bound.layerId; - result.layer_rect = gfx::Rect(bound.edgeRectInLayer); - return result; + cc_bound.layer_id = web_bound.layerId; + cc_bound.edge_top = gfx::Point(web_bound.edgeTopInLayer); + cc_bound.edge_bottom = gfx::Point(web_bound.edgeBottomInLayer); + return cc_bound; } gfx::Size CalculateDefaultTileSize() { |