diff options
author | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-17 15:35:08 +0000 |
---|---|---|
committer | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-17 15:35:08 +0000 |
commit | 13b92160af210543479551c8a80af26c6d8d9e97 (patch) | |
tree | a724325fae55346c45b5d32c0d6003911471bf38 /skia | |
parent | 23e86e818659245590f5ecf779452624c8126b99 (diff) | |
download | chromium_src-13b92160af210543479551c8a80af26c6d8d9e97.zip chromium_src-13b92160af210543479551c8a80af26c6d8d9e97.tar.gz chromium_src-13b92160af210543479551c8a80af26c6d8d9e97.tar.bz2 |
Make non-rectangular clip region apply in the correct location.
BUG=9904
R=brettw
Review URL: http://codereview.chromium.org/75020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13934 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/bitmap_platform_device_win.cc | 3 | ||||
-rw-r--r-- | skia/ext/platform_canvas_unittest.cc | 71 | ||||
-rw-r--r-- | skia/ext/platform_device_win.cc | 17 |
3 files changed, 75 insertions, 16 deletions
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index 5702b55..72eff55 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc @@ -159,9 +159,6 @@ void BitmapPlatformDeviceWin::BitmapPlatformDeviceWinData::LoadConfig() { // Transform. SkMatrix t(transform_); LoadTransformToDC(hdc_, t); - // We don't use transform_ for the clipping region since the translation is - // already applied to offset_x_ and offset_y_. - t.reset(); LoadClippingRegionToDC(hdc_, clip_region_, t); } diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc index c70f238..5e1eadd 100644 --- a/skia/ext/platform_canvas_unittest.cc +++ b/skia/ext/platform_canvas_unittest.cc @@ -56,6 +56,37 @@ bool VerifyRect(const PlatformCanvas& canvas, return true; } +bool IsOfColor(const SkBitmap& bitmap, int x, int y, uint32_t color) { + // For masking out the alpha values. + static uint32_t alpha_mask = 0xFF << SK_A32_SHIFT; + return (*bitmap.getAddr32(x, y) | alpha_mask) == (color | alpha_mask); +} + +// Return true if canvas has something that passes for a rounded-corner +// rectangle. Basically, we're just checking to make sure that the pixels in the +// middle are of rect_color and pixels in the corners are of canvas_color. +bool VerifyRoundedRect(const PlatformCanvas& canvas, + uint32_t canvas_color, uint32_t rect_color, + int x, int y, int w, int h) { + PlatformDevice& device = canvas.getTopPlatformDevice(); + const SkBitmap& bitmap = device.accessBitmap(false); + SkAutoLockPixels lock(bitmap); + + // Check corner points first. They should be of canvas_color. + if (!IsOfColor(bitmap, x, y, canvas_color)) return false; + if (!IsOfColor(bitmap, x + w, y, canvas_color)) return false; + if (!IsOfColor(bitmap, x, y + h, canvas_color)) return false; + if (!IsOfColor(bitmap, x + w, y, canvas_color)) return false; + + // Check middle points. They should be of rect_color. + if (!IsOfColor(bitmap, (x + w / 2), y, rect_color)) return false; + if (!IsOfColor(bitmap, x, (y + h / 2), rect_color)) return false; + if (!IsOfColor(bitmap, x + w, (y + h / 2), rect_color)) return false; + if (!IsOfColor(bitmap, (x + w / 2), y + h, rect_color)) return false; + + return true; +} + // Checks whether there is a white canvas with a black square at the given // location in pixels (not in the canvas coordinate system). bool VerifyBlackRect(const PlatformCanvas& canvas, int x, int y, int w, int h) { @@ -152,6 +183,9 @@ const int kInnerY = 5; const int kInnerW = 2; const int kInnerH = 3; +// Radius used by some tests to draw a rounded-corner rectangle. +const SkScalar kRadius = 2.0; + } // This just checks that our checking code is working properly, it just uses @@ -313,17 +347,44 @@ TEST(PlatformCanvas, TranslateLayer) { canvas.translate(1, 1); { LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); + canvas.drawColor(SK_ColorWHITE); canvas.translate(1, 1); - AddClip(canvas, kInnerX, kInnerY, kInnerW, kInnerH); + AddClip(canvas, kInnerX + 1, kInnerY + 1, kInnerW - 1, kInnerH - 1); DrawNativeRect(canvas, 0, 0, 100, 100); #if defined(OS_WIN) - canvas.getTopPlatformDevice().makeOpaque(kInnerX, kInnerY, - kInnerW, kInnerH); + canvas.getTopPlatformDevice().makeOpaque(kLayerX, kLayerY, + kLayerW, kLayerH); #endif } canvas.restore(); - EXPECT_TRUE(VerifyBlackRect(canvas, kInnerX + 2, kInnerY + 2, - kInnerW, kInnerH)); + EXPECT_TRUE(VerifyBlackRect(canvas, kInnerX + 3, kInnerY + 3, + kInnerW - 1, kInnerH - 1)); + + // Translate both before and after, and have a path clip. + canvas.drawColor(SK_ColorWHITE); + canvas.save(); + canvas.translate(1, 1); + { + LayerSaver layer(canvas, kLayerX, kLayerY, kLayerW, kLayerH); + canvas.drawColor(SK_ColorWHITE); + canvas.translate(1, 1); + + SkPath path; + SkRect rect; + rect.iset(kInnerX - 1, kInnerY - 1, + kInnerX + kInnerW, kInnerY + kInnerH); + path.addRoundRect(rect, kRadius, kRadius); + canvas.clipPath(path); + + DrawNativeRect(canvas, 0, 0, 100, 100); +#if defined(OS_WIN) + canvas.getTopPlatformDevice().makeOpaque(kLayerX, kLayerY, + kLayerW, kLayerH); +#endif + } + canvas.restore(); + EXPECT_TRUE(VerifyRoundedRect(canvas, SK_ColorWHITE, SK_ColorBLACK, + kInnerX + 1, kInnerY + 1, kInnerW, kInnerH)); } } // namespace skia diff --git a/skia/ext/platform_device_win.cc b/skia/ext/platform_device_win.cc index 8af393d..34f9c3d 100644 --- a/skia/ext/platform_device_win.cc +++ b/skia/ext/platform_device_win.cc @@ -200,20 +200,21 @@ void PlatformDeviceWin::LoadClippingRegionToDC(HDC context, // region can be empty, in which case everything will be clipped. hrgn = CreateRectRgn(0, 0, 0, 0); } else if (region.isRect()) { - // Do the transformation. - SkRect rect; - rect.set(region.getBounds()); - transformation.mapRect(&rect); - SkIRect irect; - rect.round(&irect); - hrgn = CreateRectRgnIndirect(&SkIRectToRECT(irect)); + // We don't apply transformation, because the translation is already applied + // to the region. + hrgn = CreateRectRgnIndirect(&SkIRectToRECT(region.getBounds())); } else { // It is complex. SkPath path; region.getBoundaryPath(&path); // Clip. Note that windows clipping regions are not affected by the // transform so apply it manually. - path.transform(transformation); + // Since the transform is given as the original translation of canvas, we + // should apply it in reverse. + SkMatrix t(transformation); + t.setTranslateX(-t.getTranslateX()); + t.setTranslateY(-t.getTranslateY()); + path.transform(t); LoadPathToDC(context, path); hrgn = PathToRegion(context); } |