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.
298 lines
9.4 KiB
298 lines
9.4 KiB
/******************************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
|