INT FASTCALL GdiSelectVisRgn(HDC hdc, HRGN hrgn) { int retval; DC *dc; PREGION prgn; if (!hrgn) { EngSetLastError(ERROR_INVALID_PARAMETER); return ERROR; } if (!(dc = DC_LockDc(hdc))) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } dc->fs &= ~DC_FLAG_DIRTY_RAO; ASSERT (dc->prgnVis != NULL); prgn = RGNOBJAPI_Lock(hrgn, NULL); retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR; RGNOBJAPI_Unlock(prgn); if ( retval != ERROR ) { IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y); CLIPPING_UpdateGCRegion(dc); } DC_UnlockDc(dc); return retval; }
/*********************************************************************** * IntersectVisRect (GDI.98) */ INT16 WINAPI IntersectVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right, INT16 bottom ) { HRGN tempRgn; INT16 ret; POINT pt[2]; HDC hdc = HDC_32( hdc16 ); DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; pt[0].x = left; pt[0].y = top; pt[1].x = right; pt[1].y = bottom; LPtoDP( hdc, pt, 2 ); TRACE("%p %ld,%ld - %ld,%ld\n", hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y); if (!(tempRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ))) ret = ERROR; else { ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_AND ); DeleteObject( tempRgn ); } if (ret != ERROR) CLIPPING_UpdateGCRegion( dc ); GDI_ReleaseObj( hdc ); return ret; }
int APIENTRY NtGdiOffsetClipRgn(HDC hDC, int XOffset, int YOffset) { INT Result; DC *dc; if(!(dc = DC_LockDc(hDC))) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } if(dc->rosdc.hClipRgn != NULL) { Result = NtGdiOffsetRgn(dc->rosdc.hClipRgn, XOffset, YOffset); CLIPPING_UpdateGCRegion(dc); } else { Result = NULLREGION; } DC_UnlockDc(dc); return Result; }
/*********************************************************************** * ExcludeVisRect (GDI.73) */ INT16 WINAPI ExcludeVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right, INT16 bottom ) { HRGN tempRgn; INT16 ret; POINT pt[2]; HDC hdc = HDC_32( hdc16 ); DC * dc = get_dc_ptr( hdc ); if (!dc) return ERROR; pt[0].x = left; pt[0].y = top; pt[1].x = right; pt[1].y = bottom; LPtoDP( hdc, pt, 2 ); TRACE("%p %d,%d - %d,%d\n", hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y); if (!(tempRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ))) ret = ERROR; else { update_dc( dc ); ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_DIFF ); DeleteObject( tempRgn ); } if (ret != ERROR) CLIPPING_UpdateGCRegion( dc ); release_dc_ptr( dc ); return ret; }
int APIENTRY NtGdiExcludeClipRect(HDC hDC, int LeftRect, int TopRect, int RightRect, int BottomRect) { INT Result; RECTL Rect; PREGION prgnNew, prgnClip; PDC dc = DC_LockDc(hDC); if (!dc) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } Rect.left = LeftRect; Rect.top = TopRect; Rect.right = RightRect; Rect.bottom = BottomRect; IntLPtoDP(dc, (LPPOINT)&Rect, 2); prgnNew = IntSysCreateRectpRgnIndirect(&Rect); if (!prgnNew) { Result = ERROR; } else { if (!dc->rosdc.hClipRgn) { dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF); REGION_UnlockRgn(prgnClip); Result = SIMPLEREGION; } else { prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn); Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF); REGION_UnlockRgn(prgnClip); } REGION_Delete(prgnNew); } if (Result != ERROR) CLIPPING_UpdateGCRegion(dc); DC_UnlockDc(dc); return Result; }
/*********************************************************************** * OffsetVisRgn (GDI.102) */ INT16 WINAPI OffsetVisRgn16( HDC16 hdc16, INT16 x, INT16 y ) { INT16 retval; HDC hdc = HDC_32( hdc16 ); DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%p %d,%d\n", hdc, x, y ); retval = OffsetRgn( dc->hVisRgn, x, y ); CLIPPING_UpdateGCRegion( dc ); GDI_ReleaseObj( hdc ); return retval; }
/*********************************************************************** * OffsetVisRgn (GDI.102) */ INT16 WINAPI OffsetVisRgn16( HDC16 hdc16, INT16 x, INT16 y ) { INT16 retval; HDC hdc = HDC_32( hdc16 ); DC * dc = get_dc_ptr( hdc ); if (!dc) return ERROR; TRACE("%p %d,%d\n", hdc, x, y ); update_dc( dc ); retval = OffsetRgn( dc->hVisRgn, x, y ); CLIPPING_UpdateGCRegion( dc ); release_dc_ptr( dc ); return retval; }
int APIENTRY NtGdiIntersectClipRect(HDC hDC, int LeftRect, int TopRect, int RightRect, int BottomRect) { INT Result; RECTL Rect; HRGN NewRgn; PDC dc = DC_LockDc(hDC); DPRINT("NtGdiIntersectClipRect(%x, %d,%d-%d,%d)\n", hDC, LeftRect, TopRect, RightRect, BottomRect); if (!dc) { EngSetLastError(ERROR_INVALID_HANDLE); return ERROR; } Rect.left = LeftRect; Rect.top = TopRect; Rect.right = RightRect; Rect.bottom = BottomRect; IntLPtoDP(dc, (LPPOINT)&Rect, 2); NewRgn = IntSysCreateRectRgnIndirect(&Rect); if (!NewRgn) { Result = ERROR; } else if (!dc->rosdc.hClipRgn) { dc->rosdc.hClipRgn = NewRgn; Result = SIMPLEREGION; } else { Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND); GreDeleteObject(NewRgn); } if (Result != ERROR) CLIPPING_UpdateGCRegion(dc); DC_UnlockDc(dc); return Result; }
int FASTCALL GdiExtSelectClipRgn(PDC dc, HRGN hrgn, int fnMode) { // dc->fs &= ~DC_FLAG_DIRTY_RAO; if (!hrgn) { if (fnMode == RGN_COPY) { if (dc->rosdc.hClipRgn != NULL) { GreDeleteObject(dc->rosdc.hClipRgn); dc->rosdc.hClipRgn = NULL; } } else { EngSetLastError(ERROR_INVALID_PARAMETER); return ERROR; } } else { if (!dc->rosdc.hClipRgn) { RECTL rect; if(dc->prgnVis) { REGION_GetRgnBox(dc->prgnVis, &rect); dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect); } else { dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0); } } if(fnMode == RGN_COPY) { NtGdiCombineRgn(dc->rosdc.hClipRgn, hrgn, 0, fnMode); } else NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode); } return CLIPPING_UpdateGCRegion(dc); }
/****************************************************************************** * ExtSelectClipRgn [GDI32.@] */ INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT fnMode ) { INT retval; RECT rect; DC * dc = get_dc_ptr( hdc ); if (!dc) return ERROR; TRACE("%p %p %d\n", hdc, hrgn, fnMode ); update_dc( dc ); if (dc->funcs->pExtSelectClipRgn) { retval = dc->funcs->pExtSelectClipRgn( dc->physDev, hrgn, fnMode ); release_dc_ptr( dc ); return retval; } if (!hrgn) { if (fnMode == RGN_COPY) { if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); dc->hClipRgn = 0; } else { FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode); release_dc_ptr( dc ); return ERROR; } } else { if (!dc->hClipRgn) create_default_clip_region( dc ); if(fnMode == RGN_COPY) CombineRgn( dc->hClipRgn, hrgn, 0, fnMode ); else CombineRgn( dc->hClipRgn, dc->hClipRgn, hrgn, fnMode); } CLIPPING_UpdateGCRegion( dc ); release_dc_ptr( dc ); return GetClipBox(hdc, &rect); }
/*********************************************************************** * SelectVisRgn (GDI32.@) * * Note: not exported on Windows, only the 16-bit version is exported. */ INT WINAPI SelectVisRgn( HDC hdc, HRGN hrgn ) { int retval; DC * dc; if (!hrgn) return ERROR; if (!(dc = get_dc_ptr( hdc ))) return ERROR; TRACE("%p %p\n", hdc, hrgn ); dc->dirty = 0; retval = CombineRgn( dc->hVisRgn, hrgn, 0, RGN_COPY ); CLIPPING_UpdateGCRegion( dc ); release_dc_ptr( dc ); return retval; }
/*********************************************************************** * IntersectClipRect (GDI32.@) */ INT WINAPI IntersectClipRect( HDC hdc, INT left, INT top, INT right, INT bottom ) { INT ret; DC *dc = get_dc_ptr( hdc ); if (!dc) return ERROR; TRACE("%p %d,%d - %d,%d\n", hdc, left, top, right, bottom ); update_dc( dc ); if(dc->funcs->pIntersectClipRect) { ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom ); /* FIXME: ret is just a success flag, we should return a proper value */ } else { POINT pt[2]; pt[0].x = left; pt[0].y = top; pt[1].x = right; pt[1].y = bottom; LPtoDP( hdc, pt, 2 ); if (!dc->hClipRgn) { dc->hClipRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ); ret = SIMPLEREGION; } else { HRGN newRgn; if (!(newRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ))) ret = ERROR; else { ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_AND ); DeleteObject( newRgn ); } } if (ret != ERROR) CLIPPING_UpdateGCRegion( dc ); } release_dc_ptr( dc ); return ret; }
/*********************************************************************** * SelectVisRgn (GDI.105) */ INT16 WINAPI SelectVisRgn16( HDC16 hdc16, HRGN16 hrgn ) { int retval; HDC hdc = HDC_32( hdc16 ); DC * dc; if (!hrgn) return ERROR; if (!(dc = DC_GetDCPtr( hdc ))) return ERROR; TRACE("%p %04x\n", hdc, hrgn ); dc->flags &= ~DC_DIRTY; retval = CombineRgn( dc->hVisRgn, HRGN_32(hrgn), 0, RGN_COPY ); CLIPPING_UpdateGCRegion( dc ); GDI_ReleaseObj( hdc ); return retval; }
INT FASTCALL GdiGetClipBox( _In_ HDC hdc, _Out_ LPRECT prc) { PDC pdc; INT iComplexity; /* Lock the DC */ pdc = DC_LockDc(hdc); if (!pdc) { return ERROR; } /* Update RAO region if necessary */ if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc); /* Check if we have a RAO region (intersection of API and VIS region) */ if (pdc->prgnRao) { /* We have a RAO region, use it */ iComplexity = REGION_GetRgnBox(pdc->prgnRao, prc); } else { /* No RAO region means no API region, so use the VIS region */ ASSERT(pdc->prgnVis); iComplexity = REGION_GetRgnBox(pdc->prgnVis, prc); } /* Unlock the DC */ DC_UnlockDc(pdc); /* Convert the rect to logical coordinates */ IntDPtoLP(pdc, (LPPOINT)prc, 2); /* Return the complexity */ return iComplexity; }
/*********************************************************************** * OffsetClipRgn (GDI32.@) */ INT WINAPI OffsetClipRgn( HDC hdc, INT x, INT y ) { INT ret = SIMPLEREGION; DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%p %d,%d\n", hdc, x, y ); if(dc->funcs->pOffsetClipRgn) { ret = dc->funcs->pOffsetClipRgn( dc->physDev, x, y ); /* FIXME: ret is just a success flag, we should return a proper value */ } else if (dc->hClipRgn) { ret = OffsetRgn( dc->hClipRgn, MulDiv( x, dc->vportExtX, dc->wndExtX ), MulDiv( y, dc->vportExtY, dc->wndExtY ) ); CLIPPING_UpdateGCRegion( dc ); } GDI_ReleaseObj( hdc ); return ret; }
/*********************************************************************** * RestoreVisRgn (GDI.130) */ INT16 WINAPI RestoreVisRgn16( HDC16 hdc16 ) { struct saved_visrgn *saved; HDC hdc = HDC_32( hdc16 ); DC *dc = get_dc_ptr( hdc ); INT16 ret = ERROR; if (!dc) return ERROR; TRACE("%p\n", hdc ); if (!(saved = dc->saved_visrgn)) goto done; ret = CombineRgn( dc->hVisRgn, saved->hrgn, 0, RGN_COPY ); dc->saved_visrgn = saved->next; DeleteObject( saved->hrgn ); HeapFree( GetProcessHeap(), 0, saved ); CLIPPING_UpdateGCRegion( dc ); done: release_dc_ptr( dc ); return ret; }
/*********************************************************************** * ExcludeClipRect (GDI32.@) */ INT WINAPI ExcludeClipRect( HDC hdc, INT left, INT top, INT right, INT bottom ) { HRGN newRgn; INT ret; DC *dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%p %dx%d,%dx%d\n", hdc, left, top, right, bottom ); if(dc->funcs->pExcludeClipRect) { ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom ); /* FIXME: ret is just a success flag, we should return a proper value */ } else { POINT pt[2]; pt[0].x = left; pt[0].y = top; pt[1].x = right; pt[1].y = bottom; LPtoDP( hdc, pt, 2 ); if (!(newRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ))) ret = ERROR; else { if (!dc->hClipRgn) create_default_clip_region( dc ); ret = CombineRgn( dc->hClipRgn, dc->hClipRgn, newRgn, RGN_DIFF ); DeleteObject( newRgn ); } if (ret != ERROR) CLIPPING_UpdateGCRegion( dc ); } GDI_ReleaseObj( hdc ); return ret; }
DWORD APIENTRY NtGdiGetBoundsRect( IN HDC hdc, OUT LPRECT prc, IN DWORD flags) { DWORD ret; PDC pdc; RECT rc; /* Lock the DC */ if (!(pdc = DC_LockDc(hdc))) return 0; if (!(flags & DCB_WINDOWMGR)) { rc = pdc->erclBoundsApp; if (RECTL_bIsEmptyRect(&rc)) { rc.left = rc.top = rc.right = rc.bottom = 0; ret = DCB_RESET; } else { RECTL rcRgn; if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc); if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn)) { REGION_GetRgnBox(pdc->prgnVis, &rcRgn); } rc.left = max( rc.left, 0 ); rc.top = max( rc.top, 0 ); rc.right = min( rc.right, rcRgn.right - rcRgn.left ); rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top ); DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top); DPRINT("rc l %d t %d\n",rc.left,rc.top); DPRINT(" r %d b %d\n",rc.right,rc.bottom); ret = DCB_SET; } IntDPtoLP( pdc, &rc, 2 ); DPRINT("rc1 l %d t %d\n",rc.left,rc.top); DPRINT(" r %d b %d\n",rc.right,rc.bottom); } else { rc = pdc->erclBounds; ret = DCB_SET; } /* Copy the rect to the caller */ _SEH2_TRY { ProbeForWrite(prc, sizeof(RECT), 1); *prc = rc; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ret = 0; } _SEH2_END; if (flags & DCB_RESET) { if (!(flags & DCB_WINDOWMGR)) { pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX; pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN; } else { pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX; pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN; } } DC_UnlockDc(pdc); return ret; }
/* rc1 and rc2 are the rectangles where we want to draw or * from where we take pixels. */ VOID FASTCALL DC_vPrepareDCsForBlit( PDC pdcDest, const RECT* rcDest, PDC pdcSrc, const RECT* rcSrc) { PDC pdcFirst, pdcSecond; const RECT *prcFirst, *prcSecond; /* Update brushes */ if (pdcDest->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(pdcDest); if (pdcDest->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(pdcDest); if(pdcDest->pdcattr->ulDirty_ & DIRTY_TEXT) DC_vUpdateTextBrush(pdcDest); /* Lock them in good order */ if(pdcSrc) { if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >= (ULONG_PTR)pdcSrc->ppdev->hsemDevLock) { pdcFirst = pdcDest; prcFirst = rcDest; pdcSecond = pdcSrc; prcSecond = rcSrc; } else { pdcFirst = pdcSrc; prcFirst = rcSrc; pdcSecond = pdcDest; prcSecond = rcDest; } } else { pdcFirst = pdcDest ; prcFirst = rcDest; pdcSecond = NULL; prcSecond = NULL; } /* Update clipping of dest DC if needed */ if (pdcDest->dctype == DCTYPE_DIRECT) { DCE* dce = DceGetDceFromDC(pdcDest->BaseObject.hHmgr); if (dce) DceUpdateVisRgn(dce, dce->pwndOrg, dce->DCXFlags); } if (pdcDest->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdcDest); /* Lock and update first DC */ if(pdcFirst->dctype == DCTYPE_DIRECT) { EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock); /* Update surface if needed */ if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface) { DC_vUpdateDC(pdcFirst); } } if(pdcFirst->dctype == DCTYPE_DIRECT) { if (!prcFirst) prcFirst = &pdcFirst->erclClip; MouseSafetyOnDrawStart(pdcFirst->ppdev, prcFirst->left, prcFirst->top, prcFirst->right, prcFirst->bottom) ; } if (!pdcSecond) return; /* Lock and update second DC */ if(pdcSecond->dctype == DCTYPE_DIRECT) { EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock); /* Update surface if needed */ if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface) { DC_vUpdateDC(pdcSecond); } } if(pdcSecond->dctype == DCTYPE_DIRECT) { if (!prcSecond) prcSecond = &pdcSecond->erclClip; MouseSafetyOnDrawStart(pdcSecond->ppdev, prcSecond->left, prcSecond->top, prcSecond->right, prcSecond->bottom) ; } }