Leaked source code of windows server 2003
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.
 
 
 
 
 
 

283 lines
9.0 KiB

/******************************Module*Header*******************************\
* Module Name: draweng.hxx
*
* Internal helper functions for GDI draw calls.
*
* Created: 19-Nov-1990
* Author: J. Andrew Goossen [andrewgo]
*
* Copyright (c) 1990-1999 Microsoft Corporation
*
\**************************************************************************/
// This constant defines how many fractional device units to expand
// an ellipse if it will be filled, so that it looks better according
// to our fill conventions:
#define GROW_ELLIPSE_SIZE 4
// Some internal DrawEng structures:
enum PARTIALARC
{
PARTIALARCTYPE_CONTINUE,
PARTIALARCTYPE_MOVETO,
PARTIALARCTYPE_LINETO
};
// Arctan constants:
#define NEGATE_X 0x01
#define NEGATE_Y 0x02
#define SWITCH_X_AND_Y 0x04
#define OCTANT_0 0
#define OCTANT_1 (SWITCH_X_AND_Y)
#define OCTANT_2 (NEGATE_X | SWITCH_X_AND_Y)
#define OCTANT_3 (NEGATE_X)
#define OCTANT_4 (NEGATE_X | NEGATE_Y)
#define OCTANT_5 (NEGATE_X | NEGATE_Y | SWITCH_X_AND_Y)
#define OCTANT_6 (NEGATE_Y | SWITCH_X_AND_Y)
#define OCTANT_7 (NEGATE_Y)
// The following fraction is for determing the control point
// placements for approximating a quarter-ellipse by a Bezier curve,
// given the vector that describes the side of the bounding box.
//
// It is is the fraction over 2^32 which for the vector of the bound box
// pointing towards the origin, describes the placement of the corresponding
// control point on that vector. This value is equal to
// (4 cos(45)) / (3 cos(45) + 1):
#define QUADRANT_TAU 1922922357L
/******************************Public*Routine******************************\
* VOID vEllipseControlsOut(pvec, pvecResult, peq)
*
* For a quarter portion of an ellipse, this function, given a vector
* pointing away from the origin of the ellipse that describes the
* boundbox, returns the vector that describes the placement of the
* corresponding control point on that vector.
*
* History:
* 4-Apr-1992 -by- J. Andrew Goossen [andrewgo]
* Wrote it.
\**************************************************************************/
inline VOID vEllipseControlsOut(
VECTORFX* pvec, // Input vector
VECTORFX* pvecResult, // Output vector
LONGLONG* peq) // Temporary EQUAD. If it's declared here,
// compiler pops function out-line
{
*peq = Int32x32To64(pvec->x, QUADRANT_TAU);
pvecResult->x = pvec->x - (LONG) (*peq >> 32);
*peq = Int32x32To64(pvec->y, QUADRANT_TAU);
pvecResult->y = pvec->y - (LONG) (*peq >> 32);
}
/******************************Public*Routine******************************\
* VOID vEllipseControlsIn(pvec, pvecResult, peq)
*
* For a quarter portion of an ellipse, this function, given a vector
* pointing towards the origin of the ellipse that describes the
* boundbox, returns the vector that describes the placement of the
* corresponding control point on that vector.
*
* History:
* 4-Apr-1992 -by- J. Andrew Goossen [andrewgo]
* Wrote it.
\**************************************************************************/
inline VOID vEllipseControlsIn(
VECTORFX* pvec, // Input vector
VECTORFX* pvecResult, // Output vector
LONGLONG* peq) // Temporary EQUAD. If it's declared here,
// compiler pops function out-line
{
*peq = Int32x32To64(pvec->x, QUADRANT_TAU);
pvecResult->x = (LONG) (*peq>>32);
*peq = Int32x32To64(pvec->y, QUADRANT_TAU);
pvecResult->y = (LONG) (*peq >> 32);
}
/************************************Class*********************************\
* class EAPOINTL
*
* EPOINTL class without any constructors, so that it can be used in
* an array. (Compiler mucks up with static constructors.)
*
* History:
* 9-Oct-1991 -by- J. Andrew Goossen [andrewgo]
* Wrote it.
\**************************************************************************/
class EAPOINTL : public _POINTL
{
public:
VOID operator=(POINTL& ptl)
{
x = ptl.x;
y = ptl.y;
}
VOID operator+=(POINTL& ptl)
{
x += ptl.x;
y += ptl.y;
}
VOID operator-=(POINTL& ptl)
{
x -= ptl.x;
y -= ptl.y;
}
};
/************************************Class*********************************\
* class EBOX
*
* Object defining the bounding box for figures requiring one. Useful
* for providing a consistent object defining the bound box for the
* various uses of the APIs requiring it.
*
* Arcs must be constructed in device coordinates because the 'snapping'
* of the control points to the grid can only be done in device space.
* As such, the bounding box goes through the World-to-Device linear
* transform and will become a parallelogram.
*
* Figures requiring a bounding box must be drawn in the same direction
* and starting at the same part of the figure, independent of the current
* Page-to-Device transform and the ordering of the rectangle given by
* the User. When the World-to-Page transform is identity, figures must
* be drawn in a counter-clockwise direction for compatiblity with Old
* Windows.
*
* As such, the 'rcl' describing the bound box must be well-ordered so
* that (yTop, xLeft) is the upper-left corner of the box in device
* coordinates when the World-to-Page transform is indentity (i.e., the
* ordering is depedent of the Page-to-Device transform).
*
* 'rcl' doesn't have to be well-ordered for the Create-region APIs
* because it doesn't matter where the figure starts and in what direction
* it is drawn when it is converted to a region.
*
* Public interface:
*
* EBOX(dco, rcl, pla, bFillEllipse)
* // Constructor when PS_INSIDEFRAME and lower-right
* // exclusion has to be done (uses WORLD_TO_DEVICE
* // DC transform on the 'rcl')
* EBOX(xfo, rcl) // Constructor when PS_INSIDEFRAME and lower-right
* // exclusion don't have to be done
* EBOX(ercl, bFillEllipse)
* // Constructor for Create-region APIs
* ptlXform(ptef) // Transforms a point constructed on the unit circle
* // centered at the origin to the ellipse described
* // by the bounding box
* bEmpty() // TRUE when no figure will be drawn
*
* Public members:
*
* rclWorld // Original rectangle expressed in world
* // coordinates that defines the box.
* ptlA // Half the vector defining the "horizontal" axis
* // of the ellipse (in device coordinates)
* ptlB // Half the vector defining the "vertical" axis
* // of the ellipse (in device coordinates)
* eptlOrigin // Center of box (in device coordinates). Note that
* // it is rounded and so the figure may be 1/16th of
* // a pel off.
* aptl // Points defining corners of the box (in device
* // coordinates)
*
* 1-------------0
* | |
* | |
* ^ | o <- eptlOrigin
* | | |
* B | |
* | 2-------------3
*
* ---A--->
*
* History:
* 19-Nov-1990 -by- J. Andrew Goossen [andrewgo]
* Wrote it.
\**************************************************************************/
class EBOX /* ebox */
{
private:
BOOL bIsEmpty;
BOOL bIsFillInsideFrame;
public:
EAPOINTL aeptl[4];
EAPOINTL eptlOrigin;
EAPOINTL eptlA;
EAPOINTL eptlB;
RECTL rclWorld;
EBOX(ERECTL& ercl, BOOL bFillEllipse = FALSE);
EBOX(EXFORMOBJ& xfo, RECTL& rcl);
EBOX(DCOBJ& dco, RECTL& rcl, PLINEATTRS pla, BOOL bFillEllipse = FALSE);
POINTL ptlXform(EPOINTFL& ptef);
BOOL bEmpty() { return(bIsEmpty); }
BOOL bFillInsideFrame() { return(bIsFillInsideFrame); }
};
// Prototypes:
BOOL bPartialArc
(
PARTIALARC paType,
EPATHOBJ& epo,
EBOX& ebox,
EPOINTFL& eptefStart,
LONG lStartQuadrant,
EFLOAT& efStartAngle,
EPOINTFL& eptefEnd,
LONG lEndQuadrant,
EFLOAT& efEndAngle,
LONG lQuadrants
);
BOOL bEllipse
(
EPATHOBJ& epo,
EBOX& ebox
);
BOOL bRoundRect
(
EPATHOBJ& epo,
EBOX& ebox,
LONG dx,
LONG dy
);
BOOL bPolyPolygon
(
EPATHOBJ& epo,
EXFORMOBJ& xfo,
PPOINTL pptl,
PLONG pcptl,
ULONG ccptl,
LONG cMaxPoints
);
BOOL GreRectBlt
(
DCOBJ& dco,
ERECTL* percl
);
VOID vArctan
(
EFLOAT x,
EFLOAT y,
EFLOAT& efTheta,
LONG& lQuadrant
);