summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 18:57:44 +0000
committerjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-22 18:59:19 +0000
commit6ef948738e7140efb20570caebedf30aa1bc0332 (patch)
tree80059706e359ee2fc6289dfb8aa6c77f9b83f019 /cc
parentc7bab312051cb4e8dbe13f1cc347841a2e76176a (diff)
downloadchromium_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.cc2
-rw-r--r--cc/input/layer_selection_bound.h5
-rw-r--r--cc/output/viewport_selection_bound.cc2
-rw-r--r--cc/output/viewport_selection_bound.h5
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc10
-rw-r--r--cc/trees/layer_tree_impl.cc53
-rw-r--r--cc/trees/layer_tree_impl_unittest.cc80
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);
}