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.
1400 lines
44 KiB
1400 lines
44 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: dcobj.cxx *
|
|
* *
|
|
* Non inline methods for DC user object. These are in a separate module *
|
|
* to save other modules from having to do more includes. *
|
|
* *
|
|
* Created: 09-Aug-1989 13:57:58 *
|
|
* Author: Donald Sidoroff [donalds] *
|
|
* *
|
|
* Copyright (c) 1989-1999 Microsoft Corporation *
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
extern RECTL rclEmpty;
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* VOID XDCOBJ::vSetDefaultFont(BOOL bDisplay)
|
|
*
|
|
*
|
|
* Effects: called from bCleanDC and CreateDC
|
|
*
|
|
* History:
|
|
* 21-Mar-1996 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID XDCOBJ::vSetDefaultFont(BOOL bDisplay)
|
|
{
|
|
// If display PDEV, then select System stock font.
|
|
|
|
HLFONT hlfntNew;
|
|
|
|
if (bDisplay)
|
|
{
|
|
ulDirty(ulDirty() | DISPLAY_DC );
|
|
hlfntNew = STOCKOBJ_SYSFONT;
|
|
}
|
|
else
|
|
{
|
|
hlfntNew = STOCKOBJ_DEFAULTDEVFONT;
|
|
}
|
|
|
|
// this can not fail with the stock fonts, also increments ref count
|
|
|
|
PLFONT plfnt = (PLFONT)HmgShareCheckLock((HOBJ)hlfntNew, LFONT_TYPE);
|
|
ASSERTGDI(plfnt, "vSetDefaultFont: plfnt == NULL\n");
|
|
|
|
pdc->hlfntNew(hlfntNew);
|
|
pdc->plfntNew(plfnt);
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DCSAVE::bDelete()
|
|
*
|
|
* Attempt to delete the DC.
|
|
*
|
|
* History:
|
|
* Sat 19-Aug-1989 00:32:58 -by- Charles Whitmer [chuckwh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL XDCOBJ::bDeleteDC(BOOL bProcessCleanup)
|
|
{
|
|
PFFLIST *pPFFList;
|
|
BOOL bIsPrivate;
|
|
|
|
RFONTOBJ rfDeadMeat(pdc->prfnt()); // deletion constructor, see rfntobj.cxx
|
|
|
|
// Nuke the brushes (unreference count to brush realization)
|
|
|
|
peboFill()->vNuke();
|
|
peboLine()->vNuke();
|
|
peboText()->vNuke();
|
|
peboBackground()->vNuke();
|
|
|
|
// remove any colortransform in this DC.
|
|
|
|
vCleanupColorTransform(bProcessCleanup);
|
|
|
|
// remove any remote fonts
|
|
|
|
if(pPFFList = pdc->pPFFList)
|
|
{
|
|
while( pPFFList )
|
|
{
|
|
PFFLIST *pTmp;
|
|
|
|
pTmp = pPFFList;
|
|
pPFFList = pPFFList->pNext;
|
|
|
|
GreAcquireSemaphoreEx(ghsemPublicPFT, SEMORDER_PUBLICPFT, NULL);
|
|
|
|
// this list is also used for local printing with embed fonts
|
|
|
|
bIsPrivate = (pTmp->pPFF->pPFT == gpPFTPrivate) ? TRUE : FALSE;
|
|
PUBLIC_PFTOBJ pfto(pTmp->pPFF->pPFT);
|
|
|
|
//pPFFList != NULL only if the PFFs have been added to the DC for remote printing.
|
|
// bUnloadWorkhorse should release the ghsemPublicPFT
|
|
|
|
if (!pfto.bUnloadWorkhorse( pTmp->pPFF, 0, ghsemPublicPFT, bIsPrivate ? FR_PRINT_EMB_FONT : FR_NOT_ENUM))
|
|
{
|
|
WARNING("XDCOBJ::bDelete unable to delete remote font.\n");
|
|
}
|
|
|
|
VFREEMEM( pTmp );
|
|
}
|
|
}
|
|
|
|
// remove this from handle manager.
|
|
|
|
HmgFree((HOBJ)pdc->hGet());
|
|
|
|
pdc = (PDC) NULL; // Prevents ~DCOBJ from doing anything.
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Data*Structure******************************\
|
|
* dclevelDefault
|
|
*
|
|
* Defines the default DC image for use by DCMEMOBJ.
|
|
*
|
|
* History:
|
|
* Thu 09-Aug-1990 20:54:02 -by- Charles Whitmer [chuckwh]
|
|
* Wrote the nearly bare bones version. We'll build it back up with the
|
|
* DC structure as we add components.
|
|
\**************************************************************************/
|
|
|
|
DC_ATTR DcAttrDefault =
|
|
{
|
|
{0}, // PVOID pvLDC;
|
|
(ULONG)DIRTY_CHARSET, // ULONG ulDirty_;
|
|
(HBRUSH)0, // HBRUSH hbrush
|
|
(HPEN)0, // HPEN hpen
|
|
(COLORREF)0x00ffffff, // COLORREF crBackgroundClr;
|
|
(COLORREF)0x00ffffff, // ULONG ulBackgroundClr;
|
|
(COLORREF)0, // COLORREF crForegroundClr;
|
|
(COLORREF)0, // ULONG ulForegroundClr;
|
|
(COLORREF)0x00ffffff, // COLORREF crDCBrushClr;
|
|
(COLORREF)0x00ffffff, // ULONG ulDCBrushClr;
|
|
(COLORREF)0, // COLORREF crDCPenClr;
|
|
(COLORREF)0, // ULONG ulDCPenClr;
|
|
(ULONG)0, // ULONG iCS_CP;
|
|
GM_COMPATIBLE, // ULONG iGraphicsMode;
|
|
R2_COPYPEN, // BYTE jROP2;
|
|
OPAQUE, // BYTE jBkMode;
|
|
ALTERNATE, // BYTE jFillMode;
|
|
BLACKONWHITE, // BYTE jStretchBltMode;
|
|
{0}, // POINTL ptlCurrent
|
|
{0}, // POINTL ptfxCurrent
|
|
OPAQUE, // LONG lBkMode;
|
|
ALTERNATE, // ULONG lFillMode;
|
|
BLACKONWHITE, // LONG lStretchBltMode;
|
|
0, // FLONG flFontMapper;
|
|
//
|
|
DC_ICM_OFF, // LONG lIcmMode;
|
|
(HANDLE)0, // HANDLE hcmXform;
|
|
(HCOLORSPACE)0, // HCOLORSPACE hColorSpace;
|
|
(DWORD)0, // DWORD dwDIBColorSpace;
|
|
(COLORREF)CLR_INVALID, // COLORREF IcmBrushColor;
|
|
(COLORREF)CLR_INVALID, // COLORREF IcmPenColor;
|
|
{0}, // PVOID pvICM;
|
|
//
|
|
TA_LEFT|TA_TOP|TA_NOUPDATECP, // FLONG flTextAlign;
|
|
TA_LEFT|TA_TOP|TA_NOUPDATECP, // LONG lTextAlign;
|
|
(LONG)0, // LONG lTextExtra;
|
|
(LONG)ABSOLUTE, // LONG lRelAbs;
|
|
(LONG)0, // LONG lBreakExtra;
|
|
(LONG)0, // LONG cBreak;
|
|
(HLFONT)0, // HLFONT hlfntNew;
|
|
|
|
{ // MATRIX mxWorldToDevice
|
|
EFLOAT_16, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_16, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_LTOFX
|
|
},
|
|
{ // MATRIX mxDeviceToWorld
|
|
EFLOAT_1Over16, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_1Over16, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_FXTOL
|
|
},
|
|
{ // MATRIX mxWorldToPage
|
|
EFLOAT_1, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_1, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_LTOL
|
|
},
|
|
|
|
EFLOAT_16, // EFLOAT efM11PtoD
|
|
EFLOAT_16, // EFLOAT efM22PtoD
|
|
EFLOAT_0, // EFLOAT efDxPtoD
|
|
EFLOAT_0, // EFLOAT efDyPtoD
|
|
|
|
MM_TEXT, // ULONG iMapMode;
|
|
0, // DWORD dwLayout;
|
|
0, // LONG lWindowOrgx;
|
|
|
|
{0,0}, // POINTL ptlWindowOrg;
|
|
{1,1}, // SIZEL szlWindowExt;
|
|
{0,0}, // POINTL ptlViewPortOrg;
|
|
{1,1}, // SIZEL szlViewPortExt;
|
|
|
|
WORLD_TO_PAGE_IDENTITY | // flXform
|
|
PAGE_TO_DEVICE_SCALE_IDENTITY |
|
|
PAGE_TO_DEVICE_IDENTITY,
|
|
|
|
{0,0}, // SIZEL szlVirtualDevicePixel;
|
|
{0,0}, // SIZEL szlVirtualDeviceMm;
|
|
{0,0}, // POINTL ptlBrushOrigin;
|
|
{0} // RECTREGION VisRectRegion;
|
|
};
|
|
|
|
DCLEVEL dclevelDefault =
|
|
{
|
|
0, // HPAL hpal;
|
|
0, // PPALETTE ppal;
|
|
0, // PVOID pColorSpace;
|
|
DC_ICM_OFF, // ULONG lIcmMode;
|
|
1, // LONG lSaveDepth;
|
|
0, // LONG lSaveDepthStartDoc;
|
|
(HDC) 0, // HDC hdcSave;
|
|
{0,0}, // POINTL ptlKmBrushOrigin;
|
|
(PBRUSH)NULL, // PBRUSH pbrFill;
|
|
(PBRUSH)NULL, // PBRUSH pbrLine;
|
|
(PLFONT)NULL, // PLFONT plfntNew_;
|
|
HPATH_INVALID, // HPATH hpath;
|
|
0, // FLONG flPath;
|
|
{ // LINEATTRS laPath;
|
|
0, // FLONG fl;
|
|
0, // ULONG iJoin;
|
|
0, // ULONG iEndCap;
|
|
{IEEE_0_0F}, // FLOAT_LONG elWidth;
|
|
IEEE_10_0F, // FLOAT eMiterLimit;
|
|
0, // ULONG cstyle;
|
|
(PFLOAT_LONG) NULL, // PFLOAT_LONG pstyle;
|
|
{IEEE_0_0F} // FLOAT_LONG elStyleState;
|
|
},
|
|
NULL, // HRGN prgnClip;
|
|
NULL, // HRGN prgnMeta;
|
|
{ // COLORADJUSTMENT ca
|
|
sizeof(COLORADJUSTMENT), // WORD caSize
|
|
CA_DEFAULT, // WORD caFlags
|
|
ILLUMINANT_DEFAULT, // WORD caIlluminantIndex
|
|
HT_DEF_RGB_GAMMA, // WORD caRedPowerGamma
|
|
HT_DEF_RGB_GAMMA, // WORD caGreenPowerGamma
|
|
HT_DEF_RGB_GAMMA, // WORD caBluePowerGamma
|
|
REFERENCE_BLACK_DEFAULT, // WORD caReferenceBlack
|
|
REFERENCE_WHITE_DEFAULT, // WORD caReferenceWhite
|
|
CONTRAST_ADJ_DEFAULT, // SHORT caContrast
|
|
BRIGHTNESS_ADJ_DEFAULT, // SHORT caBrightness
|
|
COLORFULNESS_ADJ_DEFAULT, // SHORT caColorfulness
|
|
REDGREENTINT_ADJ_DEFAULT, // SHORT caRedGreenTint
|
|
},
|
|
|
|
0, // FLONG flFontState;
|
|
{0,0}, // UNIVERSAL_FONT_ID ufi;
|
|
{{0,0},{0,0},{0,0},{0,0}}, // UNIVERSAL_FON_ID aQuickLinks[QUICK_UFI_LINKS]
|
|
0, // PUNIVERSAL_FONT_ID pufi
|
|
0, // UINT uNumLinkedFonts
|
|
0, // BOOL bTurnOffLinking
|
|
|
|
0, // FLONG flFlags;
|
|
0, // FLONG flbrush;
|
|
|
|
{ // MATRIX mxWorldToDevice
|
|
EFLOAT_16, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_16, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_LTOFX
|
|
},
|
|
{ // MATRIX mxDeviceToWorld
|
|
EFLOAT_1Over16, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_1Over16, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_FXTOL
|
|
},
|
|
{ // MATRIX mxWorldToPage
|
|
EFLOAT_1, // EFLOAT efM11
|
|
EFLOAT_0, // EFLOAT efM12
|
|
EFLOAT_0, // EFLOAT efM21
|
|
EFLOAT_1, // EFLOAT efM22
|
|
EFLOAT_0, // EFLOAT efDx
|
|
EFLOAT_0, // EFLOAT efDy
|
|
0, // FIX fxDx
|
|
0, // FIX fxDy
|
|
XFORM_SCALE | // FLONG flAccel
|
|
XFORM_UNITY |
|
|
XFORM_NO_TRANSLATION |
|
|
XFORM_FORMAT_LTOL
|
|
},
|
|
|
|
EFLOAT_16, // EFLOAT efM11PtoD
|
|
EFLOAT_16, // EFLOAT efM22PtoD
|
|
EFLOAT_0, // EFLOAT efDxPtoD
|
|
EFLOAT_0, // EFLOAT efDyPtoD
|
|
EFLOAT_0, // EFLOAT efM11_TWIPS
|
|
EFLOAT_0, // EFLOAT efM22_TWIPS
|
|
EFLOAT_0, // efPr11
|
|
EFLOAT_0, // efPr22
|
|
|
|
0, // SURFACE *pSurface;
|
|
{0,0}, // SIZEL sizl;
|
|
};
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL DCOBJ::bCleanDC ()
|
|
*
|
|
* Restores the DCLEVEL to the same as when DC was created via CreateDC (i.e,
|
|
* resets it back to dclevelDefault). Also used to clean the DC before
|
|
* deletion.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE if an error occurs.
|
|
*
|
|
* History:
|
|
* 21-May-1991 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL XDCOBJ::bCleanDC ()
|
|
{
|
|
|
|
// Set TRUE if cleaning the DC invalidates the prfnt with respect to
|
|
// the DC's transform.
|
|
|
|
BOOL bFontXformDirty;
|
|
|
|
// Sync the brush
|
|
|
|
SYNC_DRAWING_ATTRS(pdc);
|
|
|
|
// If the current map mode is MM_TEXT and the current prfnt is NOT dirty
|
|
// with respect to the transform, then after we scrub the DC clean, the
|
|
// pfrnt is still clean with respect to transform. Otherwise, the font
|
|
// is dirty with respect to transform.
|
|
|
|
if ((ulMapMode() == MM_TEXT) && !this->pdc->bXFormChange())
|
|
bFontXformDirty = FALSE;
|
|
else
|
|
bFontXformDirty = TRUE;
|
|
|
|
// Restore DC to lowest level.
|
|
|
|
if (1 < lSaveDepth())
|
|
GreRestoreDC(hdc(), 1);
|
|
|
|
// Restore the palette.
|
|
|
|
if (ppal() != ppalDefault)
|
|
GreSelectPalette(hdc(), (HPALETTE)dclevelDefault.hpal, TRUE);
|
|
|
|
if (dctp() == DCTYPE_MEMORY)
|
|
{
|
|
// Restore the bitmap if necessary.
|
|
|
|
hbmSelectBitmap(hdc(), STOCKOBJ_BITMAP, TRUE);
|
|
|
|
// Watch out that DirectDraw sometimes marks DCTYPE_MEMORY
|
|
// surfaces as being 'full-screen'. Consequently, we have
|
|
// to reset that here.
|
|
//
|
|
// (Note that we don't reset the flag for DCTYPE_DIRECT
|
|
// surfaces, because that flag is automatically updated by
|
|
// PDEVOBJ::bDisabled() for all DCTYPE_DIRECT surfaces when
|
|
// the mode changes.)
|
|
|
|
bInFullScreen(FALSE);
|
|
}
|
|
|
|
// Reset pixel format.
|
|
|
|
ipfdDevMax(-1);
|
|
|
|
// If any regions exist, delete them.
|
|
|
|
if (pdc->dclevel.prgnClip != NULL)
|
|
{
|
|
RGNOBJ ro1(pdc->dclevel.prgnClip);
|
|
|
|
// Note: GreRestoreDC(1) should guarantee regions' reference
|
|
// counts are 1
|
|
|
|
ASSERTGDI (ro1.cGet_cRefs() == 1,
|
|
"DCOBJ::bCleanDC(): bad ref count, deleting prgnClip\n");
|
|
|
|
ro1.bDeleteRGNOBJ();
|
|
pdc->dclevel.prgnClip = NULL;
|
|
}
|
|
|
|
if (pdc->dclevel.prgnMeta != NULL)
|
|
{
|
|
RGNOBJ ro2(pdc->dclevel.prgnMeta);
|
|
|
|
// Note: GreRestoreDC(1) should guarantee regions' reference
|
|
// counts are 1
|
|
|
|
ASSERTGDI (ro2.cGet_cRefs() == 1,
|
|
"DCOBJ::bCleanDC(): bad ref count, deleting prgnMeta\n");
|
|
|
|
ro2.bDeleteRGNOBJ();
|
|
pdc->dclevel.prgnMeta = NULL;
|
|
}
|
|
|
|
// delete the path
|
|
|
|
if (pdc->dclevel.hpath != HPATH_INVALID)
|
|
{
|
|
XEPATHOBJ epath(pdc->dclevel.hpath);
|
|
ASSERTGDI(epath.bValid(), "Invalid DC path");
|
|
epath.vDelete();
|
|
}
|
|
|
|
// Undo the locks from when the fill and line brushes were selected.
|
|
// (Un-reference-count the brushes.)
|
|
|
|
DEC_SHARE_REF_CNT_LAZY0(pdc->dclevel.pbrFill);
|
|
DEC_SHARE_REF_CNT_LAZY0(pdc->dclevel.pbrLine);
|
|
|
|
// make sure to delete the old logfont object if it is marked for deletion
|
|
|
|
DEC_SHARE_REF_CNT_LAZY_DEL_LOGFONT(pdc->plfntNew());
|
|
|
|
// decrement ref count for the colorspace selected in DC.
|
|
|
|
DEC_SHARE_REF_CNT_LAZY_DEL_COLORSPACE(pdc->dclevel.pColorSpace);
|
|
|
|
// Make sure everything else is set to default.
|
|
//
|
|
// Preserve 'pSurface' and 'sizl' in the DCLEVEL -- it may asynchronously
|
|
// be updated by dynamic mode changing.
|
|
|
|
RtlCopyMemory(&pdc->dclevel, &dclevelDefault, offsetof(DCLEVEL, pSurface));
|
|
RtlCopyMemory(pdc->pDCAttr, &DcAttrDefault, sizeof(DC_ATTR));
|
|
|
|
// Mark brush, charset, color space and color transform as dirty.
|
|
|
|
ulDirtyAdd(DIRTY_BRUSHES|DIRTY_CHARSET|DIRTY_COLORSPACE|DIRTY_COLORTRANSFORM);
|
|
|
|
// Lock the fill and line brushes we just selected in.
|
|
// (Reference-count the brushes.)
|
|
// These locks can't fail.
|
|
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pbrFill);
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pbrLine);
|
|
|
|
// Clean up the font stuff. (This must be done after copying the default
|
|
// dclevel).
|
|
|
|
{
|
|
PDEVOBJ pdo(hdev());
|
|
|
|
// If display PDEV, then select System stock font.
|
|
|
|
vSetDefaultFont(pdo.bDisplayPDEV());
|
|
|
|
// if primary display dc, set the DC_PRIMARY_DISPLAY flag on
|
|
|
|
if (hdev() == UserGetHDEV())
|
|
{
|
|
ulDirtyAdd(DC_PRIMARY_DISPLAY);
|
|
}
|
|
|
|
// OK, set the dclevel's font xfrom dirty flag from the value computed
|
|
// BEFORE the GreRestoreDC.
|
|
|
|
this->pdc->vXformChange(bFontXformDirty);
|
|
}
|
|
|
|
// Lock color space we just selected in.
|
|
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pColorSpace);
|
|
|
|
RFONTOBJ rfoDead(pdc->prfnt()); // special constructor deactivates
|
|
pdc->prfnt(0); // this RFONT
|
|
|
|
// free up linked UFIs if not allocated pointing to fast buffer
|
|
|
|
if(pdc->dclevel.pufi && (pdc->dclevel.pufi != pdc->dclevel.aQuickLinks))
|
|
{
|
|
VFREEMEM(pdc->dclevel.pufi);
|
|
pdc->dclevel.pufi = NULL;
|
|
}
|
|
|
|
// Set the filling origin to whatever the DC origin is.
|
|
|
|
pdc->ptlFillOrigin(pdc->eptlOrigin().x,pdc->eptlOrigin().y);
|
|
|
|
// Assume Rao has been made dirty by the above work.
|
|
|
|
pdc->vReleaseRao();
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* XDCOBJ::bSetLinkedUFIs( PFF *ppff );
|
|
*
|
|
* Add the list of linked UFIs to tDC
|
|
*
|
|
* History:
|
|
* Mon 15-Dec-1996 -by- Gerrit van Wingerden [gerritv]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL XDCOBJ::bSetLinkedUFIs(PUNIVERSAL_FONT_ID pufis, UINT uNumUFIs)
|
|
{
|
|
pdc->dclevel.bTurnOffLinking = (uNumUFIs) ? FALSE : TRUE;
|
|
|
|
// If pufi hasn't been initialized or it is too small, reinitialize it.
|
|
|
|
if(!pdc->dclevel.pufi || (uNumUFIs > pdc->dclevel.uNumLinkedFonts))
|
|
{
|
|
if(pdc->dclevel.pufi && (pdc->dclevel.pufi != pdc->dclevel.aQuickLinks))
|
|
{
|
|
VFREEMEM(pdc->dclevel.pufi);
|
|
pdc->dclevel.pufi = NULL;
|
|
}
|
|
|
|
if(uNumUFIs <= QUICK_UFI_LINKS)
|
|
{
|
|
pdc->dclevel.pufi = pdc->dclevel.aQuickLinks;
|
|
}
|
|
else
|
|
{
|
|
if(!(pdc->dclevel.pufi = (PUNIVERSAL_FONT_ID)
|
|
PALLOCMEM(sizeof(UNIVERSAL_FONT_ID) * uNumUFIs,'ddaG')))
|
|
{
|
|
WARNING("GDI: XDCOBJ::bSetLinkedUFIs of of memory\n");
|
|
pdc->dclevel.uNumLinkedFonts = 0;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
pdc->dclevel.uNumLinkedFonts = uNumUFIs;
|
|
}
|
|
|
|
memcpy(pdc->dclevel.pufi, pufis, sizeof(UNIVERSAL_FONT_ID) * uNumUFIs);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* XDCOBJ::bAddRemoteFont( PFF *ppff );
|
|
*
|
|
* Add the PFF of a remote font to this DC.
|
|
*
|
|
* History:
|
|
* Mon 06-Feb-1995 -by- Gerrit van Wingerden [gerritv]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL XDCOBJ::bAddRemoteFont( PFF *ppff )
|
|
{
|
|
BOOL bRet = FALSE;
|
|
PFFLIST *pPFFList;
|
|
|
|
pPFFList = (PFFLIST*) PALLOCMEM( sizeof(PFFLIST),'ddaG' );
|
|
|
|
if( pPFFList == NULL )
|
|
{
|
|
WARNING("XDCOBJ::bAddRemoteFont unable to allocate memory\n");
|
|
}
|
|
else
|
|
{
|
|
pPFFList->pNext = pdc->pPFFList;
|
|
pdc->pPFFList = pPFFList;
|
|
pPFFList->pPFF = ppff;
|
|
bRet = TRUE;
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/****************************Member*Function*****************************\
|
|
* XDCOBJ::bRemoveMergeFont(UNIVERSAL_FONT_ID ufi);
|
|
*
|
|
* Remove a merged font from the public font table and pPFFList in the dc.
|
|
*
|
|
* History:
|
|
* Jan-27-1997 Xudong Wu [tessiew]
|
|
* Wrote it.
|
|
\************************************************************************/
|
|
BOOL XDCOBJ::bRemoveMergeFont(UNIVERSAL_FONT_ID ufi)
|
|
{
|
|
GDIFunctionID(XDCOBJ::bRemoveMergeFont);
|
|
|
|
PFFLIST *pPFFCur, *pPFFPrev;
|
|
BOOL bRet = FALSE;
|
|
|
|
pPFFPrev = pPFFCur = pdc->pPFFList;
|
|
|
|
while(pPFFCur && !bRet)
|
|
{
|
|
PFFOBJ pffo(pPFFCur->pPFF);
|
|
|
|
if (pffo.ulCheckSum() == ufi.CheckSum)
|
|
{
|
|
UINT iFont;
|
|
|
|
// check whether the Index field also match
|
|
|
|
for (iFont = 0; iFont < pffo.cFonts(); iFont++ )
|
|
{
|
|
ASSERTGDI(pffo.ppfe(iFont), "Invalid ppfe\n");
|
|
|
|
if (pffo.ppfe(iFont)->ufi.Index == ufi.Index)
|
|
{
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bRet)
|
|
{
|
|
pPFFPrev = pPFFCur;
|
|
pPFFCur = pPFFCur->pNext;
|
|
}
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
GreAcquireSemaphoreEx(ghsemPublicPFT, SEMORDER_PUBLICPFT, NULL);
|
|
|
|
PUBLIC_PFTOBJ pfto;
|
|
|
|
// bUnloadWorkhorse should release gpsemPublicePFT
|
|
|
|
if (!(bRet = pfto.bUnloadWorkhorse(pPFFCur->pPFF, 0, ghsemPublicPFT, FR_NOT_ENUM)))
|
|
{
|
|
WARNING("Unable to delete the font.\n");
|
|
}
|
|
else
|
|
{
|
|
if (pPFFCur == pdc->pPFFList)
|
|
{
|
|
pdc->pPFFList = pPFFCur->pNext;
|
|
}
|
|
else
|
|
{
|
|
pPFFPrev->pNext = pPFFCur->pNext;
|
|
}
|
|
|
|
VFREEMEM(pPFFCur);
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DCMEMOBJ::DCMEMOBJ()
|
|
*
|
|
* Allocates RAM for a new DC. Fills the RAM with default values.
|
|
*
|
|
* History:
|
|
*
|
|
* Fri 07-Dec-1990 -by- Patrick Haluptzok [patrickh]
|
|
* Adding palette support
|
|
*
|
|
* Thu 09-Aug-1990 17:29:25 -by- Charles Whitmer [chuckwh]
|
|
* Changed a little for NT DDI.
|
|
*
|
|
* Fri 01-Sep-1989 04:36:19 -by- Charles Whitmer [chuckwh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
DCMEMOBJ::DCMEMOBJ(
|
|
ULONG iType,
|
|
BOOL bAltType)
|
|
{
|
|
pdc = (PDC) NULL;
|
|
bKeep = FALSE;
|
|
|
|
//
|
|
// Check the type.
|
|
//
|
|
|
|
ASSERTGDI((iType == DCTYPE_INFO) ||
|
|
(iType == DCTYPE_MEMORY) ||
|
|
(iType == DCTYPE_DIRECT), "Invalid DC type");
|
|
|
|
//
|
|
// Allocate the DC 0 initialized
|
|
//
|
|
|
|
PDC pdcTemp = pdc = (PDC)HmgAlloc(sizeof(DC), DC_TYPE, HMGR_ALLOC_LOCK);
|
|
|
|
if (pdcTemp != (PDC)NULL)
|
|
{
|
|
//
|
|
// if this is an alternate DC (may need special attention on the client side
|
|
// due to printing or metafiling) set the type to LO_ALTDC_TYPE from LO_TYPE
|
|
//
|
|
|
|
if (bAltType)
|
|
{
|
|
HmgModifyHandleType((HOBJ)MODIFY_HMGR_TYPE(pdcTemp->hGet(),LO_ALTDC_TYPE));
|
|
}
|
|
|
|
pdcTemp->dcattr = DcAttrDefault;
|
|
pdcTemp->pDCAttr = &pdcTemp->dcattr;
|
|
pdcTemp->dclevel = dclevelDefault;
|
|
|
|
//
|
|
// Lock the fill and line brushes we just selected in as part of the
|
|
// default DC.
|
|
// (Reference-count the brushes.)
|
|
// These locks can't fail.
|
|
//
|
|
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pbrFill);
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pbrLine);
|
|
INC_SHARE_REF_CNT(pdc->dclevel.pColorSpace);
|
|
|
|
pdcTemp->dctp((DCTYPE) iType);
|
|
pdcTemp->fs(0);
|
|
ASSERTGDI(pdcTemp->hpal() == STOCKOBJ_PAL, "Bad initial hpal for DCMEMOBJ");
|
|
ASSERTGDI(pdcTemp->hdcNext() == (HDC) 0, "ERROR this is baddfd343dc");
|
|
ASSERTGDI(pdcTemp->hdcPrev() == (HDC) 0, "ERROR this is e43-99crok4");
|
|
pdcTemp->ptlFillOrigin(0,0);
|
|
ulDirty(DIRTY_BRUSHES|DIRTY_CHARSET|DIRTY_COLORSPACE|DIRTY_COLORTRANSFORM);
|
|
|
|
//
|
|
// Update the pointer to the COLORADJUSTMENT structure for
|
|
// the 4 EBRUSHOBJ.
|
|
//
|
|
|
|
COLORADJUSTMENT *pca = pColorAdjustment();
|
|
pdcTemp->peboFill()->pColorAdjustment(pca);
|
|
pdcTemp->peboLine()->pColorAdjustment(pca);
|
|
pdcTemp->peboText()->pColorAdjustment(pca);
|
|
pdcTemp->peboBackground()->pColorAdjustment(pca);
|
|
|
|
pdcTemp->prfnt(PRFNTNULL);
|
|
pdcTemp->hlfntCur(HLFONT_INVALID);
|
|
pdcTemp->flSimulationFlags(0);
|
|
ulCopyCount((ULONG)-1);
|
|
ipfdDevMax(-1); // also reset in bCleanDC
|
|
pdcTemp->prgnVis(NULL);
|
|
pdcTemp->vPFFListSet(NULL);
|
|
pdcTemp->vCXFListSet(NULL);
|
|
}
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DCMEMOBJ::DCMEMOBJ(&dcobjs)
|
|
*
|
|
* Create a new DC and copy in the DC passed to us. This is used by
|
|
* SaveDC.
|
|
*
|
|
* History:
|
|
* 06-Jan-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
DCMEMOBJ::DCMEMOBJ(DCOBJ& dco)
|
|
{
|
|
//
|
|
// Assume failure.
|
|
//
|
|
|
|
bKeep = FALSE;
|
|
|
|
//
|
|
// Allocate the DC,
|
|
//
|
|
|
|
pdc = (PDC)HmgAlloc(sizeof(DC), DC_TYPE, HMGR_ALLOC_LOCK);
|
|
|
|
if (pdc != (PDC)NULL)
|
|
{
|
|
pdc->fs(0);
|
|
pdc->prgnVis(NULL);
|
|
pdc->ppdev(dco.pdc->ppdev());
|
|
|
|
//
|
|
// shared attrs point to self
|
|
//
|
|
|
|
pdc->pDCAttr = &pdc->dcattr;
|
|
dco.pdc->vCopyTo(*this);
|
|
}
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DCSAVE::vCopyTo
|
|
*
|
|
* Carbon copy the DCOBJ
|
|
*
|
|
* History:
|
|
* 24-Apr-1991 -by- Donald Sidoroff [donalds]
|
|
* Moved it out-of-line.
|
|
\**************************************************************************/
|
|
|
|
VOID DC::vCopyTo(XDCOBJ& dco)
|
|
{
|
|
//
|
|
// The dynamic mode changing code needs to be able to dynamically update
|
|
// some fields in the DCLEVEL, and consequently needs to be able to track
|
|
// all DCLEVELs. So this routine should be used carefully and under
|
|
// the appropriate lock to ensure that the dynamic mode change code does
|
|
// not fall over. We do both because one or the other might not have
|
|
// set DC_SYNCHRONIZE.
|
|
//
|
|
|
|
vAssertDynaLock(TRUE);
|
|
dco.pdc->vAssertDynaLock(TRUE);
|
|
|
|
//
|
|
// copy dc level and dcattr
|
|
//
|
|
|
|
*dco.pdc->pDCAttr = *pDCAttr;
|
|
dco.pdc->dclevel = dclevel;
|
|
|
|
if (dclevel.pufi == dclevel.aQuickLinks)
|
|
{
|
|
dco.pdc->dclevel.pufi = dco.pdc->dclevel.aQuickLinks;
|
|
}
|
|
else if (dclevel.pufi)
|
|
{
|
|
if(dco.pdc->dclevel.pufi = (PUNIVERSAL_FONT_ID)
|
|
PALLOCMEM(sizeof(UNIVERSAL_FONT_ID) * dclevel.uNumLinkedFonts,'ddaG'))
|
|
{
|
|
memcpy(dco.pdc->dclevel.pufi, dclevel.pufi, sizeof(UNIVERSAL_FONT_ID) * dclevel.uNumLinkedFonts);
|
|
}
|
|
else
|
|
{
|
|
WARNING("GDI: DC::vCopyTo out of memory\n");
|
|
dco.pdc->dclevel.uNumLinkedFonts = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DCMEMOBJ::~DCMEMOBJ()
|
|
*
|
|
* Frees a DC unless told to keep it.
|
|
*
|
|
* History:
|
|
* Sat 19-Aug-1989 00:30:53 -by- Charles Whitmer [chuckwh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
DCMEMOBJ::~DCMEMOBJ()
|
|
{
|
|
if (pdc != (PDC) NULL)
|
|
{
|
|
if (bKeep)
|
|
{
|
|
DEC_EXCLUSIVE_REF_CNT(pdc);
|
|
}
|
|
else
|
|
{
|
|
if (pdc->pDCAttr != &pdc->dcattr)
|
|
{
|
|
RIP("ERROR,~DCMEMOBJ on DC with client attrs\n");
|
|
}
|
|
|
|
//
|
|
// shouldn't free DC with client attrs
|
|
//
|
|
|
|
HmgFree((HOBJ)pdc->hGet());
|
|
}
|
|
|
|
pdc = (PDC) NULL;
|
|
}
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DC::vUpdate_VisRect
|
|
*
|
|
* update user-mode vis region bounding rectangle if dirty
|
|
*
|
|
* History:
|
|
* 2/18/99 LingyunW [Lingyun Wang]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
VOID DC::vUpdate_VisRect(REGION *prgn)
|
|
{
|
|
//
|
|
// update user-mode vis region bounding rectangle if dirty
|
|
//
|
|
if ((PENTRY_FROM_POBJ(this)->Flags & HMGR_ENTRY_INVALID_VIS))
|
|
{
|
|
|
|
if (prgn)
|
|
{
|
|
|
|
//
|
|
// setup user-mode region info
|
|
//
|
|
|
|
RGNOBJ roVis(prgn);
|
|
|
|
pDCAttr->VisRectRegion.Flags = roVis.iComplexity();
|
|
|
|
|
|
if (roVis.iComplexity() == NULLREGION)
|
|
{
|
|
//
|
|
// set pdcatrr vis rgn to NULLRGN
|
|
//
|
|
|
|
pDCAttr->VisRectRegion.Rect = rclEmpty;
|
|
|
|
}
|
|
else
|
|
{
|
|
PPOINTL pptlWindow = (PPOINTL)prclWindow();
|
|
|
|
RECTL rcl;
|
|
|
|
roVis.vGet_rcl(&rcl);
|
|
|
|
//
|
|
// subtract window offset from user-mode region
|
|
//
|
|
|
|
rcl.left -= pptlWindow->x;
|
|
rcl.top -= pptlWindow->y;
|
|
rcl.right -= pptlWindow->x;
|
|
rcl.bottom -= pptlWindow->y;
|
|
|
|
pDCAttr->VisRectRegion.Rect = rcl;
|
|
}
|
|
|
|
//
|
|
// mark DCATTR VIS region as valid
|
|
//
|
|
|
|
}
|
|
else
|
|
{
|
|
pDCAttr->VisRectRegion.Rect = rclEmpty;
|
|
|
|
}
|
|
PENTRY_FROM_POBJ(this)->Flags &= ~HMGR_ENTRY_INVALID_VIS;
|
|
|
|
}
|
|
}
|
|
/******************************Public*Routine******************************\
|
|
* DCREGION::bSetDefaultRegion(x, y)
|
|
*
|
|
* Set the default region and erclWindow for bitmaps and surfaces
|
|
*
|
|
* History:
|
|
* 11-Dec-1990 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL DC::bSetDefaultRegion()
|
|
{
|
|
// Release the old RaoRgn
|
|
|
|
vReleaseRao();
|
|
|
|
// Get the extents
|
|
|
|
SIZEL sizl;
|
|
|
|
vGet_sizlWindow(&sizl);
|
|
|
|
// Get a rectangle matching the device extents
|
|
|
|
ERECTL ercl(0, 0, sizl.cx, sizl.cy);
|
|
|
|
//
|
|
// Bug #310012: Under multimon, the rectangle isn't necessarily
|
|
// based at 0,0. See dcrgn.cxx.
|
|
//
|
|
|
|
ERECTL erclSurface = ercl;
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
ASSERTGDI(pdo.bValid(), "Invalid pdev\n");
|
|
{
|
|
DEVLOCKOBJ dl(pdo);
|
|
if (pdo.bMetaDriver() && bHasSurface() && pSurface()->bPDEVSurface())
|
|
{
|
|
erclSurface += *pdo.pptlOrigin();
|
|
}
|
|
}
|
|
|
|
// If a VisRgn exists, initialize it, else create a new one
|
|
|
|
if ((prgnVis() != (REGION *) NULL) &&
|
|
(prgnVis() != prgnDefault))
|
|
{
|
|
RGNOBJ ro(prgnVis());
|
|
|
|
ro.vSet((RECTL *) &erclSurface);
|
|
}
|
|
else
|
|
{
|
|
RGNMEMOBJ rmoRect;
|
|
|
|
if (!rmoRect.bValid())
|
|
{
|
|
prgnVis(prgnDefault);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Set the region to the rectangle
|
|
|
|
rmoRect.vSet((RECTL *) &erclSurface);
|
|
|
|
// Make it long lived
|
|
|
|
prgnVis(rmoRect.prgnGet());
|
|
}
|
|
prgnVis()->vStamp();
|
|
|
|
eptlOrigin((EPOINTL*) &ercl);
|
|
|
|
//
|
|
// Note that we don't use erclSurface to set erclWindow.
|
|
// erclWindow's value is a complete hack, and User won't fix it.
|
|
// Their code requires that the top left point of erclWindow is equal
|
|
// to the DC origin. On top of that, they overload the DC origin: e.g. in a
|
|
// monitor-specific DC for an 800x600 monitor
|
|
// based at (1024,0), erclWindow is (-1024, 0, -224, 600). Go figure.
|
|
//
|
|
erclWindow(&ercl);
|
|
|
|
erclClip(&erclSurface);
|
|
|
|
// Whenever DC origin changes, it affects ptlFillOrigin. Since the origin
|
|
// was set to zero, we can just copy the brush origin in as the fill origin.
|
|
|
|
// set by user using a DC not owned by the current process
|
|
|
|
ptlFillOrigin(&dcattr.ptlBrushOrigin);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* BOOL DCPATH::bOldPenNominal(exo, lPenWidth)
|
|
*
|
|
* Decides if the old-style (created with CreatePen) pen is a nominal
|
|
* width pen or a wide line, depending on the current transform.
|
|
*
|
|
* History:
|
|
* 27-Jan-1992 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#define FX_THREE_HALVES (LTOFX(1) + (LTOFX(1) >> 1))
|
|
#define FX_THREE_HALVES_SQUARED (FX_THREE_HALVES * FX_THREE_HALVES)
|
|
|
|
BOOL DC::bOldPenNominal(
|
|
EXFORMOBJ& exo, // Current world-to-device transform
|
|
LONG lPenWidth) // Pen's width
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if (!(pDCAttr->flXform & WORLD_TRANSFORM_SET))
|
|
{
|
|
// If no world transform set, use the same criteria as does Win3 (namely,
|
|
// the pen is nominal if the transformed x-value is less than 1.5)
|
|
|
|
EVECTORL evtl(lPenWidth, 0);
|
|
|
|
if (exo.bXform(&evtl, (PVECTORFX) &evtl, 1))
|
|
if (ABS(evtl.x) < FX_THREE_HALVES)
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// A world transform has been set.
|
|
|
|
VECTORL avtl[2];
|
|
|
|
avtl[0].x = lPenWidth;
|
|
avtl[0].y = 0;
|
|
avtl[1].x = 0;
|
|
avtl[1].y = lPenWidth;
|
|
|
|
// We want to be consistent under rotation when using the
|
|
// intellectually challenged CreatePen pens, so we go to the trouble
|
|
// of ensuring that the transformed axes of the pen lie within
|
|
// a circle of radius 1.5:
|
|
|
|
if (exo.bXform(avtl, (PVECTORFX) avtl, 2))
|
|
{
|
|
// We can kick out most pens with this simple test:
|
|
|
|
if ((MAX(ABS(avtl[0].x), ABS(avtl[0].y)) < FX_THREE_HALVES) &&
|
|
(MAX(ABS(avtl[1].x), ABS(avtl[1].y)) < FX_THREE_HALVES))
|
|
|
|
// We now know it's safe to compute the square of the
|
|
// Euclidean lengths in 32-bits without overflow:
|
|
|
|
if (((avtl[0].x * avtl[0].x + avtl[0].y * avtl[0].y)
|
|
< FX_THREE_HALVES_SQUARED) &&
|
|
((avtl[1].x * avtl[1].x + avtl[1].y * avtl[1].y)
|
|
< FX_THREE_HALVES_SQUARED))
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DC::vRealizeLineAttrs(exo)
|
|
*
|
|
* Initializes the given LINEATTRS structure. Uses fields from the DC
|
|
* and the current brush.
|
|
*
|
|
* This function will be called as a result of a change in current pen,
|
|
* or a change in current transform. As a result, we reset the style
|
|
* state.
|
|
*
|
|
* History:
|
|
* 23-Sep-1992 -by- Donald Sidoroff [donalds]
|
|
* Added failure case
|
|
*
|
|
* 27-Jan-1992 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID DC::vRealizeLineAttrs(EXFORMOBJ& exo)
|
|
{
|
|
PPEN ppen = (PPEN) dclevel.pbrLine;
|
|
|
|
LINEATTRS *pla = &dclevel.laPath;
|
|
|
|
// Remember that we've realized the LINEATTRS for this pen:
|
|
|
|
if (ppen->bIsOldStylePen())
|
|
{
|
|
// A pen of width zero is always nominal, regardless of the transform:
|
|
|
|
if ((exo.bIdentity() && ppen->lWidthPen() <= 1) ||
|
|
(ppen->lWidthPen() == 0) ||
|
|
bOldPenNominal(exo, ppen->lWidthPen()))
|
|
{
|
|
pla->elWidth.l = 1; // Nominal width line
|
|
if (ppen->pstyle() != (PFLOAT_LONG) NULL)
|
|
{
|
|
pla->cstyle = ppen->cstyle(); // Size of style array
|
|
pla->pstyle = ppen->pstyle();
|
|
pla->fl = LA_STYLED; // Cosmetic, styled
|
|
}
|
|
else
|
|
{
|
|
pla->cstyle = 0;
|
|
pla->pstyle = (PFLOAT_LONG) NULL;
|
|
pla->fl = 0; // Cosmetic, no style
|
|
}
|
|
pla->elStyleState.l = 0; // Reset style state
|
|
}
|
|
else
|
|
{
|
|
pla->fl = LA_GEOMETRIC; // Geometric
|
|
pla->elWidth.e = ppen->l_eWidthPen(); // Need float value of width
|
|
pla->cstyle = 0;
|
|
pla->pstyle = (PFLOAT_LONG) NULL; // Old wide pens are un-styled
|
|
pla->elStyleState.e = IEEE_0_0F;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// New-style ExtCreatePen pen:
|
|
|
|
if (ppen->bIsCosmetic())
|
|
{
|
|
pla->fl = ppen->bIsAlternate() ? LA_ALTERNATE : 0;
|
|
pla->elWidth.l = ppen->lWidthPen();
|
|
pla->elStyleState.l = 0;
|
|
}
|
|
else
|
|
{
|
|
pla->fl = LA_GEOMETRIC;
|
|
pla->elWidth.e = ppen->l_eWidthPen();
|
|
pla->elStyleState.e = IEEE_0_0F;
|
|
}
|
|
|
|
pla->cstyle = ppen->cstyle();
|
|
pla->pstyle = ppen->pstyle();
|
|
if (pla->pstyle != NULL)
|
|
{
|
|
pla->fl |= LA_STYLED;
|
|
}
|
|
}
|
|
|
|
pla->iJoin = ppen->iJoin();
|
|
pla->iEndCap = ppen->iEndCap();
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID DCOBJ::vAccumulate(ercl)
|
|
*
|
|
* Accumulate bounds
|
|
*
|
|
* History:
|
|
* 08-Dec-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID XDCOBJ::vAccumulate(ERECTL& ercl)
|
|
{
|
|
if (bAccum())
|
|
{
|
|
erclBounds() |= ercl;
|
|
}
|
|
|
|
if (bAccumApp())
|
|
{
|
|
erclBoundsApp() |= ercl;
|
|
}
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DC::bMakeInfoDC
|
|
*
|
|
* This routine is used to take a printer DC and temporarily make it a
|
|
* Metafile DC for spooled printing. This way it can be associated with
|
|
* an enhanced metafile. During this period, it should look and act just
|
|
* like an info DC.
|
|
*
|
|
* bSet determines if it should be set into the INFO DC state or restored
|
|
* to the Direct state.
|
|
*
|
|
* History:
|
|
* 06-Jan-1995 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL DC::bMakeInfoDC(
|
|
BOOL bSet)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
if (!bDisplay())
|
|
{
|
|
if (bSet)
|
|
{
|
|
if (!bTempInfoDC() && (dctp() == DCTYPE_DIRECT))
|
|
{
|
|
vSetTempInfoDC();
|
|
dctp(DCTYPE_INFO);
|
|
vSavePsurfInfo();
|
|
|
|
// now that this is an info dc, we want it to be the size of
|
|
// the entire surface
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
|
|
if ((pdo.sizl().cx != sizl().cx) ||
|
|
(pdo.sizl().cy != sizl().cy))
|
|
{
|
|
sizl(pdo.sizl());
|
|
bSetDefaultRegion();
|
|
}
|
|
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
WARNING("GreMakeInfoDC(TRUE) - already infoDC\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (bTempInfoDC() && (dctp() == DCTYPE_INFO))
|
|
{
|
|
vClearTempInfoDC();
|
|
dctp(DCTYPE_DIRECT);
|
|
vRestorePsurfInfo();
|
|
|
|
// back to an direct DC. It needs to be reset to the size of
|
|
// the surface. (band)
|
|
|
|
if (bHasSurface())
|
|
{
|
|
if ((pSurface()->sizl().cx != sizl().cx) ||
|
|
(pSurface()->sizl().cy != sizl().cy))
|
|
{
|
|
sizl(pSurface()->sizl());
|
|
bSetDefaultRegion();
|
|
}
|
|
}
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
WARNING("GreMakeInfoDC(FALSE) - not infoDC\n");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("GreMakeInfoDC - on display dc\n");
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/******************************Member*Function*****************************\
|
|
* DC::vAssertDynaLock()
|
|
*
|
|
* This routine verifies that appropriate locks are held before accessing
|
|
* DC fields that may otherwise be changed asynchronously by the dynamic
|
|
* mode-change code.
|
|
*
|
|
* History:
|
|
* 06-Feb-1996 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#if DBG
|
|
|
|
VOID DC::vAssertDynaLock(BOOL bDcLevelField)
|
|
{
|
|
//
|
|
// One of the following conditions is enough to allow the thread
|
|
// to safely access fields that may be modified by the dyanmic
|
|
// mode changing:
|
|
//
|
|
// 1. It's an info DC, or a DC with the default bitmap selected in --
|
|
// these will not change modes;
|
|
// 2. It's a DCLEVEL specific field and a DIB is selected in that
|
|
// doesn't require DevLock locking;
|
|
// 3. Direct DC's that aren't the display, such as printers --
|
|
// these will not dynamically change modes;
|
|
// 4. That the DEVLOCK is held;
|
|
// 5. That the Palette semaphore is held;
|
|
// 6. That the Handle Manager semaphore is held;
|
|
// 7. That the USER semaphore is held.
|
|
//
|
|
|
|
#if !defined(_GDIPLUS_)
|
|
|
|
ASSERTGDI(!bHasSurface() ||
|
|
((bDcLevelField) && !(fs() & DC_SYNCHRONIZEACCESS)) ||
|
|
((dctp() == DCTYPE_DIRECT) && !bDisplay()) ||
|
|
(GreIsSemaphoreOwnedByCurrentThread(hsemDcDevLock_)) ||
|
|
(GreIsSemaphoreSharedByCurrentThread(ghsemShareDevLock)) ||
|
|
(GreIsSemaphoreOwnedByCurrentThread(ghsemPalette)) ||
|
|
(GreIsSemaphoreOwnedByCurrentThread(ghsemHmgr)) ||
|
|
UserIsUserCritSecIn(),
|
|
"A dynamic mode change lock must be held to access this field");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|