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.
589 lines
18 KiB
589 lines
18 KiB
/******************************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.
|
|
|