From 402f200c874f9a4b6f8c2ae8d60f0d98b3943727 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Fri, 15 Apr 2011 16:25:58 +0100 Subject: [PATCH] gdi32: Clip solid brush fills. --- dlls/gdi32/dibdrv/objects.c | 40 ++++++++++++----- dlls/gdi32/tests/dib.c | 90 +++++++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 35 deletions(-) diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c index 2d006aaa60..c8fb7fe041 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 ); + int i, j; + const WINEREGION *clip = get_wine_region(pdev->clip); - if(get_clip_region(dc)) return FALSE; - - 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]; - pdev->dib.funcs->solid_rects(&pdev->dib, num, rects, pdev->brush_and, pdev->brush_xor); + /* 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, 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 90eb0082b1..784d8d5bc9 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); + for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); 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"); + 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++) - { - 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"); SelectObject(hdc, orig_brush); SelectObject(hdc, orig_pen);