gdi32: Add a helper function to compute the list of rectangles to paint after clipping.
This commit is contained in:
parent
5b93bb9800
commit
b761d0e1c6
|
@ -576,28 +576,17 @@ static DWORD blend_rect( dib_info *dst, const RECT *dst_rect, const dib_info *sr
|
|||
HRGN clip, BLENDFUNCTION blend )
|
||||
{
|
||||
POINT origin;
|
||||
RECT clipped_rect;
|
||||
const WINEREGION *clip_data;
|
||||
struct clipped_rects clipped_rects;
|
||||
int i;
|
||||
|
||||
origin.x = src_rect->left;
|
||||
origin.y = src_rect->top;
|
||||
|
||||
if (clip == NULL) dst->funcs->blend_rect( dst, dst_rect, src, &origin, blend );
|
||||
else
|
||||
if (!get_clipped_rects( dst, dst_rect, clip, &clipped_rects )) return ERROR_SUCCESS;
|
||||
for (i = 0; i < clipped_rects.count; i++)
|
||||
{
|
||||
clip_data = get_wine_region( clip );
|
||||
for (i = 0; i < clip_data->numRects; i++)
|
||||
{
|
||||
if (intersect_rect( &clipped_rect, dst_rect, clip_data->rects + i ))
|
||||
{
|
||||
origin.x = src_rect->left + clipped_rect.left - dst_rect->left;
|
||||
origin.y = src_rect->top + clipped_rect.top - dst_rect->top;
|
||||
dst->funcs->blend_rect( dst, &clipped_rect, src, &origin, blend );
|
||||
}
|
||||
}
|
||||
release_wine_region( clip );
|
||||
origin.x = src_rect->left + clipped_rects.rects[i].left - dst_rect->left;
|
||||
origin.y = src_rect->top + clipped_rects.rects[i].top - dst_rect->top;
|
||||
dst->funcs->blend_rect( dst, &clipped_rects.rects[i], src, &origin, blend );
|
||||
}
|
||||
free_clipped_rects( &clipped_rects );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -679,7 +668,8 @@ static void get_gradient_triangle_vertices( const GRADIENT_TRIANGLE *tri, const
|
|||
static BOOL gradient_rect( dib_info *dib, TRIVERTEX *v, int mode, HRGN clip )
|
||||
{
|
||||
int i;
|
||||
RECT rect, clipped_rect;
|
||||
struct clipped_rects clipped_rects;
|
||||
RECT rect;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (mode == GRADIENT_FILL_TRIANGLE)
|
||||
|
@ -696,26 +686,13 @@ static BOOL gradient_rect( dib_info *dib, TRIVERTEX *v, int mode, HRGN clip )
|
|||
rect.right = v[1].x;
|
||||
rect.bottom = v[1].y;
|
||||
}
|
||||
rect.left = max( rect.left, 0 );
|
||||
rect.top = max( rect.top, 0 );
|
||||
rect.right = min( rect.right, dib->width );
|
||||
rect.bottom = min( rect.bottom, dib->height );
|
||||
|
||||
if (clip)
|
||||
if (!get_clipped_rects( dib, &rect, clip, &clipped_rects )) return TRUE;
|
||||
for (i = 0; i < clipped_rects.count; i++)
|
||||
{
|
||||
const WINEREGION *clip_data = get_wine_region( clip );
|
||||
|
||||
for (i = 0; i < clip_data->numRects; i++)
|
||||
{
|
||||
if (intersect_rect( &clipped_rect, &rect, clip_data->rects + i ))
|
||||
{
|
||||
if (!(ret = dib->funcs->gradient_rect( dib, &clipped_rect, v, mode ))) break;
|
||||
}
|
||||
}
|
||||
release_wine_region( clip );
|
||||
if (!(ret = dib->funcs->gradient_rect( dib, &clipped_rects.rects[i], v, mode ))) break;
|
||||
}
|
||||
else if (!is_rect_empty( &rect )) ret = dib->funcs->gradient_rect( dib, &rect, v, mode );
|
||||
|
||||
free_clipped_rects( &clipped_rects );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,48 @@ DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, struct bit
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects )
|
||||
{
|
||||
const WINEREGION *region;
|
||||
RECT rect, *out = clip_rects->buffer;
|
||||
int i;
|
||||
|
||||
init_clipped_rects( clip_rects );
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = dib->width;
|
||||
rect.bottom = dib->height;
|
||||
if (rc && !intersect_rect( &rect, &rect, rc )) return 0;
|
||||
|
||||
if (!clip)
|
||||
{
|
||||
*out = rect;
|
||||
clip_rects->count = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(region = get_wine_region( clip ))) return 0;
|
||||
|
||||
for (i = 0; i < region->numRects; i++)
|
||||
{
|
||||
if (region->rects[i].top >= rect.bottom) break;
|
||||
if (!intersect_rect( out, &rect, ®ion->rects[i] )) continue;
|
||||
out++;
|
||||
if (out == &clip_rects->buffer[sizeof(clip_rects->buffer) / sizeof(RECT)])
|
||||
{
|
||||
clip_rects->rects = HeapAlloc( GetProcessHeap(), 0, region->numRects * sizeof(RECT) );
|
||||
if (!clip_rects->rects) return 0;
|
||||
memcpy( clip_rects->rects, clip_rects->buffer, (out - clip_rects->buffer) * sizeof(RECT) );
|
||||
out = clip_rects->rects + (out - clip_rects->buffer);
|
||||
}
|
||||
}
|
||||
release_wine_region( clip );
|
||||
clip_rects->count = out - clip_rects->rects;
|
||||
return clip_rects->count;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* add_extra_clipping_region
|
||||
*
|
||||
* Temporarily add a region to the current clipping region.
|
||||
|
|
|
@ -212,6 +212,13 @@ typedef struct
|
|||
DWORD octant;
|
||||
} bres_params;
|
||||
|
||||
struct clipped_rects
|
||||
{
|
||||
RECT *rects;
|
||||
int count;
|
||||
RECT buffer[32];
|
||||
};
|
||||
|
||||
extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN;
|
||||
extern void update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
|
||||
extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
|
||||
|
@ -225,11 +232,23 @@ 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_rects( dibdrv_physdev *pdev, int num, const RECT *rects ) DECLSPEC_HIDDEN;
|
||||
extern void solid_rects( dib_info *dib, int num, const RECT *rects, const rop_mask *color, HRGN region ) DECLSPEC_HIDDEN;
|
||||
extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN;
|
||||
extern HRGN add_extra_clipping_region( dibdrv_physdev *pdev, HRGN rgn ) DECLSPEC_HIDDEN;
|
||||
extern void restore_clipping_region( dibdrv_physdev *pdev, HRGN rgn ) 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;
|
||||
|
||||
static inline void init_clipped_rects( struct clipped_rects *clip_rects )
|
||||
{
|
||||
clip_rects->count = 0;
|
||||
clip_rects->rects = clip_rects->buffer;
|
||||
}
|
||||
|
||||
static inline void free_clipped_rects( struct clipped_rects *clip_rects )
|
||||
{
|
||||
if (clip_rects->rects != clip_rects->buffer) HeapFree( GetProcessHeap(), 0, clip_rects->rects );
|
||||
}
|
||||
|
||||
/* compute the x coordinate corresponding to y on the specified edge */
|
||||
static inline int edge_coord( int y, int x1, int y1, int x2, int y2 )
|
||||
{
|
||||
|
|
|
@ -606,36 +606,27 @@ BOOL dibdrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
|
|||
COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
|
||||
{
|
||||
dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
|
||||
int i;
|
||||
struct clipped_rects clipped_rects;
|
||||
RECT rect;
|
||||
POINT pt;
|
||||
DWORD pixel;
|
||||
const WINEREGION *clip = get_wine_region( pdev->clip );
|
||||
|
||||
TRACE( "(%p, %d, %d, %08x)\n", dev, x, y, color );
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
LPtoDP( dev->hdc, &pt, 1 );
|
||||
rect.left = pt.x;
|
||||
rect.top = pt.y;
|
||||
rect.right = rect.left + 1;
|
||||
rect.bottom = rect.top + 1;
|
||||
|
||||
/* SetPixel doesn't do the 1bpp massaging like other fg colors */
|
||||
pixel = get_pixel_color( pdev, color, FALSE );
|
||||
color = pdev->dib.funcs->pixel_to_colorref( &pdev->dib, pixel );
|
||||
|
||||
for (i = 0; i < clip->numRects; i++)
|
||||
{
|
||||
if (pt_in_rect( clip->rects + i, pt ))
|
||||
{
|
||||
RECT rect;
|
||||
rect.left = pt.x;
|
||||
rect.top = pt.y;
|
||||
rect.right = rect.left + 1;
|
||||
rect.bottom = rect.top + 1;
|
||||
|
||||
pdev->dib.funcs->solid_rects( &pdev->dib, 1, &rect, 0, pixel );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
release_wine_region( pdev->clip );
|
||||
if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return color;
|
||||
pdev->dib.funcs->solid_rects( &pdev->dib, clipped_rects.count, clipped_rects.rects, 0, pixel );
|
||||
free_clipped_rects( &clipped_rects );
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -430,12 +430,6 @@ static inline void offset_rect( RECT *rect, int offset_x, int offset_y )
|
|||
rect->bottom += offset_y;
|
||||
}
|
||||
|
||||
static inline BOOL pt_in_rect( const RECT *rect, POINT pt )
|
||||
{
|
||||
return ((pt.x >= rect->left) && (pt.x < rect->right) &&
|
||||
(pt.y >= rect->top) && (pt.y < rect->bottom));
|
||||
}
|
||||
|
||||
static inline void get_bounding_rect( RECT *rect, int x, int y, int width, int height )
|
||||
{
|
||||
rect->left = x;
|
||||
|
|
Loading…
Reference in New Issue