summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authordglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 15:35:08 +0000
committerdglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 15:35:08 +0000
commit13b92160af210543479551c8a80af26c6d8d9e97 (patch)
treea724325fae55346c45b5d32c0d6003911471bf38 /skia
parent23e86e818659245590f5ecf779452624c8126b99 (diff)
downloadchromium_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.cc3
-rw-r--r--skia/ext/platform_canvas_unittest.cc71
-rw-r--r--skia/ext/platform_device_win.cc17
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);
}