|
|
/**************************************************************************\
* * Copyright (c) 2000 Microsoft Corporation * * Module Name: * * CustomLineCap.hpp * * Abstract: * * Class used for the custom line caps. * * Revision History: * * 02/21/00 ikkof * Created it. * \**************************************************************************/
#ifndef _DPCUSTOMLINECAP_HPP
#define _DPCUSTOMLINECAP_HPP
class DpCustomLineCap : public GpObject { protected: VOID SetValid(BOOL valid) { GpObject::SetValid(valid ? ObjectTagCustomLineCap : ObjectTagInvalid); }
public: DpCustomLineCap() {}
virtual BOOL IsValid() const { // If the line cap came from a different version of GDI+, its tag
// will not match, and it won't be considered valid.
return GpObject::IsValid(ObjectTagCustomLineCap); }
INT GetFillPointCount() const { ASSERT(IsValid()); ASSERT((FillPath != NULL) && FillPath->IsValid()); return FillPath->GetPointCount(); }
INT GetStrokePointCount() const { ASSERT(IsValid()); ASSERT((StrokePath != NULL) && StrokePath->IsValid()); return StrokePath->GetPointCount(); }
const GpPointF * GetFillPoints() const { ASSERT(IsValid()); ASSERT((FillPath != NULL) && FillPath->IsValid()); return FillPath->GetPathPoints(); }
const GpPointF * GetStrokePoints() const { ASSERT(IsValid()); ASSERT((StrokePath != NULL) && StrokePath->IsValid()); return StrokePath->GetPathPoints(); }
const BYTE * GetFillTypes() const { ASSERT(IsValid()); ASSERT((FillPath != NULL) && FillPath->IsValid()); return FillPath->GetPathTypes(); }
const BYTE * GetStrokeTypes() const { ASSERT(IsValid()); ASSERT((StrokePath != NULL) && StrokePath->IsValid()); return StrokePath->GetPathTypes(); }
GpStatus SetStrokeCaps(GpLineCap lineCap) { ASSERT(IsValid()); return SetStrokeCaps(lineCap, lineCap); }
GpStatus SetStrokeCaps(GpLineCap startCap, GpLineCap endCap) { ASSERT(IsValid());
// Allow only non-anchor types of caps.
GpStatus status = Ok;
GpLineCap savedStartCap = StrokeStartCap; GpLineCap savedEndCap = StrokeEndCap;
switch(startCap) { case LineCapFlat: case LineCapSquare: case LineCapRound: case LineCapTriangle: StrokeStartCap = startCap; break;
default: status = InvalidParameter; break; }
if(status == Ok) { switch(endCap) { case LineCapFlat: case LineCapSquare: case LineCapRound: case LineCapTriangle: StrokeEndCap = endCap; break;
default: status = InvalidParameter; break; } }
if(status != Ok) { // Go back to the original caps.
StrokeStartCap = savedStartCap; StrokeEndCap = savedEndCap; }
return status; }
GpStatus GetStrokeCaps(GpLineCap* startCap, GpLineCap* endCap) const { ASSERT(IsValid());
if(startCap) *startCap = StrokeStartCap;
if(endCap) *endCap = StrokeEndCap;
return Ok; }
GpStatus SetBaseCap(GpLineCap lineCap) { ASSERT(IsValid());
// Allow only non-anchor types of caps.
GpStatus status = Ok;
switch(lineCap) { case LineCapFlat: case LineCapSquare: case LineCapRound: case LineCapTriangle: BaseCap = lineCap; break;
default: status = InvalidParameter; break; }
return status; }
GpStatus GetBaseCap(GpLineCap* baseCap) const { ASSERT(IsValid());
if(baseCap) *baseCap = BaseCap;
return Ok; }
GpStatus SetBaseInset(REAL inset) { ASSERT(IsValid());
BaseInset = inset;
return Ok; }
GpStatus GetBaseInset(REAL* inset) const { ASSERT(IsValid());
if(inset) *inset = BaseInset;
return Ok; }
GpStatus SetStrokeJoin(GpLineJoin lineJoin) { ASSERT(IsValid());
StrokeJoin = lineJoin; return Ok; }
GpStatus GetStrokeJoin(GpLineJoin* lineJoin) const { ASSERT(IsValid());
if(lineJoin) { *lineJoin = StrokeJoin; return Ok; } else return InvalidParameter; } GpStatus SetStrokeMiterLimit(REAL miterLimit) { ASSERT(IsValid());
if(miterLimit > 1) { StrokeMiterLimit = miterLimit; return Ok; } else return InvalidParameter; }
REAL GetStrokeMiterLimit() const { ASSERT(IsValid());
return StrokeMiterLimit; } REAL GetStrokeLength() const { ASSERT(IsValid());
return StrokeLength; } REAL GetFillLength() const { ASSERT(IsValid());
return FillLength; }
GpStatus SetWidthScale(REAL widthScale) { ASSERT(IsValid());
WidthScale = widthScale;
return Ok; }
GpStatus GetWidthScale(REAL* widthScale) const { ASSERT(IsValid());
if(widthScale) *widthScale = WidthScale;
return Ok; }
GpStatus SetFillHotSpot(const GpPointF& hotSpot) { ASSERT(IsValid());
FillHotSpot = hotSpot; return Ok; }
GpStatus GetFillHotSpot(GpPointF* hotSpot) { ASSERT(IsValid());
if(!hotSpot) return InvalidParameter;
*hotSpot = FillHotSpot; return Ok; }
GpStatus SetStrokeHotSpot(const GpPointF& hotSpot) { ASSERT(IsValid());
StrokeHotSpot = hotSpot; return Ok; }
GpStatus GetStrokeHotSpot(GpPointF* hotSpot) { ASSERT(IsValid());
if(!hotSpot) return InvalidParameter;
*hotSpot = StrokeHotSpot; return Ok; }
virtual BOOL IsEqual(const DpCustomLineCap* customLineCap) const = 0;
virtual INT GetTransformedFillCap( GpPointF* points, BYTE* types, INT count, const GpPointF& origin, const GpPointF& tangent, REAL lineWidth, REAL mimimumWidth ) const = 0;
virtual INT GetTransformedStrokeCap( INT cCapacity, // In, initial pPoints & pTypes capacity
GpPointF ** pPoints, // In/out, may be reallocated here
BYTE ** pTypes, // In/out, may be reallocated here
INT * pCount, // In/out, may change here if flattened
const GpPointF& origin, const GpPointF& tangent, REAL lineWidth, REAL minimumWidth ) const = 0;
virtual REAL GetRadius( REAL lineWidth, REAL minimumWidth ) const = 0;
protected: GpLineCap BaseCap; REAL BaseInset; GpPointF FillHotSpot; GpPointF StrokeHotSpot; GpLineCap StrokeStartCap; GpLineCap StrokeEndCap; GpLineJoin StrokeJoin; REAL StrokeMiterLimit; REAL WidthScale; REAL FillLength; // Length of the FillCap/StrokeCap from
REAL StrokeLength; // zero along the positive y axis.
// Used for computing the direction of
// the cap.
DpPath * FillPath; DpPath * StrokePath; };
#endif
|