[2/3] gdiplus: Store the gdi32 clip region at Graphics creation time.
Vincent Povirk
vincent at codeweavers.com
Wed Oct 4 14:54:18 CDT 2017
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
dlls/gdiplus/gdiplus_private.h | 1 +
dlls/gdiplus/graphics.c | 59 ++++++++++++++++++++++++++----------------
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 33f6ceb..566092e 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -262,6 +262,7 @@ struct GpGraphics{
INT origin_x, origin_y;
INT gdi_transform_acquire_count, gdi_transform_save;
GpMatrix gdi_transform;
+ HRGN gdi_clip;
/* For giving the caller an HDC when we technically can't: */
HBITMAP temp_hbitmap;
int temp_hbitmap_width;
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 66a3f76..0207385 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -348,6 +348,17 @@ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
GdipDeleteRegion(rgn);
}
+ if (stat == Ok && graphics->gdi_clip)
+ {
+ if (*hrgn)
+ CombineRgn(*hrgn, *hrgn, graphics->gdi_clip, RGN_AND);
+ else
+ {
+ *hrgn = CreateRectRgn(0,0,0,0);
+ CombineRgn(*hrgn, graphics->gdi_clip, graphics->gdi_clip, RGN_COPY);
+ }
+ }
+
return stat;
}
@@ -498,8 +509,7 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
save = SaveDC(graphics->hdc);
- if (hrgn)
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
if (hregion)
ExtSelectClipRgn(graphics->hdc, hregion, RGN_AND);
@@ -2315,6 +2325,13 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
(*graphics)->contid = 0;
get_gdi_transform(*graphics, &(*graphics)->gdi_transform);
+ (*graphics)->gdi_clip = CreateRectRgn(0,0,0,0);
+ if (!GetClipRgn(hdc, (*graphics)->gdi_clip))
+ {
+ DeleteObject((*graphics)->gdi_clip);
+ (*graphics)->gdi_clip = NULL;
+ }
+
TRACE("<-- %p\n", *graphics);
return Ok;
@@ -2439,6 +2456,8 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
GdipDeleteRegion(graphics->clip);
+ DeleteObject(graphics->gdi_clip);
+
/* Native returns ObjectBusy on the second free, instead of crashing as we'd
* do otherwise, but we can't have that in the test suite because it means
* accessing freed memory. */
@@ -3223,9 +3242,9 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
stat = get_clip_hrgn(graphics, &hrgn);
- if (stat == Ok && hrgn)
+ if (stat == Ok)
{
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
DeleteObject(hrgn);
}
@@ -3466,8 +3485,7 @@ static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *pat
if (retval != Ok)
goto end;
- if (hrgn)
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
gdi_transform_acquire(graphics);
@@ -4155,8 +4173,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
if (retval != Ok)
goto end;
- if (hrgn)
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
gdi_transform_acquire(graphics);
@@ -4443,32 +4460,30 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
if(!graphics->hdc || !brush_can_fill_path(brush, TRUE))
return NotImplemented;
- status = GdipGetRegionHRgn(region, graphics, &hrgn);
- if(status != Ok)
- return status;
-
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
-
- DeleteObject(hrgn);
-
hrgn = NULL;
status = get_clip_hrgn(graphics, &hrgn);
-
if (status != Ok)
{
RestoreDC(graphics->hdc, save_state);
return status;
}
- if (hrgn)
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
+ DeleteObject(hrgn);
+
+ status = GdipGetRegionHRgn(region, graphics, &hrgn);
+ if (status != Ok)
{
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
- DeleteObject(hrgn);
+ RestoreDC(graphics->hdc, save_state);
+ return status;
}
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ DeleteObject(hrgn);
+
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
{
BeginPath(graphics->hdc);
@@ -7001,9 +7016,9 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
status = get_clip_hrgn(graphics, &hrgn);
- if (status == Ok && hrgn)
+ if (status == Ok)
{
- ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
+ ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
DeleteObject(hrgn);
}
--
2.7.4
More information about the wine-patches
mailing list