NodeBlender Class Reference

A NodeBlender is the class that actually renders the blend stages of a blend object. It also generates NodePath objects when the user does a 'make shapes' on a blend. More...

#include <nodebldr.h>

Inheritance diagram for NodeBlender:

NodeRenderableInk NodeRenderableBounded NodeRenderable Node CCObject SimpleCCObject List of all members.

Public Member Functions

 NodeBlender ()
 This constructor creates a NodeBlender linked to no other with all status flags false and an uninitialized bounding rectangle. Note: Initialise() must be called before the NodeBlender is in a state in which it can be used.
 ~NodeBlender ()
 Default deconstructor.
 NodeBlender (Node *ContextNode, AttachNodeDirection Direction, BOOL Locked=FALSE, BOOL Mangled=FALSE, BOOL Marked=FALSE, BOOL Selected=FALSE)
 This constructor initialises the nodes flags and links it to ContextNode in the direction specified by Direction. All neccesary tree links are updated.
BOOL Initialise (NodeRenderableInk *pNodeStart, NodeRenderableInk *pNodeEnd, INT32 PathIndexStart, INT32 PathIndexEnd, UndoableOperation *pUndoOp, Progress *pProgress, BOOL IgnoreEscape)
 This initialises the blender node so that it is in a state in which it can blend the two nodes together.
void Deinit (BOOL bNodesMayBeChanged=FALSE)
 This deinits the node, setting its internal Initialised flag to FALSE, and deleting any memory that is created during initialisation. It's like a combination of the constructor and destructor, leaving it in a state similar to defualt construction. The state is such that a call to Reinit() can exactly recreate the blender node. Used when hiding NodeBlenders to free up some memory.
BOOL Reinit (NodeRenderableInk *pInkNodeStart=NULL, NodeRenderableInk *pInkNodeEnd=NULL, BOOL ProgressBar=TRUE)
 This will try and reinitialise the blender by using either the relative reference values ObjIndexStart and ObjIndexEnd (if input params are NULL) or the nodes provided.
NodeRenderableInkGetNodeStart ()
NodeRenderableInkGetNodeEnd ()
virtual NodeSimpleCopy ()
 Makes a copy of all the data in the node.
virtual DocRect GetBoundingRect (BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
 if the bounding rect is valid it is returned, if not, it is recalculated and then returned.
virtual DocRect GetBlobBoundingRect ()
 At the moment, blender nodes don't have any blobs, so just the standard bounding box is returned.
DocRect GetUnionBlendedBounds (DocRect &BoundsStart, DocRect &BoundsEnd)
 Finds the blended bounds that lies at point BlendRatio and tests for intersection. Takes into account the path the blend is following, if it has one.
virtual void Render (RenderRegion *pRender)
 Will render the blended steps of this blender node.
virtual void RenderEorDrag (RenderRegion *)
 Renders a version of the blender node for EORed dragging of blends.
virtual void RenderBlendBlobs (RenderRegion *pRender, BOOL RenderStart, BOOL RenderEnd)
 Renders the blobs of the blend paths associated with the given blender NOTE: This only renders blobs if there's only one blend path in both the start and the end of the blend.
virtual void PreExportRender (RenderRegion *pRender)
 Called before this node or any of its children have been rendered to the export region. This outputs the "start blender" command. Supports ArtWorks EPS and Camelot EPS.
virtual BOOL ExportRender (RenderRegion *pRender)
 Called after this node and all of its children have been rendered to the export region. This outputs the "end blender" command. Supports ArtWorks EPS and Camelot EPS.
BOOL IsArtWorksEPSCompatible ()
 A blender is AW EPS compatible if ALL the following conditions are TRUE: 1) This node is between two path nodes. 2) The blender is blending the two path nodes it lies between 3) The two path nodes contain the same number of sub paths.
BOOL IsComplex ()
 The blender is "complex" as far as AW EPS is concerned, if either the start path or the end path of the blend has more that one sub-path.
INT32 GetAWStartPathIndex ()
 This converts PathIndexStart into an index AW understands (compatible with RISCOS path format).
INT32 GetAWEndPathIndex ()
 This converts PathIndexEnd into an index AW understands (compatible with RISCOS path format).
INT32 GetAWPathIndex (BlendRef *pRef, INT32 PathIndex)
 This converts the index into an index AW understands (compatible with RISCOS path format).
virtual void Transform (TransformBase &)
 Transforms all the paths attached to this blender node.
BOOL IsPointOverBlob (DocCoord *pPointerPos, BlendPath **ppBlendPath, INT32 *pIndex, BOOL *pAStart)
 This sees if the point given lies on a selected blob. If a match is found, the ptr to the blend path and index to blob element is returned. Also, if found,*pAStart = TRUE if it belongs to the start path, FALSE for the end path.
BOOL Remap (DocCoord PosStart, DocCoord PosEnd, DocCoord *pInvPosStart, DocCoord *pInvPosEnd)
 If this blender manages to remap a pair of blend paths, then this will return TRUE.
BOOL ConvertAWPathIndexesToCamelot (INT32 *pPathIndexStart, INT32 *pPathIndexEnd)
 This converts ArtWorks path indexes to a Camelot path indexes, for this blender. An AW index is just an index to the nth end point, so all that's done is the nth end point in the path is found.
BOOL FindPathEndPoint (Node *pNodePath, INT32 *pIndex)
 This finds the N'th end point in the given NodePath. This is used to convert AW end point indexes into Camelot end point indexes. If *pIndex <=0 on entry, *pIndex = 0 on exit.
NodeRenderableInkFindObjIndexedNode (INT32 ObjIndex)
 This scans the children of the parent of this blender, until it finds the ObjIndex'th NodeRenderableInk. I.e. if ObjIndex == 0, it returns the first child NodeRenderableInk. if ObjIndex == 1, returns the second child NodeRenderableInk. Fails if: ObjIndex >= number of children the parent has The node found is not a NodeRenderableInk or is a NodeBlender.
virtual BOOL CanSelectAsSimple ()
 Ask a node whether or not it's prepared to become selected when it's clicked on. This function is called in the FindSimple routines when they have just detected a "hit" on a node. This virtual base function is overridden here to indicate that the NodeBlender object is definitely NOT prepared to become selected!
NodeBlendGetNodeBlend ()
 Central NodeBlend "getter".
BOOL IsOneToOne ()
 Gets the one-to-one blend mapping state for this blender, by asking the parent blend node.
BOOL IsNotAntialiased ()
 Gets the NotAntialiased state for this blender, by asking the parent blend node.
virtual UINT32 GetNodeSize () const
 For finding the size of the node.
virtual BOOL CanBecomeA (BecomeA *pBecomeA)
 This function is used by the convert to shapes operation. It determines if the node or any of its children can convert themselves into an InkClass object.
virtual BOOL DoBecomeA (BecomeA *pBecomeA)
 Transforms the object into another type of object.
void GetDebugDetails (StringBase *Str)
 Displays debugging info of the tree For obtaining debug information about the Node.
void GetDebugDetails (StringBase *Str, BlendRef *pBlendRef)
 For obtaining debug information about the blend reference.
virtual BOOL OnClick (DocCoord, ClickType, ClickModifiers, Spread *)
 Allows the Node to respond to clicks by selecting its blobs or starting drags etc. This functions should be overridden in the all the NodeRenderableInk classes so that this version never gets called. Eg the NodePath class might claim the click if it happened over one of its unselected blobs.
virtual BOOL HidingNode ()
 Called whenever the node gets hidden. It calls the Deinit() member function.
virtual BOOL ShowingNode ()
 Called whenever the node gets shown after it's been hidden. It calls the Reinit() member function.
virtual BOOL Snap (DocCoord *pDocCoord)
 Snaps to given coord to the nearest point on the blender node. Just returns FALSE currently.
virtual BOOL Snap (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Snaps the given rect to the nearest CMapPtrToPtr::iterator on the grid, preserving its width and height. The coords of the rect used for the snapping are determined by the PrevCoord and CurCoord coords supplied. This is done to allow the user to control how a selection rectangle is snapped to the grid by the direction of his/her last mouse movement. To force the bottom left hand corner of the rect to be snapped, supply PrevCoord=(0,0) and CurCoord(-1,-1).
UINT32 GetNumBlendSteps ()
 Gets the number of blend steps for this blender, by asking the parent blend node for its num blend steps.
ColourBlendType GetColourBlendType ()
 Gets the way colours are blended by asking the parent blend node.
void SetPathIndexStart (INT32 Index)
void SetPathIndexEnd (INT32 Index)
INT32 GetPathIndexStart ()
INT32 GetPathIndexEnd ()
void SetObjIndexStart (INT32 ObjIndex)
void SetObjIndexEnd (INT32 ObjIndex)
INT32 GetObjIndexStart ()
INT32 GetObjIndexEnd ()
virtual BOOL WritePreChildrenWeb (BaseCamelotFilter *pFilter)
 Writes the blender record to the filter.
virtual BOOL WritePreChildrenNative (BaseCamelotFilter *pFilter)
virtual BOOL WriteBeginChildRecordsWeb (BaseCamelotFilter *pFilter)
 Same as the Native version.
virtual BOOL WriteBeginChildRecordsNative (BaseCamelotFilter *pFilter)
 Begins the child record sequence for the blender.
virtual BOOL WriteEndChildRecordsWeb (BaseCamelotFilter *pFilter)
 Same as the Native version.
virtual BOOL WriteEndChildRecordsNative (BaseCamelotFilter *pFilter)
 Ends the child record sequence for the blend.
virtual BOOL WriteBoundsRecord (BaseCamelotFilter *pFilter)
 Write out a record containing the bounds of this object.
BOOL GetPointOnNodeBlendPath (double BlendRatio, DocCoord *pPoint, double *pAngle)
 Access function to make it easy to get the correct point in the path for this NodeBlender with the given blend ratio.
BOOL GetPointFromDistance (double Distance, DocCoord *pPoint, double *pAngle)
 Access function to make it easy to get the correct point in the path for this NodeBlender with the given distance along the path.
NodeBlendPathGetNodeBlendPath ()
 It gets the node blend path from its parent.
Trans2DMatrixGetRotateMatrix (NodeRenderableBounded *pNode, double Angle)
 Function that returns a matrix that will rotate around the centre of the bounds of the given node.
double GetProportionOfPathDistStart ()
double GetProportionOfPathDistEnd ()
void SetProportionOfPathDistStart (double p)
void SetProportionOfPathDistEnd (double p)
double GetAngleStart ()
double GetAngleEnd ()
void SetAngleStart (double Angle)
void SetAngleEnd (double Angle)
void RotateBounds (DocRect &Bounds, double Angle)
 The bounds are updated to contain the rotated version.
double GetLinearDistance ()
 to get the distance between the start and end nodes of the blender when the blend is not on a curve. Note that it will return an incorrect value if the blend is on a curve.
BOOL GetBlendDirection (double *Gradient)
 To get a vector of the direction of a linear blend.
BOOL GetBlendObjectCentres (DocCoord *FirstCentre, DocCoord *LastCentre)
 To get the centres of the objects that are blended between.
BOOL IsTangential ()
 See above.
void SetUninitialised ()
void SetBlendedOnCurve (BOOL value)
BOOL IsBlendedOnCurve ()
void SetReversed (BOOL value)
BOOL IsReversed ()
void SetNodeBlendPathIndex (INT32 Index)
 See above.
INT32 GetNodeBlendPathIndex ()
 See above.
BOOL ReverseEnds ()
 reverses the blend so that the start node becomes the end node and vice versa
void UpdateBlendStartAngles (Trans2DMatrix &trans)
 Updates a blend on curves start angles after we have rotated the blend.
virtual INT32 EstimateNodeComplexity (OpParam *details)
 This function estimates a complexity value for the node. The complexity value is based upon the total length of all paths in the node.
virtual void PolyCopyNodeContents (NodeRenderable *pNodeCopy)
 Polymorphically copies the contents of this node to another.

Static Public Member Functions

static BOOL ConvertLineToShape (Path *pPath, Path *pShapePath)
 This takes a line and creates a shape out of it, placing the shape in pShapePath.
static BOOL ProcessBlendedPath (DocCoord *pCoords, PathVerb *pVerbs, PathFlags *pFlags, UINT32 Len, BOOL Filled)
 This does any processing necessary on the path generated by GBlend. The three arrays can be used to generate renderable paths, and also legal paths that can be used to create NodePath objects on the tree.
static void SetPathFlags (PathVerb *pVerbs, PathFlags *pFlags, UINT32 Len)
 This generates a legal path flags array based on the given verbs. All it does is set the end point flags correctly, leaving all other flags FALSE.
static void ReversePath (DocCoord *Coords, PathVerb *Verbs, UINT32 Len)
 This will reverse the path definition given in the two arrays.

Private Member Functions

 CC_DECLARE_DYNCREATE (NodeBlender)
void ResetVars ()
 Resets all the member vars to default values. Should only be called by NodeBlender constructors.
void CopyNodeContents (NodeBlender *NodeCopy)
 Copies the data in this node to pCopyOfNode by first calling the base class to get it to copy its stuff, and then copying its own stuff Scope: protected.
BOOL InitBlendRef (NodeRenderableInk *pNode, BlendRef **ppRef, INT32 Index, UndoableOperation *pUndoOp, Progress *pProgress, BOOL IgnoreEscape, Trans2DMatrix *pMatrix)
 This creates and initialises a blend reference.
BOOL CalcObjIndex (NodeRenderableInk *pInkNode, INT32 *pObjIndex)
 Firstly, this will check that this node and pInkNode have the same NodeBlend parent node. If all's well, it will scan the children of the NodeBlend, starting with the first child, counting until it comes to pInkNode. If pInkNode is the first child, *pObjIndex == 0. If the second child, *pObjIndex == 1, etc.
void CheckFullyInitialised ()
 This will set the object's Initialise member to TRUE if it is fully initialised, i.e. pRefStart & pRefEnd != NULL, and ObjIndexStart and ObjIndexEnd and >= 0.
BOOL BlendPaths (BlendPath *pBlendPathStart, BlendPath *pBlendPathEnd, double BlendRatio)
 Blends two BlendPath objects by the amount specified in BlendRatio.
void CreateBlends (RenderRegion *pRender, HandleBecomeA *pHandleBecomeA)
 Will generate the blended steps of this blender node. If pRender != NULL, it will render each blend step to it. if pHandleBecomeA != NULL, it will pass each blend step to pHandleBecomeA->PassBack() as it's generated.
Matrix MakeMatrix (BlendPath *pBlendPathStart, BlendPath *pBlendPathEnd, double BlendRatio)
 Makes the matrix for the transfrom that should be applied to blend paths and attributes.
BOOL CheckBoundsIntersect (RenderRegion *pRender, DocRect &BoundsStart, DocRect &BoundsEnd, double BlendRatio)
 Finds the blended bounds that lies at point BlendRatio and tests for intersection.
DocRect BlendBounds (DocRect &BoundsStart, DocRect &BoundsEnd, double BlendRatio, BOOL UseBlendPath)
 Finds the blended bounds that lies at point BlendRatio and tests for intersection. Takes into account the path the blend is following, if it has one.
BOOL BlendAttributes (RenderRegion *pRender, BlendPath *pBlendPathStart, BlendPath *pBlendPathEnd, CCAttrMap *pBlendedAttribMap, double BlendRatio, double objectRatio, BOOL objectProfileProcessing)
 Blends the attributes of the two BlendPath objects by the amount specified in BlendRatio.
void RenderAttributes (RenderRegion *pRender, CCAttrMap *pAttribMap)
 Renders the attributes to the given render region.
BOOL PreBlend ()
 This should be called just before blending occurs. At the moment it does the following - Initialises stuff so you can call GetCoordArray(), GetVerbArray() and GetFlagArray().
void PostBlend ()
 This should be called just after blending occurs. At the moment it does the following - Releases memory allocated for the temp path arrays.
BOOL ReallocTempBuffers (UINT32 Size)
 Allocates memory for the temp path arrays, and sets the size var to 0 You can use calls to GetCoordArray(), GetVerbArray() and GetFlagArray() to get the alloced arrays.
void DeallocTempBuffers ()
 Releases memory allocated for the temp path arrays, and sets the size var to 0.
DocCoordGetCoordArray (UINT32 MinSize)
 Used to get an array you can write to.
PathVerbGetVerbArray (UINT32 MinSize)
 Used to get an array you can write to.
PathFlagsGetFlagArray (UINT32 MinSize)
 Used to get an array you can write to.
UINT32GetGBlendBuff (UINT32 MinSize)
 Used to get a buffer you can write to.
double MapObjectBlendRatio (double BlendRatio)
 Function that works out what blend ratio to use when creating a blended bath. Allows non-linear processing of blends.
double MapAttrBlendRatio (double BlendRatio)
 Function that works out what blend ratio to use when blending attributes Allows non-linear processing of blend attributes.
double MapPositionBlendRatio (double BlendRatio)
 Function that works out what blend ratio to use when CMapPtrToPtr::iteratoring the blended shapes Allows non-linear processing of blend shape CMapPtrToPtr::iteratoring.
double GetObjectRatio ()
 returns the current mapping of objects
double GetInvertedAttributeRatio ()
 Function that inverts the current attribute profile and returns the mapped value This is needed to fix the problem with profiles and transparencies and other fills that use control points.
BOOL CallBeginBlendStep (BlendNodeParam *pParam, BOOL *usingSumAllPathsPathProcessor)
 Calls all begin blend step functions on appropriate nodes.
BOOL CallEndBlendStep (BlendNodeParam *pParam)
 Calls all end blend step functions on appropriate nodes.

Private Attributes

BlendRefm_pRefStart
BlendRefm_pRefEnd
NodeRenderableInkm_pNodeStart
NodeRenderableInkm_pNodeEnd
INT32 m_ObjIndexStart
INT32 m_ObjIndexEnd
BOOL m_Initialised
UINT32 m_BlendStep
UINT32 m_TempArraySize
DocCoordm_pTempCoords
PathVerbm_pTempVerbs
PathFlagsm_pTempFlags
UINT32 m_GBlendBuffSize
UINT32m_pGBlendBuff
UINT32 m_ArrayLength
INT32 m_PathIndexStart
INT32 m_PathIndexEnd
double m_ProportionOfPathDistStart
double m_ProportionOfPathDistEnd
double m_AngleStart
double m_AngleEnd
BOOL m_BlendedOnCurve
BOOL m_Reversed
INT32 m_NodeBlendPathIndex

Detailed Description

A NodeBlender is the class that actually renders the blend stages of a blend object. It also generates NodePath objects when the user does a 'make shapes' on a blend.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/10/94

Definition at line 360 of file nodebldr.h.


Constructor & Destructor Documentation

NodeBlender::NodeBlender  ) 
 

This constructor creates a NodeBlender linked to no other with all status flags false and an uninitialized bounding rectangle. Note: Initialise() must be called before the NodeBlender is in a state in which it can be used.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/10/94
See also:
Initialise()

Definition at line 317 of file nodebldr.cpp.

00317                         : NodeRenderableInk()
00318 {
00319     ResetVars();
00320 }

NodeBlender::~NodeBlender  ) 
 

Default deconstructor.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/94

Definition at line 332 of file nodebldr.cpp.

00333 {
00334     // Call PostBlend() in case we're trying to be deleted in the middle of rendering.
00335     PostBlend();
00336 
00337     // Delete the two blend references
00338     DELPTR(m_pRefStart);
00339     DELPTR(m_pRefEnd);
00340 }

NodeBlender::NodeBlender Node ContextNode,
AttachNodeDirection  Direction,
BOOL  Locked = FALSE,
BOOL  Mangled = FALSE,
BOOL  Marked = FALSE,
BOOL  Selected = FALSE
 

This constructor initialises the nodes flags and links it to ContextNode in the direction specified by Direction. All neccesary tree links are updated.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/10/94
Parameters:
ContextNode,: Pointer to a node which this node is to be attached to. [INPUTS] MonoOn Direction: MonoOff Specifies the direction in which the node is to be attached to the ContextNode. The values this variable can take are as follows:
PREV : Attach node as a previous sibling of the context node NEXT : Attach node as a next sibling of the context node FIRSTCHILD: Attach node as the first child of the context node LASTCHILD : Attach node as a last child of the context node

BoundingRect: Bounding rectangle

The remaining inputs specify the status of the node:

Locked: Is node locked ? Mangled: Is node mangled ? Marked: Is node marked ? Selected: Is node selected ?

Note: Initialise() must be called before the NodeBlender is in a state in which it can be used.

See also:
Initialise()
Returns:
Errors: An assertion error will occur if ContextNode is NULL

Definition at line 289 of file nodebldr.cpp.

00295                :NodeRenderableInk(ContextNode, Direction, Locked, Mangled, Marked, Selected )  
00296 {                         
00297     ResetVars();
00298 }


Member Function Documentation

BOOL NodeBlender::BlendAttributes RenderRegion pRender,
BlendPath pBlendPathStart,
BlendPath pBlendPathEnd,
CCAttrMap pBlendedAttrMap,
double  BlendRatio,
double  objectRatio,
BOOL  objectProfileProcessing
[private]
 

Blends the attributes of the two BlendPath objects by the amount specified in BlendRatio.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/94
Parameters:
pRender = The Render Region into which we are rendering the blend, or [INPUTS] NULL if not rendering (i.e. doing a make shapes) pBlendPathStart = ptr to blend path to blend from pBlendPathEnd = ptr to blend path to blend to pBlendedAttrMap = ptr to map to store the blended attributes in BlendRatio = amount to blend by (0.0 <= BlendPath <= 1.0) objectRatio = the corresponding object ratio (CGS: allows us to blend object stuff with attributes) objectProfileProcessing = whether we are allowed to blend object (i.e. CMapPtrToPtr::iterator) data of attributes
- [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise
See also:
-

Definition at line 1661 of file nodebldr.cpp.

01665 {
01666     // Check entry params
01667     BOOL ok = (pBlendPathStart != NULL &&
01668                 pBlendPathEnd != NULL && pBlendedAttrMap != NULL);
01669     ERROR3IF(!ok,"One or more NULL entry params");
01670     if (!ok) return FALSE;
01671 
01672     // Find the attributes that are applied to the blend paths
01673     CCAttrMap* pAttrMapStart = m_pRefStart->FindAppliedAttributes(pBlendPathStart);
01674     CCAttrMap* pAttrMapEnd   = m_pRefEnd  ->FindAppliedAttributes(pBlendPathEnd);
01675 
01676     // If either are NULL, return FALSE
01677     if (pAttrMapStart == NULL || pAttrMapEnd == NULL) return FALSE;
01678 
01679 //#ifdef _DEBUG
01680 //  AttrTranspFillGeometry* pLineWidth = NULL;
01681 //  pMap->Lookup((void *)CC_RUNTIME_CLASS(AttrLineWidth), (void *&)pIndent);
01682 //  //UINT32* pCol = pLineWidth->GetStartTransp ();
01683 //
01684 //  pAttrMapEnd->Lookup((void*) CC_RUNTIME_CLASS(AttrTranspFillGeometry),(void* &)pLineWidth);
01685 //  //ol = pLineWidth->GetStartTransp ();
01686 //#endif
01687 
01688     pAttrMapStart->attrMapCreator = pBlendPathStart->GetBlendNode ();
01689     pAttrMapEnd->attrMapCreator = pBlendPathEnd->GetBlendNode ();
01690 
01691     if (GetNodeBlendPath() != NULL)
01692     {
01693         Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pNodeStart,360.0 - m_AngleStart);
01694         Trans2DMatrix* pRotateEnd   = GetRotateMatrix(m_pNodeEnd  ,360.0 - m_AngleEnd  );
01695         if (pRotateStart)   pAttrMapStart->Transform(*pRotateStart);
01696         if (pRotateEnd)     pAttrMapEnd  ->Transform(*pRotateEnd);
01697         DELPTR(pRotateStart);
01698         DELPTR(pRotateEnd);
01699     }
01700 
01701     // Diccon 24/5/2000 Brush attributes need to know about stroke colour, so we need to 
01702     // keep track of both as we find them
01703     AttrBrushType* pBlendedAttrBrush = NULL;
01704     AttrStrokeColour* pBlendedStrokeColour = NULL;;
01705         
01706     // These vars are used as params to the CCAttrMap funcs
01707     CCRuntimeClass* pTypeStart;
01708     void* pValStart;
01709     void* pValEnd;
01710     double OldBlendRatio = BlendRatio;
01711     // Process each attribute in turn
01712     CMapPtrToPtr::iterator PosStart = pAttrMapStart->GetStartPosition();
01713     while ( PosStart != pAttrMapStart->GetEndPosition() )
01714     {
01715         // Get a ptr to the attr at CMapPtrToPtr::iterator PosStart in the start node's attr map
01716         pAttrMapStart->GetNextAssoc(PosStart,pTypeStart,pValStart);
01717         NodeAttribute* pNodeAttrStart = (NodeAttribute *)pValStart;
01718     
01719         BlendRatio = OldBlendRatio; 
01720         // Diccon 10/99 When using non-linear profiles for the objects those attributes
01721         // that make use of control points were not being profiled, making the objects look strange.
01722         // to avoid this those attributes now share the same profiles as the objects.
01723         if (pNodeAttrStart->IsAGradFill())
01724         {
01725         
01726             if (!((AttrFillGeometry*)pNodeAttrStart)->IsAColourFill())
01727             {
01728                 
01729                 BlendRatio = GetObjectRatio();
01730             
01731             }
01732             else
01733             {
01734                 BlendRatio = GetInvertedAttributeRatio();
01735             
01736             }
01737 
01738         }
01739         if (pNodeAttrStart->IsAFlatFill() || (pNodeAttrStart->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrLineWidth)))
01740         {
01741             BlendRatio = GetInvertedAttributeRatio();
01742         }
01743     
01744         // Get a blended attribute
01745         NodeAttribute* pBlendedNodeAttr = NULL;
01746 
01747         // Find an attr of the same type in the end object's attr list,
01748         // and blend the two attrs together
01749         if (pAttrMapEnd->Lookup(pTypeStart,pValEnd))
01750         {
01751             // We've found a matching end attr, so try to blend it with the start attr
01752 
01753             // Set up the param object to pass to the start attr's blend method
01754             BlendAttrParam BlendParam;
01755 
01756             // Initialise the BlendParam with the end attr and blend ratio
01757             if (BlendParam.Init(pRender,
01758                                 (NodeAttribute *)pValEnd,BlendRatio,objectRatio,objectProfileProcessing,GetColourBlendType(),
01759                                 pAttrMapStart, pAttrMapEnd) )
01760             {
01761                 // Successfully initialised, so now try blending the attributes
01762                 if (pNodeAttrStart->Blend(&BlendParam))
01763                 {
01764                     // Attrs successfully blended, now get a ptr to the new attr.
01765                     // Once we get the blended attr ptr, it belongs to us, so we have
01766                     // to delete it when it is not needed
01767                     pBlendedNodeAttr = BlendParam.GetBlendedAttr();
01768                 }
01769                 else
01770                 {
01771 #ifdef _DEBUG
01772                     void *tmp = NULL;
01773                     ENSURE(!pBlendedAttrMap->Lookup(pNodeAttrStart->GetRuntimeClass(),tmp),"Didn't blend attr, but there's still one in pBlendedAttrMap");
01774 #endif
01775                 }
01776             }
01777         }
01778 
01779         // If we have a blended attr, pBlendedNodeAttr != NULL
01780         if (pBlendedNodeAttr != NULL)
01781         {
01782             // Get the type of the blended attr
01783             CCRuntimeClass* pTypeBlend = pBlendedNodeAttr->GetAttributeType();
01784             void* pValBlend;
01785 
01786             // If we already have an attr in the blended attr map of the same type,
01787             // remove it and delete it, before inserting a new attr of this type
01788             if (pBlendedAttrMap->Lookup(pTypeBlend,pValBlend))
01789             {
01790                 if (pValBlend != NULL)
01791                 {
01792                     pBlendedAttrMap->RemoveKey(pTypeBlend);
01793                     delete (NodeAttribute*)pValBlend;
01794                 }
01795             }
01796             // add it to the blend map
01797             pBlendedAttrMap->SetAt(pTypeBlend,pBlendedNodeAttr);
01798 
01799             // find out if we are a stroke colour or a brush
01800             if (pBlendedNodeAttr->IsAStrokeColour())
01801                 pBlendedStrokeColour = (AttrStrokeColour*)pBlendedNodeAttr;
01802             if (pBlendedNodeAttr->IsABrush())
01803                 pBlendedAttrBrush = (AttrBrushType*)pBlendedNodeAttr;
01804         }
01805     }
01806 
01807     if (GetNodeBlendPath() != NULL)
01808     {
01809         Trans2DMatrix* pRotateStart = GetRotateMatrix(m_pNodeStart,m_AngleStart);
01810         Trans2DMatrix* pRotateEnd   = GetRotateMatrix(m_pNodeEnd  ,m_AngleEnd  );
01811         if (pRotateStart)   pAttrMapStart->Transform(*pRotateStart);
01812         if (pRotateEnd)     pAttrMapEnd  ->Transform(*pRotateEnd);
01813         DELPTR(pRotateStart);
01814         DELPTR(pRotateEnd);
01815     }
01816 
01817     // if we got a stroke colour and a brush then tell the brush what the stroke colour is
01818     if (pBlendedAttrBrush != NULL && pBlendedStrokeColour != NULL)
01819         pBlendedAttrBrush->SetBlendedStrokeColour(&(pBlendedStrokeColour->Value.Colour));
01820 
01821     return TRUE;
01822 }

DocRect NodeBlender::BlendBounds DocRect BoundsStart,
DocRect BoundsEnd,
double  BlendRatio,
BOOL  UseBlendPath
[private]
 

Finds the blended bounds that lies at point BlendRatio and tests for intersection. Takes into account the path the blend is following, if it has one.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/5/99
Parameters:
BoundsStart = the blob bounds of start object [INPUTS] BoundsEnd = the blob bounds of end object BlendRatio = current blend point (between 0.0 and 1.0)
- [OUTPUTS]
Returns:
The blended bounds.
See also:
-

Definition at line 1434 of file nodebldr.cpp.

01435 {
01436     DocRect BlendedBounds,OldBoundsStart,OldBoundsEnd;
01437 
01438     if (UseBlendPath)
01439     {
01440         OldBoundsStart = BoundsStart;
01441         OldBoundsEnd   = BoundsEnd;
01442         RotateBounds(BoundsStart,-m_AngleStart);
01443         RotateBounds(BoundsEnd,-m_AngleEnd);
01444     }
01445 
01446     BlendedBounds.lo.x = INT32(BoundsStart.lo.x + ((BoundsEnd.lo.x-BoundsStart.lo.x)*BlendRatio));
01447     BlendedBounds.lo.y = INT32(BoundsStart.lo.y + ((BoundsEnd.lo.y-BoundsStart.lo.y)*BlendRatio));
01448     BlendedBounds.hi.x = INT32(BoundsStart.hi.x + ((BoundsEnd.hi.x-BoundsStart.hi.x)*BlendRatio));
01449     BlendedBounds.hi.y = INT32(BoundsStart.hi.y + ((BoundsEnd.hi.y-BoundsStart.hi.y)*BlendRatio));
01450 
01451     if (UseBlendPath)
01452     {
01453         DocCoord PointOnPath;
01454         double Angle = 0.0;
01455         if (GetPointOnNodeBlendPath(BlendRatio,&PointOnPath,&Angle))
01456         {
01457             DocCoord BBCentre = BlendedBounds.Centre();
01458             BlendedBounds.Translate(PointOnPath.x-BBCentre.x,PointOnPath.y-BBCentre.y);
01459 
01460             RotateBounds(BlendedBounds,Angle);
01461         }
01462     }
01463 
01464     if (UseBlendPath)
01465     {
01466         BoundsStart = OldBoundsStart;
01467         BoundsEnd   = OldBoundsEnd;
01468     }
01469 
01470     return BlendedBounds;
01471 }

BOOL NodeBlender::BlendPaths BlendPath pBlendPathStart,
BlendPath pBlendPathEnd,
double  BlendRatio
[private]
 

Blends two BlendPath objects by the amount specified in BlendRatio.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/10/94
Parameters:
pBlendPathStart = ptr to blend path to blend from [INPUTS] pBlendPathEnd = ptr to blend path to blend to BlendRatio = amount to blend by (0.0 <= BlendPath <= 1.0)
The blended path is stored in three arrays: the coords, the verbs, and the flags. [OUTPUTS] The arrays are:
pTempCoords pTempVerbs pTempFlags

ArrayLength = the length of all three arrays

This allows the caller to decide what to do with the blended path in a very flexible way.

Returns:
TRUE if successful, FALSE otherwise
See also:
-

Definition at line 1850 of file nodebldr.cpp.

01851 {
01852     // Check entry params
01853     BOOL    ok = (pBlendPathStart != NULL && pBlendPathEnd != NULL);
01854     if (ok) ok = (pBlendPathStart->GetBlendNode() != NULL && pBlendPathEnd->GetBlendNode() != NULL);
01855     ERROR3IF(!ok,"One or more NULL entry params");
01856     if (!ok) return FALSE;
01857 
01858     // Get the types of the two paths
01859     PathTypeEnum PathTypeStart = pBlendPathStart->GetPathType();
01860     PathTypeEnum PathTypeEnd   = pBlendPathEnd  ->GetPathType();
01861 
01862     // The blended path will be closed if either of the paths is a shape
01863     BOOL Closed = (PathTypeStart == PATHTYPE_SHAPE) || (PathTypeEnd == PATHTYPE_SHAPE);
01864 
01865     Path * pPathStart = NULL;
01866 
01867     // Find the paths associated with the start and end blend paths
01868     if (pBlendPathStart->GetBlendNode()->IsNodePath())
01869     {
01870         pPathStart = &(((NodePath *)pBlendPathStart->GetBlendNode())->InkPath);
01871     }
01872     else
01873     {
01874         pPathStart = &(((NodePath *)((NodeCompound *)pBlendPathStart->GetBlendNode())->GetNodeToBlend())->InkPath);
01875     }
01876 
01877     Path * pPathEnd = NULL;
01878 
01879     if (pBlendPathEnd->GetBlendNode()->IsNodePath())
01880     {
01881         pPathEnd   = &(((NodePath *)pBlendPathEnd->GetBlendNode())->InkPath);
01882     }
01883     else
01884     {
01885         pPathEnd = &(((NodePath *)((NodeCompound *)pBlendPathEnd->GetBlendNode())->GetNodeToBlend())->InkPath);
01886     }
01887 
01888     // Calculate how large the arrays have to be to store the blended path definition
01889     INT32 DestPathSize = ((pPathStart->GetNumCoords()+pPathEnd->GetNumCoords())*3)+500;
01890 
01891     // Get some arrays used to hold the blended path data, and error if any are NULL
01892     DocCoord*   pDestCoords = GetCoordArray(DestPathSize);
01893     PathVerb*   pDestVerbs  = GetVerbArray(DestPathSize);
01894     PathFlags*  pDestFlags  = GetFlagArray(DestPathSize);
01895     UINT32*         pBuff       = GetGBlendBuff(DestPathSize);
01896     if (pDestCoords == NULL || pDestVerbs == NULL || pDestFlags == NULL || pBuff == NULL)
01897         return FALSE;
01898 
01899     // This section copes with the case when blending a line with a shape.
01900     // In this case we need to get a temp path the is actually a shape version of the line.
01901     // The line is simply reversed back onto itself to form a shape that would look identical to the 
01902     // line if rendered.  This allows the line to appear to open up to the shape when blended.
01903     Path Shape;
01904     if (PathTypeStart != PathTypeEnd)
01905     {
01906         BOOL ok = FALSE;
01907         if (!Shape.Initialise()) return FALSE;
01908 
01909         // if going from a line to a shape, convert the start path to a shape
01910         if (PathTypeStart == PATHTYPE_LINE && PathTypeEnd == PATHTYPE_SHAPE)
01911         {
01912             ok = NodeBlender::ConvertLineToShape(pPathStart,&Shape);
01913             pPathStart = &Shape;
01914         }
01915 
01916         // if going from a shape to a line, convert the end path to a shape
01917         if (PathTypeStart == PATHTYPE_SHAPE && PathTypeEnd == PATHTYPE_LINE)
01918         {
01919             ok = NodeBlender::ConvertLineToShape(pPathEnd,&Shape);
01920             pPathEnd = &Shape;
01921         }
01922 
01923         if (!ok) return FALSE;
01924     }
01925 
01926     // The blend should do a one-to-one mapping when the OneToOne flag is set AND both paths
01927     // have the same number of elements
01928     BOOL OneToOne = FALSE;
01929     if (IsOneToOne())
01930         OneToOne = (pBlendPathStart->GetNumElements() == pBlendPathEnd->GetNumElements());
01931 
01932     // Now actually blend the two paths
01933 
01934     GBlend GBlendObj;
01935 
01936     // Define the blend
01937     GBlendObj.Define(   (PPOINT)pPathStart->GetCoordArray(),    // Specify the start path
01938                         pPathStart->GetVerbArray(),
01939                         pPathStart->GetNumCoords(),
01940 
01941                         (PPOINT)pPathEnd  ->GetCoordArray(),    // Specify the end path
01942                         pPathEnd  ->GetVerbArray(),
01943                         pPathEnd  ->GetNumCoords(),
01944 
01945                         OneToOne,                               // The one-to-one flag
01946                         FLATNESS,                               // Flatness
01947 
01948                         pBuff,                                  // Buffer for GBlend to use
01949                         DestPathSize*sizeof(UINT32));           // The buffer size
01950 
01951     // Blend the paths
01952     m_ArrayLength = GBlendObj.Blend(BlendRatio,                 // The blend ratio, 0.0 < BlendRatio < 1.0
01953                                     (PPOINT)pDestCoords,        // Array to store blended coords
01954                                     pDestVerbs,                 // Array to store blended verbs
01955                                     DestPathSize);              // The num elements in the two arrays
01956 
01957 
01958     // If we're blending a line to another line, we need to make sure that the blended line
01959     // is going in a direction that corresponds to the source lines.  This ensures attributes
01960     // that depend on this direction (e.g. start and end arrows) look correct.
01961     //
01962     // When creating blend paths of lines, we can detect if the blend path has been reversed,
01963     // in relation to the original path, by the original mapping value.
01964     // If it's 0 it has NOT been reversed, otherwise it's been reversed.
01965     //
01966     // If the blend ratio is <=0.5, the blended path is closest to the start blend path,
01967     // so we look at the start blend path's original mapping.
01968     //
01969     // If blend ration > 0.5, look at the end blend path's original mapping.
01970     //
01971     // The (BlendRation <= 0.5) cut-off point is the same as the cut-off point used in the blending
01972     // of attributes.
01973     if (pBlendPathStart->IsLine() && pBlendPathEnd->IsLine())
01974     {
01975         BlendPath* pBlendPath;
01976         if (BlendRatio <= 0.5) 
01977             pBlendPath = pBlendPathStart;
01978         else
01979             pBlendPath = pBlendPathEnd;
01980 
01981         if (pBlendPath->GetOrigMapping() != 0)
01982             ReversePath(pDestCoords,pDestVerbs,m_ArrayLength);
01983     }
01984 
01985     // We need to do some work on the blended path
01986     if (!ProcessBlendedPath(pDestCoords,pDestVerbs,pDestFlags,m_ArrayLength,Closed))
01987         return FALSE;
01988 
01989     return TRUE;
01990 }

BOOL NodeBlender::CalcObjIndex NodeRenderableInk pInkNode,
INT32 *  pObjIndex
[private]
 

Firstly, this will check that this node and pInkNode have the same NodeBlend parent node. If all's well, it will scan the children of the NodeBlend, starting with the first child, counting until it comes to pInkNode. If pInkNode is the first child, *pObjIndex == 0. If the second child, *pObjIndex == 1, etc.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/10/94
Parameters:
pInkNode = ptr to a node that this blender will blend [INPUTS] pObjIndex = ptr to place to store the relative reference to this node
*pObjIndex will contain the reference if TRUE is returned, -1 if FALSE is returned [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise
See also:
-

Definition at line 3188 of file nodebldr.cpp.

03189 {
03190     ERROR2IF(pInkNode == NULL,FALSE,"pInkNode is NULL");
03191     ERROR2IF(pObjIndex == NULL,FALSE,"pObjIndex is NULL");
03192 
03193     Node* pParent = pInkNode->FindParent();
03194 
03195     /*if (pInkNode->IsNodeHidden ())
03196     {
03197         ERROR3 ("Node is hidden!");
03198     }*/
03199 
03200     ERROR2IF(pParent == NULL,FALSE,"pInkNode has no parent");
03201 
03202     if (!pParent->IsController ())      // CGS:  we can now have compound nodes in here!
03203     {
03204         ERROR2IF(!IS_A(pParent,NodeBlend),FALSE,"pInkNode parent is not a NodeBlend");
03205         ERROR2IF(pParent != this->FindParent(),FALSE,"pInkNode has different parent to this node");
03206     }
03207     else
03208     {
03209         // compound might be shadowed - if it is, find the shadow, and check that its parent is the NodeBlend ....
03210         if (IS_A (pParent->FindParent (), NodeShadowController))
03211         {
03212             pParent = pParent->FindParent ()->FindParent ();
03213         }
03214         
03215         ERROR2IF(pParent->FindParent () != this->FindParent(),FALSE,"pInkNode has different parent to this node");
03216     }
03217 
03218     INT32 Index = 0;
03219     Node* pNode = pParent->FindFirstChild();
03220 
03221     while (pNode != NULL && pNode != pInkNode)
03222     {
03223         if (pNode->IS_KIND_OF(NodeRenderableInk))
03224             Index++;
03225         if (pNode->IS_KIND_OF(NodeBlendPath))
03226             Index--;
03227         pNode = pNode->FindNext();
03228     }
03229 
03230     if (pNode == pInkNode)
03231         *pObjIndex = Index;
03232     else
03233         *pObjIndex = -1;
03234 
03235     return (pNode == pInkNode);
03236 }

BOOL NodeBlender::CallBeginBlendStep BlendNodeParam pParam,
BOOL *  usingSumAllPathsPathProcessor
[private]
 

Calls all begin blend step functions on appropriate nodes.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/3/2000
Parameters:
pParam - the bevel node parameter to pass to all nodes [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 687 of file nodebldr.cpp.

00688 {
00689     if (pParam->