Leaked source code of windows server 2003
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

/******************************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");
}