|
|
/******************************Module*Header*******************************\
* Module Name: clipobj.hxx * * Clipping object * * Created: 15-Sep-1990 15:13:06 * Author: Donald Sidoroff [donalds] * * Copyright (c) 1990-1999 Microsoft Corporation * \**************************************************************************/
#ifndef _CLIPOBJ_HXX
#define _CLIPOBJ_HXX 1
/*********************************Class************************************\
* CLIPLINE structures. * * These structures have been divided into two halves. CLIPLINEEENUM * contains those fields that are needed to hold the state of enumerating * through a single line and enumerate through a series of lines within a * path. * * ENUMER is also used for holding part of the clipped line state. * * History: * 07-Mar-1991 -by- Eric Kutter [erick] * Wrote it. \**************************************************************************/
VOID vIntersectHorizontal(DDA_CLIPLINE*, LONG, POINTL*, POINTL*, LONG*); VOID vIntersectVertical(DDA_CLIPLINE*, LONG, POINTL*, POINTL*, LONG*);
// the bottom 16 flags have been left blank so that they do not overlap
// the PD_ (PATHDATA) flags. PD_ALL should be set too all PD_ flags so
// (CLO_ALL & PD_ALL) == 0. This is asserted in clipline setup code.
#define CLO_LINEDONE 0x00010000
#define CLO_RECORD 0x00020000
#define CLO_VERTICAL 0x00040000
#define CLO_HORIZONTAL 0x00080000
#define CLO_CLOSING 0x00100000
#define CLO_PATHDONE 0x00200000
#define CLO_LEFTTORIGHT 0x00400000
#define CLO_TOPTOBOTTOM 0x00800000
#define CLO_COMPLEXINTERSECTION 0x01000000
#define CLO_ENUMDONE 0x02000000
#define CLO_ALL 0xffff0000
#define CLO_PATHFLAGS (CLO_CLOSING | CLO_PATHDONE)
typedef struct _CLIPLINEENUM // cle
{ // fields for enumerating through a single line.
ULONG cPoints; POINTFIX ptfx0; POINTFIX* pptfx1; // fixed point start
FLONG fl; // misc flags
LONG iStart; // start index of current run - 1
LONG iC; // end index of current run
ULONG cMaxRuns; ULONG* pcRuns; RUN* prun; LONG iPrevStop;
DDA_CLIPLINE dda; // DDA variables for the line
LONG lX0; // dda.lX0 transformed to real coordintates
LONG lY0; // dda.lY0 transformed to real coordintates
LONG lX1; // dda.lX1 transformed to real coordintates
LONG lY1; // dda.lY1 transformed to real coordintates
POINTL ptB; // first point in current segment
POINTL ptC; // last point in current segment
POINTL ptE; // last point in scan
POINTL ptF; // first point out of scan
LONG iE;
LONG lYEnter; // y value entering current scan.
LONG lYLeave; // y value leaving current scan.
// style state:
STYLEPOS spStyleStart; // style position at beginning of current line
STYLEPOS spStyleEnd; // style position at end of current line
STYLEPOS spTotal2; // twice the sum of the style array
LONG* plStyleState; // pointer to style state in LINEATTRS
// style variables from device:
ULONG xStep; ULONG yStep; ULONG xyDensity;
// fields for connecting lines properly:
POINTFIX ptfxStartSub; // first point of current sub path
} CLIPLINEENUM, *PCLIPLINEENUM;
/*********************************Class************************************\
* * Public Interface: * * History: * * 22-Mar-1991 -by- Eric Kutter [erick] * Added clipline stuff * * 15-Sep-1990 -by- Donald Sidoroff [donalds] * Wrote it. * \**************************************************************************/
// Enumerate stuff
typedef PSCAN (*PSCNFN)(RGNOBJ *, SCAN *, LONG *, BOOL);
typedef struct _ENUMER /* enmr */ { ERECTL ercl; // Enumerate in this rectangle
PSCAN pscn; // Current scan
COUNT cScans; // How many scans to enumerate
COUNT iFirst; // Start at this wall
COUNT iWall; // Current wall
LONG iOff; // Offset to advance to next wall
COUNT iFinal; // Stop at this wall
ULONG iDir; // Direction we are going
ULONG iType; // Rectangles or trapezoids?
LONG yCurr; // Current y-coordinate
LONG yDelta; // Change in y-coordinate
LONG yFinal; // Stop at this y-coordinate
BOOL bAll; // Enumerate whole CLIPOBJ?
} ENUMER, *PENUMER; // trapezoid broken up by clipping
//
// 'NOTUSED' is a misnomer. This is used to expose the WNDOBJ fields
// and must match the WNDOBJ declaration in 'winddi.h', except for
// 'coClient':
//
class NOTUSED { public: PVOID pvConsumer; RECTL rclClient; SURFOBJ* psoOwner; };
//
// The following values are passed to vSetup.
//
#define CLIP_NOFORCE 0
#define CLIP_FORCE 1
#define CLIP_NOFORCETRIV 2
// XCLIPOBJ is padded to look like WNDOBJ so EWNDOBJ can derive
// from it and use all its methods. Also if we decide to pass
// WNDOBJ instead of CLIPOBJ in DDI one day, we won't need to
// worry about backward compatibility stuff.
class XCLIPOBJ : public _CLIPOBJ, public NOTUSED, public RGNOBJ { protected: ENUMER enmr; // Enumerator
COUNT cObjs; // Number of objects
PCLIPLINEENUM pcle; // Clip line enumeration state
// clipline methods
BOOL bGetLine(EPATHOBJ *ppo, FLONG *pfl); BOOL bGetMorePoints(EPATHOBJ *ppo, FLONG *pfl); BOOL bSetup();
BOOL bFindFirstScan(); BOOL bFindFirstSegment();
BOOL bFindNextScan(); BOOL bFindNextSegment();
BOOL bRecordSegment(); BOOL bRecordRun(LONG& iEnd);
BOOL bStyling() {return(pcle->spTotal2 > 0); }
BOOL bComplexIntersection() {return(pcle->fl & CLO_COMPLEXINTERSECTION); } VOID vSetComplexIntersection() {pcle->fl |= CLO_COMPLEXINTERSECTION; } VOID vClearComplexIntersection(){pcle->fl &= ~CLO_COMPLEXINTERSECTION;}
BOOL bRecordPending() {return(pcle->fl & CLO_RECORD); } VOID vSetRecordPending() {pcle->fl |= CLO_RECORD; } VOID vClearRecordPending() {pcle->fl &= ~CLO_RECORD; }
BOOL bLineDone() {return(pcle->fl & CLO_LINEDONE); } VOID vSetLineDone() {pcle->fl |= CLO_LINEDONE; }
BOOL bPathDone() {return(pcle->fl & CLO_PATHDONE); } BOOL bClosing() {return(pcle->fl & CLO_CLOSING); } BOOL bCloseFigure() {return(pcle->fl & PD_CLOSEFIGURE); } BOOL bEnumDone() {return(pcle->fl & CLO_ENUMDONE); }
VOID vSetVertical() {pcle->fl |= CLO_VERTICAL; } VOID vSetHorizontal() {pcle->fl |= CLO_HORIZONTAL; } BOOL bSimpleClip() {return(pcle->fl & (CLO_VERTICAL | CLO_HORIZONTAL)); }
// bTopToBottom and bLeftToRight must return 0 or 1.
BOOL bTopToBottom() {return(!!(pcle->fl & CLO_TOPTOBOTTOM)); } BOOL bLeftToRight() {return(!!(pcle->fl & CLO_LEFTTORIGHT)); }
BOOL bEmptyScan() {return(enmr.pscn->cWalls == 0); }
VOID vSetLeftToRight(BOOL b) { if (b) { pcle->fl |= CLO_LEFTTORIGHT; enmr.iOff = 1; } else { pcle->fl &= ~CLO_LEFTTORIGHT; enmr.iOff = -1; }
}
LONG xWall(LONG l) { return(xGet(enmr.pscn,(PTRDIFF)(enmr.iWall + l))); }
VOID vIntersectScan(LONG y, PPOINTL ppt0, PPOINTL ppt1, PLONG pi0); BOOL bIntersectWall(LONG i, PPOINTL ppt0, PPOINTL ppt1, PLONG pi0);
VOID DBGDISPLAYDDA(); VOID DBGDISPLAYSTATE(PSZ psz);
public: VOID vSetup(REGION *prgn, ERECTL& ercl_, int iForcedClip = CLIP_NOFORCE); ERECTL& erclExclude() { return(*((ERECTL *) &rclBounds)); }
// Merge the clipping bounding box with the region in CLIP_bEnum().
VOID vMergeWhenEnumerate() { enmr.bAll = FALSE; }
ULONG cEnumStart(BOOL, ULONG, ULONG, ULONG); // CLIPOBJ.CXX
BOOL bEnum(ULONG, PVOID, ULONG* pcjFilled=0); // CLIPOBJ.CXX
PATHOBJ *ppoGetPath(); // CLIPOBJ.CXX
VOID vEnumPathStart(PATHOBJ*, SURFACE*, LINEATTRS* ); BOOL bEnumPath(PATHOBJ* ppo, ULONG cj, CLIPLINE* pcl);
BOOL bEnumStartLine(FLONG flPath); BOOL bEnumLine(ULONG cj, CLIPLINE* pcl); VOID vUpdateStyleState(); LONG lGetStyleState(IN STYLEPOS sp) { return(MAKELONG(sp % pcle->xyDensity, sp / pcle->xyDensity)); }
VOID vFindScan(RECTL *prcl, LONG y); VOID vFindSegment(RECTL *prcl, LONG x, LONG y); };
class ECLIPOBJ : public XCLIPOBJ { public:
ECLIPOBJ(REGION *prgn, ERECTL& ercl_, int iForcedClip = CLIP_NOFORCE) { vSetup(prgn,ercl_,iForcedClip); }
ECLIPOBJ() {prgn = (REGION *) NULL;} };
// Define some stuff for Engine components that use ECLIPOBJs
#define CLIPOBJ_ENUM_LIMIT 20
typedef struct _CLIPENUMRECT { ULONG c; RECTL arcl[CLIPOBJ_ENUM_LIMIT]; } CLIPENUMRECT;
#endif // #ifndef _CLIPOBJ_HXX
|