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
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
|
|
);
|