|
|
/******************************Module*Header*******************************\
* Module Name: brush.hxx * * This contains the prototypes and constants for the brush class. * * Created: 20-May-1991 17:01:25 * Author: Patrick Haluptzok patrickh * * Copyright (c) 1990-1999 Microsoft Corporation \**************************************************************************/
#ifndef _BRUSH_HXX
// The following flags are for the fl field of the BRUSH class
//
// The BR_NEED_ flags are used to flag which colors are needed for the
// physical realization of the brush.
#define BR_NEED_FG_CLR 0x00000001L
#define BR_NEED_BK_CLR 0x00000002L
#define BR_DITHER_OK 0x00000004L
// The BR_IS_ flags just tell us what type of brush was created.
#define BR_IS_SOLID 0x00000010L
#define BR_IS_HATCH 0x00000020L
#define BR_IS_BITMAP 0x00000040L
#define BR_IS_DIB 0x00000080L
#define BR_IS_NULL 0x00000100L
#define BR_IS_GLOBAL 0x00000200L
#define BR_IS_PEN 0x00000400L
#define BR_IS_OLDSTYLEPEN 0x00000800L
#define BR_IS_DIBPALCOLORS 0x00001000L
#define BR_IS_DIBPALINDICES 0x00002000L
#define BR_IS_DEFAULTSTYLE 0x00004000L
#define BR_IS_MASKING 0x00008000L
#define BR_IS_INSIDEFRAME 0x00010000L
#define BR_IS_MONOCHROME 0x00020000L
#define BR_IS_FIXEDSTOCK 0x00040000L
#define BR_IS_MAKENONSTOCK 0x00080000L
// This is for determining what's cached
#define BR_CACHED_ENGINE 0x40000000L
#define BR_CACHED_IS_SOLID 0x80000000L
// define HS_HORIZONTAL 0 /* ----- */
// define HS_VERTICAL 1 /* ||||| */
// define HS_FDIAGONAL 2 /* \\\\\ */
// define HS_BDIAGONAL 3 /* ///// */
// define HS_CROSS 4 /* +++++ */
// define HS_DIAGCROSS 5 /* xxxxx */
// define HS_SOLIDCLR 6 Color as passed in
// define HS_DITHEREDCLR 7 Color as passed in, can dither
// define HS_SOLIDTEXTCLR 8 Color of foreground
// define HS_DITHEREDTEXTCLR 9 Color of foreground, can dither
// define HS_SOLIDBKCLR 10 Color of background
// define HS_DITHEREDBKCLR 11 Color of background, can dither
// define HS_API_MAX 12
#define HS_NULL (HS_API_MAX)
#define HS_PAT (HS_API_MAX + 1)
#define HS_MSK (HS_API_MAX + 2)
#define HS_PATMSK (HS_API_MAX + 3)
#define HS_STYLE_MAX (HS_API_MAX + 4)
// Indicates whether the realization being sought in the cache in the logical
// brush is an engine or driver realization
#define CR_DRIVER_REALIZATION 0
#define CR_ENGINE_REALIZATION 1
#ifndef GDIFLAGS_ONLY // used for gdikdx
typedef struct _ICM_DIB_LIST { HANDLE hcmXform; HBITMAP hDIB; struct _ICM_DIB_LIST *pNext; }ICM_DIB_LIST,*PICM_DIB_LIST;
/*********************************Class************************************\
* class BRUSH * * Base class for brushes * * History: * 30-Oct-1992 -by- Michael Abrash [mikeab] * Added caching of the first realization in the logical brush. * * Mon 02-Mar-1992 -by- Patrick Haluptzok [patrickh] * Vastly simplified, remove most fields, rework logic. * * Thu 27-Jun-1991 -by- Patrick Haluptzok [patrickh] * Remove reference counting * * Fri 17-May-1991 -by- Patrick Haluptzok [patrickh] * Lot's of changes * * Sun 02-Dec-1990 21:59:00 -by- Walt Moore [waltm] * Initial version. \**************************************************************************/
// A brush maintains the original information passed to the create call
// necesary for physical realization.
//
// crColor This is the color passed to the create function.
//
// ulStyle This is the style of brush.
//
//
// The following fields are required for the physical realization of the
// brush, and caching those realizations.
//
// hsurf Either a clone of hsurfOrig, or a bitmap created with the
// DIB information passed to us.
//
// flAttrs Various flags previously defined.
class BRUSH: public OBJECT /* br */ { public:
// Uniqueness so a logical handle can be reused without having it look like
// the same brush as before. We don't really care where this starts.
static ULONG _ulGlobalBrushUnique;
// Uniqueness for the current brush, to tell it apart from other brushes
// when we do the are-you-really-dirty check at the start of vInitBrush.
ULONG _ulStyle; // style of brush
HBITMAP _hbmPattern; // cloned DIB for brush
HBITMAP _hbmClient; // client handle passed in
FLONG _flAttrs; // Flags as defined above
ULONG _ulBrushUnique;
PBRUSHATTR _pBrushattr;
// ULONG AttrFlags;
// COLORREF lbColor;
BRUSHATTR _Brushattr;
ULONG _iUsage; // iUsage brush created with
PICM_DIB_LIST _pIcmDIBList; // DIB brushes only:
// If ICM is enabled for a DC this
// brush is selected into, then a
// copy of the DIB must be made
// corrected to the DCs color space.
//
//
// Caching info (we cache the first realization in the logical brush).
//
BOOL _bCacheGrabbed; // FALSE if it's okay to cache a realization in
// this brush, TRUE if it's too late (some other
// realization has been cached or is in the
// process of being cached). Must be set with
// InterlockedExchange. Note that this does not
// mean that the cache ID data is actually set and
// ready to use yet; check for that via psoTarg1,
// which is NULL until all the cache data is ready
// to be used
COLORREF _crFore; // foreground color when cached realization created
// set to BO_NOTCACHED initially, when the logical
// brush is created; set to its proper value only
// after all other cache IDs have been set
COLORREF _crBack; // background color when cached realization created
ULONG _ulPalTime; // DC logical palette sequence # at cached creation
ULONG _ulSurfTime; // surface palette sequence # when cached created
ULONG_PTR _ulRealization; // if solid brush, the cached realized index;
// otherwise, pointer to DBRUSH
HDEV _hdevRealization; // hdev owner of DBRUSH
// (if ulRealization points DBRUSH)
COLORREF _crPalColor; // Quantaized color through DC palette
public: // Our information for the brush.
//
// ICM (Image Color Matching)
//
BOOL bAddIcmDIB(HANDLE hcmXform,HBITMAP hDIB); VOID vDeleteIcmDIBs(VOID); HBITMAP hFindIcmDIB(HANDLE hcmXform);
VOID pIcmDIBList(PICM_DIB_LIST _pidl) {_pIcmDIBList = _pidl;} PICM_DIB_LIST pIcmDIBList() { return(_pIcmDIBList); }
ULONG ulGlobalBrushUnique() { return(ulGetNewUniqueness(_ulGlobalBrushUnique)); }
ULONG iUsage() {return(_iUsage);} VOID iUsage(ULONG ul) {_iUsage = ul;}
//
// kernel uniqie
//
ULONG ulBrushUnique() { return(_ulBrushUnique); }
ULONG ulBrushUnique(ULONG ulNewUnique) { return(_ulBrushUnique = ulNewUnique); }
//
// user unique
//
BOOL bCachedIsSolid() { return(_flAttrs & BR_CACHED_IS_SOLID); } BOOL bIsEngine() { return(_flAttrs & BR_CACHED_ENGINE); } VOID vSetNotCached() { _bCacheGrabbed = FALSE; } BOOL bGrabCache() { return(InterlockedExchange((LPLONG)&_bCacheGrabbed, TRUE) == FALSE); } BOOL bCacheGrabbed() { return(_bCacheGrabbed); } COLORREF crFore() { return(_crFore); } COLORREF crBack() { return(_crBack); } ULONG ulPalTime() { return(_ulPalTime); } ULONG ulSurfTime() { return(_ulSurfTime); } ULONG_PTR ulRealization() { return(_ulRealization); } HDEV hdevRealization() { return(_hdevRealization); } COLORREF crPalColor() { return(_crPalColor); } VOID SetEngineRealization() { _flAttrs |= BR_CACHED_ENGINE; } VOID SetDriverRealization() { _flAttrs &= ~BR_CACHED_ENGINE; } VOID SetSolidRealization() { _flAttrs |= BR_CACHED_IS_SOLID; } VOID vClearSolidRealization(){ _flAttrs &= ~BR_CACHED_IS_SOLID; } BOOL bCareAboutFg() { return(_flAttrs & BR_NEED_FG_CLR); } BOOL bCareAboutBg() { return(_flAttrs & BR_NEED_BK_CLR); }
//
// The following fields should only be set as part of setting up the cache
// fields, and there we need to know that crFore1 is set last, for
// synchronization purposes; that's why we use InterlockedExchange(). Here's
// the exact mechanism:
// 1) When the logical brush is created, bCacheGrabbed1 is set to FALSE, and
// crFore is set to BO_NOTCACHED. Threads check for a cached realization by
// seeing if crFore is BO_NOTCACHED; if it is, there's no cached realization,
// else it contains the foreground color, and the other cache ID fields are
// all set. (Actually, they just see if crFore matches first, which can only
// happen when crFore != BO_NOTCACHED.)
// 2) When a thread finds crFore is BO_NOTCACHED, it realizes the brush, then
// checks whether bCacheGrabbed1 is FALSE. If not, caching has already
// happened. If it is FALSE, the thread attempts to grab bCacheGrabbed1 via
// InterlockedExchange(). If this succeeds (bCacheGrabbed1 was still FALSE),
// then the thread sets the cache ID fields, and then sets crFore to its
// new, cached value last via InterlockedExchange() (so that crFore is set
// after all the cache ID fields). At this point, other threads can use the
// cached realization.
// Note that only the first realization for any given logical brush is cached.
//
COLORREF crFore(COLORREF cr) { return(_crFore = cr); } COLORREF crForeLocked(COLORREF cr) { return((COLORREF)InterlockedExchange((LONG *)&_crFore, (LONG)cr)); } COLORREF crBack(COLORREF cr) { return(_crBack = cr); } ULONG ulPalTime(ULONG ul) { return(_ulPalTime = ul); } ULONG ulSurfTime(ULONG ul) { return(_ulSurfTime = ul); } ULONG_PTR ulRealization(ULONG_PTR ul) { return(_ulRealization = ul); } HDEV hdevRealization(HDEV hdev) { return(_hdevRealization = hdev); } COLORREF crPalColor(COLORREF cr) { return(_crPalColor = cr); }
HBRUSH hbrush() { return((HBRUSH)hGet()); } FLONG flAttrs() { return(_flAttrs); } FLONG flAttrs(FLONG flNew) { return(_flAttrs = flNew); } PBRUSHATTR pBrushattr (PBRUSHATTR p) {return(_pBrushattr = p);} PBRUSHATTR pBrushattr () {return(_pBrushattr);} HBITMAP hbmPattern() { return(_hbmPattern); } HBITMAP hbmPattern(HBITMAP hbrNew) { return((_hbmPattern = hbrNew)); } HBITMAP hbmClient() { return(_hbmClient); } HBITMAP hbmClient(HBITMAP hbrNew) { return((_hbmClient = hbrNew)); } ULONG ulStyle(ULONG ulNew) { return(_ulStyle = ulNew); } ULONG ulStyle() { return(_ulStyle); }
//
// crColor uses the lbcolor in the Brushattr part of this structure
// because (hungapp) calls this routine from a different process than
// the brush was created in and this cannot reference user-mode
// fields. Brushattr is kept up to date by SetSolidColor(Light)
//
ULONG crColor() { return((ULONG)(_Brushattr.lbColor)); } COLORREF crColor(COLORREF crNew) { return(_Brushattr.lbColor = (COLORREF)crNew); }
ULONG AttrFlags(ULONG ul) {return(_pBrushattr->AttrFlags=ul);} ULONG AttrFlags() {return(_pBrushattr->AttrFlags);} BOOL bIsPen() { return(_flAttrs & BR_IS_PEN); } BOOL bIsNull() { return(_flAttrs & BR_IS_NULL); } BOOL bIsGlobal() { return(_flAttrs & BR_IS_GLOBAL); } BOOL bPalColors() { return(_flAttrs & BR_IS_DIBPALCOLORS); } BOOL bPalIndices() { return(_flAttrs & BR_IS_DIBPALINDICES); } BOOL bNeedFore() { return(_flAttrs & BR_NEED_FG_CLR); } BOOL bNeedBack() { return(_flAttrs & BR_NEED_BK_CLR); } BOOL bIsMasking() { return(_flAttrs & BR_IS_MASKING); }
BOOL bCanDither() { return(_flAttrs & BR_DITHER_OK); } BOOL bIsFixedStock() { return(_flAttrs & BR_IS_FIXEDSTOCK); } BOOL bIsMakeNonStock() { return(_flAttrs & BR_IS_MAKENONSTOCK); } VOID vEnableDither() { _flAttrs |= BR_DITHER_OK; } VOID vDisableDither() { _flAttrs &= ~BR_DITHER_OK; }
VOID vSetMakeNonStock() { _flAttrs |= BR_IS_MAKENONSTOCK; } VOID vClearMakeNonStock(){ _flAttrs &= ~BR_IS_MAKENONSTOCK; }
};
//
// This value is never a valid value for crFore1, so we use it to indicate
// whether the cached data is valid yet, as described above.
//
#define BO_NOTCACHED ((COLORREF)-1)
/*********************************Class************************************\
* class PEN * * Base class for pens. * * History: * 3-Feb-1992 -by- J. Andrew Goossen [andrewgo] * Wrote it. \**************************************************************************/
class PEN: public BRUSH /* pen */ { private: LONG _lWidth; // Width passed in at API
FLOATL _l_eWidth; // Width for geometric lines
FLONG _flStylePen; // Pen style passed in at API
PFLOAT_LONG _pstyle; // Pointer to style array
ULONG _cstyle; // Size of style array
BYTE _iJoin; // Join style for geometric lines
BYTE _iEndCap; // End cap style for geometric lines
LONG _lBrushStyle; // lbstyle
ULONG_PTR _lHatch; // lbHatch
public:
//
// Pen attributes:
//
PFLOAT_LONG pstyle() { return(_pstyle); } ULONG cstyle() { return(_cstyle); } LONG lWidthPen() { return(_lWidth); } FLOATL l_eWidthPen() { return(_l_eWidth); } ULONG iEndCap() { return((ULONG) _iEndCap); } ULONG iJoin() { return((ULONG) _iJoin); } FLONG flStylePen() { return(_flStylePen); } BOOL bIsGeometric() { return((_flStylePen & PS_TYPE_MASK) == PS_GEOMETRIC); } BOOL bIsCosmetic() { return((_flStylePen & PS_TYPE_MASK) == PS_COSMETIC); } BOOL bIsAlternate() { return((_flStylePen & PS_STYLE_MASK) == PS_ALTERNATE); } BOOL bIsUserStyled() { return((_flStylePen & PS_STYLE_MASK) == PS_USERSTYLE); } BOOL bIsInsideFrame() { return(flAttrs() & BR_IS_INSIDEFRAME); } BOOL bIsOldStylePen() { return(flAttrs() & BR_IS_OLDSTYLEPEN); } BOOL bIsDefaultStyle() { return(flAttrs() & BR_IS_DEFAULTSTYLE); }
LONG lBrushStyle() { return(_lBrushStyle);} ULONG_PTR lHatch() { return(_lHatch);}
// Set pen attributes:
VOID vSetDefaultStyle() { flAttrs(flAttrs() | BR_IS_DEFAULTSTYLE); } VOID vSetInsideFrame() { flAttrs(flAttrs() | BR_IS_INSIDEFRAME); } VOID vSetPen() { flAttrs(flAttrs() | BR_IS_PEN); }
VOID vSetOldStylePen() { flAttrs(flAttrs() | (BR_IS_OLDSTYLEPEN | BR_IS_PEN)); }
LONG lWidthPen(LONG l) { return(_lWidth = l); } FLOATL l_eWidthPen(FLOATL e){ return(_l_eWidth = e); } FLONG flStylePen(FLONG fl) { return(_flStylePen = fl); } ULONG iEndCap(ULONG ii) { return(_iEndCap = (BYTE) ii); } ULONG iJoin(ULONG ii) { return(_iJoin = (BYTE) ii); } ULONG cstyle(ULONG c) { return(_cstyle = c); } PFLOAT_LONG pstyle(PFLOAT_LONG pel) { return(_pstyle = pel); }
LONG lBrushStyle(LONG l) { return(_lBrushStyle=l);} ULONG_PTR lHatch(ULONG_PTR l) { return(_lHatch=l);}
};
typedef BRUSH *PBRUSH; typedef PEN *PPEN;
typedef union _PBRUSHPEN /* pbp */ { BRUSH *pbr; PEN *ppen; } PBRUSHPEN;
#define PBRUSHNULL ((PBRUSH) NULL)
BOOL bDeleteBrush(HBRUSH,BOOL);
BOOL bSyncBrushObj( PBRUSH pbrush);
//
// foreward reference
//
class DC; typedef DC *PDC;
BOOL GreSetSolidBrushInternal(HBRUSH,COLORREF,BOOL,BOOL);
BOOL GreSetSolidBrushLight(PBRUSH,COLORREF,BOOL); HBRUSH GreDCSelectBrush(PDC,HBRUSH); HPEN GreDCSelectPen(PDC,HPEN); BOOL bSyncDCBrush (PDC pdc); BOOL bSyncBrush(HBRUSH hbr);
/*********************************Class************************************\
* class RBRUSH * * Base class for brush realizations. * This is the class that ENGBRUSH and DBRUSH are derived from; this is so we * can access the reference count field without knowing with which type of * brush realization we're dealing * * History: * 1-Nov-1993 -by- Michael Abrash [mikeab] * Wrote it. \**************************************************************************/
// RBRUSH type: engine or driver
typedef enum { RB_DRIVER = 0, RB_ENGINE } RBTYPE;
// Forward reference
class RBRUSH;
typedef RBRUSH *PRBRUSH;
// Global pointer to the last DBRUSH and ENGBRUSH freed, if any (for one-deep
// caching).
extern PRBRUSH gpCachedDbrush; extern PRBRUSH gpCachedEngbrush;
class RBRUSH { private: LONG cRef1; // # of places this realization is in use (when this goes
// to 0, the realization is deleted, because at that point
// it is no longer selected into any DC, and the logical
// brush it's cached in, if any, has been deleted)
ULONG ulSize; // # of bytes allocated for the realization in this brush
BOOL _bMultiBrush; // was this realization created by the DDML?
BOOL _bUMPDRBrush; // is this a realization created by user mode printer driver?
public: LONG cRef(const LONG lval) { return(cRef1 = lval); }
// The following bMultiBrush() methods are only valid for DBRUSHES
BOOL bMultiBrush() { return(_bMultiBrush); } BOOL bMultiBrush(BOOL bval) { return(_bMultiBrush = bval); }
BOOL bUMPDRBrush() { return(_bUMPDRBrush); } BOOL bUMPDRBrush(BOOL bval) { return(_bUMPDRBrush = bval); }
ULONG ulSizeGet() { return(ulSize); }
ULONG ulSizeSet(const ULONG ulNewSize) { return(ulSize = ulNewSize); }
VOID vAddRef() { InterlockedIncrement((LPLONG)&cRef1); }
VOID vFreeOrCacheRBrush(RBTYPE rbtype); VOID vRemoveRef(RBTYPE rbtype) { #if DBG
LONG l; if ((l = InterlockedDecrement((LPLONG)&cRef1)) == 0) #else
if (InterlockedDecrement((LPLONG)&cRef1) == 0) #endif
{ vFreeOrCacheRBrush(rbtype); } #if DBG
ASSERTGDI(l >= 0, "ERROR brush realization reference counted < 0"); #endif
} };
class ENGBRUSH : public RBRUSH { public: ULONG cxPatR; // Realized width of pattern
ULONG cxPat; // Actual width of pattern
ULONG cyPat; // Actual height of pattern
LONG lDeltaPat; // Offset to next scan of pattern
PBYTE pjPat; // Pointer to pattern data
ULONG cxMskR; // Realized width of mask
ULONG cxMsk; // Actual width of mask
ULONG cyMsk; // Actual height of mask
PBYTE pjMsk; // Offset to next scan of mask
LONG lDeltaMsk; // Pointer to mask data
ULONG iColorBack; // Background color
ULONG iDitherFormat; // Bitmap color depth
// Not so public
BYTE aj[4]; };
typedef ENGBRUSH *PENGBRUSH;
#endif // GDIFLAGS_ONLY used for gdikdx
#define _BRUSH_HXX
#endif
|