You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1292 lines
31 KiB
1292 lines
31 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: dcrgn.cxx
|
|
*
|
|
* Non inline DC Region object routines
|
|
*
|
|
* Created: 02-Jul-1990 12:36:30
|
|
* Author: Donald Sidoroff [donalds]
|
|
*
|
|
* Copyright (c) 1990-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
RECTL rclEmpty = {POS_INFINITY,POS_INFINITY,NEG_INFINITY,NEG_INFINITY};
|
|
|
|
#if DBG
|
|
|
|
ULONG dbgrgn = 0;
|
|
HDC gflhdc = 0;
|
|
|
|
VOID DisplayRegion(
|
|
PREGION prgn,
|
|
PCHAR s
|
|
)
|
|
{
|
|
DbgPrint("DisplayRegion %s = 0x%p\n",s,prgn);
|
|
if (prgn)
|
|
{
|
|
DbgPrint("Region bounding rect = (%li,%li) to (%li,%li)\n",
|
|
prgn->rcl.left,
|
|
prgn->rcl.top,
|
|
prgn->rcl.right,
|
|
prgn->rcl.bottom
|
|
);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
* DC::bCompute()
|
|
*
|
|
* Compute the current Rao region. The Rao region is the ANDed version of
|
|
* all the regions. Since the only region that must exist is the Vis region
|
|
* we allow this to be the Rao without actually computing it. (Refer to the
|
|
* prgnEffRao() method) This is only done if no other regions are defined.
|
|
* This is a nifty accelerator.
|
|
*
|
|
* WARNING: This routine should only be called while the device is locked.
|
|
* calling at any other time doesn't make sense, since our vis region may
|
|
* change asynchronously.
|
|
*
|
|
* History:
|
|
*
|
|
* 11-Jul-1995 -by- Mark Enstrom [marke]
|
|
*
|
|
* Don't always delete and re-allocate rao region
|
|
*
|
|
* 07-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* Complete rewrite
|
|
*
|
|
* 09-Jul-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL DC::bCompute()
|
|
{
|
|
ASSERTDEVLOCK(this);
|
|
|
|
RGNLOG rl(prgnVis(),"DC::bCompute",(ULONG_PTR)prgnRao());
|
|
|
|
ASSERTGDI(prgnVis() != NULL,"DC::bCompute - prgnVis == NULL\n");
|
|
|
|
BOOL bRes = FALSE;
|
|
|
|
if (!(prgnVis() == NULL))
|
|
{
|
|
bRes = TRUE;
|
|
|
|
//
|
|
// quick check to see if there is just the vis rgn. Better to pay
|
|
// the cost of the check twice in the rare case to speed up the check
|
|
// for the common case
|
|
//
|
|
|
|
RGNOBJ roVis(prgnVis());
|
|
|
|
if (((ULONG_PTR)prgnClip() | (ULONG_PTR)prgnMeta() | (ULONG_PTR)prgnAPI()) == 0)
|
|
{
|
|
//
|
|
// get rid of RAO now since it won't be needed
|
|
//
|
|
|
|
if (prgnRao() != NULL)
|
|
{
|
|
RGNOBJ roRao(prgnRao());
|
|
roRao.bDeleteRGNOBJ();
|
|
prgnRao(NULL);
|
|
}
|
|
|
|
//
|
|
// set erclClip to the bounding rcl
|
|
//
|
|
|
|
roVis.vGetSubRect(&(erclClip()));
|
|
|
|
//
|
|
// Mark as clean
|
|
//
|
|
|
|
fsClr(DC_DIRTY_RAO);
|
|
}
|
|
else
|
|
{
|
|
PREGION aprgn[3];
|
|
int cRgn = 0;
|
|
|
|
//
|
|
// Load the regions into the buffer
|
|
//
|
|
|
|
if ((aprgn[cRgn] = prgnClip()) != NULL)
|
|
{
|
|
cRgn++;
|
|
}
|
|
|
|
if ((aprgn[cRgn] = prgnMeta()) != NULL)
|
|
{
|
|
cRgn++;
|
|
}
|
|
|
|
if ((aprgn[cRgn] = prgnAPI()) != NULL)
|
|
{
|
|
cRgn++;
|
|
}
|
|
|
|
RGNOBJ roRao(prgnRao());
|
|
|
|
if (roRao.prgn == NULL)
|
|
{
|
|
//
|
|
// need to create RAO
|
|
//
|
|
|
|
RGNMEMOBJ rmoRao;
|
|
|
|
if (rmoRao.bValid())
|
|
{
|
|
roRao.prgn = rmoRao.prgn;
|
|
}
|
|
}
|
|
|
|
if (!roRao.bValid())
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
else if (cRgn == 1)
|
|
{
|
|
RGNOBJ ro(aprgn[0]);
|
|
|
|
if (!roRao.bCopy(ro))
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
}
|
|
else if (cRgn == 2)
|
|
{
|
|
RGNOBJ roA(aprgn[0]);
|
|
RGNOBJ roB(aprgn[1]);
|
|
|
|
if (roRao.iCombine(roA, roB, RGN_AND) == ERROR)
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RGNMEMOBJTMP rmo;
|
|
RGNOBJ roA(aprgn[0]);
|
|
RGNOBJ roB(aprgn[1]);
|
|
RGNOBJ roC(aprgn[2]);
|
|
|
|
if (!rmo.bValid() ||
|
|
(rmo.iCombine(roA, roB, RGN_AND) == ERROR) ||
|
|
(roRao.iCombine(rmo, roC, RGN_AND) == ERROR))
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bRes)
|
|
{
|
|
roRao.vStamp();
|
|
|
|
//
|
|
// We first have to offset the new Rao,
|
|
//
|
|
|
|
if (roRao.bOffset((PPOINTL) prclWindow()))
|
|
{
|
|
//
|
|
// If the Vis is a rectangle and bounds the Rao, we are done
|
|
//
|
|
|
|
if (roVis.bRectl() && roVis.bContain(roRao))
|
|
{
|
|
prgnRao(roRao.prgnGet());
|
|
roRao.vGetSubRect(&(erclClip()));
|
|
fsClr(DC_DIRTY_RAO);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Sigh, once again we find ourselves looking for a place to do a merge.
|
|
//
|
|
|
|
RGNMEMOBJTMP rmo;
|
|
|
|
if (!rmo.bValid() ||
|
|
(rmo.iCombine(roVis, roRao, RGN_AND) == ERROR) ||
|
|
!roRao.bCopy(rmo))
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
else
|
|
{
|
|
prgnRao(roRao.prgnGet());
|
|
roRao.vGetSubRect(&(erclClip()));
|
|
fsClr(DC_DIRTY_RAO);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRes = FALSE;
|
|
}
|
|
}
|
|
|
|
if (!bRes)
|
|
{
|
|
WARNING("DC::bCompute failed");
|
|
|
|
//
|
|
// RAO creation failed at some point, bswap may have
|
|
// already deleted the old RAO rgn, so the DC pointer
|
|
// must be set to NULL
|
|
//
|
|
|
|
prgnRao(NULL);
|
|
|
|
if (roRao.bValid())
|
|
{
|
|
//
|
|
// if the RAO still exists,
|
|
// then delete it.
|
|
//
|
|
|
|
roRao.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// update user-mode vis region bounding rectangle if dirty
|
|
//
|
|
vUpdate_VisRect(prgnVis());
|
|
|
|
}
|
|
|
|
return(bRes);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* LONG DC::iCombine(prcl, iMode)
|
|
*
|
|
* Combine the clip region with the rectangle by the mode
|
|
*
|
|
* History:
|
|
* 09-Jul-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
LONG DC::iCombine(
|
|
RECTL *prcl,
|
|
LONG iMode)
|
|
{
|
|
PREGION prgn = prgnClip();
|
|
LONG iTmp;
|
|
|
|
if (!VALID_SCRPRC(prcl))
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
|
|
return(ERROR);
|
|
}
|
|
|
|
RGNMEMOBJ rmoRcl;
|
|
if (!rmoRcl.bValid())
|
|
return(ERROR);
|
|
|
|
rmoRcl.vSet(prcl);
|
|
|
|
vReleaseRao();
|
|
|
|
if (prgn != NULL)
|
|
{
|
|
RGNMEMOBJ rmo;
|
|
|
|
if (!rmo.bValid())
|
|
{
|
|
iTmp = ERROR;
|
|
}
|
|
else
|
|
{
|
|
RGNOBJ ro(prgn);
|
|
|
|
iTmp = rmo.iCombine(ro, rmoRcl, iMode);
|
|
|
|
if (iTmp != ERROR)
|
|
{
|
|
rmo.vSelect((HDC)hGet());
|
|
|
|
|
|
prgnClip(rmo.prgnGet());
|
|
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
// If nobody is using the old clip region, delete it.
|
|
|
|
ro.vUnselect();
|
|
|
|
if (ro.cGet_cRefs() == 0)
|
|
ro.bDeleteRGNOBJ();
|
|
}
|
|
else
|
|
{
|
|
rmo.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
|
|
rmoRcl.bDeleteRGNOBJ();
|
|
}
|
|
else if (iMode == RGN_AND)
|
|
{
|
|
rmoRcl.vSelect((HDC)hGet());
|
|
|
|
prgnClip(rmoRcl.prgnGet());
|
|
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
iTmp = SIMPLEREGION;
|
|
}
|
|
else
|
|
{
|
|
RGNMEMOBJ rmo2;
|
|
RGNMEMOBJTMP rmo3;
|
|
SIZEL sizl;
|
|
|
|
if (!rmo2.bValid())
|
|
{
|
|
iTmp = ERROR;
|
|
}
|
|
else if (!rmo3.bValid())
|
|
{
|
|
rmo2.bDeleteRGNOBJ();
|
|
iTmp = ERROR;
|
|
}
|
|
else
|
|
{
|
|
vGet_sizlWindow(&sizl);
|
|
|
|
ERECTL ercl(0, 0, sizl.cx, sizl.cy);
|
|
|
|
//
|
|
// Bug #310012: Under multimon, the rectangle isn't necessarily
|
|
// based at 0,0.
|
|
//
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
ASSERTGDI(pdo.bValid(), "Invalid pdev\n");
|
|
{
|
|
DEVLOCKOBJ dl(pdo);
|
|
if (pdo.bMetaDriver() && bHasSurface() && pSurface()->bPDEVSurface())
|
|
{
|
|
ercl += *pdo.pptlOrigin();
|
|
}
|
|
}
|
|
|
|
// Clip Rgn is maintained in the DC coordinate space;
|
|
// so, the window on physical device surface needs to be
|
|
// converted into DC coordinates. DC Window shown in PDEV
|
|
// coordinates.
|
|
//
|
|
// (0,0) sizl.cx
|
|
// +-----------------------+
|
|
// | |
|
|
// | PDEV Surface |
|
|
// (eptlOrigin) | |
|
|
// +----------+-----------+ |
|
|
// | | | | sizl.cy
|
|
// | DC Window | |
|
|
// | (erclWindow) | |
|
|
// | | | |
|
|
// +----------+-----------+ |
|
|
// | |
|
|
// +-----------------------+
|
|
//
|
|
// With the eptlOrigin adjustment the clip will be positioned
|
|
// as shown below.
|
|
//
|
|
// (0,0) (-eptlOrigin)
|
|
// +----------+-----------+-----------+
|
|
// | | | |
|
|
// | DC Window | |
|
|
// | (erclWindow-eptlOrigin) |
|
|
// | | | |
|
|
// +----------+-----------+ |
|
|
// | |
|
|
// | Default Clip Region |
|
|
// | |
|
|
// | |
|
|
// +-----------------------+
|
|
//
|
|
// Note: erclWindow-epltOrigin-eptlOrigin may give us more
|
|
// narrow clip region, but using dclevel.sizl-eptlOrigin
|
|
// will get the job done since we get that more narrow
|
|
// area when combined with prgnVis.
|
|
|
|
ercl -= eptlOrigin();
|
|
|
|
if (!ercl.bEmpty() && ercl.bWrapped())
|
|
{
|
|
iTmp = ERROR;
|
|
}
|
|
|
|
if (iTmp != ERROR)
|
|
{
|
|
rmo3.vSet((PRECTL) &ercl);
|
|
|
|
iTmp = rmo2.iCombine(rmo3, rmoRcl, iMode);
|
|
|
|
if (iTmp != ERROR)
|
|
{
|
|
rmo2.vSelect((HDC)hGet());
|
|
prgnClip(rmo2.prgnGet());
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
rmo2.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
|
|
rmoRcl.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
|
|
return(iTmp);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* LONG DC::iCombine(pexo, prcl, iMode)
|
|
*
|
|
* Combine the clip region a possibly transformed rectangle by the given mode
|
|
*
|
|
* History:
|
|
* 28-Apr-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
LONG DC::iCombine(
|
|
EXFORMOBJ *pexo,
|
|
RECTL *prcl,
|
|
LONG iMode)
|
|
{
|
|
POINTL aptl[4];
|
|
|
|
aptl[0].x = prcl->left;
|
|
aptl[0].y = prcl->top;
|
|
aptl[1].x = prcl->right;
|
|
aptl[1].y = prcl->top;
|
|
aptl[2].x = prcl->right;
|
|
aptl[2].y = prcl->bottom;
|
|
aptl[3].x = prcl->left;
|
|
aptl[3].y = prcl->bottom;
|
|
|
|
// Create a path, and draw the parallelogram.
|
|
|
|
PATHMEMOBJ pmo;
|
|
|
|
if (!pmo.bValid())
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
|
|
return(ERROR);
|
|
}
|
|
|
|
if (!pmo.bMoveTo(pexo, &aptl[0]))
|
|
return(ERROR);
|
|
|
|
if (!pmo.bPolyLineTo(pexo, &aptl[1], 3))
|
|
return(ERROR);
|
|
|
|
if (!pmo.bCloseFigure())
|
|
return(ERROR);
|
|
|
|
// Now, convert it back into a region.
|
|
|
|
RGNMEMOBJ rmoPlg(pmo, ALTERNATE);
|
|
|
|
if (!rmoPlg.bValid())
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
|
|
return(ERROR);
|
|
}
|
|
|
|
// Merge it into the current clipping region.
|
|
|
|
REGION *prgn = prgnClip();
|
|
LONG iTmp = ERROR;
|
|
|
|
vReleaseRao();
|
|
|
|
if (prgn != NULL)
|
|
{
|
|
RGNMEMOBJ rmo;
|
|
|
|
if (rmo.bValid())
|
|
{
|
|
RGNOBJ ro(prgn);
|
|
|
|
iTmp = rmo.iCombine(ro, rmoPlg, iMode);
|
|
|
|
if (iTmp != ERROR)
|
|
{
|
|
rmo.vSelect((HDC)hGet());
|
|
prgnClip(rmo.prgnGet());
|
|
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%lx, new region = 0x%lx\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
// If nobody is using the old clip region, delete it.
|
|
|
|
ro.vUnselect();
|
|
|
|
if (ro.cGet_cRefs() == 0)
|
|
ro.bDeleteRGNOBJ();
|
|
}
|
|
else
|
|
{
|
|
rmo.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
|
|
rmoPlg.bDeleteRGNOBJ();
|
|
}
|
|
else if (iMode == RGN_AND)
|
|
{
|
|
rmoPlg.vSelect((HDC)hGet());
|
|
prgnClip(rmoPlg.prgnGet());
|
|
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
iTmp = rmoPlg.iComplexity();
|
|
}
|
|
else
|
|
{
|
|
RGNMEMOBJ rmo2;
|
|
SIZEL sizl;
|
|
|
|
if (rmo2.bValid())
|
|
{
|
|
RGNMEMOBJTMP rmo3;
|
|
|
|
if (!rmo3.bValid())
|
|
{
|
|
rmo2.bDeleteRGNOBJ();
|
|
}
|
|
else
|
|
{
|
|
vGet_sizlWindow(&sizl);
|
|
|
|
ERECTL ercl(0, 0, sizl.cx, sizl.cy);
|
|
|
|
//
|
|
// Bug #310012: Under multimon, the rectangle isn't necessarily
|
|
// based at 0,0.
|
|
//
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
ASSERTGDI(pdo.bValid(), "Invalid pdev\n");
|
|
{
|
|
DEVLOCKOBJ dl(pdo);
|
|
if (pdo.bMetaDriver() && bHasSurface() && pSurface()->bPDEVSurface())
|
|
{
|
|
ercl += *pdo.pptlOrigin();
|
|
}
|
|
}
|
|
|
|
// Place Clip Region in DC Coordinates
|
|
// See comments in DC::iCombine(lprcl, iMode) above.
|
|
ercl -= eptlOrigin();
|
|
|
|
rmo3.vSet((PRECTL) &ercl);
|
|
|
|
iTmp = rmo2.iCombine(rmo3, rmoPlg, iMode);
|
|
|
|
if (iTmp == ERROR)
|
|
{
|
|
rmo2.bDeleteRGNOBJ();
|
|
}
|
|
else
|
|
{
|
|
rmo2.vSelect((HDC)hGet());
|
|
prgnClip(rmo2.prgnGet());
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("iCombine: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
rmoPlg.bDeleteRGNOBJ();
|
|
}
|
|
|
|
return(iTmp);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL DC::bReset()
|
|
*
|
|
* Reset regions associated with the DC
|
|
*
|
|
* History:
|
|
* 05-Jul-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL DC::bReset()
|
|
{
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("DC::bReset()\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
REGION *prgn;
|
|
|
|
if ((prgn = dclevel.prgnMeta) != NULL)
|
|
{
|
|
RGNOBJ roMeta(prgn);
|
|
|
|
roMeta.vUnselect();
|
|
|
|
if (roMeta.cGet_cRefs() == 0)
|
|
roMeta.bDeleteRGNOBJ();
|
|
|
|
dclevel.prgnMeta = NULL;
|
|
|
|
vReleaseRao();
|
|
}
|
|
|
|
if ((prgn = dclevel.prgnClip) != NULL)
|
|
{
|
|
RGNOBJ roClip(prgn);
|
|
|
|
roClip.vUnselect();
|
|
|
|
if (roClip.cGet_cRefs() == 0)
|
|
roClip.bDeleteRGNOBJ();
|
|
|
|
dclevel.prgnClip = NULL;
|
|
|
|
vReleaseRao();
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL bSaveRegion(dco, cLevel)
|
|
*
|
|
* Save the DC's regions
|
|
*
|
|
* History:
|
|
* 07-May-1991 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL bSaveRegion(DCOBJ& dco, LONG cLevel)
|
|
{
|
|
if (cLevel == 1)
|
|
{
|
|
RECTL rcl;
|
|
SIZEL sizl;
|
|
|
|
dco.pdc->vGet_sizl(&sizl);
|
|
|
|
rcl.left = 0;
|
|
rcl.bottom = 0;
|
|
rcl.right = sizl.cx;
|
|
rcl.top = sizl.cy;
|
|
|
|
{
|
|
RGNMEMOBJ rmo;
|
|
|
|
if (!rmo.bValid())
|
|
return(FALSE);
|
|
|
|
//
|
|
// Bug #310012: Under multimon, the rectangle isn't necessarily
|
|
// based at 0,0.
|
|
//
|
|
|
|
PDEVOBJ pdo(dco.hdev());
|
|
ASSERTGDI(pdo.bValid(), "Invalid pdev\n");
|
|
{
|
|
DEVLOCKOBJ dl(pdo);
|
|
if (pdo.bMetaDriver() && dco.bHasSurface() && dco.pSurface()->bPDEVSurface())
|
|
{
|
|
((ERECTL) rcl) += *pdo.pptlOrigin();
|
|
}
|
|
}
|
|
|
|
rmo.vSet(&rcl);
|
|
|
|
dco.pdc->prgnVis(rmo.prgnGet());
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
DCOBJ dcoSaved(dco.hdcSave());
|
|
|
|
if (!dcoSaved.bLocked())
|
|
return(FALSE);
|
|
|
|
PREGION prgn;
|
|
|
|
if ((prgn = dcoSaved.pdc->prgnMeta()) != NULL)
|
|
{
|
|
RGNOBJ roMeta(prgn);
|
|
|
|
roMeta.vSelect(dco.hdc());
|
|
}
|
|
|
|
if ((prgn = dcoSaved.pdc->prgnClip()) != NULL)
|
|
{
|
|
RGNOBJ roClip(prgn);
|
|
|
|
roClip.vSelect(dco.hdc());
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vRestoreRegion(dco, cLevel)
|
|
*
|
|
* Restore the DC's regions
|
|
*
|
|
* History:
|
|
* 08-May-1991 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vRestoreRegion(DCOBJ& dco, LONG cLevel)
|
|
{
|
|
DONTUSE(cLevel); // needed to keep save/restore calls happy
|
|
|
|
PREGION prgn;
|
|
|
|
if ((prgn = dco.pdc->prgnMeta()) != NULL)
|
|
{
|
|
RGNOBJ roMeta(prgn);
|
|
|
|
roMeta.vUnselect();
|
|
|
|
if (roMeta.cGet_cRefs() == 0)
|
|
roMeta.bDeleteRGNOBJ();
|
|
}
|
|
|
|
if ((prgn = dco.pdc->prgnClip()) != NULL)
|
|
{
|
|
RGNOBJ roClip(prgn);
|
|
|
|
roClip.vUnselect();
|
|
|
|
if (roClip.cGet_cRefs() == 0)
|
|
roClip.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* int DC::iSelect(hrgn, iMode)
|
|
*
|
|
* Select the region into the DC as the current clip region
|
|
*
|
|
* History:
|
|
* 17-Sep-1991 -by- Donald Sidoroff [donalds]
|
|
* Made DC::iSelect for SelectObject/SelectClipRgn compatibility.
|
|
*
|
|
* 02-Sep-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
int DC::iSelect(HRGN hrgn, int iMode)
|
|
{
|
|
int iRet;
|
|
|
|
if (hrgn != (HRGN)0)
|
|
{
|
|
RGNOBJAPI ro(hrgn,TRUE);
|
|
if (ro.bValid())
|
|
iRet = iSelect(ro.prgnGet(),iMode);
|
|
else
|
|
iRet = RGN_ERROR;
|
|
}
|
|
else
|
|
{
|
|
if (iMode == RGN_COPY)
|
|
iRet = iSelect((PREGION)NULL,iMode);
|
|
else
|
|
iRet = RGN_ERROR;
|
|
}
|
|
return(iRet);
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
*
|
|
* History:
|
|
* 23-Oct-1993 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
int DC::iSelect(PREGION prgn, int iMode)
|
|
{
|
|
PREGION prgnOld = prgnClip();
|
|
PREGION prgnNew = NULL;
|
|
int iRet = RGN_ERROR;
|
|
|
|
if ((iMode == RGN_COPY) ||
|
|
((iMode == RGN_AND) && (prgn != NULL) && (prgnOld == NULL)))
|
|
{
|
|
|
|
//
|
|
// Select in a region?
|
|
//
|
|
|
|
if (prgn != NULL)
|
|
{
|
|
RGNOBJ ro(prgn);
|
|
RGNOBJ roClip(prgnOld);
|
|
|
|
//
|
|
// There was no old region so create a new region and
|
|
// copy the input region to it, or the old region can't
|
|
// be modified due to other references.
|
|
//
|
|
|
|
if ((prgnOld == NULL) || (roClip.cGet_cRefs() != 1))
|
|
{
|
|
|
|
RGNMEMOBJ rmo(ro.sizeRgn());
|
|
|
|
if (rmo.bValid())
|
|
{
|
|
rmo.vCopy(ro);
|
|
rmo.vSelect((HDC)hGet());
|
|
prgnNew = rmo.prgnGet();
|
|
|
|
iRet = (int) rmo.iComplexity();
|
|
|
|
//
|
|
// select new region in and release RAO
|
|
//
|
|
|
|
prgnClip(prgnNew);
|
|
vReleaseRao();
|
|
|
|
//
|
|
// If there was an old clip region, it must be
|
|
// unreferenced.
|
|
//
|
|
|
|
if (prgnOld != NULL)
|
|
{
|
|
roClip.vUnselect();
|
|
|
|
if (roClip.cGet_cRefs() == 0)
|
|
{
|
|
roClip.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// select in a new region, there already was an old one so
|
|
// bCopy the new to the old
|
|
//
|
|
|
|
if (roClip.bCopy(ro))
|
|
{
|
|
|
|
//
|
|
// bCopy might change prgn
|
|
//
|
|
|
|
prgnNew = roClip.prgnGet();
|
|
|
|
iRet = (int) roClip.iComplexity();
|
|
|
|
//
|
|
// set new region pointer and release RAO
|
|
//
|
|
|
|
prgnClip(prgnNew);
|
|
|
|
vReleaseRao();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iRet = SIMPLEREGION;
|
|
|
|
//
|
|
// new clip region is NULL, delete old if it exists
|
|
//
|
|
|
|
if (prgnOld != NULL)
|
|
{
|
|
|
|
RGNOBJ roClip(prgnOld);
|
|
|
|
roClip.vUnselect();
|
|
|
|
if (roClip.cGet_cRefs() == 0)
|
|
{
|
|
roClip.bDeleteRGNOBJ();
|
|
}
|
|
|
|
prgnClip(NULL);
|
|
vReleaseRao();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// We didn't simply select the new region.
|
|
//
|
|
|
|
RGNOBJ ro(prgn);
|
|
|
|
RGNMEMOBJ rmo;
|
|
|
|
if (rmo.bValid())
|
|
{
|
|
|
|
if (prgnOld != NULL)
|
|
{
|
|
RGNOBJ roClip(prgnOld);
|
|
|
|
if ((iRet = (int) rmo.iCombine(roClip,ro,iMode)) != RGN_ERROR)
|
|
{
|
|
rmo.vSelect((HDC)hGet());
|
|
prgnNew = rmo.prgnGet();
|
|
|
|
prgnClip(prgnNew);
|
|
|
|
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("iSelect: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
vReleaseRao();
|
|
|
|
roClip.vUnselect();
|
|
if (roClip.cGet_cRefs() == 0)
|
|
{
|
|
roClip.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Since no clip region exists, make a dummy the size of the surface
|
|
//
|
|
|
|
RGNMEMOBJTMP rmo2;
|
|
SIZEL sizl;
|
|
|
|
if (rmo2.bValid())
|
|
{
|
|
vGet_sizlWindow(&sizl);
|
|
|
|
ERECTL ercl(0, 0, sizl.cx, sizl.cy);
|
|
|
|
//
|
|
// Bug #310012: Under multimon, the rectangle isn't necessarily
|
|
// based at 0,0.
|
|
//
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
ASSERTGDI(pdo.bValid(), "Invalid pdev\n");
|
|
{
|
|
DEVLOCKOBJ dl(pdo);
|
|
if (pdo.bMetaDriver() && bHasSurface() && pSurface()->bPDEVSurface())
|
|
{
|
|
ercl += *pdo.pptlOrigin();
|
|
}
|
|
}
|
|
|
|
// Place Clip Region in DC Coordinates
|
|
// See comments in DC::iCombine(lprcl, iMode) above.
|
|
ercl -= eptlOrigin();
|
|
|
|
rmo2.vSet((PRECTL) &ercl);
|
|
iRet = (int) rmo.iCombine(rmo2,ro,iMode);
|
|
|
|
if (iRet != RGN_ERROR)
|
|
{
|
|
rmo.vSelect((HDC)hGet());
|
|
prgnNew = rmo.prgnGet();
|
|
|
|
prgnClip(prgnNew);
|
|
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("iSelect: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
vReleaseRao();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (iRet == RGN_ERROR)
|
|
{
|
|
rmo.bDeleteRGNOBJ();
|
|
}
|
|
}
|
|
}
|
|
|
|
return(iRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* int DC::iSetMetaRgn()
|
|
*
|
|
* Select the region into the DC as the current meta region
|
|
*
|
|
* History:
|
|
* 01-Nov-1991 19:13:33 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
*
|
|
* 25-Nov-1992 -by- Eric Kutter [erick]
|
|
* rewrote
|
|
\**************************************************************************/
|
|
|
|
int DC::iSetMetaRgn()
|
|
{
|
|
|
|
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("DC::iSetMetaRgn()\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
int iRet = RGN_ERROR;
|
|
|
|
if (prgnMeta() == (PREGION)0)
|
|
{
|
|
if (prgnClip() == NULL)
|
|
return(SIMPLEREGION);
|
|
|
|
RGNOBJ ro(prgnClip());
|
|
|
|
iRet = (int) ro.iComplexity();
|
|
|
|
// NOTE: Since we're just copying the handle, the reference counts should
|
|
// remain the same.
|
|
|
|
prgnMeta(prgnClip());
|
|
|
|
prgnClip(NULL);
|
|
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("iSetMetaRgn: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
return(iRet);
|
|
}
|
|
else
|
|
{
|
|
RGNOBJ roMeta(prgnMeta());
|
|
|
|
// if we only have a meta rgn, just return that.
|
|
|
|
if (prgnClip() == NULL)
|
|
return(roMeta.iComplexity());
|
|
|
|
// need the merge the two into a new region
|
|
|
|
RGNOBJ roClip(prgnClip());
|
|
|
|
RGNMEMOBJ rmo;
|
|
|
|
if (!rmo.bValid())
|
|
return(iRet);
|
|
|
|
// combine the regions
|
|
|
|
iRet = (int) rmo.iCombine(roMeta,roClip,RGN_AND);
|
|
|
|
if (iRet != RGN_ERROR)
|
|
{
|
|
rmo.vSelect((HDC)hGet());
|
|
|
|
// delete the old meta rgn
|
|
|
|
prgnMeta(rmo.prgnGet());
|
|
|
|
roMeta.vUnselect();
|
|
if (roMeta.cGet_cRefs() == 0)
|
|
roMeta.bDeleteRGNOBJ();
|
|
|
|
// delete the old clip rgn
|
|
|
|
prgnClip(NULL);
|
|
|
|
|
|
#if DBG
|
|
|
|
if (dbgrgn)
|
|
{
|
|
DbgPrint("iSetMetaRgn: hdc = 0x%p, new region = 0x%p\n",hHmgr,prgnClip());
|
|
}
|
|
|
|
#endif
|
|
|
|
roClip.vUnselect();
|
|
if (roClip.cGet_cRefs() == 0)
|
|
roClip.bDeleteRGNOBJ();
|
|
|
|
vReleaseRao();
|
|
|
|
}
|
|
else
|
|
rmo.bDeleteRGNOBJ();
|
|
}
|
|
return(iRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DC::vReleaseVis()
|
|
*
|
|
* Release the current VisRgn
|
|
*
|
|
* History:
|
|
* 06-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID DC::vReleaseVis()
|
|
{
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("DC::vReleaseVis\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
fsSet(DC_DIRTY_RAO);
|
|
PENTRY_FROM_POBJ(this)->Flags |= HMGR_ENTRY_INVALID_VIS;
|
|
|
|
erclClip(&rclEmpty);
|
|
|
|
ASSERTGDI(prgnVis() != NULL,"DC::vReleaseVis - prgnVis == NULL\n");
|
|
|
|
RGNLOG rl((HRGN)prgnVis(),0,"DC::vReleaseVis");
|
|
|
|
prgnVis()->vDeleteREGION();
|
|
prgnVis(prgnDefault);
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DC::vReleaseRao()
|
|
*
|
|
* Release the current RaoRgn
|
|
*
|
|
* History:
|
|
* 06-Mar-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID DC::vReleaseRao()
|
|
{
|
|
|
|
#if DBG
|
|
|
|
if ((dbgrgn) && (gflhdc == hGet()))
|
|
{
|
|
DbgPrint("DC::vReleaseRao\n");
|
|
}
|
|
|
|
#endif
|
|
|
|
fsSet(DC_DIRTY_RAO);
|
|
|
|
PENTRY_FROM_POBJ(this)->Flags |= HMGR_ENTRY_INVALID_VIS;
|
|
|
|
erclClip(&rclEmpty);
|
|
|
|
RGNLOG rl(prgnRao(),"DC::vReleaseRao");
|
|
}
|