/******************************Module*Header*******************************\ * Module Name: pathobj.hxx * * Path user object * * Created: 28-Sep-1990 12:39:30 * Author: Paul Butzi [paulb] * * Copyright (c) 1990-1999 Microsoft Corporation \**************************************************************************/ #ifndef GDIFLAGS_ONLY // Some forward declarations to reduce included header files: class RGNOBJ; class WIDEPATHOBJ; class EDGE; typedef EDGE *PEDGE; // Some useful structures for statically initializing FLOAT_LONG and // LINEATTRS structures. The regular definitions can only be initialized // with floats because C only allows union initialization using the first // union field: typedef struct _LONGLINEATTRS { FLONG fl; ULONG iJoin; ULONG iEndCap; LONG_FLOAT leWidth; FLOATL l_eMiterLimit; ULONG cstyle; LONG_FLOAT* pstyle; LONG_FLOAT leStyleState; } LONGLINEATTRS; typedef union { LONGLINEATTRS lla; LINEATTRS la; } LA; extern LA glaSimpleStroke; /*********************************Class************************************\ * class PATHRECORD * * Public Interface: * * History: * 05-Sep-1990 -by- Paul Butzi [paulb] * Wrote it. \**************************************************************************/ /*************************************************************************** * The macro below makes sure that the next PATHRECORD lies on a good * boundary. This is only needed on some machines. For the x86 and MIPS * DWORD alignment of the structure suffices, so the macro below would only * waste RAM. (Save it for later reference.) * * #define NEXTPATHREC(ppr) (ppr + (offsetof(PATHRECORD, aptfx) + \ * sizeof(POINTFIX) * ppr->count + \ * sizeof(PATHRECORD) - 1) / sizeof(PATHRECORD)) ***************************************************************************/ #define NEXTPATHREC(ppr) ((PATHRECORD *) ((BYTE *) ppr + \ offsetof(PATHRECORD,aptfx) + \ sizeof(POINTFIX) * ppr->count)) struct _PATHRECORD { struct _PATHRECORD *pprnext; // ptr to next pathrec in path struct _PATHRECORD *pprprev; // ptr to previous pathrec in path FLONG flags; // flags describing content of record ULONG count; // number of control points in record POINTFIX aptfx[2]; // variable length array of points // (we make it size 2 because we'll actually // be declaring this structure on the // stack to handle a LineTo, which needs // two points) }; typedef struct _PATHRECORD PATHRECORD; typedef struct _PATHRECORD *PPATHREC; /*********************************Struct***********************************\ * struct PATHDATAL * * Used like a PATHDATA but describes POINTLs not POINTFIXs * * History: * 08-Nov-1990 -by- Paul Butzi [paulb] * Wrote it. \**************************************************************************/ struct _PATHDATAL { FLONG flags; ULONG count; PPOINTL pptl; }; typedef struct _PATHDATAL PATHDATAL; typedef struct _PATHDATAL *PPATHDATAL; /*********************************Class************************************\ * class PATHALLOC * * The storage for PATHRECs is allocated from the space inside PATHALLOCS. * The PATHALLOCS for a path are on a singly linked list. The two friend * functions newpathalloc() and freepathalloc() are used to allocate and * free pathalloc blocks. * * Public Interface: * * friend PATHALLOC *newpathalloc() // allocate a new pathalloc * friend void freepathalloc() // free a pathalloc * * History: * 05-Sep-1990 -by- Paul Butzi [paulb] * Wrote it. \**************************************************************************/ class PATHALLOC { static HSEMAPHORE hsemFreelist; // Semaphore for freelist static PATHALLOC *freelist; // Free-list of pathallocs static COUNT cFree; // Count of free pathallocs static COUNT cAllocated; // Count of pathallocs allocated public: PATHALLOC *ppanext; // ptr to next pathalloc in path PATHRECORD *pprfreestart; // ptr to first free spot in pathalloc ULONG siztPathAlloc; // Size of path alloc PATHRECORD apr[1]; // variable length array of pathrecs friend BOOL bInitPathAlloc(); // initialize the free list friend PATHALLOC *newpathalloc(); // allocate a new pathalloc friend VOID freepathalloc(PATHALLOC *); // free a pathalloc friend VOID vPathDebug(); // Displays debug stats #ifdef _HYDRA_ friend VOID MultiUserCleanupPathAlloc(); // cleanup memory #endif }; typedef PATHALLOC *PPATHALLOC; #endif // GDIFLAGS_ONLY for gdikdx #define PATHALLOCSIZE (4096-64) #define PATHALLOCTHRESHOLD 8 #define FREELIST_MAX 4 // These flags shouldn't interfere with any PD_ DDI flags: #define PATH_JOURNAL 0x8000 // Flags for flOptions in bStrokeAndOrFill: #define PATH_STROKE 1 #define PATH_FILL 2 // A private LINEATTRS flag to denote that the pen for a geometric line // may have zero dimensions. Set in the high word so as not to conflict // with the LA_ definitions in winddi.h: #define LA_ALLOW_ZERO_DIMENSIONS 0x10000L /*********************************Class************************************\ * class PATH * * Path structure itself. We never actually use objects of this type, * instead we use EPATHOBJ's which are derived from this type. * * History: * 05-Sep-1990 -by- Paul Butzi [paulb] * Wrote it. \**************************************************************************/ #define PATHTYPE_KEEPMEM 0x0001 #define PATHTYPE_STACK 0x0002 #ifndef GDIFLAGS_ONLY class PATH : public OBJECT { public: PATH() {} PATHALLOC *ppachain; // ptr to pathalloc chain PATHRECORD *pprfirst; // ptr to first record in path PATHRECORD *pprlast; // ptr to last record in path // rcfxBoundBox cannot be an ERECTFX because then CFront will insist // on creating a static constructor for PATH(): RECTFX rcfxBoundBox; // bounding box for path POINTFIX ptfxSubPathStart; // start of next sub-path FLONG flags; // flags describing state of path PATHRECORD *pprEnum; // pointer for Enumeration FLONG flType; // denotes path type (stack, mem, keep) FLONG fl; // These are used for saving the PATHOBJ ULONG cCurves; // accelerator values when the path is // unlocked. CLIPLINEENUM cle; // used for enumerating and clipping }; typedef PATH *PPATH; /*********************************Class************************************\ * class EPATHOBJ * * User object for PATH class that has no constructor or destructor. * * Public Interface: * * History: * 17-Oct-1992 -by- J. Andrew Goossen [andrewgo] * Moved the constructors and destructor to derived XEPATHOBJ. * * 05-Apr-1991 -by- Wendy Wu [wendywu] * Added bInitLines friend function and cTotalPts member function. * Put in filling support. * * 28-Sep-1990 -by- Paul Butzi [paulb] * Wrote it. \**************************************************************************/ class EPATHOBJ : public _PATHOBJ /* epo */ { private: friend VOID vConstructGET(EPATHOBJ& po, PEDGE pedgeHead, PEDGE pedgeFree,RECTL *pBound); public: PPATH ppath; protected: BOOL addpoints(EXFORMOBJ *pxfo, PATHDATAL *); VOID growlastrec(EXFORMOBJ *pxfo,PATHDATAL *,POINTFIX *); VOID reinit(); BOOL createrec(EXFORMOBJ *xfo,PATHDATAL *,POINTFIX *); BOOL newpathrec(PATHRECORD **pppr,COUNT *pcMax,COUNT cNeeded); PATHRECORD *pprFlattenRec(PATHRECORD *ppr); public: EPATHOBJ() {} CLIPOBJ *pco; // save the clipobj for enumeration PCLIPLINEENUM pcleGet() { return(&ppath->cle); } HPATH hpath() { return((HPATH) ppath->hGet()); } RECTFX rcfxBoundBox() { return(ppath->rcfxBoundBox); } BOOL bValid() { return(ppath != (PATH*) NULL); } // Path maintenance: VOID vLock(HPATH hpath) { ppath = (PPATH)HmgShareLock((HOBJ)hpath, PATH_TYPE); } VOID vDelete(); VOID vFreeBlocks(); BOOL bClone(EPATHOBJ& epo); ULONGSIZE_T cjSize(); VOID vUpdateCosmeticStyleState(SURFACE*, LINEATTRS*); // Methods to add world space data to a path: BOOL bMoveTo(EXFORMOBJ* pxfo, POINTL* pptl); BOOL bPolyLineTo(EXFORMOBJ* pxfo, POINTL* pptl, ULONG cPts); BOOL bPolyBezierTo(EXFORMOBJ* pxfo, POINTL* pptl, ULONG cPts); // Methods to add device space data to a path: BOOL bMoveTo(POINTFIX* pptfx) { return(bMoveTo((EXFORMOBJ*) NULL, (POINTL*) pptfx)); } BOOL bPolyLineTo(POINTFIX* pptfx, ULONG cPts) { return(bPolyLineTo((EXFORMOBJ*) NULL, (POINTL*) pptfx, cPts)); } BOOL bPolyBezierTo(POINTFIX* pptfx, ULONG cPts) { return(bPolyBezierTo((EXFORMOBJ*) NULL, (POINTL*) pptfx, cPts)); } BOOL bAppend(EPATHOBJ *ppoNew,POINTFIX *pptfxDelta); // Macro to add a polygon. BOOL bAddPolygon(EXFORMOBJ *pxo,POINTL *pptl,int c) { return(bMoveTo(pxo,pptl) && bPolyLineTo(pxo,pptl+1,c-1) && bCloseFigure()); } // Methods to transform or manipulate a path: VOID vOffset(EPOINTL &eptl); // Get path's current point, remembering that if the last path operation // was a bMoveTo, the CP value is retrieved from ptfxSubPathStart: POINTFIX ptfxGetCurrent() { return((ppath->flags & PD_BEGINSUBPATH) ? ppath->ptfxSubPathStart : ppath->pprlast->aptfx[(ppath->pprlast->count) - 1]); } BOOL bCloseFigure(); VOID vCloseAllFigures(); BOOL bFlatten(); // Output functions that do pointer exclusion, device locking, etc: BOOL bStrokeAndOrFill(XDCOBJ &dco, LINEATTRS *pla, EXFORMOBJ *pxfo, FLONG flOptions); BOOL bStrokeAndFill(XDCOBJ &dco, LINEATTRS *pla, EXFORMOBJ *pxfo) { return(bStrokeAndOrFill(dco, pla, pxfo, PATH_STROKE|PATH_FILL)); } BOOL bStroke(XDCOBJ &dco, LINEATTRS *pla, EXFORMOBJ *pxfo) { return(bStrokeAndOrFill(dco, pla, pxfo, PATH_STROKE)); } BOOL bFill(XDCOBJ &dco) { return(bStrokeAndOrFill(dco, (LINEATTRS*) NULL, (EXFORMOBJ*) NULL, PATH_FILL)); } // Output functions for when you've done all the setup work and you want // to take advantage of smart devices: BOOL bSimpleFill(FLONG,PDEVOBJ*,SURFACE*,CLIPOBJ*,BRUSHOBJ*,POINTL*,MIX,FLONG); BOOL bTextOutSimpleFill(XDCOBJ&,RFONTOBJ&,PDEVOBJ*,SURFACE*,CLIPOBJ*,BRUSHOBJ*,POINTL*,MIX,FLONG); BOOL bSimpleStroke(FLONG,PDEVOBJ*,SURFACE*,CLIPOBJ*,XFORMOBJ*,BRUSHOBJ*,POINTL*,LINEATTRS*,MIX); BOOL bSimpleStrokeAndFill(FLONG,PDEVOBJ*,SURFACE*,CLIPOBJ*, XFORMOBJ*,BRUSHOBJ*,LINEATTRS*, BRUSHOBJ*,POINTL*,MIX,FLONG); BOOL bSimpleStroke1(FLONG flCaps, // For device graphics caps PDEVOBJ* plo, SURFACE* pSurface, CLIPOBJ* pco, BRUSHOBJ* pbo, POINTL* pptlBrushOrg, MIX mix) { // Make a copy of the default LINEATTRS because the driver might // try to update the style state: LINEATTRS laTmp = glaSimpleStroke.la; return(bSimpleStroke(flCaps, plo, pSurface, pco, (XFORMOBJ*) NULL, pbo, pptlBrushOrg, &laTmp, mix)); } BOOL bTextOutSimpleStroke1(XDCOBJ& dco, RFONTOBJ& rfo, PDEVOBJ* plo, SURFACE* pSurface, CLIPOBJ* pco, BRUSHOBJ* pbo, POINTL* pptlBrushOrg, MIX mix); // Modification methods: VOID vBecome(WIDEPATHOBJ&); VOID vReComputeBounds(); BOOL bComputeWidenedBounds(EPATHOBJ&, XFORMOBJ*, LINEATTRS*); BOOL bComputeWidenedBounds(XFORMOBJ* pxfo, LINEATTRS* pla) { return(bComputeWidenedBounds(*this, pxfo, pla)); } BOOL bWiden(EPATHOBJ&, XFORMOBJ*, LINEATTRS*); BOOL bWiden(XFORMOBJ* pxfo, LINEATTRS* pla) { return(bWiden(*this, pxfo, pla)); } VOID vWidenSetupForFrameRgn(XDCOBJ&, LONG, LONG, EXFORMOBJ*, LINEATTRS*); // Methods to enumerate a path VOID vEnumStart() { fl &= ~PO_ENUM_AS_INTEGERS; // A driver may have left this set ppath->pprEnum = ppath->pprfirst; } BOOL bEnum(PATHDATA *); BOOL bBeziers() { return(fl & PO_BEZIERS); } ULONG cTotalPts(); ULONG cTotalCurves(); // For persistent path objects: VOID vSetppath(PPATH ppath_) { ppath = ppath_; } // Debug routines: BOOL bAllClosed(); VOID vPrint(); VOID vDiag(); }; /*********************************Class************************************\ * class XEPATHOBJ * * User object for PATH class that has constructors and a destructor. * * Public Interface: * * History: * 17-Oct-1992 -by- J. Andrew Goossen [andrewgo] * Made it from old EPATHOBJ. \**************************************************************************/ class XEPATHOBJ : public EPATHOBJ { public: XEPATHOBJ() { cCurves = 0; fl = 0; } // Used when creating a new path XEPATHOBJ(HPATH hpath); // Get path given handle XEPATHOBJ(XDCOBJ& dco); // Get DC's path ~XEPATHOBJ(); }; /*********************************Class************************************\ * class PATHMEMOBJ : public EPATHOBJ * * Memory object for PATH class. * * Public Interface: * * PATHMEMOBJ Constructor * ~PATHMEMOBJ() Destructor * * VOID vKeepIt() Make memory object long lived * * History: * 09-Jul-1990 -by- Donald Sidoroff [donalds] * Wrote it. \**************************************************************************/ class PATHMEMOBJ : public EPATHOBJ /* pmo */ { public: PATHMEMOBJ(); ~PATHMEMOBJ(); VOID vKeepIt() { ppath->flType |= PATHTYPE_KEEPMEM; } }; #endif // GDIFLAGS_ONLY for gdikdx /*********************************Class************************************\ * class PATHSTACKOBJ : public EPATHOBJ * * Object for creating paths on the stack. It can hold a small number * of points on the stack; if the path gets too big, it will expand onto * the heap. * * History: * 22-Mar-1992 -by- J. Andrew Goossen [andrewgo] * Wrote it. \**************************************************************************/ // This value must be less than PATHALLOCSIZE, and allow the end of the // structure to be aligned on the most restrictive boundary: #define PATHSTACKALLOCSIZE 256 #ifndef GDIFLAGS_ONLY class PATHSTACKOBJ : public EPATHOBJ /* pso */ { private: PATH path; union { PATHALLOC pa; CHAR achBuffer[PATHSTACKALLOCSIZE]; } paBuf; public: PATHSTACKOBJ(XDCOBJ& dco, BOOL bUseCP = TRUE); PATHSTACKOBJ(); ~PATHSTACKOBJ(); }; /*********************************Class************************************\ * class EPATHFONTOBJ : public EPATHOBJ * * * * History: * 20-May-92 -by- Paul Butzi * Wrote it. \**************************************************************************/ class EPATHFONTOBJ : public EPATHOBJ { public: PATH path; PATHALLOC pa; public: VOID vInit(ULONGSIZE_T); }; /*********************************Class************************************\ * class LINETOPATHOBJ * * Special fast-track path constructor for LineTo's that are done when * there isn't an active DC path, and is to be drawn with a cosmetic * pen (can't handle geometric pens because WidenPath might be called, * and it requires more path structures to be initialized than I wish * to do here). * * History: * 17-Oct-1992 -by- J. Andrew Goossen [andrewgo] * Wrote it. \**************************************************************************/ class LINETOPATHOBJ : public EPATHOBJ { public: PATH path; PATHRECORD pr; LINETOPATHOBJ() {} }; /*********************************Class************************************\ * class RECTANGLEPATHOBJ * * Special fast-track path constructor for Rectangles that are done when * there isn't an active DC path, and is to be drawn with a cosmetic * pen (can't handle geometric pens because WidenPath might be called, * and it requires more path structures to be initialized than I wish * to do here). * * History: * 13-Dec-1992 -by- J. Andrew Goossen [andrewgo] * Wrote it. \**************************************************************************/ class RECTANGLEPATHOBJ : public EPATHOBJ { protected: PATH path; struct { PATHRECORD pr; POINTFIX aptfxBuf[2]; // We use this to leave room for the // additional 2 points we need to // complete the Rectangle. } prRect; public: RECTANGLEPATHOBJ() {} VOID vInit(RECTL*, BOOL); }; #endif // GDIFLAGS_ONLY for gdikdx.