gdi32: Add helper functions for manipulating bounds rectangles.

oldstable
Alexandre Julliard 2012-04-10 16:04:39 +02:00
parent baa7c3b18a
commit b1ccff1a9c
4 changed files with 46 additions and 43 deletions

View File

@ -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];

View File

@ -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;

View File

@ -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 */

View File

@ -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;