summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/image_grid.cc5
-rw-r--r--ash/wm/image_grid.h2
-rw-r--r--ash/wm/image_grid_unittest.cc28
-rw-r--r--cc/software_renderer.cc45
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc3
-rw-r--r--ui/aura/root_window.cc12
-rw-r--r--ui/aura/window_unittest.cc14
-rw-r--r--ui/compositor/layer_unittest.cc6
-rw-r--r--ui/gfx/rect_conversions.cc24
-rw-r--r--ui/gfx/rect_conversions.h6
-rw-r--r--ui/gfx/rect_unittest.cc27
-rw-r--r--ui/gfx/skia_util.cc23
-rw-r--r--ui/gfx/skia_util.h4
-rw-r--r--ui/gfx/transform.cc15
-rw-r--r--ui/gfx/transform.h6
-rw-r--r--ui/views/controls/table/table_view_views.cc5
-rw-r--r--ui/views/controls/tree/tree_view_views.cc5
-rw-r--r--ui/views/view.cc12
-rw-r--r--ui/views/view_unittest.cc5
-rw-r--r--ui/views/widget/widget.cc2
20 files changed, 161 insertions, 88 deletions
diff --git a/ash/wm/image_grid.cc b/ash/wm/image_grid.cc
index facd566..369ab82 100644
--- a/ash/wm/image_grid.cc
+++ b/ash/wm/image_grid.cc
@@ -11,6 +11,7 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/transform.h"
using std::max;
@@ -19,9 +20,9 @@ using std::min;
namespace ash {
namespace internal {
-gfx::Rect ImageGrid::TestAPI::GetTransformedLayerBounds(
+gfx::RectF ImageGrid::TestAPI::GetTransformedLayerBounds(
const ui::Layer& layer) {
- gfx::Rect bounds = layer.bounds();
+ gfx::RectF bounds = layer.bounds();
layer.transform().TransformRect(&bounds);
return bounds;
}
diff --git a/ash/wm/image_grid.h b/ash/wm/image_grid.h
index 8a15735..cb3b7bb 100644
--- a/ash/wm/image_grid.h
+++ b/ash/wm/image_grid.h
@@ -78,7 +78,7 @@ class ASH_EXPORT ImageGrid {
}
// Returns |layer|'s bounds after applying the layer's current transform.
- gfx::Rect GetTransformedLayerBounds(const ui::Layer& layer);
+ gfx::RectF GetTransformedLayerBounds(const ui::Layer& layer);
private:
ImageGrid* grid_; // not owned
diff --git a/ash/wm/image_grid_unittest.cc b/ash/wm/image_grid_unittest.cc
index cf533b5..73a07f1 100644
--- a/ash/wm/image_grid_unittest.cc
+++ b/ash/wm/image_grid_unittest.cc
@@ -57,31 +57,31 @@ TEST_F(ImageGridTest, Basic) {
grid.SetSize(size);
// The top-left layer should be flush with the top-left corner and unscaled.
- EXPECT_EQ(gfx::Rect(0, 0, kBorder, kBorder).ToString(),
+ EXPECT_EQ(gfx::RectF(0, 0, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.top_left_layer()).ToString());
// The top layer should be flush with the top edge and stretched horizontally
// between the two top corners.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
kBorder, 0, size.width() - 2 * kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.top_layer()).ToString());
// The top-right layer should be flush with the top-right corner and unscaled.
- EXPECT_EQ(gfx::Rect(size.width() - kBorder, 0, kBorder, kBorder).ToString(),
+ EXPECT_EQ(gfx::RectF(size.width() - kBorder, 0, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.top_right_layer()).ToString());
// The left layer should be flush with the left edge and stretched vertically
// between the two left corners.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
0, kBorder, kBorder, size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.left_layer()).ToString());
// The center layer should fill the space in the middle of the grid.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
kBorder, kBorder, size.width() - 2 * kBorder,
size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
@@ -89,7 +89,7 @@ TEST_F(ImageGridTest, Basic) {
// The right layer should be flush with the right edge and stretched
// vertically between the two right corners.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
size.width() - kBorder, kBorder,
kBorder, size.height() - 2 * kBorder).ToString(),
test_api.GetTransformedLayerBounds(
@@ -97,13 +97,13 @@ TEST_F(ImageGridTest, Basic) {
// The bottom-left layer should be flush with the bottom-left corner and
// unscaled.
- EXPECT_EQ(gfx::Rect(0, size.height() - kBorder, kBorder, kBorder).ToString(),
+ EXPECT_EQ(gfx::RectF(0, size.height() - kBorder, kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.bottom_left_layer()).ToString());
// The bottom layer should be flush with the bottom edge and stretched
// horizontally between the two bottom corners.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
kBorder, size.height() - kBorder,
size.width() - 2 * kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
@@ -111,7 +111,7 @@ TEST_F(ImageGridTest, Basic) {
// The bottom-right layer should be flush with the bottom-right corner and
// unscaled.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
size.width() - kBorder, size.height() - kBorder,
kBorder, kBorder).ToString(),
test_api.GetTransformedLayerBounds(
@@ -142,7 +142,7 @@ TEST_F(ImageGridTest, SetContentBounds) {
// The master layer is positioned above the top-left corner of the content
// bounds and has height/width that contain the grid and bounds.
- EXPECT_EQ(gfx::Rect(origin.x() - kBorder,
+ EXPECT_EQ(gfx::RectF(origin.x() - kBorder,
origin.y() - kBorder,
size.width() + 2 * kBorder,
size.height() + 2 * kBorder).ToString(),
@@ -175,7 +175,7 @@ TEST_F(ImageGridTest, SingleImage) {
// The top layer should be scaled horizontally across the entire width, but it
// shouldn't be scaled vertically.
- EXPECT_EQ(gfx::Rect(0, 0, kSize.width(), kBorder).ToString(),
+ EXPECT_EQ(gfx::RectF(0, 0, kSize.width(), kBorder).ToString(),
test_api.GetTransformedLayerBounds(
*grid.top_layer()).ToString());
}
@@ -245,21 +245,21 @@ TEST_F(ImageGridTest, SmallerSides) {
// The top layer should be flush with the top edge and stretched horizontally
// between the two top corners.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
kCorner, 0, kSize.width() - 2 * kCorner, kEdge).ToString(),
test_api.GetTransformedLayerBounds(
*grid.top_layer()).ToString());
// The left layer should be flush with the left edge and stretched vertically
// between the top left corner and the bottom.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
0, kCorner, kEdge, kSize.height() - kCorner).ToString(),
test_api.GetTransformedLayerBounds(
*grid.left_layer()).ToString());
// The right layer should be flush with the right edge and stretched
// vertically between the top right corner and the bottom.
- EXPECT_EQ(gfx::Rect(
+ EXPECT_EQ(gfx::RectF(
kSize.width() - kEdge, kCorner,
kEdge, kSize.height() - kCorner).ToString(),
test_api.GetTransformedLayerBounds(
diff --git a/cc/software_renderer.cc b/cc/software_renderer.cc
index 565218a..5c31d7b 100644
--- a/cc/software_renderer.cc
+++ b/cc/software_renderer.cc
@@ -15,6 +15,7 @@
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/effects/SkLayerRasterizer.h"
#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/skia_util.h"
#include <public/WebCompositorSoftwareOutputDevice.h>
#include <public/WebImage.h>
#include <public/WebSize.h>
@@ -28,28 +29,18 @@ namespace cc {
namespace {
-SkRect toSkRect(const gfx::RectF& rect)
-{
- return SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
-}
-
-SkIRect toSkIRect(const gfx::Rect& rect)
-{
- return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
-}
-
void toSkMatrix(SkMatrix* flattened, const WebTransformationMatrix& m)
{
// Convert from 4x4 to 3x3 by dropping the third row and column.
- flattened->set(0, m.m11());
- flattened->set(1, m.m21());
- flattened->set(2, m.m41());
- flattened->set(3, m.m12());
- flattened->set(4, m.m22());
- flattened->set(5, m.m42());
- flattened->set(6, m.m14());
- flattened->set(7, m.m24());
- flattened->set(8, m.m44());
+ flattened->set(0, SkDoubleToScalar(m.m11()));
+ flattened->set(1, SkDoubleToScalar(m.m21()));
+ flattened->set(2, SkDoubleToScalar(m.m41()));
+ flattened->set(3, SkDoubleToScalar(m.m12()));
+ flattened->set(4, SkDoubleToScalar(m.m22()));
+ flattened->set(5, SkDoubleToScalar(m.m42()));
+ flattened->set(6, SkDoubleToScalar(m.m14()));
+ flattened->set(7, SkDoubleToScalar(m.m24()));
+ flattened->set(8, SkDoubleToScalar(m.m44()));
}
bool isScaleAndTranslate(const SkMatrix& matrix)
@@ -138,7 +129,7 @@ bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const Scope
void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect)
{
- m_skCurrentCanvas->clipRect(toSkRect(scissorRect), SkRegion::kReplace_Op);
+ m_skCurrentCanvas->clipRect(gfx::RectToSkRect(scissorRect), SkRegion::kReplace_Op);
}
void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame)
@@ -219,7 +210,7 @@ void SoftwareRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const Debu
{
// We need to apply the matrix manually to have pixel-sized stroke width.
SkPoint vertices[4];
- toSkRect(quadVertexRect()).toQuad(vertices);
+ gfx::RectFToSkRect(quadVertexRect()).toQuad(vertices);
SkPoint transformedVertices[4];
m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
m_skCurrentCanvas->resetMatrix();
@@ -235,7 +226,7 @@ void SoftwareRenderer::drawSolidColorQuad(const DrawingFrame& frame, const Solid
{
m_skCurrentPaint.setColor(quad->color());
m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color()));
- m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint);
+ m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
}
void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
@@ -249,11 +240,11 @@ void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureD
ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resourceId());
const SkBitmap* bitmap = lock.skBitmap();
gfx::RectF uvRect = gfx::ScaleRect(quad->uvRect(), bitmap->width(), bitmap->height());
- SkRect skUvRect = toSkRect(uvRect);
+ SkRect skUvRect = gfx::RectFToSkRect(uvRect);
if (quad->flipped())
m_skCurrentCanvas->scale(1, -1);
m_skCurrentCanvas->drawBitmapRectToRect(*bitmap, &skUvRect,
- toSkRect(quadVertexRect()),
+ gfx::RectFToSkRect(quadVertexRect()),
&m_skCurrentPaint);
}
@@ -267,7 +258,7 @@ void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQua
quad->quadRect().width(), quad->quadRect().height());
m_skCurrentPaint.setFilterBitmap(true);
m_skCurrentCanvas->drawBitmapRectToRect(*lock.skBitmap(), &uvRect,
- toSkRect(quadVertexRect()),
+ gfx::RectFToSkRect(quadVertexRect()),
&m_skCurrentPaint);
}
@@ -280,7 +271,7 @@ void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const Rende
DCHECK(isSoftwareResource(contentTexture->id()));
ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTexture->id());
- SkRect destRect = toSkRect(quadVertexRect());
+ SkRect destRect = gfx::RectFToSkRect(quadVertexRect());
const SkBitmap* content = lock.skBitmap();
@@ -333,7 +324,7 @@ void SoftwareRenderer::drawUnsupportedQuad(const DrawingFrame& frame, const Draw
{
m_skCurrentPaint.setColor(SK_ColorMAGENTA);
m_skCurrentPaint.setAlpha(quad->opacity() * 255);
- m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint);
+ m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
}
bool SoftwareRenderer::swapBuffers()
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 1dad713..3147897 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -50,6 +50,7 @@
#include "ui/compositor/layer.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/display.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
@@ -603,7 +604,7 @@ void RenderWidgetHostViewAura::DidUpdateBackingStore(
if (paint_canvas_) {
SkRect sk_clip_rect;
if (paint_canvas_->sk_canvas()->getClipBounds(&sk_clip_rect))
- clip_rect = gfx::SkRectToRect(sk_clip_rect);
+ clip_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(sk_clip_rect));
}
if (!scroll_rect.IsEmpty())
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 38ea96d..a98aac4 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -39,6 +39,7 @@
#include "ui/gfx/display.h"
#include "ui/gfx/point3_f.h"
#include "ui/gfx/point_conversions.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/screen.h"
using std::vector;
@@ -927,14 +928,15 @@ void RootWindow::OnHostResized(const gfx::Size& size) {
DispatchHeldMouseMove();
// The compositor should have the same size as the native root window host.
// Get the latest scale from display because it might have been changed.
- compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this),
- size);
- gfx::Size old(bounds().size());
+ compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this), size);
+
// The layer, and all the observers should be notified of the
// transformed size of the root window.
- gfx::Rect bounds(ui::ConvertSizeToDIP(layer(), size));
+ gfx::Size old(bounds().size());
+ gfx::RectF bounds(ui::ConvertSizeToDIP(layer(), size));
layer()->transform().TransformRect(&bounds);
- SetBounds(bounds);
+ // The transform is expected to produce an integer rect as its output.
+ SetBounds(gfx::ToNearestRect(bounds));
FOR_EACH_OBSERVER(RootWindowObserver, observers_,
OnRootWindowResized(this, old));
}
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index b19d6a7..14d6166 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -421,12 +421,20 @@ TEST_F(WindowTest, MoveCursorToWithComplexTransform) {
CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get()));
RootWindow* root = root_window();
+
+ // The root window expects transforms that produce integer rects.
+ gfx::Transform root_transform;
+ root_transform.ConcatScale(2.0f, 3.0f);
+ root_transform.ConcatTranslate(-50, -50);
+ root_transform.ConcatRotate(-90.0f);
+ root_transform.ConcatTranslate(60, 70);
+
gfx::Transform transform;
transform.ConcatScale(0.3f, 0.5f);
transform.ConcatRotate(10.0f);
transform.ConcatTranslate(10, 20);
- root->SetTransform(transform);
+ root->SetTransform(root_transform);
w1->SetTransform(transform);
w11->SetTransform(transform);
w111->SetTransform(transform);
@@ -435,8 +443,8 @@ TEST_F(WindowTest, MoveCursorToWithComplexTransform) {
w1111->MoveCursorTo(gfx::Point(10, 10));
#if !defined(OS_WIN)
- // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.OD
- EXPECT_EQ("11,47", root->QueryMouseLocationForTest().ToString());
+ // TODO(yoshiki): fix this to build on Windows. See crbug.com/133413.
+ EXPECT_EQ("169,80", root->QueryMouseLocationForTest().ToString());
#endif
EXPECT_EQ("20,53",
gfx::Screen::GetScreenFor(root)->GetCursorScreenPoint().ToString());
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index 140c356..74b9cfd 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -1038,7 +1038,7 @@ class SchedulePaintLayerDelegate : public LayerDelegate {
return value;
}
- const gfx::Rect& last_clip_rect() const { return last_clip_rect_; }
+ const gfx::RectF& last_clip_rect() const { return last_clip_rect_; }
private:
// Overridden from LayerDelegate:
@@ -1050,7 +1050,7 @@ class SchedulePaintLayerDelegate : public LayerDelegate {
}
SkRect sk_clip_rect;
if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
- last_clip_rect_ = gfx::SkRectToRect(sk_clip_rect);
+ last_clip_rect_ = gfx::SkRectToRectF(sk_clip_rect);
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
@@ -1063,7 +1063,7 @@ class SchedulePaintLayerDelegate : public LayerDelegate {
int paint_count_;
Layer* layer_;
gfx::Rect schedule_paint_rect_;
- gfx::Rect last_clip_rect_;
+ gfx::RectF last_clip_rect_;
DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
};
diff --git a/ui/gfx/rect_conversions.cc b/ui/gfx/rect_conversions.cc
index 160c547..c0391b3 100644
--- a/ui/gfx/rect_conversions.cc
+++ b/ui/gfx/rect_conversions.cc
@@ -4,6 +4,9 @@
#include "ui/gfx/rect_conversions.h"
+#include <cmath>
+
+#include "base/logging.h"
#include "ui/gfx/safe_integer_conversions.h"
namespace gfx {
@@ -28,6 +31,27 @@ Rect ToEnclosedRect(const RectF& rect) {
return Rect(min_x, min_y, width, height);
}
+Rect ToNearestRect(const RectF& rect) {
+ float float_min_x = rect.origin().x();
+ float float_min_y = rect.origin().y();
+ float float_max_x = float_min_x + rect.size().width();
+ float float_max_y = float_min_y + rect.size().height();
+
+ int min_x = ToRoundedInt(float_min_x);
+ int min_y = ToRoundedInt(float_min_y);
+ int max_x = ToRoundedInt(float_max_x);
+ int max_y = ToRoundedInt(float_max_y);
+
+ // If these DCHECKs fail, you're using the wrong method, consider using
+ // ToEnclosingRect or ToEnclosedRect instead.
+ DCHECK(std::abs(min_x - float_min_x) < 0.01f);
+ DCHECK(std::abs(min_y - float_min_y) < 0.01f);
+ DCHECK(std::abs(max_x - float_max_x) < 0.01f);
+ DCHECK(std::abs(max_y - float_max_y) < 0.01f);
+
+ return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
+}
+
Rect ToFlooredRectDeprecated(const RectF& rect) {
return Rect(ToFlooredInt(rect.origin().x()),
ToFlooredInt(rect.origin().y()),
diff --git a/ui/gfx/rect_conversions.h b/ui/gfx/rect_conversions.h
index c8170cc..7c971b3 100644
--- a/ui/gfx/rect_conversions.h
+++ b/ui/gfx/rect_conversions.h
@@ -16,6 +16,12 @@ UI_EXPORT Rect ToEnclosingRect(const RectF& rect);
// Returns the largest Rect that is enclosed by the given RectF.
UI_EXPORT Rect ToEnclosedRect(const RectF& rect);
+// Returns the Rect after snapping the corners of the RectF to an integer grid.
+// This should only be used when the RectF you provide is expected to be an
+// integer rect with floating point error. If it is an arbitrary RectF, then
+// you should use a different method.
+UI_EXPORT Rect ToNearestRect(const RectF& rect);
+
// Returns a Rect obtained by flooring the values of the given RectF.
// Please prefer the previous two functions in new code.
UI_EXPORT Rect ToFlooredRectDeprecated(const RectF& rect);
diff --git a/ui/gfx/rect_unittest.cc b/ui/gfx/rect_unittest.cc
index f8222c6..be1df46 100644
--- a/ui/gfx/rect_unittest.cc
+++ b/ui/gfx/rect_unittest.cc
@@ -394,10 +394,18 @@ TEST(RectTest, SharesEdgeWith) {
EXPECT_FALSE(r.SharesEdgeWith(just_right_no_edge));
}
-TEST(RectTest, SkRectToRect) {
- Rect src(10, 20, 30, 40);
- SkRect skrect = RectToSkRect(src);
- EXPECT_EQ(src, SkRectToRect(skrect));
+TEST(RectTest, SkiaRectConversions) {
+ Rect isrc(10, 20, 30, 40);
+ RectF fsrc(10.5f, 20.5f, 30.5f, 40.5f);
+
+ SkIRect skirect = RectToSkIRect(isrc);
+ EXPECT_EQ(isrc.ToString(), SkIRectToRect(skirect).ToString());
+
+ SkRect skrect = RectToSkRect(isrc);
+ EXPECT_EQ(gfx::RectF(isrc).ToString(), SkRectToRectF(skrect).ToString());
+
+ skrect = RectFToSkRect(fsrc);
+ EXPECT_EQ(fsrc.ToString(), SkRectToRectF(skrect).ToString());
}
// Similar to EXPECT_FLOAT_EQ, but lets NaN equal NaN
@@ -551,6 +559,17 @@ TEST(RectTest, ToEnclosingRect) {
}
}
+TEST(RectTest, ToNearestRect) {
+ Rect rect;
+ EXPECT_EQ(rect.ToString(), ToNearestRect(RectF(rect)).ToString());
+
+ rect = Rect(-1, -1, 3, 3);
+ EXPECT_EQ(rect.ToString(), ToNearestRect(RectF(rect)).ToString());
+
+ RectF rectf(-1.00001f, -0.999999f, 3.0000001f, 2.999999f);
+ EXPECT_EQ(rect.ToString(), ToNearestRect(rectf).ToString());
+}
+
TEST(RectTest, ToFlooredRect) {
static const struct Test {
float x1; // source
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc
index af108da..5046b6a 100644
--- a/ui/gfx/skia_util.cc
+++ b/ui/gfx/skia_util.cc
@@ -14,6 +14,7 @@
#include "third_party/skia/include/effects/SkLayerDrawLooper.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/rect.h"
+#include "ui/gfx/rect_f.h"
#include "ui/gfx/shadow_value.h"
namespace gfx {
@@ -28,17 +29,25 @@ SkIRect RectToSkIRect(const Rect& rect) {
return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
}
-Rect SkRectToRect(const SkRect& rect) {
- return Rect(static_cast<int>(rect.left()),
- static_cast<int>(rect.top()),
- static_cast<int>(rect.width()),
- static_cast<int>(rect.height()));
-}
-
Rect SkIRectToRect(const SkIRect& rect) {
return Rect(rect.x(), rect.y(), rect.width(), rect.height());
}
+SkRect RectFToSkRect(const RectF& rect) {
+ return SkRect::MakeXYWH(SkFloatToScalar(rect.x()),
+ SkFloatToScalar(rect.y()),
+ SkFloatToScalar(rect.width()),
+ SkFloatToScalar(rect.height()));
+}
+
+RectF SkRectToRectF(const SkRect& rect) {
+ return RectF(SkScalarToFloat(rect.x()),
+ SkScalarToFloat(rect.y()),
+ SkScalarToFloat(rect.width()),
+ SkScalarToFloat(rect.height()));
+}
+
+
SkShader* CreateImageRepShader(const gfx::ImageSkiaRep& image_rep,
SkShader::TileMode tile_mode,
const SkMatrix& local_matrix) {
diff --git a/ui/gfx/skia_util.h b/ui/gfx/skia_util.h
index c5dfe63..08eb2203 100644
--- a/ui/gfx/skia_util.h
+++ b/ui/gfx/skia_util.h
@@ -21,13 +21,15 @@ namespace gfx {
class ImageSkiaRep;
class Rect;
+class RectF;
class ShadowValue;
// Convert between Skia and gfx rect types.
UI_EXPORT SkRect RectToSkRect(const Rect& rect);
UI_EXPORT SkIRect RectToSkIRect(const Rect& rect);
-UI_EXPORT Rect SkRectToRect(const SkRect& rect);
UI_EXPORT Rect SkIRectToRect(const SkIRect& rect);
+UI_EXPORT SkRect RectFToSkRect(const RectF& rect);
+UI_EXPORT RectF SkRectToRectF(const SkRect& rect);
// Creates a bitmap shader for the image rep with the image rep's scale factor.
// Sets the created shader's local matrix such that it displays the image rep at
diff --git a/ui/gfx/transform.cc b/ui/gfx/transform.cc
index d34c907..bc214af 100644
--- a/ui/gfx/transform.cc
+++ b/ui/gfx/transform.cc
@@ -4,8 +4,9 @@
#include "ui/gfx/transform.h"
+#include "ui/gfx/point.h"
#include "ui/gfx/point3_f.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/rect_f.h"
#include "ui/gfx/safe_integer_conversions.h"
#include "ui/gfx/skia_util.h"
@@ -151,21 +152,21 @@ bool Transform::TransformPointReverse(Point3F& point) const {
return true;
}
-void Transform::TransformRect(Rect* rect) const {
- SkRect src = RectToSkRect(*rect);
+void Transform::TransformRect(RectF* rect) const {
+ SkRect src = RectFToSkRect(*rect);
const SkMatrix& matrix = matrix_;
matrix.mapRect(&src);
- *rect = SkRectToRect(src);
+ *rect = SkRectToRectF(src);
}
-bool Transform::TransformRectReverse(Rect* rect) const {
+bool Transform::TransformRectReverse(RectF* rect) const {
SkMatrix44 inverse;
if (!matrix_.invert(&inverse))
return false;
const SkMatrix& matrix = inverse;
- SkRect src = RectToSkRect(*rect);
+ SkRect src = RectFToSkRect(*rect);
matrix.mapRect(&src);
- *rect = SkRectToRect(src);
+ *rect = SkRectToRectF(src);
return true;
}
diff --git a/ui/gfx/transform.h b/ui/gfx/transform.h
index 4385c1c..233df68 100644
--- a/ui/gfx/transform.h
+++ b/ui/gfx/transform.h
@@ -10,7 +10,7 @@
namespace gfx {
-class Rect;
+class RectF;
class Point;
class Point3F;
@@ -102,13 +102,13 @@ class UI_EXPORT Transform {
// Applies transformation on the rectangle. Returns true if the transformed
// rectangle was axis aligned. If it returns false, rect will be the
// smallest axis aligned bounding box containing the transformed rect.
- void TransformRect(Rect* rect) const;
+ void TransformRect(RectF* rect) const;
// Applies the reverse transformation on the rectangle. Returns true if
// the transformed rectangle was axis aligned. If it returns false,
// rect will be the smallest axis aligned bounding box containing the
// transformed rect.
- bool TransformRectReverse(Rect* rect) const;
+ bool TransformRectReverse(RectF* rect) const;
// Returns the underlying matrix.
const SkMatrix44& matrix() const { return matrix_; }
diff --git a/ui/views/controls/table/table_view_views.cc b/ui/views/controls/table/table_view_views.cc
index bb53113..b9139b8 100644
--- a/ui/views/controls/table/table_view_views.cc
+++ b/ui/views/controls/table/table_view_views.cc
@@ -9,6 +9,7 @@
#include "ui/base/models/table_model.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/table/table_view_observer.h"
@@ -220,7 +221,9 @@ void TableView::OnPaint(gfx::Canvas* canvas) {
{
SkRect sk_clip_rect;
if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect)) {
- gfx::Rect clip_rect = gfx::SkRectToRect(sk_clip_rect);
+ // Pixels partially inside the clip rect should be included.
+ gfx::Rect clip_rect = gfx::ToEnclosingRect(
+ gfx::SkRectToRectF(sk_clip_rect));
min_y = clip_rect.y();
max_y = clip_rect.bottom();
} else {
diff --git a/ui/views/controls/tree/tree_view_views.cc b/ui/views/controls/tree/tree_view_views.cc
index f24a24d..694f8a1 100644
--- a/ui/views/controls/tree/tree_view_views.cc
+++ b/ui/views/controls/tree/tree_view_views.cc
@@ -15,6 +15,7 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/background.h"
#include "ui/views/controls/scroll_view.h"
@@ -512,7 +513,9 @@ void TreeView::OnPaint(gfx::Canvas* canvas) {
{
SkRect sk_clip_rect;
if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect)) {
- gfx::Rect clip_rect = gfx::SkRectToRect(sk_clip_rect);
+ // Pixels partially inside the clip rect should be included.
+ gfx::Rect clip_rect = gfx::ToEnclosingRect(
+ gfx::SkRectToRectF(sk_clip_rect));
min_y = clip_rect.y();
max_y = clip_rect.bottom();
} else {
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 69fb8a0..8fd3c67 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -24,6 +24,7 @@
#include "ui/gfx/path.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/point3_f.h"
+#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/views/background.h"
@@ -354,8 +355,10 @@ gfx::Rect View::GetVisibleBounds() const {
if (vis_bounds.IsEmpty())
return vis_bounds;
// Convert back to this views coordinate system.
- transform.TransformRectReverse(&vis_bounds);
- return vis_bounds;
+ gfx::RectF views_vis_bounds(vis_bounds);
+ transform.TransformRectReverse(&views_vis_bounds);
+ // Partially visible pixels should be considered visible.
+ return gfx::ToEnclosingRect(views_vis_bounds);
}
gfx::Rect View::GetBoundsInScreen() const {
@@ -677,10 +680,11 @@ void View::ConvertPointFromScreen(const View* dst, gfx::Point* p) {
}
gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
- gfx::Rect x_rect = rect;
+ gfx::RectF x_rect = rect;
GetTransform().TransformRect(&x_rect);
x_rect.Offset(GetMirroredPosition().OffsetFromOrigin());
- return x_rect;
+ // Pixels we partially occupy in the parent should be included.
+ return gfx::ToEnclosingRect(x_rect);
}
gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const {
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 73d6a05..122c6ce 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -2483,9 +2483,8 @@ TEST_F(ViewTest, ConvertRectWithTransform) {
EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
// |v2| now occupies (20, 20) to (120, 70) in |widget|
- // There are some rounding of floating values here. These values may change if
- // floating operations are improved/changed.
- EXPECT_EQ(gfx::Rect(22, 60, 20, 7), v2->ConvertRectToWidget(rect));
+ EXPECT_EQ(gfx::Rect(22, 60, 21, 8).ToString(),
+ v2->ConvertRectToWidget(rect).ToString());
widget->CloseNow();
}
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 6226b3a..b07a75c 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -1062,7 +1062,7 @@ bool Widget::OnNativeWidgetPaintAccelerated(const gfx::Rect& dirty_region) {
force_clear = true;
} else {
// Determine if the layer fills the client area.
- gfx::Rect layer_bounds = GetRootView()->layer()->bounds();
+ gfx::RectF layer_bounds = GetRootView()->layer()->bounds();
layer_transform.TransformRect(&layer_bounds);
gfx::Rect client_bounds = GetClientAreaBoundsInScreen();
// Translate bounds to origin (client area bounds are offset to account