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.
453 lines
11 KiB
453 lines
11 KiB
/**************************************************************************\
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
* Module Name:
|
|
*
|
|
* PathWidener.hpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Class used for Path widening
|
|
*
|
|
* Revision History:
|
|
*
|
|
* 11/24/99 ikkof
|
|
* Created it.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifndef _PATHWIDENER_HPP
|
|
#define _PATHWIDENER_HPP
|
|
|
|
enum GpLineCapMode
|
|
{
|
|
LineCapDefaultMode = 0,
|
|
LineCapDashMode = 1
|
|
};
|
|
|
|
class GpPathWidener
|
|
{
|
|
private:
|
|
// We now use an ObjectTag to determine if the object is valid
|
|
// instead of using a BOOL. This is much more robust and helps
|
|
// with debugging. It also enables us to version our objects
|
|
// more easily with a version number in the ObjectTag.
|
|
ObjectTag Tag; // Keep this as the 1st value in the object!
|
|
|
|
protected:
|
|
VOID SetValid(BOOL valid)
|
|
{
|
|
Tag = valid ? ObjectTagPathWidener : ObjectTagInvalid;
|
|
}
|
|
|
|
public:
|
|
|
|
GpPathWidener(
|
|
const GpPointF* points,
|
|
const BYTE* types,
|
|
INT count,
|
|
const DpPen* pen,
|
|
const GpMatrix* matrix,
|
|
REAL dpiX,
|
|
REAL dpiY,
|
|
BOOL isAntiAliased,
|
|
BOOL isInsetPen = FALSE
|
|
)
|
|
{
|
|
Initialize(
|
|
points,
|
|
types,
|
|
count,
|
|
pen,
|
|
matrix,
|
|
dpiX,
|
|
dpiY,
|
|
isAntiAliased,
|
|
isInsetPen
|
|
);
|
|
}
|
|
|
|
GpPathWidener(
|
|
GpPath *path,
|
|
const DpPen* pen,
|
|
const GpMatrix* matrix,
|
|
REAL dpiX,
|
|
REAL dpiY,
|
|
BOOL isAntiAliased,
|
|
BOOL isInsetPen = FALSE
|
|
)
|
|
{
|
|
const GpPointF* points = path->GetPathPoints();
|
|
const BYTE* types = path->GetPathTypes();
|
|
INT count = path->GetPointCount();
|
|
|
|
Initialize(
|
|
points,
|
|
types,
|
|
count,
|
|
pen,
|
|
matrix,
|
|
dpiX,
|
|
dpiY,
|
|
isAntiAliased,
|
|
isInsetPen
|
|
);
|
|
}
|
|
|
|
GpPathWidener(
|
|
const GpPointF* points,
|
|
const BYTE* types,
|
|
INT count,
|
|
const DpPen* pen,
|
|
const GpMatrix* matrix,
|
|
REAL dpiX,
|
|
REAL dpiY,
|
|
BOOL isAntiAliased,
|
|
BYTE* centerTypesBuffer,
|
|
GpPointF* centerPointsBuffer,
|
|
GpPointF* gradientsBuffer,
|
|
GpPointF* normalsBuffer,
|
|
BYTE* leftTypesBuffer,
|
|
GpPointF* leftPointsBuffer,
|
|
BYTE* rightTypesBuffer,
|
|
GpPointF* rightPointsBuffer,
|
|
INT bufferCount,
|
|
BOOL isInsetPen = FALSE
|
|
) : CenterTypes(centerTypesBuffer, bufferCount),
|
|
CenterPoints(centerPointsBuffer, bufferCount),
|
|
Gradients(gradientsBuffer, bufferCount),
|
|
Normals(normalsBuffer, bufferCount),
|
|
LeftTypes(leftTypesBuffer, bufferCount),
|
|
LeftPoints(leftPointsBuffer, bufferCount),
|
|
RightTypes(rightTypesBuffer, bufferCount),
|
|
RightPoints(rightPointsBuffer, bufferCount)
|
|
{
|
|
Initialize(points, types, count, pen, matrix, dpiX, dpiY,
|
|
isAntiAliased, isInsetPen);
|
|
}
|
|
|
|
~GpPathWidener()
|
|
{
|
|
SetValid(FALSE); // so we don't use a deleted object
|
|
}
|
|
|
|
GpStatus Widen(
|
|
DynPointFArray* widenedPoints,
|
|
DynByteArray* widenedTypes
|
|
);
|
|
|
|
GpStatus Widen(GpPath **path);
|
|
|
|
BOOL IsValid() const
|
|
{
|
|
ASSERT((Tag == ObjectTagPathWidener) || (Tag == ObjectTagInvalid));
|
|
#if DBG
|
|
if (Tag == ObjectTagInvalid)
|
|
{
|
|
WARNING1("Invalid PathWidener");
|
|
}
|
|
#endif
|
|
|
|
return (Tag == ObjectTagPathWidener);
|
|
}
|
|
|
|
REAL GetPenDelta();
|
|
|
|
|
|
protected:
|
|
VOID Initialize(
|
|
const GpPointF* points,
|
|
const BYTE* types,
|
|
INT count,
|
|
const DpPen* pen,
|
|
const GpMatrix* matrix,
|
|
REAL dpiX,
|
|
REAL dpiY,
|
|
BOOL isAntiAliased,
|
|
BOOL isInsetPen = FALSE
|
|
);
|
|
|
|
GpStatus WidenSubpath(
|
|
DynPointFArray* widenedPoints,
|
|
DynByteArray* widenedTypes,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
INT startIndex,
|
|
INT endIndex,
|
|
BOOL isClosed,
|
|
GpLineCap startCap,
|
|
GpLineCap endCap,
|
|
BOOL useBevelJoinInside
|
|
);
|
|
|
|
GpStatus CalculateGradients(
|
|
INT startIndex,
|
|
INT endIndex
|
|
);
|
|
|
|
GpStatus CalculateNormals(
|
|
REAL leftWidth,
|
|
REAL rightWidth
|
|
);
|
|
|
|
GpStatus SetPolygonJoin(
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
BOOL isAntialiased
|
|
);
|
|
|
|
GpStatus SetStartCapInset(
|
|
REAL inset
|
|
)
|
|
{
|
|
Inset1 = inset;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus SetEndCapInset(
|
|
REAL inset
|
|
)
|
|
{
|
|
Inset2 = inset;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
VOID WidenFirstPoint(
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
GpLineJoin lineJoin,
|
|
REAL miterLimit2,
|
|
GpPointF* leftPoints,
|
|
BYTE* leftTypes,
|
|
INT* addedLeftCount,
|
|
GpPointF* rightPoints,
|
|
BYTE* rightTypes,
|
|
INT* addedRightCount,
|
|
GpPointF* leftEndPt,
|
|
GpPointF* rightEndPt,
|
|
const GpPointF* grad,
|
|
const GpPointF* norm,
|
|
const GpPointF* dataPoints,
|
|
INT dataCount,
|
|
GpPointF* lastPt,
|
|
const REAL* firstInsets,
|
|
INT flag
|
|
);
|
|
|
|
GpStatus
|
|
WidenEachPathType(
|
|
BYTE pathType,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
GpLineJoin lineJoin,
|
|
REAL miterLimit2,
|
|
GpPointF* leftPoints,
|
|
BYTE* leftTypes,
|
|
INT* addedLeftCount,
|
|
GpPointF* rightPoints,
|
|
BYTE* rightTypes,
|
|
INT* addedRightCount,
|
|
const GpPointF* grad,
|
|
const GpPointF* norm,
|
|
const GpPointF* dataPoints,
|
|
INT dataCount,
|
|
GpPointF* lastPt,
|
|
const REAL* lastInsets,
|
|
INT flag
|
|
);
|
|
|
|
GpStatus
|
|
WidenLinePoints(
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
GpLineJoin lineJoin,
|
|
REAL miterLimit2,
|
|
GpPointF* leftPoints,
|
|
BYTE* leftTypes,
|
|
INT* addedLeftCount,
|
|
GpPointF* rightPoints,
|
|
BYTE* rightTypes,
|
|
INT* addedRightCount,
|
|
const GpPointF* grad,
|
|
const GpPointF* norm,
|
|
const GpPointF* dataPoints,
|
|
INT dataCount,
|
|
GpPointF* lastPt,
|
|
const REAL* lastInsets,
|
|
INT flag
|
|
);
|
|
|
|
GpStatus
|
|
WidenBezierPoints(
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
GpLineJoin lineJoin,
|
|
REAL miterLimit2,
|
|
GpPointF* leftPoints,
|
|
BYTE* leftTypes,
|
|
INT* addedLeftCount,
|
|
GpPointF* rightPoints,
|
|
BYTE* rightTypes,
|
|
INT* addedRightCount,
|
|
const GpPointF* grad,
|
|
const GpPointF* norm,
|
|
const GpPointF* dataPoints,
|
|
INT dataCount,
|
|
GpPointF* lastPt,
|
|
const REAL* lastInsets,
|
|
INT flag
|
|
);
|
|
|
|
GpStatus SetCaps(
|
|
GpLineCap startCap,
|
|
GpLineCap endCap,
|
|
const GpPointF& startPoint,
|
|
const GpPointF& startGrad,
|
|
const GpPointF& startNorm,
|
|
const GpPointF& endPoint,
|
|
const GpPointF& endGrad,
|
|
const GpPointF& endNorm,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
const GpPointF *points,
|
|
INT pointCount
|
|
);
|
|
|
|
GpStatus SetCustomFillCaps(
|
|
GpCustomLineCap* customStartCap,
|
|
GpCustomLineCap* customEndCap,
|
|
const GpPointF& startPoint,
|
|
const GpPointF& endPoint,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
const GpPointF *centerPoints,
|
|
const BYTE *centerTypes,
|
|
INT centerPointCount,
|
|
DynPointFArray *startCapPoints,
|
|
DynPointFArray *endCapPoints,
|
|
DynByteArray *startCapTypes,
|
|
DynByteArray *endCapTypes
|
|
);
|
|
|
|
GpStatus SetCustomStrokeCaps(
|
|
GpCustomLineCap* customStartCap,
|
|
GpCustomLineCap* customEndCap,
|
|
const GpPointF& startPoint,
|
|
const GpPointF& endPoint,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
const GpPointF *centerPoints,
|
|
const BYTE *centerTypes,
|
|
INT centerPointCount,
|
|
DynPointFArray *startCapPoints,
|
|
DynPointFArray *endCapPoints,
|
|
DynByteArray *startCapTypes,
|
|
DynByteArray *endCapTypes
|
|
);
|
|
|
|
GpStatus SetRoundCap(
|
|
const GpPointF& point,
|
|
const GpPointF& grad,
|
|
BOOL isStartCap,
|
|
REAL leftWidth,
|
|
REAL rightWidth
|
|
);
|
|
|
|
GpStatus SetDoubleRoundCap(
|
|
const GpPointF& point,
|
|
const GpPointF& grad,
|
|
BOOL isStartCap,
|
|
REAL leftWidth,
|
|
REAL rightWidth
|
|
);
|
|
|
|
GpStatus SetTriangleCap(
|
|
const GpPointF& point,
|
|
const GpPointF& grad,
|
|
BOOL isStartCap,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
const GpPointF *points,
|
|
INT pointCount
|
|
);
|
|
|
|
GpStatus CombineSubpathOutlines(
|
|
DynPointFArray* widenedPoints,
|
|
DynByteArray* widenedTypes,
|
|
BOOL isClosed,
|
|
BOOL closeStartCap = FALSE,
|
|
BOOL closeEndCap = FALSE
|
|
);
|
|
|
|
GpStatus CombineClosedCaps(
|
|
DynPointFArray* widenedPoints,
|
|
DynByteArray* widenedTypes,
|
|
DynPointFArray *daStartCapPoints,
|
|
DynPointFArray *daEndCapPoints,
|
|
DynByteArray *daStartCapTypes,
|
|
DynByteArray *daEndCapTypes
|
|
);
|
|
|
|
GpStatus AddCompoundCaps(
|
|
DynPointFArray* widenedPoints,
|
|
DynByteArray* widenedTypes,
|
|
REAL leftWidth,
|
|
REAL rightWidth,
|
|
INT startIndex,
|
|
INT endIndex,
|
|
GpLineCap startCap,
|
|
GpLineCap endCap
|
|
);
|
|
|
|
REAL GetSubpathPenMiterDelta(BOOL isClosed);
|
|
|
|
protected:
|
|
DpPathIterator Iterator;
|
|
DynByteArray CenterTypes;
|
|
DynPointFArray CenterPoints;
|
|
DynPointFArray Gradients;
|
|
DynPointFArray Normals;
|
|
|
|
DynByteArray LeftTypes;
|
|
DynPointFArray LeftPoints;
|
|
DynByteArray RightTypes;
|
|
DynPointFArray RightPoints;
|
|
|
|
BOOL InsetPenMode; // are we doing inset pen using a center pen.
|
|
const DpPen* Pen;
|
|
GpMatrix XForm;
|
|
GpMatrix InvXForm;
|
|
REAL UnitScale; // Scale factor for Page to Device units
|
|
REAL StrokeWidth;
|
|
REAL OriginalStrokeWidth; // StrokeWidth is clamped to a minimum value
|
|
// but OriginalStrokeWidth is actual transformed
|
|
// pen width.
|
|
REAL MinimumWidth;
|
|
REAL MaximumWidth;
|
|
BOOL IsAntiAliased;
|
|
BOOL NeedsToTransform;
|
|
BOOL NeedsToAdjustNormals;
|
|
|
|
REAL DpiX;
|
|
REAL DpiY;
|
|
|
|
DynPointFArray JoinPolygonPoints;
|
|
DynRealArray JoinPolygonAngles;
|
|
|
|
// CapTypes1 and CapPoints1 are used for the start cap and left join.
|
|
|
|
DynByteArray CapTypes1;
|
|
DynPointFArray CapPoints1;
|
|
REAL Inset1; // Inset value for the starting position.
|
|
|
|
// CapTypes2 and CapPoints2 are used for the end cap and right join.
|
|
|
|
DynByteArray CapTypes2;
|
|
DynPointFArray CapPoints2;
|
|
REAL Inset2; // Inset value for the ending position.
|
|
};
|
|
|
|
#endif
|