WindowsXP-SP1/windows/advcore/gdiplus/engine/entry/pathwidener.hpp
2020-09-30 16:53:49 +02:00

454 lines
11 KiB
C++

/**************************************************************************\
*
* 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