Huw Davies : gdi32: Clip solid brush fills.
Alexandre Julliard
julliard at winehq.org
Mon Apr 18 11:10:59 CDT 2011
Module: wine
Branch: master
Commit: 402f200c874f9a4b6f8c2ae8d60f0d98b3943727
URL: http://source.winehq.org/git/wine.git/?a=commit;h=402f200c874f9a4b6f8c2ae8d60f0d98b3943727
Author: Huw Davies <huw at codeweavers.com>
Date: Fri Apr 15 16:25:58 2011 +0100
gdi32: Clip solid brush fills.
---
dlls/gdi32/dibdrv/objects.c | 40 ++++++++++++++-----
dlls/gdi32/tests/dib.c | 88 +++++++++++++++++++++++++++++++-----------
2 files changed, 94 insertions(+), 34 deletions(-)
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 2d006aa..c8fb7fe 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -275,20 +275,38 @@ COLORREF CDECL dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
*/
static BOOL solid_brush(dibdrv_physdev *pdev, int num, RECT *rects)
{
- int i;
- DC *dc = get_dibdrv_dc( &pdev->dev );
-
- if(get_clip_region(dc)) return FALSE;
+ int i, j;
+ const WINEREGION *clip = get_wine_region(pdev->clip);
- for(i = 0; i < num; i++) /* simple clip to extents */
+ for(i = 0; i < num; i++)
{
- if(rects[i].left < dc->vis_rect.left) rects[i].left = dc->vis_rect.left;
- if(rects[i].top < dc->vis_rect.top) rects[i].top = dc->vis_rect.top;
- if(rects[i].right > dc->vis_rect.right) rects[i].right = dc->vis_rect.right;
- if(rects[i].bottom > dc->vis_rect.bottom) rects[i].bottom = dc->vis_rect.bottom;
- }
+ for(j = 0; j < clip->numRects; j++)
+ {
+ RECT rect = rects[i];
+
+ /* Optimize unclipped case */
+ if(clip->rects[j].top <= rect.top && clip->rects[j].bottom >= rect.bottom &&
+ clip->rects[j].left <= rect.left && clip->rects[j].right >= rect.right)
+ {
+ pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, pdev->brush_and, pdev->brush_xor);
+ break;
+ }
+
+ if(clip->rects[j].top >= rect.bottom) break;
+ if(clip->rects[j].bottom <= rect.top) continue;
+
+ if(clip->rects[j].right > rect.left && clip->rects[j].left < rect.right)
+ {
+ rect.left = max(rect.left, clip->rects[j].left);
+ rect.top = max(rect.top, clip->rects[j].top);
+ rect.right = min(rect.right, clip->rects[j].right);
+ rect.bottom = min(rect.bottom, clip->rects[j].bottom);
- pdev->dib.funcs->solid_rects(&pdev->dib, num, rects, pdev->brush_and, pdev->brush_xor);
+ pdev->dib.funcs->solid_rects(&pdev->dib, 1, &rect, pdev->brush_and, pdev->brush_xor);
+ }
+ }
+ }
+ release_wine_region(pdev->clip);
return TRUE;
}
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index 90eb008..784d8d5 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -78,9 +78,10 @@ static const char *sha1_graphics_a8r8g8b8[] =
"a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
"2426172d9e8fec27d9228088f382ef3c93717da9",
"9e8f27ca952cdba01dbf25d07c34e86a7820c012",
- "76343ceb04e6295e0560019249d3c0318a23c8a6",
- "6ecee6ba1c06dcb6b70ff42a8ea2df7803847860",
"17b2c177bdce5e94433574a928bda5c94a8cdfa5",
+ "fe6cc678fb13a3ead67839481bf22348adc69f52",
+ "d51bd330cec510cdccf5394328bd8e5411901e9e",
+ "f2af53dd073a09b1031d0032d28da35c82adc566",
NULL
};
@@ -144,7 +145,7 @@ static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const
bmi->bmiHeader.biBitCount, info, **sha1, hash);
(*sha1)++;
}
- else trace("\"%s\",\n", hash);
+ else ok(**sha1 != NULL, "missing hash, got \"%s\",\n", hash);
HeapFree(GetProcessHeap(), 0, hash);
}
@@ -161,7 +162,11 @@ static const RECT hline_clips[] =
{120, 99, 140, 99}, /* t edgecase clipped */
{120, 199, 140, 199}, /* b edgecase */
{120, 200, 140, 200}, /* b edgecase clipped */
- {120, 132, 310, 132} /* inside two clip rects */
+ {120, 132, 310, 132}, /* inside two clip rects */
+ { 10, 134, 101, 134}, /* r end on l edgecase */
+ { 10, 136, 100, 136}, /* r end on l edgecase clipped */
+ {199, 138, 220, 138}, /* l end on r edgecase */
+ {200, 140, 220, 200} /* l end on r edgecase clipped */
};
static const RECT vline_clips[] =
@@ -176,7 +181,32 @@ static const RECT vline_clips[] =
{126, 99, 126, 140}, /* t edgecase clipped */
{128, 120, 128, 200}, /* b edgecase */
{130, 120, 130, 201}, /* b edgecase clipped */
- {132, 12, 132, 140} /* inside two clip rects */
+ {132, 12, 132, 140}, /* inside two clip rects */
+ {134, 90, 134, 101}, /* b end on t edgecase */
+ {136, 90, 136, 100}, /* b end on t edgecase clipped */
+ {138, 199, 138, 220}, /* t end on b edgecase */
+ {140, 200, 140, 220} /* t end on b edgecase clipped */
+};
+
+static const RECT patblt_clips[] =
+{
+ {120, 120, 140, 126}, /* unclipped */
+ {100, 130, 140, 136}, /* l edgecase */
+ { 99, 140, 140, 146}, /* l edgecase clipped */
+ {180, 130, 200, 136}, /* r edgecase */
+ {180, 140, 201, 146}, /* r edgecase clipped */
+ {120, 100, 130, 110}, /* t edgecase */
+ {140, 99, 150, 110}, /* t edgecase clipped */
+ {120, 180, 130, 200}, /* b edgecase */
+ {140, 180, 150, 201}, /* b edgecase */
+ {199, 150, 210, 156}, /* l edge on r edgecase */
+ {200, 160, 210, 166}, /* l edge on r edgecase clipped */
+ { 90, 150, 101, 156}, /* r edge on l edgecase */
+ { 90, 160, 100, 166}, /* r edge on l edgecase clipped */
+ {160, 90, 166, 101}, /* b edge on t edgecase */
+ {170, 90, 176, 101}, /* b edge on t edgecase clipped */
+ {160, 199, 166, 210}, /* t edge on b edgecase */
+ {170, 200, 176, 210}, /* t edge on b edgecase clipped */
};
static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
@@ -221,6 +251,29 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sh
compare_hash(bmi, bits, sha1, "diagonal solid lines");
memset(bits, 0xcc, dib_size);
+ /* solid brush PatBlt */
+ solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
+ orig_brush = SelectObject(hdc, solid_brush);
+
+ for(i = 0, y = 10; i < 256; i++)
+ {
+ BOOL ret;
+
+ ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
+
+ if(rop_uses_src(rop3[i]))
+ ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
+ else
+ {
+ ok(ret, "got FALSE for %x\n", rop3[i]);
+ y += 20;
+ }
+
+ }
+ compare_hash(bmi, bits, sha1, "solid patblt");
+ memset(bits, 0xcc, dib_size);
+
+ /* clipped lines */
hrgn = CreateRectRgn(10, 10, 200, 20);
hrgn2 = CreateRectRgn(100, 100, 200, 200);
CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
@@ -246,27 +299,16 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sh
compare_hash(bmi, bits, sha1, "clipped solid vlines");
memset(bits, 0xcc, dib_size);
- ExtSelectClipRgn(hdc, NULL, RGN_COPY);
-
- solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
- orig_brush = SelectObject(hdc, solid_brush);
-
- for(i = 0, y = 10; i < 256; i++)
+ for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
{
- BOOL ret;
-
- ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
+ PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
+ patblt_clips[i].right - patblt_clips[i].left,
+ patblt_clips[i].bottom - patblt_clips[i].top, PATCOPY);
+ }
+ compare_hash(bmi, bits, sha1, "clipped patblt");
- if(rop_uses_src(rop3[i]))
- ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
- else
- {
- ok(ret, "got FALSE for %x\n", rop3[i]);
- y += 20;
- }
+ ExtSelectClipRgn(hdc, NULL, RGN_COPY);
- }
- compare_hash(bmi, bits, sha1, "solid patblt");
SelectObject(hdc, orig_brush);
SelectObject(hdc, orig_pen);
More information about the wine-cvs
mailing list