mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[WIN32K]
- Correctly use the Clip, Meta, Rao, API and Vis Regions in DCs - Update the DC clipping object on demand each time a blt is performed - Reduce the number of region allocated with handles when it's not needed This commit fixes numerous bugs regarding clipping, most notably SetDIBitsToDevice overlapping foreground windows CORE-8353 #resolve #comment There are still a few quirks in winetests which will get fixed in a next commit CORE-7628 #comment should be fixed in rev 63731, please confirm. svn path=/trunk/; revision=63731
This commit is contained in:
parent
022f198f1e
commit
df7f9319c2
20 changed files with 610 additions and 614 deletions
|
@ -335,8 +335,7 @@ NtGdiAngleArc(
|
|||
|
||||
worker.l = dwStartAngle;
|
||||
worker1.l = dwSweepAngle;
|
||||
DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds,
|
||||
NULL, pDC->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(pDC, NULL, NULL, NULL);
|
||||
if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(pDC);
|
||||
if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
|
||||
|
@ -381,8 +380,7 @@ NtGdiArcInternal(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, dc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
|
||||
|
||||
if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(dc);
|
||||
|
|
|
@ -107,7 +107,7 @@ NtGdiAlphaBlend(
|
|||
|
||||
/* Prepare DCs for blit */
|
||||
TRACE("Preparing DCs for blit\n");
|
||||
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
|
||||
DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
|
||||
|
||||
/* Determine surfaces to be used in the bitblt */
|
||||
BitmapDest = DCDest->dclevel.pSurface;
|
||||
|
@ -268,7 +268,7 @@ NtGdiTransparentBlt(
|
|||
rcSrc.bottom += DCSrc->ptlDCOrig.y;
|
||||
|
||||
/* Prepare for blit */
|
||||
DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc);
|
||||
DC_vPrepareDCsForBlit(DCDest, &rcDest, DCSrc, &rcSrc);
|
||||
|
||||
BitmapDest = DCDest->dclevel.pSurface;
|
||||
if (!BitmapDest)
|
||||
|
@ -456,7 +456,7 @@ NtGdiMaskBlt(
|
|||
}
|
||||
|
||||
/* Prepare blit */
|
||||
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
|
||||
DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(DCDest);
|
||||
|
@ -647,7 +647,7 @@ GreStretchBltMask(
|
|||
BrushOrigin.y = 0;
|
||||
|
||||
/* Only prepare Source and Dest, hdcMask represents a DIB */
|
||||
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
|
||||
DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(DCDest);
|
||||
|
@ -826,7 +826,7 @@ IntPatBlt(
|
|||
BrushOrigin.y = pbrush->ptOrigin.y + pdc->ptlDCOrig.y;
|
||||
#endif
|
||||
|
||||
DC_vPrepareDCsForBlit(pdc, DestRect, NULL, DestRect);
|
||||
DC_vPrepareDCsForBlit(pdc, &DestRect, NULL, NULL);
|
||||
|
||||
psurf = pdc->dclevel.pSurface;
|
||||
|
||||
|
|
|
@ -11,164 +11,102 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
int FASTCALL
|
||||
CLIPPING_UpdateGCRegion(DC* Dc)
|
||||
VOID
|
||||
FASTCALL
|
||||
GdiSelectVisRgn(
|
||||
HDC hdc,
|
||||
PREGION prgn)
|
||||
{
|
||||
PROSRGNDATA CombinedRegion;
|
||||
//HRGN hRgnVis;
|
||||
PREGION prgnClip, prgnGCClip;
|
||||
DC *dc;
|
||||
|
||||
/* Would prefer this, but the rest of the code sucks... */
|
||||
//ASSERT(Dc->rosdc.hGCClipRgn);
|
||||
//ASSERT(Dc->rosdc.hClipRgn);
|
||||
ASSERT(Dc->prgnVis);
|
||||
//hRgnVis = Dc->prgnVis->BaseObject.hHmgr;
|
||||
if (!(dc = DC_LockDc(hdc)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Dc->rosdc.hGCClipRgn == NULL)
|
||||
Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn);
|
||||
ASSERT(prgnGCClip);
|
||||
ASSERT(dc->prgnVis != NULL);
|
||||
ASSERT(prgn != NULL);
|
||||
|
||||
if (Dc->rosdc.hClipRgn == NULL)
|
||||
IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY);
|
||||
else
|
||||
{
|
||||
prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: Locking order, ugh!
|
||||
IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND);
|
||||
REGION_UnlockRgn(prgnClip);
|
||||
}
|
||||
REGION_UnlockRgn(prgnGCClip);
|
||||
|
||||
NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
|
||||
|
||||
if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
|
||||
{
|
||||
CLIPOBJ *CombinedClip;
|
||||
|
||||
CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
|
||||
CombinedRegion->Buffer,
|
||||
&CombinedRegion->rdh.rcBound);
|
||||
|
||||
RGNOBJAPI_Unlock(CombinedRegion);
|
||||
|
||||
if ( !CombinedClip )
|
||||
{
|
||||
DPRINT1("IntEngCreateClipRegion() failed\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(Dc->rosdc.CombinedClip != NULL)
|
||||
IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
|
||||
|
||||
Dc->rosdc.CombinedClip = CombinedClip ;
|
||||
}
|
||||
|
||||
return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY);
|
||||
IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
|
||||
CLIPPING_UpdateGCRegion(dc);
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return retval;
|
||||
DC_UnlockDc(dc);
|
||||
}
|
||||
|
||||
|
||||
int FASTCALL GdiExtSelectClipRgn(PDC dc,
|
||||
HRGN hrgn,
|
||||
int fnMode)
|
||||
int
|
||||
FASTCALL
|
||||
IntGdiExtSelectClipRgn(
|
||||
PDC dc,
|
||||
PREGION prgn,
|
||||
int fnMode)
|
||||
{
|
||||
// dc->fs &= ~DC_FLAG_DIRTY_RAO;
|
||||
if (!prgn)
|
||||
{
|
||||
if (fnMode == RGN_COPY)
|
||||
{
|
||||
if (dc->dclevel.prgnClip != NULL)
|
||||
{
|
||||
REGION_Delete(dc->dclevel.prgnClip);
|
||||
dc->dclevel.prgnClip = NULL;
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
}
|
||||
return SIMPLEREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hrgn)
|
||||
{
|
||||
if (fnMode == RGN_COPY)
|
||||
if (!dc->dclevel.prgnClip)
|
||||
{
|
||||
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)
|
||||
{
|
||||
RECTL rect;
|
||||
|
||||
REGION_GetRgnBox(dc->prgnVis, &rect);
|
||||
dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
|
||||
}
|
||||
dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect);
|
||||
}
|
||||
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);
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
if(fnMode == RGN_COPY)
|
||||
return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, 0, fnMode);
|
||||
|
||||
return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode);
|
||||
}
|
||||
|
||||
|
||||
int APIENTRY NtGdiExtSelectClipRgn(HDC hDC,
|
||||
HRGN hrgn,
|
||||
int fnMode)
|
||||
int
|
||||
APIENTRY
|
||||
NtGdiExtSelectClipRgn(
|
||||
HDC hDC,
|
||||
HRGN hrgn,
|
||||
int fnMode)
|
||||
{
|
||||
int retval;
|
||||
DC *dc;
|
||||
int retval;
|
||||
DC *dc;
|
||||
PREGION prgn;
|
||||
|
||||
if (!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
if (!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
retval = GdiExtSelectClipRgn ( dc, hrgn, fnMode );
|
||||
prgn = REGION_LockRgn(hrgn);
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return retval;
|
||||
/* IntGdiExtSelectClipRgn takes care of checking for NULL region */
|
||||
retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
|
||||
|
||||
if (prgn)
|
||||
REGION_UnlockRgn(prgn);
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
INT FASTCALL
|
||||
|
@ -177,7 +115,6 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
|
|||
INT retval;
|
||||
PDC dc;
|
||||
PROSRGNDATA pRgnNew, pRgn = NULL;
|
||||
BOOL Unlock = FALSE; // Small HACK
|
||||
|
||||
if (!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
|
@ -193,10 +130,9 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
|
|||
{
|
||||
pRgn = dc->dclevel.prgnMeta;
|
||||
}
|
||||
else if (dc->rosdc.hClipRgn)
|
||||
else if (dc->dclevel.prgnClip) // CLIPRGN
|
||||
{
|
||||
Unlock = TRUE ;
|
||||
pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN
|
||||
pRgn = dc->dclevel.prgnClip;
|
||||
}
|
||||
|
||||
if (pRgn)
|
||||
|
@ -206,7 +142,6 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
|
|||
if (!pRgnNew)
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
if(Unlock) REGION_UnlockRgn(pRgn);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
@ -217,12 +152,11 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
|
|||
REGION_Delete(pRgnNew);
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
if(Unlock) REGION_UnlockRgn(pRgn);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = REGION_GetRgnBox(dc->prgnVis, rc);
|
||||
IntDPtoLP(dc, (LPPOINT)rc, 2);
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return retval;
|
||||
|
@ -265,53 +199,49 @@ int APIENTRY NtGdiExcludeClipRect(HDC hDC,
|
|||
int RightRect,
|
||||
int BottomRect)
|
||||
{
|
||||
INT Result;
|
||||
RECTL Rect;
|
||||
PREGION prgnNew, prgnClip;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
INT Result;
|
||||
RECTL Rect;
|
||||
PREGION prgnNew;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Rect.left = LeftRect;
|
||||
Rect.top = TopRect;
|
||||
Rect.right = RightRect;
|
||||
Rect.bottom = BottomRect;
|
||||
Rect.left = LeftRect;
|
||||
Rect.top = TopRect;
|
||||
Rect.right = RightRect;
|
||||
Rect.bottom = BottomRect;
|
||||
|
||||
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
|
||||
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);
|
||||
prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
|
||||
if (!prgnNew)
|
||||
{
|
||||
Result = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dc->dclevel.prgnClip)
|
||||
{
|
||||
dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
IntGdiCombineRgn(dc->dclevel.prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
|
||||
Result = SIMPLEREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgnNew, RGN_DIFF);
|
||||
}
|
||||
REGION_Delete(prgnNew);
|
||||
}
|
||||
if (Result != ERROR)
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return Result;
|
||||
return Result;
|
||||
}
|
||||
|
||||
int APIENTRY NtGdiIntersectClipRect(HDC hDC,
|
||||
|
@ -320,200 +250,191 @@ int APIENTRY NtGdiIntersectClipRect(HDC hDC,
|
|||
int RightRect,
|
||||
int BottomRect)
|
||||
{
|
||||
INT Result;
|
||||
RECTL Rect;
|
||||
HRGN NewRgn;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
INT Result;
|
||||
RECTL Rect;
|
||||
PREGION pNewRgn;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
|
||||
DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
|
||||
hDC, LeftRect, TopRect, RightRect, BottomRect);
|
||||
DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
|
||||
hDC, LeftRect, TopRect, RightRect, BottomRect);
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
Rect.left = LeftRect;
|
||||
Rect.top = TopRect;
|
||||
Rect.right = RightRect;
|
||||
Rect.bottom = BottomRect;
|
||||
Rect.left = LeftRect;
|
||||
Rect.top = TopRect;
|
||||
Rect.right = RightRect;
|
||||
Rect.bottom = BottomRect;
|
||||
|
||||
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
|
||||
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);
|
||||
pNewRgn = IntSysCreateRectpRgnIndirect(&Rect);
|
||||
if (!pNewRgn)
|
||||
{
|
||||
Result = ERROR;
|
||||
}
|
||||
else if (!dc->dclevel.prgnClip)
|
||||
{
|
||||
dc->dclevel.prgnClip = pNewRgn;
|
||||
Result = SIMPLEREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND);
|
||||
REGION_Delete(pNewRgn);
|
||||
}
|
||||
if (Result != ERROR)
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return Result;
|
||||
return Result;
|
||||
}
|
||||
|
||||
int APIENTRY NtGdiOffsetClipRgn(HDC hDC,
|
||||
int XOffset,
|
||||
int YOffset)
|
||||
{
|
||||
INT Result;
|
||||
DC *dc;
|
||||
INT Result;
|
||||
DC *dc;
|
||||
|
||||
if(!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return ERROR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if(dc->dclevel.prgnClip != NULL)
|
||||
{
|
||||
Result = IntGdiOffsetRgn(dc->dclevel.prgnClip,
|
||||
XOffset,
|
||||
YOffset);
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = NULLREGION;
|
||||
}
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return Result;
|
||||
DC_UnlockDc(dc);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BOOL APIENTRY NtGdiPtVisible(HDC hDC,
|
||||
int X,
|
||||
int Y)
|
||||
{
|
||||
HRGN rgn;
|
||||
DC *dc;
|
||||
BOOL ret = FALSE;
|
||||
PDC dc;
|
||||
|
||||
if(!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
if(!(dc = DC_LockDc(hDC)))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rgn = dc->rosdc.hGCClipRgn;
|
||||
DC_UnlockDc(dc);
|
||||
if (dc->prgnRao)
|
||||
{
|
||||
POINT pt = {X, Y};
|
||||
IntLPtoDP(dc, &pt, 1);
|
||||
ret = REGION_PtInRegion(dc->prgnRao, pt.x, pt.y);
|
||||
}
|
||||
|
||||
return (rgn ? NtGdiPtInRegion(rgn, X, Y) : FALSE);
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL APIENTRY NtGdiRectVisible(HDC hDC,
|
||||
LPRECT UnsafeRect)
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiRectVisible(
|
||||
HDC hDC,
|
||||
LPRECT UnsafeRect)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PROSRGNDATA Rgn;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
BOOL Result = FALSE;
|
||||
RECTL Rect;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
BOOL Result = FALSE;
|
||||
RECTL Rect;
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
if (!dc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(UnsafeRect,
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(UnsafeRect,
|
||||
sizeof(RECT),
|
||||
1);
|
||||
Rect = *UnsafeRect;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
Rect = *UnsafeRect;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dc->rosdc.hGCClipRgn)
|
||||
{
|
||||
if((Rgn = (PROSRGNDATA)RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
|
||||
{
|
||||
if (dc->fs & DC_FLAG_DIRTY_RAO)
|
||||
CLIPPING_UpdateGCRegion(dc);
|
||||
|
||||
if (dc->prgnRao)
|
||||
{
|
||||
IntLPtoDP(dc, (LPPOINT)&Rect, 2);
|
||||
Result = REGION_RectInRegion(Rgn, &Rect);
|
||||
RGNOBJAPI_Unlock(Rgn);
|
||||
}
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
Result = REGION_RectInRegion(dc->prgnRao, &Rect);
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return Result;
|
||||
return Result;
|
||||
}
|
||||
|
||||
int
|
||||
FASTCALL
|
||||
IntGdiSetMetaRgn(PDC pDC)
|
||||
{
|
||||
INT Ret = ERROR;
|
||||
PROSRGNDATA TempRgn;
|
||||
INT Ret = ERROR;
|
||||
|
||||
if ( pDC->dclevel.prgnMeta )
|
||||
{
|
||||
if ( pDC->dclevel.prgnClip )
|
||||
{
|
||||
TempRgn = IntSysCreateRectpRgn(0,0,0,0);
|
||||
if (TempRgn)
|
||||
if ( pDC->dclevel.prgnMeta )
|
||||
{
|
||||
if ( pDC->dclevel.prgnClip )
|
||||
{
|
||||
Ret = IntGdiCombineRgn( TempRgn,
|
||||
pDC->dclevel.prgnMeta,
|
||||
pDC->dclevel.prgnClip,
|
||||
RGN_AND);
|
||||
if ( Ret )
|
||||
{
|
||||
GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
|
||||
if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
|
||||
REGION_Delete(pDC->dclevel.prgnMeta);
|
||||
|
||||
pDC->dclevel.prgnMeta = TempRgn;
|
||||
|
||||
GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
|
||||
if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
|
||||
REGION_Delete(pDC->dclevel.prgnClip);
|
||||
|
||||
pDC->dclevel.prgnClip = NULL;
|
||||
|
||||
IntGdiReleaseRaoRgn(pDC);
|
||||
}
|
||||
else
|
||||
REGION_Delete(TempRgn);
|
||||
Ret = IntGdiCombineRgn(pDC->dclevel.prgnMeta, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip, RGN_AND);
|
||||
if (Ret != ERROR)
|
||||
{
|
||||
REGION_Delete(pDC->dclevel.prgnClip);
|
||||
pDC->dclevel.prgnClip = NULL;
|
||||
IntGdiReleaseRaoRgn(pDC);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pDC->dclevel.prgnClip )
|
||||
{
|
||||
Ret = REGION_Complexity(pDC->dclevel.prgnClip);
|
||||
pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
|
||||
pDC->dclevel.prgnClip = NULL;
|
||||
}
|
||||
else
|
||||
Ret = SIMPLEREGION;
|
||||
}
|
||||
return Ret;
|
||||
else
|
||||
Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pDC->dclevel.prgnClip )
|
||||
{
|
||||
Ret = REGION_Complexity(pDC->dclevel.prgnClip);
|
||||
pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
|
||||
pDC->dclevel.prgnClip = NULL;
|
||||
}
|
||||
else
|
||||
Ret = SIMPLEREGION;
|
||||
}
|
||||
|
||||
if (Ret != ERROR)
|
||||
pDC->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -533,88 +454,95 @@ int APIENTRY NtGdiSetMetaRgn(HDC hDC)
|
|||
return Ret;
|
||||
}
|
||||
|
||||
INT FASTCALL
|
||||
NEW_CLIPPING_UpdateGCRegion(PDC pDC)
|
||||
VOID
|
||||
FASTCALL
|
||||
CLIPPING_UpdateGCRegion(PDC pDC)
|
||||
{
|
||||
CLIPOBJ * co;
|
||||
CLIPOBJ * co;
|
||||
|
||||
/* Must have VisRgn set to a valid state! */
|
||||
ASSERT (pDC->prgnVis);
|
||||
/* Must have VisRgn set to a valid state! */
|
||||
ASSERT (pDC->prgnVis);
|
||||
|
||||
// FIXME: this seems to be broken!
|
||||
if (pDC->prgnAPI)
|
||||
{
|
||||
REGION_Delete(pDC->prgnAPI);
|
||||
pDC->prgnAPI = NULL;
|
||||
}
|
||||
|
||||
if (pDC->prgnAPI)
|
||||
{
|
||||
REGION_Delete(pDC->prgnAPI);
|
||||
pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
|
||||
}
|
||||
if (pDC->prgnRao)
|
||||
REGION_Delete(pDC->prgnRao);
|
||||
|
||||
if (pDC->prgnRao)
|
||||
{
|
||||
REGION_Delete(pDC->prgnRao);
|
||||
pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
|
||||
}
|
||||
pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
|
||||
|
||||
if (!pDC->prgnRao)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
ASSERT(pDC->prgnRao);
|
||||
|
||||
if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip)
|
||||
{
|
||||
IntGdiCombineRgn( pDC->prgnAPI,
|
||||
pDC->dclevel.prgnClip,
|
||||
pDC->dclevel.prgnMeta,
|
||||
RGN_AND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pDC->dclevel.prgnClip)
|
||||
{
|
||||
IntGdiCombineRgn( pDC->prgnAPI,
|
||||
pDC->dclevel.prgnClip,
|
||||
NULL,
|
||||
RGN_COPY);
|
||||
}
|
||||
else if (pDC->dclevel.prgnMeta)
|
||||
{
|
||||
IntGdiCombineRgn( pDC->prgnAPI,
|
||||
pDC->dclevel.prgnMeta,
|
||||
NULL,
|
||||
RGN_COPY);
|
||||
}
|
||||
}
|
||||
if (pDC->dclevel.prgnMeta || pDC->dclevel.prgnClip)
|
||||
{
|
||||
pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
|
||||
if (!pDC->dclevel.prgnMeta)
|
||||
{
|
||||
IntGdiCombineRgn(pDC->prgnAPI,
|
||||
pDC->dclevel.prgnClip,
|
||||
NULL,
|
||||
RGN_COPY);
|
||||
}
|
||||
else if (!pDC->dclevel.prgnClip)
|
||||
{
|
||||
IntGdiCombineRgn(pDC->prgnAPI,
|
||||
pDC->dclevel.prgnMeta,
|
||||
NULL,
|
||||
RGN_COPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
IntGdiCombineRgn(pDC->prgnAPI,
|
||||
pDC->dclevel.prgnClip,
|
||||
pDC->dclevel.prgnMeta,
|
||||
RGN_AND);
|
||||
}
|
||||
}
|
||||
|
||||
IntGdiCombineRgn( pDC->prgnRao,
|
||||
pDC->prgnVis,
|
||||
pDC->prgnAPI,
|
||||
RGN_AND);
|
||||
if (pDC->prgnAPI)
|
||||
{
|
||||
IntGdiCombineRgn(pDC->prgnRao,
|
||||
pDC->prgnVis,
|
||||
pDC->prgnAPI,
|
||||
RGN_AND);
|
||||
}
|
||||
else
|
||||
{
|
||||
IntGdiCombineRgn(pDC->prgnRao,
|
||||
pDC->prgnVis,
|
||||
NULL,
|
||||
RGN_COPY);
|
||||
}
|
||||
|
||||
RtlCopyMemory(&pDC->erclClip,
|
||||
|
||||
IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
|
||||
|
||||
RtlCopyMemory(&pDC->erclClip,
|
||||
&pDC->prgnRao->rdh.rcBound,
|
||||
sizeof(RECTL));
|
||||
|
||||
pDC->fs &= ~DC_FLAG_DIRTY_RAO;
|
||||
pDC->fs &= ~DC_FLAG_DIRTY_RAO;
|
||||
|
||||
IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
|
||||
// pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
|
||||
// the rects from region objects rects in pClipRgn->Buffer.
|
||||
// With pDC->co.pClipRgn->Buffer,
|
||||
// pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
|
||||
|
||||
// pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
|
||||
// the rects from region objects rects in pClipRgn->Buffer.
|
||||
// With pDC->co.pClipRgn->Buffer,
|
||||
// pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
|
||||
co = IntEngCreateClipRegion(pDC->prgnRao->rdh.nCount,
|
||||
pDC->prgnRao->Buffer,
|
||||
&pDC->erclClip);
|
||||
if (co)
|
||||
{
|
||||
if (pDC->rosdc.CombinedClip != NULL)
|
||||
IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
|
||||
|
||||
co = IntEngCreateClipRegion(pDC->prgnRao->rdh.nCount,
|
||||
pDC->prgnRao->Buffer,
|
||||
&pDC->erclClip);
|
||||
if (co)
|
||||
{
|
||||
if (pDC->rosdc.CombinedClip != NULL)
|
||||
IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
|
||||
pDC->rosdc.CombinedClip = co;
|
||||
}
|
||||
|
||||
pDC->rosdc.CombinedClip = co;
|
||||
}
|
||||
|
||||
return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
|
||||
IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
INT FASTCALL GdiGetClipBox(HDC hDC, RECTL *rc);
|
||||
INT FASTCALL GdiSelectVisRgn(HDC hdc, HRGN hrgn);
|
||||
INT FASTCALL GdiExtSelectClipRgn (PDC dc, HRGN hrgn, int fnMode);
|
||||
int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
|
||||
VOID FASTCALL GdiSelectVisRgn(HDC hdc, PREGION prgn);
|
||||
INT FASTCALL IntGdiExtSelectClipRgn (PDC dc, PREGION prgn, int fnMode);
|
||||
VOID FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
|
||||
|
|
|
@ -48,9 +48,6 @@ typedef enum _DCTYPE
|
|||
|
||||
typedef struct _ROS_DC_INFO
|
||||
{
|
||||
HRGN hClipRgn; /* Clip region (may be 0) */
|
||||
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
|
||||
|
||||
CLIPOBJ *CombinedClip;
|
||||
} ROS_DC_INFO;
|
||||
|
||||
|
@ -199,9 +196,9 @@ BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
|
|||
|
||||
BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
|
||||
VOID FASTCALL DC_vUpdateViewportExt(PDC pdc);
|
||||
VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL to);
|
||||
VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To);
|
||||
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2);
|
||||
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
|
||||
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT* rcDest, PDC pdcSrc, const RECT* rcSrc);
|
||||
|
||||
VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
|
||||
|
||||
|
|
|
@ -95,22 +95,11 @@ DC_AllocDcWithHandle()
|
|||
void
|
||||
DC_InitHack(PDC pdc)
|
||||
{
|
||||
HRGN hVisRgn;
|
||||
|
||||
TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
|
||||
pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
|
||||
|
||||
/* This should never fail */
|
||||
ASSERT(pdc->dclevel.ppal);
|
||||
|
||||
/* Select regions */
|
||||
pdc->rosdc.hClipRgn = NULL;
|
||||
pdc->rosdc.hGCClipRgn = NULL;
|
||||
|
||||
hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
|
||||
ASSERT(hVisRgn);
|
||||
GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
|
||||
GreDeleteObject(hVisRgn);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -170,7 +159,7 @@ DC_vInitDc(
|
|||
pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
|
||||
pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
|
||||
pdc->erclClip = pdc->erclBounds;
|
||||
// pdc->co
|
||||
pdc->co = gxcoTrivial;
|
||||
|
||||
pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
|
||||
}
|
||||
|
@ -185,7 +174,7 @@ DC_vInitDc(
|
|||
pdc->erclBounds.bottom = 0;
|
||||
pdc->erclBoundsApp = pdc->erclBounds;
|
||||
pdc->erclClip = pdc->erclWindow;
|
||||
//pdc->co = NULL
|
||||
pdc->co = gxcoTrivial;
|
||||
}
|
||||
|
||||
//pdc->dcattr.VisRectRegion:
|
||||
|
@ -237,6 +226,8 @@ DC_vInitDc(
|
|||
/* Setup regions */
|
||||
pdc->prgnAPI = NULL;
|
||||
pdc->prgnRao = NULL;
|
||||
pdc->dclevel.prgnClip = NULL;
|
||||
pdc->dclevel.prgnMeta = NULL;
|
||||
/* Allocate a Vis region */
|
||||
pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
|
||||
ASSERT(pdc->prgnVis);
|
||||
|
@ -372,17 +363,17 @@ DC_vCleanup(PVOID ObjectBody)
|
|||
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
|
||||
|
||||
/* Free regions */
|
||||
if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
|
||||
GreDeleteObject(pdc->rosdc.hClipRgn);
|
||||
if (pdc->dclevel.prgnClip)
|
||||
REGION_Delete(pdc->dclevel.prgnClip);
|
||||
if (pdc->dclevel.prgnMeta)
|
||||
REGION_Delete(pdc->dclevel.prgnMeta);
|
||||
if (pdc->prgnVis)
|
||||
{
|
||||
REGION_Delete(pdc->prgnVis);
|
||||
}
|
||||
if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn))
|
||||
{
|
||||
GreDeleteObject(pdc->rosdc.hGCClipRgn);
|
||||
}
|
||||
if (NULL != pdc->rosdc.CombinedClip)
|
||||
if (pdc->prgnRao)
|
||||
REGION_Delete(pdc->prgnRao);
|
||||
if (pdc->prgnAPI)
|
||||
REGION_Delete(pdc->prgnAPI);
|
||||
if (pdc->rosdc.CombinedClip)
|
||||
IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
|
||||
|
||||
PATH_Delete(pdc->dclevel.hPath);
|
||||
|
@ -397,17 +388,6 @@ VOID
|
|||
NTAPI
|
||||
DC_vSetOwner(PDC pdc, ULONG ulOwner)
|
||||
{
|
||||
|
||||
if (pdc->rosdc.hClipRgn)
|
||||
{
|
||||
IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
|
||||
}
|
||||
|
||||
if (pdc->rosdc.hGCClipRgn)
|
||||
{
|
||||
IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
|
||||
}
|
||||
|
||||
if (pdc->dclevel.hPath)
|
||||
{
|
||||
GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
|
||||
|
@ -466,7 +446,7 @@ static
|
|||
void
|
||||
DC_vUpdateDC(PDC pdc)
|
||||
{
|
||||
HRGN hVisRgn ;
|
||||
// PREGION VisRgn ;
|
||||
PPDEVOBJ ppdev = pdc->ppdev ;
|
||||
|
||||
pdc->dhpdev = ppdev->dhpdev;
|
||||
|
@ -475,10 +455,12 @@ DC_vUpdateDC(PDC pdc)
|
|||
pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
|
||||
|
||||
PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
|
||||
hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
|
||||
ASSERT(hVisRgn);
|
||||
GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
|
||||
GreDeleteObject(hVisRgn);
|
||||
#if 0
|
||||
VisRgn = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
|
||||
ASSERT(VisRgn);
|
||||
GdiSelectVisRgn(pdc->BaseObject.hHmgr, VisRgn);
|
||||
REGION_Delete(VisRgn);
|
||||
#endif
|
||||
|
||||
pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
|
||||
pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
|
||||
|
@ -492,76 +474,107 @@ DC_vUpdateDC(PDC pdc)
|
|||
* from where we take pixels. */
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vPrepareDCsForBlit(PDC pdc1,
|
||||
RECT rc1,
|
||||
PDC pdc2,
|
||||
RECT rc2)
|
||||
DC_vPrepareDCsForBlit(
|
||||
PDC pdcDest,
|
||||
const RECT* rcDest,
|
||||
PDC pdcSrc,
|
||||
const RECT* rcSrc)
|
||||
{
|
||||
PDC pdcFirst, pdcSecond;
|
||||
PRECT prcFirst, prcSecond;
|
||||
const RECT *prcFirst, *prcSecond;
|
||||
|
||||
/* Update brushes */
|
||||
if (pdc1->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(pdc1);
|
||||
if (pdc1->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
|
||||
DC_vUpdateLineBrush(pdc1);
|
||||
if(pdc1->pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||
DC_vUpdateTextBrush(pdc1);
|
||||
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(pdc2)
|
||||
if(pdcSrc)
|
||||
{
|
||||
if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
|
||||
if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >= (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
|
||||
{
|
||||
pdcFirst = pdc1;
|
||||
prcFirst = &rc1;
|
||||
pdcSecond = pdc2;
|
||||
prcSecond = &rc2;
|
||||
pdcFirst = pdcDest;
|
||||
prcFirst = rcDest;
|
||||
pdcSecond = pdcSrc;
|
||||
prcSecond = rcSrc;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdcFirst = pdc2;
|
||||
prcFirst = &rc2;
|
||||
pdcSecond = pdc1;
|
||||
prcSecond = &rc1;
|
||||
pdcFirst = pdcSrc;
|
||||
prcFirst = rcSrc;
|
||||
pdcSecond = pdcDest;
|
||||
prcSecond = rcDest;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdcFirst = pdc1 ;
|
||||
prcFirst = &rc1;
|
||||
pdcFirst = pdcDest ;
|
||||
prcFirst = rcDest;
|
||||
pdcSecond = NULL;
|
||||
prcSecond = NULL;
|
||||
}
|
||||
|
||||
if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
|
||||
/* 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);
|
||||
MouseSafetyOnDrawStart(pdcFirst->ppdev,
|
||||
prcFirst->left,
|
||||
prcFirst->top,
|
||||
prcFirst->right,
|
||||
prcFirst->bottom) ;
|
||||
/* Update surface if needed */
|
||||
if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
|
||||
{
|
||||
DC_vUpdateDC(pdcFirst);
|
||||
}
|
||||
}
|
||||
if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
|
||||
|
||||
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);
|
||||
MouseSafetyOnDrawStart(pdcSecond->ppdev,
|
||||
prcSecond->left,
|
||||
prcSecond->top,
|
||||
prcSecond->right,
|
||||
prcSecond->bottom) ;
|
||||
/* 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) ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finishes a blit for one or two DCs */
|
||||
|
|
|
@ -330,7 +330,7 @@ NtGdiSelectBitmap(
|
|||
PDC pdc;
|
||||
HBITMAP hbmpOld;
|
||||
PSURFACE psurfNew, psurfOld;
|
||||
HRGN hVisRgn;
|
||||
PREGION VisRgn;
|
||||
HDC hdcOld;
|
||||
ULONG cBitsPixel;
|
||||
ASSERT_NOGDILOCKS();
|
||||
|
@ -452,15 +452,15 @@ NtGdiSelectBitmap(
|
|||
pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
|
||||
|
||||
/* FIXME: Improve by using a region without a handle and selecting it */
|
||||
hVisRgn = IntSysCreateRectRgn( 0,
|
||||
VisRgn = IntSysCreateRectpRgn( 0,
|
||||
0,
|
||||
pdc->dclevel.sizl.cx,
|
||||
pdc->dclevel.sizl.cy);
|
||||
|
||||
if (hVisRgn)
|
||||
if (VisRgn)
|
||||
{
|
||||
GdiSelectVisRgn(hdc, hVisRgn);
|
||||
GreDeleteObject(hVisRgn);
|
||||
GdiSelectVisRgn(hdc, VisRgn);
|
||||
REGION_Delete(VisRgn);
|
||||
}
|
||||
|
||||
/* Unlock the DC */
|
||||
|
@ -509,7 +509,10 @@ NtGdiSelectClipPath(
|
|||
/* Construct a region from the path */
|
||||
else if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnPath))
|
||||
{
|
||||
success = GdiExtSelectClipRgn(pdc, hrgnPath, Mode) != ERROR;
|
||||
PREGION prgnPath = REGION_LockRgn(hrgnPath);
|
||||
ASSERT(prgnPath);
|
||||
success = IntGdiExtSelectClipRgn(pdc, prgnPath, Mode) != ERROR;
|
||||
REGION_UnlockRgn(prgnPath);
|
||||
GreDeleteObject( hrgnPath );
|
||||
|
||||
/* Empty the path */
|
||||
|
@ -693,9 +696,7 @@ NtGdiGetRandomRgn(
|
|||
{
|
||||
INT ret = 0;
|
||||
PDC pdc;
|
||||
HRGN hrgnSrc = NULL;
|
||||
PREGION prgnSrc = NULL;
|
||||
POINTL ptlOrg;
|
||||
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
|
@ -707,8 +708,7 @@ NtGdiGetRandomRgn(
|
|||
switch (iCode)
|
||||
{
|
||||
case CLIPRGN:
|
||||
hrgnSrc = pdc->rosdc.hClipRgn;
|
||||
// if (pdc->dclevel.prgnClip) prgnSrc = pdc->dclevel.prgnClip;
|
||||
prgnSrc = pdc->dclevel.prgnClip;
|
||||
break;
|
||||
|
||||
case METARGN:
|
||||
|
@ -716,14 +716,15 @@ NtGdiGetRandomRgn(
|
|||
break;
|
||||
|
||||
case APIRGN:
|
||||
if (pdc->fs & DC_FLAG_DIRTY_RAO)
|
||||
CLIPPING_UpdateGCRegion(pdc);
|
||||
if (pdc->prgnAPI)
|
||||
{
|
||||
prgnSrc = pdc->prgnAPI;
|
||||
}
|
||||
// else if (pdc->dclevel.prgnClip) prgnSrc = pdc->dclevel.prgnClip;
|
||||
else if (pdc->rosdc.hClipRgn)
|
||||
else if (pdc->dclevel.prgnClip)
|
||||
{
|
||||
hrgnSrc = pdc->rosdc.hClipRgn;
|
||||
prgnSrc = pdc->dclevel.prgnClip;
|
||||
}
|
||||
else if (pdc->dclevel.prgnMeta)
|
||||
{
|
||||
|
@ -739,28 +740,20 @@ NtGdiGetRandomRgn(
|
|||
break;
|
||||
}
|
||||
|
||||
if (hrgnSrc)
|
||||
{
|
||||
ret = NtGdiCombineRgn(hrgnDest, hrgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
|
||||
}
|
||||
else if (prgnSrc)
|
||||
if (prgnSrc)
|
||||
{
|
||||
PREGION prgnDest = REGION_LockRgn(hrgnDest);
|
||||
if (prgnDest)
|
||||
{
|
||||
ret = IntGdiCombineRgn(prgnDest, prgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
|
||||
if ((ret == 1) && (iCode == SYSRGN))
|
||||
IntGdiOffsetRgn(prgnDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
REGION_UnlockRgn(prgnDest);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (iCode == SYSRGN)
|
||||
{
|
||||
ptlOrg = pdc->ptlDCOrig;
|
||||
NtGdiOffsetRgn(hrgnDest, ptlOrg.x, ptlOrg.y );
|
||||
}
|
||||
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -51,23 +51,26 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
|
|||
pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt;
|
||||
|
||||
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
|
||||
if (To) // Copy "To" SaveDC state.
|
||||
if (!To)
|
||||
{
|
||||
if (pdcSrc->rosdc.hClipRgn)
|
||||
IntGdiExtSelectClipRgn(pdcDst, pdcSrc->dclevel.prgnClip, RGN_COPY);
|
||||
if (pdcDst->dclevel.prgnMeta)
|
||||
{
|
||||
pdcDst->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
|
||||
NtGdiCombineRgn(pdcDst->rosdc.hClipRgn, pdcSrc->rosdc.hClipRgn, 0, RGN_COPY);
|
||||
REGION_Delete(pdcDst->dclevel.prgnMeta);
|
||||
pdcDst->dclevel.prgnMeta = NULL;
|
||||
}
|
||||
// FIXME: Handle prgnMeta!
|
||||
}
|
||||
else // Copy "!To" RestoreDC state.
|
||||
{ /* The VisRectRegion field needs to be set to a valid state */
|
||||
GdiExtSelectClipRgn(pdcDst, pdcSrc->rosdc.hClipRgn, RGN_COPY);
|
||||
if (pdcSrc->dclevel.prgnMeta)
|
||||
{
|
||||
pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
IntGdiCombineRgn(pdcDst->dclevel.prgnMeta, pdcSrc->dclevel.prgnMeta, NULL, RGN_COPY);
|
||||
}
|
||||
pdcDst->fs |= DC_FLAG_DIRTY_RAO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL FASTCALL
|
||||
BOOL
|
||||
FASTCALL
|
||||
IntGdiCleanDC(HDC hDC)
|
||||
{
|
||||
PDC dc;
|
||||
|
@ -87,6 +90,16 @@ IntGdiCleanDC(HDC hDC)
|
|||
DC_vUpdateTextBrush(dc);
|
||||
}
|
||||
|
||||
/* DC_vCopyState frees the Clip rgn and the Meta rgn. Take care of the other ones
|
||||
* There is no need to clear prgnVis, as UserGetDC updates it immediately. */
|
||||
if (dc->prgnRao)
|
||||
REGION_Delete(dc->prgnRao);
|
||||
if (dc->prgnAPI)
|
||||
REGION_Delete(dc->prgnAPI);
|
||||
dc->prgnRao = dc->prgnAPI = NULL;
|
||||
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return TRUE;
|
||||
|
@ -272,7 +285,7 @@ NtGdiSaveDC(
|
|||
GDIOBJ_vSetObjectOwner(&pdcSave->BaseObject, GDI_OBJ_HMGR_PUBLIC);
|
||||
|
||||
/* Copy the current state */
|
||||
DC_vCopyState(pdc, pdcSave, TRUE);
|
||||
DC_vCopyState(pdc, pdcSave, FALSE);
|
||||
|
||||
/* Only memory DC's change their surface */
|
||||
if (pdc->dctype == DCTYPE_MEMORY)
|
||||
|
|
|
@ -367,7 +367,7 @@ IntGdiSetHookFlags(HDC hDC, WORD Flags)
|
|||
}
|
||||
else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
|
||||
{
|
||||
dc->fs &= ~DC_FLAG_DIRTY_RAO;
|
||||
//dc->fs &= ~DC_FLAG_DIRTY_RAO;
|
||||
}
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
|
|
|
@ -502,7 +502,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
}
|
||||
|
||||
/* This is actually a blit */
|
||||
DC_vPrepareDCsForBlit(pDC, rcDest, NULL, rcDest);
|
||||
DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
|
||||
pSurf = pDC->dclevel.pSurface;
|
||||
if (!pSurf)
|
||||
{
|
||||
|
@ -1184,7 +1184,7 @@ NtGdiStretchDIBitsInternal(
|
|||
}
|
||||
|
||||
/* Prepare DC for blit */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDst, NULL, rcSrc);
|
||||
DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
|
||||
|
||||
psurfDst = pdc->dclevel.pSurface;
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ NtGdiEllipse(
|
|||
tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
|
||||
tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);
|
||||
DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
|
||||
|
||||
ret = IntFillEllipse( dc,
|
||||
CenterX - RadiusX,
|
||||
|
@ -480,8 +480,7 @@ NtGdiPolyPolyDraw( IN HDC hDC,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, dc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
|
||||
|
||||
if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(dc);
|
||||
|
@ -567,7 +566,7 @@ IntRectangle(PDC dc,
|
|||
DestRect.bottom--;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
|
||||
DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(dc);
|
||||
|
@ -796,7 +795,7 @@ IntRoundRect(
|
|||
else
|
||||
{
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);
|
||||
DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
|
||||
|
||||
RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp));
|
||||
brushTemp.ptOrigin.x += RectBounds.left - Left;
|
||||
|
@ -962,9 +961,9 @@ GreGradientFill(
|
|||
|
||||
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
|
||||
|
||||
ASSERT(pdc->rosdc.CombinedClip);
|
||||
DC_vPrepareDCsForBlit(pdc, &rclExtent, NULL, NULL);
|
||||
|
||||
DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
|
||||
ASSERT(pdc->rosdc.CombinedClip);
|
||||
|
||||
bRet = IntEngGradientFill(&psurf->SurfObj,
|
||||
pdc->rosdc.CombinedClip,
|
||||
|
@ -1091,6 +1090,13 @@ NtGdiExtFloodFill(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
psurf = dc->dclevel.pSurface;
|
||||
if (!psurf)
|
||||
{
|
||||
Ret = FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pdcattr = dc->pdcattr;
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
|
@ -1103,20 +1109,18 @@ NtGdiExtFloodFill(
|
|||
Pt.y = YStart;
|
||||
IntLPtoDP(dc, (LPPOINT)&Pt, 1);
|
||||
|
||||
Ret = NtGdiPtInRegion(dc->rosdc.hGCClipRgn, Pt.x, Pt.y);
|
||||
if (Ret)
|
||||
IntGdiGetRgnBox(dc->rosdc.hGCClipRgn,(LPRECT)&DestRect);
|
||||
else
|
||||
goto cleanup;
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
|
||||
|
||||
psurf = dc->dclevel.pSurface;
|
||||
if (!psurf)
|
||||
if (dc->prgnRao)
|
||||
{
|
||||
Ret = FALSE;
|
||||
goto cleanup;
|
||||
Ret = REGION_PtInRegion(dc->prgnRao, Pt.x, Pt.y);
|
||||
if (Ret)
|
||||
REGION_GetRgnBox(dc->prgnRao ,(LPRECT)&DestRect);
|
||||
else
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
RECTL_vSetRect(&DestRect, 0, psurf->SurfObj.sizlBitmap.cx, 0, psurf->SurfObj.sizlBitmap.cy);
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
|
||||
|
||||
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
|
||||
|
||||
|
@ -1127,10 +1131,11 @@ NtGdiExtFloodFill(
|
|||
ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
|
||||
Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
|
||||
|
||||
DC_vFinishBlit(dc, NULL);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
cleanup:
|
||||
DC_vFinishBlit(dc, NULL);
|
||||
DC_UnlockDc(dc);
|
||||
return Ret;
|
||||
}
|
||||
|
|
|
@ -3212,7 +3212,7 @@ GreExtTextOutW(
|
|||
LONGLONG TextLeft, RealXStart;
|
||||
ULONG TextTop, previous, BackgroundLeft;
|
||||
FT_Bool use_kerning;
|
||||
RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0};
|
||||
RECTL DestRect, MaskRect;
|
||||
POINTL SourcePoint, BrushOrigin;
|
||||
HBITMAP HSourceGlyph;
|
||||
SURFOBJ *SourceGlyphSurf;
|
||||
|
@ -3308,7 +3308,7 @@ GreExtTextOutW(
|
|||
DestRect.right += dc->ptlDCOrig.x;
|
||||
DestRect.bottom += dc->ptlDCOrig.y;
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
|
||||
DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
|
||||
|
||||
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
|
||||
DC_vUpdateBackgroundBrush(dc);
|
||||
|
@ -3502,7 +3502,7 @@ GreExtTextOutW(
|
|||
BackgroundLeft = (RealXStart + 32) >> 6;
|
||||
|
||||
/* Lock blit with a dummy rect */
|
||||
DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect);
|
||||
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
|
||||
|
||||
psurf = dc->dclevel.pSurface ;
|
||||
if(!psurf) psurf = psurfDefaultBitmap;
|
||||
|
|
|
@ -257,8 +257,7 @@ IntGdiPolyline(DC *dc,
|
|||
if (PATH_IsPathOpen(dc->dclevel))
|
||||
return PATH_Polyline(dc, pt, Count);
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, dc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(dc);
|
||||
|
@ -411,7 +410,7 @@ NtGdiLineTo(HDC hDC,
|
|||
rcLockRect.right += dc->ptlDCOrig.x;
|
||||
rcLockRect.bottom += dc->ptlDCOrig.y;
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, rcLockRect, NULL, rcLockRect);
|
||||
DC_vPrepareDCsForBlit(dc, &rcLockRect, NULL, NULL);
|
||||
|
||||
if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
|
||||
DC_vUpdateLineBrush(dc);
|
||||
|
|
|
@ -2511,8 +2511,7 @@ NtGdiFillPath(HDC hDC)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, dc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
|
||||
|
||||
pdcattr = dc->pdcattr;
|
||||
|
||||
|
@ -2777,8 +2776,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, pDc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(pDc, NULL, NULL, NULL);
|
||||
|
||||
pdcattr = pDc->pdcattr;
|
||||
|
||||
|
@ -2822,8 +2820,7 @@ NtGdiStrokePath(HDC hDC)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
|
||||
NULL, pDc->rosdc.CombinedClip->rclBounds);
|
||||
DC_vPrepareDCsForBlit(pDc, NULL, NULL, NULL);
|
||||
|
||||
pdcattr = pDc->pdcattr;
|
||||
|
||||
|
|
|
@ -2300,11 +2300,13 @@ REGION_Delete(PROSRGNDATA pRgn)
|
|||
VOID FASTCALL
|
||||
IntGdiReleaseRaoRgn(PDC pDC)
|
||||
{
|
||||
INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
|
||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
||||
pDC->fs |= DC_FLAG_DIRTY_RAO;
|
||||
Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
|
||||
RECTL_vSetEmptyRect(&pDC->erclClip);
|
||||
INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
|
||||
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
|
||||
pDC->fs |= DC_FLAG_DIRTY_RAO;
|
||||
Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
|
||||
RECTL_vSetEmptyRect(&pDC->erclClip);
|
||||
REGION_Delete(pDC->prgnRao);
|
||||
pDC->prgnRao = NULL;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
|
@ -2503,8 +2505,6 @@ IntGdiPaintRgn(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
NtGdiCombineRgn(tmpVisRgn, tmpVisRgn, dc->rosdc.hGCClipRgn, RGN_AND);
|
||||
|
||||
visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
|
||||
if (visrgn == NULL)
|
||||
{
|
||||
|
@ -2512,6 +2512,9 @@ IntGdiPaintRgn(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (dc->prgnRao)
|
||||
IntGdiCombineRgn(visrgn, visrgn, dc->prgnRao, RGN_AND);
|
||||
|
||||
ClipRegion = IntEngCreateClipRegion(visrgn->rdh.nCount,
|
||||
visrgn->Buffer,
|
||||
&visrgn->rdh.rcBound );
|
||||
|
@ -2535,6 +2538,29 @@ IntGdiPaintRgn(
|
|||
return bRet;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FASTCALL
|
||||
REGION_PtInRegion(
|
||||
PREGION prgn,
|
||||
INT X,
|
||||
INT Y)
|
||||
{
|
||||
ULONG i;
|
||||
PRECT r;
|
||||
|
||||
if (prgn->rdh.nCount > 0 && INRECT(prgn->rdh.rcBound, X, Y))
|
||||
{
|
||||
r = prgn->Buffer;
|
||||
for (i = 0; i < prgn->rdh.nCount; i++)
|
||||
{
|
||||
if (INRECT(r[i], X, Y))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FASTCALL
|
||||
REGION_RectInRegion(
|
||||
|
@ -3861,27 +3887,19 @@ NtGdiPtInRegion(
|
|||
INT Y
|
||||
)
|
||||
{
|
||||
PROSRGNDATA rgn;
|
||||
ULONG i;
|
||||
PRECTL r;
|
||||
PREGION prgn;
|
||||
BOOL ret;
|
||||
|
||||
if (!(rgn = RGNOBJAPI_Lock(hRgn, NULL) ) )
|
||||
if (!(prgn = RGNOBJAPI_Lock(hRgn, NULL) ) )
|
||||
return FALSE;
|
||||
|
||||
if (rgn->rdh.nCount > 0 && INRECT(rgn->rdh.rcBound, X, Y))
|
||||
{
|
||||
r = rgn->Buffer;
|
||||
for (i = 0; i < rgn->rdh.nCount; i++)
|
||||
{
|
||||
if (INRECT(*r, X, Y))
|
||||
{
|
||||
RGNOBJAPI_Unlock(rgn);
|
||||
return TRUE;
|
||||
}
|
||||
r++;
|
||||
}
|
||||
}
|
||||
RGNOBJAPI_Unlock(rgn);
|
||||
ret = REGION_PtInRegion(prgn, X, Y);
|
||||
|
||||
RGNOBJAPI_Unlock(prgn);
|
||||
return ret;
|
||||
|
||||
|
||||
RGNOBJAPI_Unlock(prgn);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ PROSRGNDATA FASTCALL REGION_AllocUserRgnWithHandle(INT n);
|
|||
VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
|
||||
INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
|
||||
BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
|
||||
BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);
|
||||
BOOL FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
|
||||
VOID FASTCALL REGION_SetRectRgn(PROSRGNDATA pRgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
|
||||
VOID NTAPI REGION_vCleanup(PVOID ObjectBody);
|
||||
|
|
|
@ -1287,7 +1287,7 @@ UserDrawIconEx(
|
|||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
|
||||
/* Prepare the underlying surface */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||
DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
|
||||
|
||||
/* Get the clip object */
|
||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||
|
@ -1472,7 +1472,7 @@ done:
|
|||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
|
||||
/* Prepare the underlying surface */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||
DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
|
||||
|
||||
/* Get the clip object */
|
||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||
|
|
|
@ -1195,7 +1195,7 @@ UserDrawIconEx(
|
|||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
|
||||
/* Prepare the underlying surface */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||
DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
|
||||
|
||||
/* We now have our destination surface and rectangle */
|
||||
psurfDest = pdc->dclevel.pSurface;
|
||||
|
|
|
@ -51,3 +51,5 @@ void FASTCALL DceFreeClassDCE(HDC);
|
|||
HWND FASTCALL UserGethWnd(HDC,PWNDOBJ*);
|
||||
void FASTCALL DceFreeWindowDCE(PWND);
|
||||
void FASTCALL DceFreeThreadDCE(PTHREADINFO);
|
||||
VOID FASTCALL DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags);
|
||||
DCE* FASTCALL DceGetDceFromDC(HDC hdc);
|
||||
|
|
|
@ -46,21 +46,47 @@ DceCreateDisplayDC(VOID)
|
|||
return IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
|
||||
}
|
||||
|
||||
/* Returns the DCE pointer from the HDC handle */
|
||||
DCE*
|
||||
FASTCALL
|
||||
DceGetDceFromDC(HDC hdc)
|
||||
{
|
||||
LIST_ENTRY* Entry = LEDce.Flink;
|
||||
DCE* dce;
|
||||
|
||||
while (Entry != &LEDce)
|
||||
{
|
||||
dce = CONTAINING_RECORD(Entry, DCE, List);
|
||||
if (dce->hDC == hdc)
|
||||
return dce;
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
HRGN FASTCALL
|
||||
PREGION FASTCALL
|
||||
DceGetVisRgn(PWND Window, ULONG Flags, HWND hWndChild, ULONG CFlags)
|
||||
{
|
||||
HRGN VisRgn;
|
||||
PREGION RetRgn;
|
||||
HRGN hVisRgn;
|
||||
hVisRgn = VIS_ComputeVisibleRegion( Window,
|
||||
0 == (Flags & DCX_WINDOW),
|
||||
0 != (Flags & DCX_CLIPCHILDREN),
|
||||
0 != (Flags & DCX_CLIPSIBLINGS));
|
||||
|
||||
VisRgn = VIS_ComputeVisibleRegion( Window,
|
||||
0 == (Flags & DCX_WINDOW),
|
||||
0 != (Flags & DCX_CLIPCHILDREN),
|
||||
0 != (Flags & DCX_CLIPSIBLINGS));
|
||||
RetRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
|
||||
if (VisRgn == NULL)
|
||||
VisRgn = IntSysCreateRectRgn(0, 0, 0, 0);
|
||||
if (hVisRgn != NULL)
|
||||
{
|
||||
PREGION VisRgn = REGION_LockRgn(hVisRgn);
|
||||
IntGdiCombineRgn(RetRgn, VisRgn, NULL, RGN_COPY);
|
||||
REGION_UnlockRgn(VisRgn);
|
||||
GreDeleteObject(hVisRgn);
|
||||
}
|
||||
|
||||
return VisRgn;
|
||||
return RetRgn;
|
||||
}
|
||||
|
||||
PDCE FASTCALL
|
||||
|
@ -150,6 +176,7 @@ DceSetDrawable( PWND Window OPTIONAL,
|
|||
dc->ptlDCOrig.y = Window->rcClient.top;
|
||||
}
|
||||
}
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
DC_UnlockDc(dc);
|
||||
}
|
||||
|
||||
|
@ -175,10 +202,11 @@ DceDeleteClipRgn(DCE* Dce)
|
|||
IntGdiSetHookFlags(Dce->hDC, DCHF_INVALIDATEVISRGN);
|
||||
}
|
||||
|
||||
static VOID FASTCALL
|
||||
VOID
|
||||
FASTCALL
|
||||
DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
|
||||
{
|
||||
HANDLE hRgnVisible = NULL;
|
||||
PREGION RgnVisible = NULL;
|
||||
ULONG DcxFlags;
|
||||
PWND DesktopWindow;
|
||||
|
||||
|
@ -189,7 +217,7 @@ DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
|
|||
Parent = Window->spwndParent;
|
||||
if(!Parent)
|
||||
{
|
||||
hRgnVisible = NULL;
|
||||
RgnVisible = NULL;
|
||||
goto noparent;
|
||||
}
|
||||
|
||||
|
@ -202,23 +230,23 @@ DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
|
|||
{
|
||||
DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
|
||||
}
|
||||
hRgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags);
|
||||
RgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags);
|
||||
}
|
||||
else if (Window == NULL)
|
||||
{
|
||||
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
|
||||
if (NULL != DesktopWindow)
|
||||
{
|
||||
hRgnVisible = IntSysCreateRectRgnIndirect(&DesktopWindow->rcWindow);
|
||||
RgnVisible = IntSysCreateRectpRgnIndirect(&DesktopWindow->rcWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
hRgnVisible = NULL;
|
||||
RgnVisible = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hRgnVisible = DceGetVisRgn(Window, Flags, 0, 0);
|
||||
RgnVisible = DceGetVisRgn(Window, Flags, 0, 0);
|
||||
}
|
||||
|
||||
noparent:
|
||||
|
@ -226,33 +254,37 @@ noparent:
|
|||
{
|
||||
if(Dce->hrgnClip != NULL)
|
||||
{
|
||||
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_AND);
|
||||
PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip);
|
||||
IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_AND);
|
||||
REGION_UnlockRgn(RgnClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hRgnVisible != NULL)
|
||||
if(RgnVisible != NULL)
|
||||
{
|
||||
GreDeleteObject(hRgnVisible);
|
||||
REGION_Delete(RgnVisible);
|
||||
}
|
||||
hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0);
|
||||
RgnVisible = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL)
|
||||
else if ((Flags & DCX_EXCLUDERGN) && Dce->hrgnClip != NULL)
|
||||
{
|
||||
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF);
|
||||
PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip);
|
||||
IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_DIFF);
|
||||
REGION_UnlockRgn(RgnClip);
|
||||
}
|
||||
|
||||
Dce->DCXFlags &= ~DCX_DCEDIRTY;
|
||||
GdiSelectVisRgn(Dce->hDC, hRgnVisible);
|
||||
GdiSelectVisRgn(Dce->hDC, RgnVisible);
|
||||
|
||||
if (VerifyWnd(Window)) // Window maybe dead by this time before finishing the DCE release.
|
||||
{
|
||||
IntEngWindowChanged(Window, WOC_RGN_CLIENT);
|
||||
}
|
||||
|
||||
if (hRgnVisible != NULL)
|
||||
if (RgnVisible != NULL)
|
||||
{
|
||||
GreDeleteObject(hRgnVisible);
|
||||
REGION_Delete(RgnVisible);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,10 +921,10 @@ DceResetActiveDCEs(PWND Window)
|
|||
dc->ptlDCOrig.y = CurrentWindow->rcClient.top;
|
||||
}
|
||||
|
||||
if (NULL != dc->rosdc.hClipRgn)
|
||||
if (NULL != dc->dclevel.prgnClip)
|
||||
{
|
||||
NtGdiOffsetRgn(dc->rosdc.hClipRgn, DeltaX, DeltaY);
|
||||
CLIPPING_UpdateGCRegion(dc);
|
||||
IntGdiOffsetRgn(dc->dclevel.prgnClip, DeltaX, DeltaY);
|
||||
dc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
}
|
||||
if (NULL != pDCE->hrgnClip)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue