Alexandre Julliard : gdi32: Add helper functions for manipulating bounds rectangles.
Alexandre Julliard
julliard at winehq.org
Mon Apr 16 13:35:45 CDT 2012
Module: wine
Branch: master
Commit: b1ccff1a9c7bd3028821ae1745de83ef111daa28
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b1ccff1a9c7bd3028821ae1745de83ef111daa28
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Apr 10 16:04:39 2012 +0200
gdi32: Add helper functions for manipulating bounds rectangles.
---
dlls/gdi32/bitblt.c | 3 +-
dlls/gdi32/dc.c | 52 +++++++++++++++++----------------------------
dlls/gdi32/font.c | 16 +++++++-------
dlls/gdi32/gdi_private.h | 18 +++++++++++++++-
4 files changed, 46 insertions(+), 43 deletions(-)
diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index 71b8e8f..a97231c 100644
--- a/dlls/gdi32/bitblt.c
+++ b/dlls/gdi32/bitblt.c
@@ -408,8 +408,7 @@ BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
LPtoDP( dev->hdc, pts, nvert );
/* compute bounding rect of all the rectangles/triangles */
- dst.visrect.left = dst.visrect.top = INT_MAX;
- dst.visrect.right = dst.visrect.bottom = INT_MIN;
+ reset_bounds( &dst.visrect );
for (i = 0; i < ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2); i++)
{
ULONG v = ((ULONG *)grad_array)[i];
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 478100d..c256f26 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -114,6 +114,8 @@ DC *alloc_dc_ptr( WORD magic )
dc->xformVport2World = dc->xformWorld2Wnd;
dc->vport2WorldValid = TRUE;
+ reset_bounds( &dc->bounds );
+
if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs )))
{
HeapFree( GetProcessHeap(), 0, dc );
@@ -1316,21 +1318,23 @@ UINT WINAPI GetBoundsRect(HDC hdc, LPRECT rect, UINT flags)
if (rect)
{
- *rect = dc->BoundsRect;
- ret = is_rect_empty( rect ) ? DCB_RESET : DCB_SET;
- rect->left = max( rect->left, 0 );
- rect->top = max( rect->top, 0 );
- rect->right = min( rect->right, dc->vis_rect.right - dc->vis_rect.left );
- rect->bottom = min( rect->bottom, dc->vis_rect.bottom - dc->vis_rect.top );
+ if (is_rect_empty( &dc->bounds ))
+ {
+ rect->left = rect->top = rect->right = rect->bottom = 0;
+ ret = DCB_RESET;
+ }
+ else
+ {
+ *rect = dc->bounds;
+ rect->left = max( rect->left, 0 );
+ rect->top = max( rect->top, 0 );
+ rect->right = min( rect->right, dc->vis_rect.right - dc->vis_rect.left );
+ rect->bottom = min( rect->bottom, dc->vis_rect.bottom - dc->vis_rect.top );
+ ret = DCB_SET;
+ }
DPtoLP( hdc, (POINT *)rect, 2 );
}
- if (flags & DCB_RESET)
- {
- dc->BoundsRect.left = 0;
- dc->BoundsRect.top = 0;
- dc->BoundsRect.right = 0;
- dc->BoundsRect.bottom = 0;
- }
+ if (flags & DCB_RESET) reset_bounds( &dc->bounds );
release_dc_ptr( dc );
return ret;
}
@@ -1348,32 +1352,16 @@ UINT WINAPI SetBoundsRect(HDC hdc, const RECT* rect, UINT flags)
if (!(dc = get_dc_ptr( hdc ))) return 0;
ret = (dc->bounds_enabled ? DCB_ENABLE : DCB_DISABLE) |
- (is_rect_empty( &dc->BoundsRect ) ? DCB_RESET : DCB_SET);
+ (is_rect_empty( &dc->bounds ) ? DCB_RESET : DCB_SET);
- if (flags & DCB_RESET)
- {
- dc->BoundsRect.left = 0;
- dc->BoundsRect.top = 0;
- dc->BoundsRect.right = 0;
- dc->BoundsRect.bottom = 0;
- }
+ if (flags & DCB_RESET) reset_bounds( &dc->bounds );
if ((flags & DCB_ACCUMULATE) && rect)
{
RECT rc = *rect;
LPtoDP( hdc, (POINT *)&rc, 2 );
- if (!is_rect_empty( &rc ))
- {
- if (!is_rect_empty( &dc->BoundsRect))
- {
- dc->BoundsRect.left = min( dc->BoundsRect.left, rc.left );
- dc->BoundsRect.top = min( dc->BoundsRect.top, rc.top );
- dc->BoundsRect.right = max( dc->BoundsRect.right, rc.right );
- dc->BoundsRect.bottom = max( dc->BoundsRect.bottom, rc.bottom );
- }
- else dc->BoundsRect = rc;
- }
+ add_bounds_rect( &dc->bounds, &rc );
}
if (flags & DCB_ENABLE) dc->bounds_enabled = TRUE;
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index f5c44d8..d9c16a4 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1761,20 +1761,20 @@ static RECT get_total_extents( HDC hdc, INT x, INT y, UINT flags, UINT aa_flags,
LPCWSTR str, UINT count, const INT *dx )
{
int i;
- RECT rect;
+ RECT rect, bounds;
- rect.left = rect.top = INT_MAX;
- rect.right = rect.bottom = INT_MIN;
+ reset_bounds( &bounds );
for (i = 0; i < count; i++)
{
GLYPHMETRICS metrics;
if (get_glyph_bitmap( hdc, (UINT)str[i], aa_flags, &metrics, NULL )) continue;
- rect.left = min( rect.left, x + metrics.gmptGlyphOrigin.x );
- rect.top = min( rect.top, y - metrics.gmptGlyphOrigin.y );
- rect.right = max( rect.right, x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX );
- rect.bottom = max( rect.bottom, y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY );
+ rect.left = x + metrics.gmptGlyphOrigin.x;
+ rect.top = y - metrics.gmptGlyphOrigin.y;
+ rect.right = rect.left + metrics.gmBlackBoxX;
+ rect.bottom = rect.top + metrics.gmBlackBoxY;
+ add_bounds_rect( &bounds, &rect );
if (dx)
{
@@ -1791,7 +1791,7 @@ static RECT get_total_extents( HDC hdc, INT x, INT y, UINT flags, UINT aa_flags,
y += metrics.gmCellIncY;
}
}
- return rect;
+ return bounds;
}
/* helper for nulldrv_ExtTextOut */
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 5728a53..20b522d 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -21,6 +21,7 @@
#ifndef __WINE_GDI_PRIVATE_H
#define __WINE_GDI_PRIVATE_H
+#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -149,7 +150,7 @@ typedef struct tagDC
XFORM xformWorld2Vport; /* World-to-viewport transformation */
XFORM xformVport2World; /* Inverse of the above transformation */
BOOL vport2WorldValid; /* Is xformVport2World valid? */
- RECT BoundsRect; /* Current bounding rect */
+ RECT bounds; /* Current bounding rect */
} DC;
/* Certain functions will do no further processing if the driver returns this.
@@ -457,6 +458,21 @@ static inline void get_bounding_rect( RECT *rect, int x, int y, int width, int h
}
}
+static inline void reset_bounds( RECT *bounds )
+{
+ bounds->left = bounds->top = INT_MAX;
+ bounds->right = bounds->bottom = INT_MIN;
+}
+
+static inline void add_bounds_rect( RECT *bounds, const RECT *rect )
+{
+ if (is_rect_empty( rect )) return;
+ bounds->left = min( bounds->left, rect->left );
+ bounds->top = min( bounds->top, rect->top );
+ bounds->right = max( bounds->right, rect->right );
+ bounds->bottom = max( bounds->bottom, rect->bottom );
+}
+
static inline int get_bitmap_stride( int width, int bpp )
{
return ((width * bpp + 15) >> 3) & ~1;
More information about the wine-cvs
mailing list