From 3ea711dd7ce7c56b5d6294241d2c41be16c3a9fd Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Wed, 25 Apr 2012 13:15:24 +0200
Subject: [PATCH] gdi32: Store the bounds rectangle as a pointer in the DIB
 driver.

---
 dlls/gdi32/dibdrv/bitblt.c   | 10 +++++-----
 dlls/gdi32/dibdrv/dc.c       | 33 +++++++++++----------------------
 dlls/gdi32/dibdrv/dibdrv.h   |  4 ++--
 dlls/gdi32/dibdrv/graphics.c | 15 ++++++++-------
 4 files changed, 26 insertions(+), 36 deletions(-)

diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c
index 2d088c32121..e35c4cb30fd 100644
--- a/dlls/gdi32/dibdrv/bitblt.c
+++ b/dlls/gdi32/dibdrv/bitblt.c
@@ -964,7 +964,7 @@ DWORD dibdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info
             clip = tmp_rgn;
         }
         else if (!clip) clip = pdev->clip;
-        add_clipped_bounds( &pdev->bounds, &dst->visrect, clip );
+        add_clipped_bounds( pdev, &dst->visrect, clip );
     }
 
     if (!get_clipped_rects( dib, &dst->visrect, clip, &clipped_rects ))
@@ -1021,7 +1021,7 @@ DWORD dibdrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct gdi_image_b
 
     init_dib_info_from_bitmapinfo( &src_dib, info, bits->ptr, 0 );
     src_dib.bits.is_copy = bits->is_copy;
-    add_clipped_bounds( &pdev->bounds, &dst->visrect, pdev->clip );
+    add_clipped_bounds( pdev, &dst->visrect, pdev->clip );
     return blend_rect( &pdev->dib, &dst->visrect, &src_dib, &src->visrect, pdev->clip, blend );
 
 update_format:
@@ -1407,7 +1407,7 @@ BOOL dibdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
             /* Windows bug: no alpha on a8r8g8b8 created with bitfields */
             if (pdev->dib.funcs == &funcs_8888 && pdev->dib.compression == BI_BITFIELDS)
                 vert[0].Alpha = vert[1].Alpha = 0;
-            add_clipped_bounds( &pdev->bounds, &bounds, pdev->clip );
+            add_clipped_bounds( pdev, &bounds, pdev->clip );
             gradient_rect( &pdev->dib, vert, mode, pdev->clip, &bounds );
         }
         break;
@@ -1419,7 +1419,7 @@ BOOL dibdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
             /* Windows bug: no alpha on a8r8g8b8 created with bitfields */
             if (pdev->dib.funcs == &funcs_8888 && pdev->dib.compression == BI_BITFIELDS)
                 vert[0].Alpha = vert[1].Alpha = 0;
-            add_clipped_bounds( &pdev->bounds, &bounds, pdev->clip );
+            add_clipped_bounds( pdev, &bounds, pdev->clip );
             gradient_rect( &pdev->dib, vert, mode, pdev->clip, &bounds );
         }
         break;
@@ -1431,7 +1431,7 @@ BOOL dibdrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
             /* Windows bug: no alpha on a8r8g8b8 created with bitfields */
             if (pdev->dib.funcs == &funcs_8888 && pdev->dib.compression == BI_BITFIELDS)
                 vert[0].Alpha = vert[1].Alpha = vert[2].Alpha = 0;
-            add_clipped_bounds( &pdev->bounds, &bounds, pdev->clip );
+            add_clipped_bounds( pdev, &bounds, pdev->clip );
             if (!gradient_rect( &pdev->dib, vert, mode, pdev->clip, &bounds )) ret = FALSE;
         }
         break;
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index b861f79b6ee..00d6c01fb1d 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -298,19 +298,22 @@ int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct cl
     return clip_rects->count;
 }
 
-void add_clipped_bounds( RECT *bounds, const RECT *rect, HRGN clip )
+void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip )
 {
     const WINEREGION *region;
     RECT rc;
 
+    if (!dev->bounds) return;
     if (clip)
     {
         if (!(region = get_wine_region( clip ))) return;
-        if (!rect) add_bounds_rect( bounds, &region->extents );
-        else if (intersect_rect( &rc, rect, &region->extents )) add_bounds_rect( bounds, &rc );
+        if (!rect) rc = region->extents;
+        else intersect_rect( &rc, rect, &region->extents );
         release_wine_region( clip );
     }
-    else if (rect) add_bounds_rect( bounds, rect );
+    else rc = *rect;
+
+    add_bounds_rect( dev->bounds, &rc );
 }
 
 /**********************************************************************
@@ -325,7 +328,6 @@ static BOOL dibdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
     clear_dib_info(&pdev->dib);
     clear_dib_info(&pdev->brush.dib);
     clear_dib_info(&pdev->pen_brush.dib);
-    reset_bounds( &pdev->bounds );
     push_dc_driver( dev, &pdev->dev, &dib_driver );
     return TRUE;
 }
@@ -394,19 +396,6 @@ static void dibdrv_SetDeviceClipping( PHYSDEV dev, HRGN rgn )
     pdev->clip = rgn;
 }
 
-/***********************************************************************
- *           dibdrv_GetBoundsRect
- */
-static UINT dibdrv_GetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
-{
-    dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
-
-    if (is_rect_empty( &pdev->bounds )) return DCB_RESET;
-    if (rect) *rect = pdev->bounds;
-    if (flags & DCB_RESET) reset_bounds( &pdev->bounds );
-    return DCB_SET;
-}
-
 /***********************************************************************
  *           dibdrv_SetBoundsRect
  */
@@ -414,9 +403,9 @@ static UINT dibdrv_SetBoundsRect( PHYSDEV dev, RECT *rect, UINT flags )
 {
     dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
 
-    if (is_rect_empty( &pdev->bounds )) return DCB_RESET;
-    if (flags & DCB_RESET) reset_bounds( &pdev->bounds );
-    return DCB_SET;
+    if (flags & DCB_DISABLE) pdev->bounds = NULL;
+    else if (flags & DCB_ENABLE) pdev->bounds = rect;
+    return DCB_RESET;  /* we don't have device-specific bounds */
 }
 
 /***********************************************************************
@@ -640,7 +629,7 @@ const struct gdi_dc_funcs dib_driver =
     NULL,                               /* pFrameRgn */
     NULL,                               /* pGdiComment */
     NULL,                               /* pGdiRealizationInfo */
-    dibdrv_GetBoundsRect,               /* pGetBoundsRect */
+    NULL,                               /* pGetBoundsRect */
     NULL,                               /* pGetCharABCWidths */
     NULL,                               /* pGetCharABCWidthsI */
     NULL,                               /* pGetCharWidth */
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 7efb882452d..9431ff08d83 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -96,7 +96,7 @@ typedef struct dibdrv_physdev
     dib_brush brush;
 
     HRGN clip;
-    RECT bounds;
+    RECT *bounds;
 
     /* pen */
     DWORD pen_style, pen_endcap, pen_join;
@@ -247,7 +247,7 @@ extern COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL
 extern DWORD get_pixel_color(dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup) DECLSPEC_HIDDEN;
 extern BOOL brush_rect( dibdrv_physdev *pdev, dib_brush *brush, const RECT *rect, HRGN clip, INT rop ) DECLSPEC_HIDDEN;
 extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN;
-extern void add_clipped_bounds( RECT *bounds, const RECT *rect, HRGN clip ) DECLSPEC_HIDDEN;
+extern void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip ) DECLSPEC_HIDDEN;
 extern int clip_line(const POINT *start, const POINT *end, const RECT *clip,
                      const bres_params *params, POINT *pt1, POINT *pt2) DECLSPEC_HIDDEN;
 
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index e904efd9058..ddf620523bd 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -92,6 +92,7 @@ static void add_pen_lines_bounds( dibdrv_physdev *dev, int count, const POINT *p
     RECT bounds, rect;
     int width = 0;
 
+    if (!dev->bounds) return;
     reset_bounds( &bounds );
 
     if (dev->pen_uses_region)
@@ -127,7 +128,7 @@ static void add_pen_lines_bounds( dibdrv_physdev *dev, int count, const POINT *p
         points++;
     }
 
-    add_clipped_bounds( &dev->bounds, &bounds, dev->clip );
+    add_clipped_bounds( dev, &bounds, dev->clip );
 }
 
 /* compute the points for the first quadrant of an ellipse, counterclockwise from the x axis */
@@ -703,7 +704,7 @@ BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
             origin.y += metrics.gmCellIncY;
         }
     }
-    add_clipped_bounds( &pdev->bounds, &bounds, pdev->clip );
+    add_clipped_bounds( pdev, &bounds, pdev->clip );
 
 done:
     free_clipped_rects( &clipped_rects );
@@ -805,7 +806,7 @@ BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type )
 
     if (!is_interior( &pdev->dib, pdev->clip, x, y, pixel, type )) return FALSE;
 
-    rgn = CreateRectRgn( 0, 0, 0, 0 );
+    if (!(rgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
     row.left = x;
     row.right = x + 1;
     row.top = y;
@@ -813,7 +814,7 @@ BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type )
 
     fill_row( &pdev->dib, pdev->clip, &row, pixel, type, rgn );
 
-    add_clipped_bounds( &pdev->bounds, NULL, rgn );
+    add_clipped_bounds( pdev, NULL, rgn );
     brush_region( pdev, rgn );
 
     DeleteObject( rgn );
@@ -908,7 +909,7 @@ BOOL dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
 
     TRACE("(%p, %d, %d, %d, %d, %06x)\n", dev, dst->x, dst->y, dst->width, dst->height, rop);
 
-    add_bounds_rect( &pdev->bounds, &dst->visrect );
+    add_clipped_bounds( pdev, &dst->visrect, 0 );
     return brush_rect( pdev, &pdev->brush, &dst->visrect, pdev->clip, get_rop2_from_rop(rop) );
 }
 
@@ -938,7 +939,7 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn )
     }
 
     release_wine_region( rgn );
-    add_clipped_bounds( &pdev->bounds, &bounds, pdev->clip );
+    add_clipped_bounds( pdev, &bounds, pdev->clip );
     return TRUE;
 }
 
@@ -1277,7 +1278,7 @@ COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
     rect.top =  pt.y;
     rect.right = rect.left + 1;
     rect.bottom = rect.top + 1;
-    add_clipped_bounds( &pdev->bounds, &rect, pdev->clip );
+    add_clipped_bounds( pdev, &rect, pdev->clip );
 
     /* SetPixel doesn't do the 1bpp massaging like other fg colors */
     pixel = get_pixel_color( pdev, color, FALSE );
-- 
2.24.1