From: "Changhui Liu" Subject: [PATCH 2/3] gdiplus: fix get_clip_hrgn when window origin point changed (try 2) Message-Id: Date: Wed, 24 Dec 2014 00:01:40 +0800 Superseded patch 108339: http://source.winehq.org/patches/data/108339 Change log: try 2: modify code as Dmitry Timoshkov suggested. Thanks Dmitry. ------------------ Regards.
Superseded patch 108339:
http://source.winehq.org/patches/data/108339

Change log:
try 2: modify code as Dmitry Timoshkov suggested.

Thanks Dmitry.






------------------
Regards.
 
From 083e66d48da92273094eff8285816075bd0d1a0c Mon Sep 17 00:00:00 2001 From: Changhui Liu Date: Mon, 22 Dec 2014 16:48:11 +0800 Subject: gdiplus: fix get_clip_hrgn when window origin point changed To: wine-patches Reply-To: wine-devel --- dlls/gdiplus/graphics.c | 13 ++++++- dlls/gdiplus/tests/graphics.c | 90 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 68a4ee5..ce4a3ab 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -350,7 +350,18 @@ static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn) { /* clipping region is in device coords */ - return GdipGetRegionHRgn(graphics->clip, NULL, hrgn); + GpStatus status = GdipGetRegionHRgn(graphics->clip, NULL, hrgn); + if ( status == Ok && graphics->hdc) + { + POINT pt = {0, 0}; + LPtoDP(graphics->hdc, &pt, 1); + if (pt.x!=0 || pt.y!=0) + { + OffsetRgn(*hrgn, pt.x, pt.y); + } + } + + return status; } /* Draw non-premultiplied ARGB data to the given graphics object */ diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 395c04b..6406f27 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -5603,6 +5603,95 @@ static void test_GdipGetVisibleClipBounds_memoryDC(void) ReleaseDC(hwnd, dc); } +#define BLUE_COLOR (0xff0000ff) +#define is_blue_color(color) ( ((color) & 0x00ffffff) == 0xff ) +#define get_bitmap_pixel(x,y) pixel[(y)*(width) + (x)] +static DWORD* GetBitmapPixelBuffer(HDC hdc, HBITMAP hbmp, int width, int height) +{ + BITMAPINFOHEADER bi; + UINT lines = 0; + DWORD *buffer = (DWORD *)GdipAlloc(width*height*4); + + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = width; + bi.biHeight = -height; /*very Important, set negative, indicating a top-down DIB*/ + bi.biPlanes = 1; + bi.biBitCount = 32; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + lines = GetDIBits(hdc, hbmp, 0, height, buffer, (BITMAPINFO *)&bi, DIB_RGB_COLORS); + ok(lines == height, "Expected GetDIBits:%p,%d->%d,%d\n", buffer, height, lines, GetLastError()); + + return buffer; +} + +static void ReleaseBitmapPixelBuffer(DWORD* buffer) +{ + if (buffer) GdipFree(buffer); +} + +static void test_GdipFillRectanglesOnMemoryDCSolidBrush(void) +{ + ARGB color[6] = {0,0,0,0,0,0}; + POINT pt = {0,0}; + RECT rect = {100, 100, 180, 180}; + UINT width = rect.right - rect.left; + UINT height = rect.bottom - rect.top; + GpStatus status = 0; + GpSolidFill *brush = NULL; + GpGraphics *graphics = NULL; + HDC dc = GetDC( hwnd); + HDC hdc = CreateCompatibleDC(dc); + HBITMAP bmp = CreateCompatibleBitmap(dc, width, height); + HGDIOBJ old = SelectObject(hdc, bmp); + DWORD* pixel = NULL; + + /*Change the window origin is the key test point*/ + SetWindowOrgEx(hdc, rect.left, rect.top, &pt); + + status = GdipCreateSolidFill(BLUE_COLOR, &brush); + expect(Ok, status); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + + status = GdipSetClipRectI(graphics, rect.left+width/2, rect.top+height/2, + width, height, CombineModeReplace); + expect(Ok, status); + + status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, rect.right, rect.bottom); + expect(Ok, status); + + GdipDeleteBrush((GpBrush*)brush); + GdipDeleteGraphics(graphics); + + pixel = GetBitmapPixelBuffer(hdc, bmp, width, height); + if (pixel) + { + color[0] = get_bitmap_pixel(width/2, height/2); + color[1] = get_bitmap_pixel(width/2+1, height/2); + color[2] = get_bitmap_pixel(width/2, height/2+1); + color[3] = get_bitmap_pixel(width/2-1, height/2-1); + color[4] = get_bitmap_pixel(width/2-1, height-1); + color[5] = get_bitmap_pixel(width-1, height/2-1); + } + + ok(is_blue_color(color[0]) && is_blue_color(color[1]) && is_blue_color(color[2]) && + color[3] == 0 && color[4] == 0 && color[5] == 0, + "Expected GdipFillRectangleI take effect!\n" ); + ReleaseBitmapPixelBuffer(pixel); + + SelectObject(hdc, old); + DeleteObject(bmp); + DeleteDC(hdc); + ReleaseDC(hwnd, dc); +} + START_TEST(graphics) { struct GdiplusStartupInput gdiplusStartupInput; @@ -5675,6 +5764,7 @@ START_TEST(graphics) test_bitmapfromgraphics(); test_GdipFillRectangles(); test_GdipGetVisibleClipBounds_memoryDC(); + test_GdipFillRectanglesOnMemoryDCSolidBrush(); GdiplusShutdown(gdiplusToken); DestroyWindow( hwnd ); -- 1.9.1