static BOOL get_vis_rectangles( DC *dc_dst, struct bitblt_coords *dst, DC *dc_src, struct bitblt_coords *src ) { RECT rect; /* get the destination visible rectangle */ rect.left = dst->log_x; rect.top = dst->log_y; rect.right = dst->log_x + dst->log_width; rect.bottom = dst->log_y + dst->log_height; LPtoDP( dc_dst->hSelf, (POINT *)&rect, 2 ); dst->x = rect.left; dst->y = rect.top; dst->width = rect.right - rect.left; dst->height = rect.bottom - rect.top; if (dst->layout & LAYOUT_RTL && dst->layout & LAYOUT_BITMAPORIENTATIONPRESERVED) { dst->x += dst->width; dst->width = -dst->width; } get_bounding_rect( &rect, dst->x, dst->y, dst->width, dst->height ); clip_visrect( dc_dst, &dst->visrect, &rect ); /* get the source visible rectangle */ if (!src) return !is_rect_empty( &dst->visrect ); rect.left = src->log_x; rect.top = src->log_y; rect.right = src->log_x + src->log_width; rect.bottom = src->log_y + src->log_height; LPtoDP( dc_src->hSelf, (POINT *)&rect, 2 ); src->x = rect.left; src->y = rect.top; src->width = rect.right - rect.left; src->height = rect.bottom - rect.top; if (src->layout & LAYOUT_RTL && src->layout & LAYOUT_BITMAPORIENTATIONPRESERVED) { src->x += src->width; src->width = -src->width; } get_bounding_rect( &rect, src->x, src->y, src->width, src->height ); if (!clip_device_rect( dc_src, &src->visrect, &rect )) return FALSE; if (is_rect_empty( &dst->visrect )) return FALSE; return intersect_vis_rectangles( dst, src ); }
/*********************************************************************** * GetClipBox (GDI32.@) */ INT WINAPI GetClipBox( HDC hdc, LPRECT rect ) { RECT visrect; INT ret; DC *dc = get_dc_ptr( hdc ); if (!dc) return ERROR; update_dc( dc ); if (get_dc_region( dc )) { ret = GetRgnBox( get_dc_region( dc ), rect ); } else { ret = is_rect_empty( &dc->vis_rect ) ? ERROR : SIMPLEREGION; *rect = dc->vis_rect; } if (get_dc_device_rect( dc, &visrect ) && !intersect_rect( rect, rect, &visrect )) ret = NULLREGION; if (dc->layout & LAYOUT_RTL) { int tmp = rect->left; rect->left = rect->right - 1; rect->right = tmp - 1; } DPtoLP( hdc, (LPPOINT)rect, 2 ); release_dc_ptr( dc ); TRACE("%p => %d %s\n", hdc, ret, wine_dbgstr_rect( rect )); return ret; }
int clip_rect_to_dib( const dib_info *dib, RECT *rc ) { RECT rect; rect.left = max( 0, -dib->rect.left ); rect.top = max( 0, -dib->rect.top ); rect.right = min( dib->rect.right, dib->width ) - dib->rect.left; rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top; if (is_rect_empty( &rect )) return 0; return intersect_rect( rc, &rect, rc ); }
/*********************************************************************** * GetRandomRgn [GDI32.@] * * NOTES * This function is documented in MSDN online for the case of * iCode == SYSRGN (4). * * For iCode == 1 it should return the clip region * 2 " " " the meta region * 3 " " " the intersection of the clip with * the meta region (== 'Rao' region). * * See http://www.codeproject.com/gdi/cliprgnguide.asp */ INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode) { INT ret = 1; DC *dc = get_dc_ptr( hDC ); if (!dc) return -1; switch (iCode) { case 1: if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY ); else ret = 0; break; case 2: if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY ); else ret = 0; break; case 3: if (dc->hClipRgn && dc->hMetaRgn) CombineRgn( hRgn, dc->hClipRgn, dc->hMetaRgn, RGN_AND ); else if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY ); else if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY ); else ret = 0; break; case SYSRGN: /* == 4 */ update_dc( dc ); if (dc->hVisRgn) { CombineRgn( hRgn, dc->hVisRgn, 0, RGN_COPY ); /* On Windows NT/2000, the SYSRGN returned is in screen coordinates */ if (!(GetVersion() & 0x80000000)) OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top ); } else if (!is_rect_empty( &dc->device_rect )) SetRectRgn( hRgn, dc->device_rect.left, dc->device_rect.top, dc->device_rect.right, dc->device_rect.bottom ); else ret = 0; break; default: WARN("Unknown code %d\n", iCode); ret = -1; break; } release_dc_ptr( dc ); return ret; }
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) rc = region->extents; else intersect_rect( &rc, rect, ®ion->extents ); release_wine_region( clip ); } else rc = *rect; if (is_rect_empty( &rc )) return; offset_rect( &rc, dev->dib.rect.left, dev->dib.rect.top ); add_bounds_rect( dev->bounds, &rc ); }
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 = max( 0, -dib->rect.left ); rect.top = max( 0, -dib->rect.top ); rect.right = min( dib->rect.right, dib->width ) - dib->rect.left; rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top; if (is_rect_empty( &rect )) return 0; 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; }
/****************************************************************************** * GdiAlphaBlend [GDI32.@] */ BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst, HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFunction) { BOOL ret = FALSE; DC *dcDst, *dcSrc; dcSrc = get_dc_ptr( hdcSrc ); if (!dcSrc) return FALSE; if ((dcDst = get_dc_ptr( hdcDst ))) { struct bitblt_coords src, dst; update_dc( dcSrc ); update_dc( dcDst ); src.log_x = xSrc; src.log_y = ySrc; src.log_width = widthSrc; src.log_height = heightSrc; src.layout = GetLayout( hdcSrc ); dst.log_x = xDst; dst.log_y = yDst; dst.log_width = widthDst; dst.log_height = heightDst; dst.layout = GetLayout( hdcDst ); ret = !get_vis_rectangles( dcDst, &dst, dcSrc, &src ); TRACE("src %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s dst %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s blend=%02x/%02x/%02x/%02x\n", hdcSrc, src.log_x, src.log_y, src.log_width, src.log_height, src.x, src.y, src.width, src.height, wine_dbgstr_rect(&src.visrect), hdcDst, dst.log_x, dst.log_y, dst.log_width, dst.log_height, dst.x, dst.y, dst.width, dst.height, wine_dbgstr_rect(&dst.visrect), blendFunction.BlendOp, blendFunction.BlendFlags, blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat ); if (src.x < 0 || src.y < 0 || src.width < 0 || src.height < 0 || src.log_width < 0 || src.log_height < 0 || (!is_rect_empty( &dcSrc->device_rect ) && (src.width > dcSrc->device_rect.right - dcSrc->vis_rect.left - src.x || src.height > dcSrc->device_rect.bottom - dcSrc->vis_rect.top - src.y))) { WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src.x, src.y, src.width, src.height ); SetLastError( ERROR_INVALID_PARAMETER ); ret = FALSE; } else if (dst.log_width < 0 || dst.log_height < 0) { WARN( "Invalid dst coords: (%d,%d), size %dx%d\n", dst.log_x, dst.log_y, dst.log_width, dst.log_height ); SetLastError( ERROR_INVALID_PARAMETER ); ret = FALSE; } else if (dcSrc == dcDst && src.x + src.width > dst.x && src.x < dst.x + dst.width && src.y + src.height > dst.y && src.y < dst.y + dst.height) { WARN( "Overlapping coords: (%d,%d), %dx%d and (%d,%d), %dx%d\n", src.x, src.y, src.width, src.height, dst.x, dst.y, dst.width, dst.height ); SetLastError( ERROR_INVALID_PARAMETER ); ret = FALSE; } else if (!ret) { PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend ); PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend ); ret = dst_dev->funcs->pAlphaBlend( dst_dev, &dst, src_dev, &src, blendFunction ); } release_dc_ptr( dcDst ); } release_dc_ptr( dcSrc ); return ret; }
/* return the DC device rectangle if not empty */ static inline BOOL get_dc_device_rect( DC *dc, RECT *rect ) { *rect = dc->device_rect; offset_rect( rect, -dc->vis_rect.left, -dc->vis_rect.top ); return !is_rect_empty( rect ); }
static inline void lock_surface( struct windrv_physdev *dev ) { GDI_CheckNotLock(); dev->surface->funcs->lock( dev->surface ); if (is_rect_empty( dev->dibdrv->bounds )) dev->start_ticks = GetTickCount(); }