diff options
-rw-r--r-- | ash/wm/image_grid.cc | 5 | ||||
-rw-r--r-- | ash/wm/image_grid.h | 2 | ||||
-rw-r--r-- | ash/wm/image_grid_unittest.cc | 28 | ||||
-rw-r--r-- | cc/software_renderer.cc | 45 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_aura.cc | 3 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 12 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 14 | ||||
-rw-r--r-- | ui/compositor/layer_unittest.cc | 6 | ||||
-rw-r--r-- | ui/gfx/rect_conversions.cc | 24 | ||||
-rw-r--r-- | ui/gfx/rect_conversions.h | 6 | ||||
-rw-r--r-- | ui/gfx/rect_unittest.cc | 27 | ||||
-rw-r--r-- | ui/gfx/skia_util.cc | 23 | ||||
-rw-r--r-- | ui/gfx/skia_util.h | 4 | ||||
-rw-r--r-- | ui/gfx/transform.cc | 15 | ||||
-rw-r--r-- | ui/gfx/transform.h | 6 | ||||
-rw-r--r-- | ui/views/controls/table/table_view_views.cc | 5 | ||||
-rw-r--r-- | ui/views/controls/tree/tree_view_views.cc | 5 | ||||
-rw-r--r-- | ui/views/view.cc | 12 | ||||
-rw-r--r-- | ui/views/view_unittest.cc | 5 | ||||
-rw-r--r-- | ui/views/widget/widget.cc | 2 |
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 |