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.
239 lines
7.0 KiB
239 lines
7.0 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: pathflat.hxx
|
|
*
|
|
* Path flattening defines.
|
|
*
|
|
* Created: 9-Oct-1991
|
|
* Author: J. Andrew Goossen [andrewgo]
|
|
*
|
|
* Copyright (c) 1991-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
// Flatten to an error of 2/3. During initial phase, use 18.14 format.
|
|
|
|
#define TEST_MAGNITUDE_INITIAL (6 * 0x00002aa0L)
|
|
|
|
// Error of 2/3. During normal phase, use 15.17 format.
|
|
|
|
#define TEST_MAGNITUDE_NORMAL (TEST_MAGNITUDE_INITIAL << 3)
|
|
|
|
/**********************************Class***********************************\
|
|
* class HFDBASIS32
|
|
*
|
|
* Class for HFD vector objects.
|
|
*
|
|
* Public Interface:
|
|
*
|
|
* vInit(p1, p2, p3, p4) - Re-parameterizes the given control points
|
|
* to our initial HFD error basis.
|
|
* vLazyHalveStepSize(cShift) - Does a lazy shift. Caller has to remember
|
|
* it changes 'cShift' by 2.
|
|
* vSteadyState(cShift) - Re-parameterizes to our working normal
|
|
* error basis.
|
|
*
|
|
* vTakeStep() - Forward steps to next sub-curve
|
|
* vHalveStepSize() - Adjusts down (subdivides) the sub-curve
|
|
* vDoubleStepSize() - Adjusts up the sub-curve
|
|
* lError() - Returns error if current sub-curve were
|
|
* to be approximated using a straight line
|
|
* (value is actually multiplied by 6)
|
|
* fxValue() - Returns rounded coordinate of first point in
|
|
* current sub-curve. Must be in steady
|
|
* state.
|
|
*
|
|
* History:
|
|
* 10-Nov-1990 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class HFDBASIS32
|
|
{
|
|
private:
|
|
LONG e0;
|
|
LONG e1;
|
|
LONG e2;
|
|
LONG e3;
|
|
|
|
public:
|
|
VOID vInit(FIX p1, FIX p2, FIX p3, FIX p4);
|
|
VOID vLazyHalveStepSize(LONG cShift);
|
|
VOID vSteadyState(LONG cShift);
|
|
VOID vHalveStepSize();
|
|
VOID vDoubleStepSize();
|
|
VOID vTakeStep();
|
|
|
|
LONG lParentErrorDividedBy4() { return(MAX(ABS(e3), ABS(e2 + e2 - e3))); }
|
|
LONG lError() { return(MAX(ABS(e2), ABS(e3))); }
|
|
FIX fxValue() { return((e0 + (1L << 12)) >> 13); }
|
|
};
|
|
|
|
/**********************************Class***********************************\
|
|
* class BEZIER32
|
|
*
|
|
* Bezier cracker.
|
|
*
|
|
* A hybrid cubic Bezier curve flattener based on KirkO's error factor.
|
|
* Generates line segments fast without using the stack. Used to flatten
|
|
* a path.
|
|
*
|
|
* For an understanding of the methods used, see:
|
|
*
|
|
* Kirk Olynyk, "..."
|
|
* Goossen and Olynyk, "System and Method of Hybrid Forward
|
|
* Differencing to Render Bezier Splines"
|
|
* Lien, Shantz and Vaughan Pratt, "Adaptive Forward Differencing for
|
|
* Rendering Curves and Surfaces", Computer Graphics, July 1987
|
|
* Chang and Shantz, "Rendering Trimmed NURBS with Adaptive Forward
|
|
* Differencing", Computer Graphics, August 1988
|
|
* Foley and Van Dam, "Fundamentals of Interactive Computer Graphics"
|
|
*
|
|
* Public Interface:
|
|
*
|
|
* vInit(pptfx) - pptfx points to 4 control points of
|
|
* Bezier. Current point is set to the first
|
|
* point after the start-point.
|
|
* BEZIER32(pptfx) - Constructor with initialization.
|
|
* vGetCurrent(pptfx) - Returns current polyline point.
|
|
* bCurrentIsEndPoint() - TRUE if current point is end-point.
|
|
* vNext() - Moves to next polyline point.
|
|
*
|
|
* History:
|
|
* 1-Oct-1991 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
extern LONGLONG* gpeqErrorHigh;
|
|
extern LONGLONG* gpeqErrorLow;
|
|
|
|
class BEZIER32
|
|
{
|
|
//private:
|
|
public:
|
|
LONG cSteps;
|
|
HFDBASIS32 x;
|
|
HFDBASIS32 y;
|
|
RECTFX rcfxBound;
|
|
|
|
public:
|
|
BOOL bInit(POINTFIX* aptfx, RECTFX*);
|
|
BOOL bNext(POINTFIX* pptfx);
|
|
};
|
|
|
|
#define FRACTION64 28
|
|
|
|
class HFDBASIS64
|
|
{
|
|
private:
|
|
LONGLONG e0;
|
|
LONGLONG e1;
|
|
LONGLONG e2;
|
|
LONGLONG e3;
|
|
|
|
public:
|
|
VOID vInit(FIX p1, FIX p2, FIX p3, FIX p4);
|
|
VOID vHalveStepSize();
|
|
VOID vDoubleStepSize();
|
|
VOID vTakeStep();
|
|
VOID vUntransform(FIX* afx);
|
|
|
|
VOID vParentError(LONGLONG* peq);
|
|
VOID vError(LONGLONG* peq);
|
|
FIX fxValue();
|
|
};
|
|
|
|
class BEZIER64
|
|
{
|
|
//private:
|
|
public:
|
|
HFDBASIS64 xLow;
|
|
HFDBASIS64 yLow;
|
|
HFDBASIS64 xHigh;
|
|
HFDBASIS64 yHigh;
|
|
|
|
LONGLONG eqErrorLow;
|
|
RECTFX* prcfxClip;
|
|
RECTFX rcfxClip;
|
|
|
|
LONG cStepsHigh;
|
|
|
|
|
|
LONG cStepsLow;
|
|
|
|
//public:
|
|
|
|
BOOL bNext(POINTFIX* pptfx);
|
|
VOID vInit(POINTFIX* aptfx, RECTFX* prcfx, LONGLONG* peq);
|
|
};
|
|
|
|
/**********************************Class***********************************\
|
|
* class BEZIER
|
|
*
|
|
* Bezier cracker. Flattens any Bezier in our 28.4 device space down
|
|
* to a smallest 'error' of 2^-7 = 0.0078. Will use fast 32 bit cracker
|
|
* for small curves and slower 64 bit cracker for big curves.
|
|
*
|
|
* Public Interface:
|
|
*
|
|
* vInit(aptfx, prcfxClip, peqError)
|
|
* - pptfx points to 4 control points of Bezier. The first point
|
|
* retrieved by bNext() is the the first point in the approximation
|
|
* after the start-point.
|
|
*
|
|
* - prcfxClip is an optional pointer to the bound box of the visible
|
|
* region. This is used to optimize clipping of Bezier curves that
|
|
* won't be seen. Note that this value should account for the pen's
|
|
* width!
|
|
*
|
|
* - optional maximum error in 32.32 format, corresponding to Kirko's
|
|
* error factor.
|
|
*
|
|
* bNext(pptfx)
|
|
* - pptfx points to where next point in approximation will be
|
|
* returned. Returns FALSE if the point is the end-point of the
|
|
* curve.
|
|
*
|
|
* History:
|
|
* 1-Oct-1991 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class BEZIER
|
|
{
|
|
private:
|
|
|
|
//
|
|
// Can't do a straight union of BEZIER32 and BEZIER64 here because
|
|
// C++ doesn't like the static constructors and destructors of the
|
|
// EQUADs:
|
|
//
|
|
// Note:
|
|
//
|
|
|
|
union
|
|
{
|
|
BEZIER64 bez64;
|
|
BEZIER32 bez32;
|
|
} bez;
|
|
|
|
BOOL bBez32;
|
|
|
|
public:
|
|
BEZIER() {}
|
|
|
|
VOID vInit(POINTFIX* aptfx,
|
|
RECTFX* prcfxClip = (RECTFX*) NULL,
|
|
LONGLONG* peqError = gpeqErrorLow)
|
|
{
|
|
bBez32 = (peqError == gpeqErrorLow &&
|
|
bez.bez32.bInit(aptfx, prcfxClip));
|
|
if (!bBez32)
|
|
bez.bez64.vInit(aptfx, prcfxClip, peqError);
|
|
}
|
|
|
|
BOOL bNext(POINTFIX* pptfx)
|
|
{
|
|
return(bBez32 ?
|
|
bez.bez32.bNext(pptfx) :
|
|
bez.bez64.bNext(pptfx));
|
|
}
|
|
};
|