NodePath Class Reference

Puts path objects into the tree. More...

#include <nodepath.h>

Inheritance diagram for NodePath:

NodeRenderableInk NodeRenderableBounded NodeRenderable Node CCObject SimpleCCObject NodeBlendPath NodeMouldPath NodeBrushPath List of all members.

Public Member Functions

 NodePath ()
 This constructor creates a NodePath linked to no other with all status flags false and an uninitialized bounding rectangle.
 NodePath (Node *ContextNode, AttachNodeDirection Direction, BOOL Locked=FALSE, BOOL Mangled=FALSE, BOOL Marked=FALSE, BOOL Selected=FALSE)
BOOL SetUpPath (INT32 RequiredSize=12, INT32 BlockSize=12)
 To initialise the Nodepath into a state that can be used, by allocating memory, setting up member variables properly and inserting an EndPath element into the path.
virtual NodeSimpleCopy ()
 Makes a copy of all the data in the node.
virtual DocRect GetBoundingRect (BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
 returns the paths bounding rectangle and recalculates it if it is invalid
virtual DocRect GetBlobBoundingRect ()
 This calculates the bounding box of the path and adds in the influence of the selection blobs. It does not consider if the blobs are visible or not, it just gives the bounding box that they would occupy if they were visible.
virtual void Render (RenderRegion *pRender)
 Will render the path contained within the object to the given render region.
virtual void RenderEorDrag (RenderRegion *)
 Renders a version of the path for EORed dragging of shapes.
virtual void RenderObjectBlobs (RenderRegion *pRender)
 Draws the paths object blobs into the render region supplied.
virtual void RenderTinyBlobs (RenderRegion *pRender)
 Draws the paths Tiny blob into the render region supplied.
virtual void RenderPenBlobs (RenderRegion *pRender)
 Draws the paths pen blobs into the render region supplied.
virtual BOOL WritePreChildrenWeb (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
virtual BOOL WritePreChildrenNative (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
virtual BOOL WriteBeginChildRecordsNative (BaseCamelotFilter *pFilter)
 Begin to write out you child records, in the native format.
virtual BOOL WriteEndChildRecordsNative (BaseCamelotFilter *pFilter)
 End writing out you child records, in the native format.
virtual UINT32 ChooseTagValue ()
 Writes the path record to the filter.
virtual BOOL WritePathRecord (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
virtual BOOL WritePathRefRecord (BaseCamelotFilter *pFilter, UINT32 SrcPathRecNum, Matrix *pTransform)
 Writes the path reference record to the filter.
virtual INT32 CalcPathRecordSize ()
 This func is the centre point at which the size of the record that will contain the path is calculated.
virtual BOOL WritePathToRecord (CamelotFileRecord *pRecord)
 Central func writes out the correct path record.
virtual BOOL CanBecomeA (BecomeA *pBecomeA)
 Interrogation routine to see if a node can be changed into a different node type. Returns TRUE if pClass is a NodePath, FALSE otherwise.
virtual BOOL DoBecomeA (BecomeA *pBecomeA)
 Actually tries to change the node into a different node type. This responds to BECOMEA_PASSBACK reason by making a duplicate NodePath and passing it to the pfnPassBack func provided in the pBecomeA class.
void ClearSubSelection (Spread *pSpread)
 Clears the paths sub-selection and re-draws the blobs to show this.
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 verion never gets called. Eg the NodePath class might claim the click if it happened over one of its unselected blobs.
virtual BOOL OnBlobPopUp (Spread *, DocCoord, ContextMenu *)
 Allows the Node to respond to pop up menu clicks on blobs.
virtual BOOL OnNodePopUp (Spread *, DocCoord, ContextMenu *)
 Allows the Node to respond to pop up menu clicks on it (rather than its blobs).
virtual void Transform (TransformBase &)
 Will Transform all the coords in the path with the transform provided.
virtual String Describe (BOOL Plural, BOOL Verbose)
 To return a description of the NodePath object in either the singular or the plural. This method is called by the DescribeRange method. The description will always begin with a lower case letter.
void GetDebugDetails (StringBase *Str)
 Displays debugging info of the tree For obtaining debug information about the Node.
virtual UINT32 GetNodeSize () const
 For finding the size of the node.
virtual BOOL IsNodePath () const
 Override the node virtual function IsNodePath() and return TRUE as we definitely are one.
virtual BOOL IsPathAllowable ()
 This function following some operations on the path. It allows the path (and objects derived from NodePath) to say wether the operation has left them in an invalid state. For example, following a delete a closed path of one segment is not allowed. Further example, Mould paths can override this function to ensure there is at least four points on the path after a delete.
virtual BOOL Snap (DocCoord *pDocCoord)
 Snaps to given coord to the nearest point on the path. If it is not appropriate to snap the coord to the path (at the moment this means the coord is too far awawy), then FALSE is returned.
virtual BOOL Snap (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Snaps the given rect to the nearest position 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). Scope: public.
virtual BOOL SnapToCoords (DocCoord *pDocCoord)
 Snaps the point to all the magnetic points in a NodePath. These include all the endpoint in the path (ie MoveTos, LineTos and the last point in CurveTos). If it is close enough to any of these points in the path then the coord ischanged to match the point on the path and TRUE is returned. pDocCoord is not effected if it is not close enough to any of the points in the path.
virtual double GetRotationAngle ()
 The overridden function for determining the current angle of rotation of this path.
virtual void DeSelect (BOOL ReDraw, BOOL bDeselectChildren=FALSE)
 When you select a NodePath we can to clear all the selection flags in the path before deselecting the node.
virtual BOOL NeedsToExport (RenderRegion *pRender, BOOL VisibleLayersOnly=FALSE, BOOL CheckSelected=FALSE)
 Virtual function - this version currently returns false if the path is an immediate child of a text story otherwise its always exportable.
virtual BOOL AllowOp (ObjChangeParam *pParam, BOOL SetOpPermissionState=TRUE, BOOL DoPreTriggerEdit=TRUE)
 To get node paths inside text objects to reformat themselves correctly when their paths change. Also see: TextStory::AllowOp().
virtual BOOL IsANodeBlendPath ()
 virtual identifier function,will move to node.h/.cpp when i have time to wait for the rebuild
virtual ChangeCode OnChildChange (ObjChangeParam *pParam)
 It is now necessary to know when the nodepath has been updated because if it has a brush applied to it the brush needs to clear its cache.
NodePathMakeNodePathFromAttributes (double Flatness=750.0, CCAttrMap *pAttrMap=NULL, BOOL bIncludeClosedPaths=FALSE, BOOL IncludeWidth=TRUE)
 See returns.
virtual NodePathGetVariableWidthStrokePath ()
 If we have a variable width stroke applied to us then this will get the path generated by that stroke. This base class version returns NULL, overridden versions must supply their own outline path.
virtual NodePathGetSmoothVariableWidthStrokePath ()
 If we have a variable width stroke applied to us then this will get the path generated by that stroke. This base class version returns NULL, overridden versions must supply their own outline path.
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.
BOOL RetroSmoothMe (double Smoothness)
 Use and abuse the retrosmoother to smooth our ink path. The Retrosmoother is normally activated from the gadget in the shape editor tool however we are hijacking it here for our purposes.
virtual BOOL GetAreaDetails (XLONG *pxlArea, XLONG *pXLPerimeter)
 Work out 2-dimensional properties of this node.
virtual BOOL IsDifferent (Node *pOther)
 Determine if 2 nodes are considered different.
virtual BOOL IsTypeExtendible () const
virtual DocRect ValidateExtend (const ExtendParams &ExtParams)
 Tests to see whether this path's control points are positioned so as to make an extend operation irreversible.
virtual void Extend (const ExtendParams &ExtParams)
void TransformTranslateObject (const ExtendParams &ExtParams)
 Do an extend (as opposed to stretch) operation on this path, using ExtParams as the source of the extend data, together with the extend-centre of this path, defined in NodeRenderable::FindExtendCentre().
virtual DocRect GetExtendTargetBounds (const ExtendParams &ExtParams)
 Return a DocRect which contains the bounds of this node as defined and required by the Extending mechanism.
PathGetPathCopy ()
 A quick'n'easy way to get a permanent copy of our path.
virtual void PolyCopyNodeContents (NodeRenderable *pNodeCopy)
 Polymorphically copies the contents of this node to another.

Static Public Member Functions

static BOOL CreateFromPath (NodePath **ppNewPath, Path *pSrcPath=NULL, Operation *pOp=NULL)
 Create and initialise a new NodePath, using the given path information if provided.

Public Attributes

Path InkPath

Protected Member Functions

void CopyNodeContents (NodePath *NodeCopy)
 Copies the data in the node by first calling the base class to get it to copy its stuff, and then copying its own stuff Scope: protected.

Protected Attributes

double CurrentRotation

Private Member Functions

void HandleBlobClick (DocCoord *, PathFlags *, INT32, INT32, BOOL, BOOL)
 This will handle the selection and deselection of points on a path. For curve segments all the Bezier control points etc will be drawn in. This routine will also spot closed paths and select endpoints as well Scope: Private.

Detailed Description

Puts path objects into the tree.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
See also:
Path

Definition at line 128 of file nodepath.h.


Constructor & Destructor Documentation

NodePath::NodePath  ) 
 

This constructor creates a NodePath linked to no other with all status flags false and an uninitialized bounding rectangle.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/6/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
Note: SetUpPath() must be called before the NodePath is in a state in which it can be used.

See also:
SetUpPath

Definition at line 251 of file nodepath.cpp.

00251                   : NodeRenderableInk()
00252 {
00253     CurrentRotation = 0.0;
00254 }

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


Member Function Documentation

BOOL NodePath::AllowOp ObjChangeParam pParam,
BOOL  SetOpPermissionState = TRUE,
BOOL  DoPreTriggerEdit = TRUE
[virtual]
 

To get node paths inside text objects to reformat themselves correctly when their paths change. Also see: TextStory::AllowOp().

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>; Karim 19/01/2000
Date:
8/5/95
Parameters:
pParam - pointer to the change parameter object [INPUTS] SetOpPermissionState - TRUE to set the Nodes permission flags DoPreTriggerEdit - if TRUE then calls NameGallery::PreTriggerEdit. Must* be TRUE if the calling Op may make any nodes change their bounds, eg move, line width, cut. Use TRUE if unsure.
Returns:
TRUE if the operation can proceede, FALSE to stop it

Reimplemented from Node.

Reimplemented in NodeBlendPath.

Definition at line 2322 of file nodepath.cpp.

02324 {
02325     // call its default AllowOp(); we never want to do a PreTriggerEdit for this.
02326     BOOL allowed = NodeRenderableInk::AllowOp(pParam, SetOpPermissionState, FALSE);
02327 
02328 /*
02329  *  Karim 15/11/2000
02330  *  Commented this out, as I see no point in pretending to be an Op. *Any* parent of ours
02331  *  will have its AllowOp() called anyway, via our base class.
02332  *  
02333     // if allowed, and our parent is a textstory, call the TextStory's AllowOp() as though called directly by the op
02334     Node* pParent=FindParent();
02335     if (allowed && pParent!=NULL && IS_A(pParent,TextStory))
02336         allowed=pParent->AllowOp(pParam,SetOpPermissionState,DoPreTriggerEdit);
02337  */
02338 
02339     // if we're ok so far and were asked to do a PreTriggerEdit, then
02340     // determine whether the Op may change the bounds of some nodes.
02341     // If it may, then call NameGallery::PreTriggerEdit.
02342     if (allowed && DoPreTriggerEdit)
02343     {
02344         // if the Op is non-NULL then query its MayChangeNodeBounds() method.
02345         UndoableOperation* pChangeOp = pParam->GetOpPointer();
02346         if (pChangeOp != NULL && pChangeOp->MayChangeNodeBounds() && NameGallery::Instance())
02347         {
02348             allowed = NameGallery::Instance()->PreTriggerEdit(pChangeOp, pParam, this);
02349         }
02350     }
02351     if (SetOpPermissionState)
02352         SetOpPermission(PERMISSION_ALLOWED);
02353 
02354     return allowed;
02355 }

INT32 NodePath::CalcPathRecordSize  )  [virtual]
 

This func is the centre point at which the size of the record that will contain the path is calculated.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/9/96
Parameters:
- [INPUTS]
Returns:
The size of the record in bytes
See also:
BaseCamelotFilter::WritePathsInRelativeFormat()

Definition at line 2445 of file nodepath.cpp.

02446 {
02447     INT32 NumCoords = InkPath.GetNumCoords();
02448 
02449     if (BaseCamelotFilter::WritePathsInRelativeFormat())
02450         return (sizeof(PathVerb)*NumCoords)+(sizeof(DocCoord)*NumCoords);
02451     else
02452         return sizeof(INT32)+(sizeof(PathVerb)*NumCoords)+(sizeof(DocCoord)*NumCoords);
02453 }

BOOL NodePath::CanBecomeA BecomeA pBecomeA  )  [virtual]
 

Interrogation routine to see if a node can be changed into a different node type. Returns TRUE if pClass is a NodePath, FALSE otherwise.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/10/94
Parameters:
pClass = runtime class to node you wish this node to become [INPUTS] pNumObjects = ptr to place number of objects of type pClass that will be created (Note: can be NULL). pNumObects in undefined on entry
- [OUTPUTS]
Returns:
TRUE if it can, FALSE if it can't
The number you put into pNumObjects (if it's not NULL) should exactly equal the total number of pClass objects you create. It should NOT contain any additional objects you may produce such as group objects for containing the pClass object, or attributes.

Also, the entry value of *pNumObjects cannot be assumed to be 0.

Returns:
Errors: -
See also:
NodePath::DoBecomeA()

Reimplemented from Node.

Definition at line 1358 of file nodepath.cpp.

01359 {
01360     if (pBecomeA->BAPath())
01361     {
01362         pBecomeA->AddCount(1);
01363 
01364         return TRUE;
01365     }
01366 
01367     return FALSE;
01368 }

UINT32 NodePath::ChooseTagValue  )  [virtual]
 

Writes the path record to the filter.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/8/96
Parameters:
- [INPUTS]
Returns:
The tag value that should be used for saving this path
See also:
This function chooses the tag to use based on the filled & stroked flags of the path

Definition at line 2372 of file nodepath.cpp.

02373 {
02374 #ifdef DO_EXPORT
02375     UINT32 Tag = TAG_UNDEFINED;
02376 
02377     if (BaseCamelotFilter::WritePathsInRelativeFormat())
02378     {
02379         Tag = TAG_PATH_RELATIVE;
02380         if (InkPath.IsFilled && !InkPath.IsStroked) 
02381             Tag = TAG_PATH_RELATIVE_FILLED;
02382         else if (!InkPath.IsFilled && InkPath.IsStroked) 
02383             Tag = TAG_PATH_RELATIVE_STROKED;
02384         else if (InkPath.IsFilled && InkPath.IsStroked) 
02385             Tag = TAG_PATH_RELATIVE_FILLED_STROKED;
02386     }
02387     else
02388     {
02389         Tag = TAG_PATH;
02390         if (InkPath.IsFilled && !InkPath.IsStroked) 
02391             Tag = TAG_PATH_FILLED;
02392         else if (!InkPath.IsFilled && InkPath.IsStroked) 
02393             Tag = TAG_PATH_STROKED;
02394         else if (InkPath.IsFilled && InkPath.IsStroked) 
02395             Tag = TAG_PATH_FILLED_STROKED;
02396     }
02397 
02398     return Tag;
02399 #else
02400     return TAG_UNDEFINED;
02401 #endif
02402 }

void NodePath::ClearSubSelection Spread pSpread  ) 
 

Clears the paths sub-selection and re-draws the blobs to show this.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/4/94
Parameters:
pSpread - Pointer to the nodes parent spread [INPUTS]

Definition at line 670 of file nodepath.cpp.

00671 {
00672 #if !defined(EXCLUDE_FROM_RALPH)
00673     ENSURE( pSpread!=NULL, "Parent Spread was NULL in NodePath::ClearSubSelection" );
00674 
00675     if ((pSpread!=NULL) && (InkPath.IsSubSelection()))
00676     {
00677         InkPath.RenderPathBlobs(pSpread);
00678         InkPath.ClearSubSelection();
00679         InkPath.RenderPathBlobs(pSpread);
00680     }
00681 #endif
00682 }

void NodePath::CopyNodeContents NodePath NodeCopy  )  [protected]
 

Copies the data in the node by first calling the base class to get it to copy its stuff, and then copying its own stuff Scope: protected.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
Parameters:
NodeCopy - The node to copy [INPUTS]
See also:
NodeRenderableInk::CopyNodeContents

Definition at line 450 of file nodepath.cpp.

00451 {
00452     NodeRenderableInk::CopyNodeContents( NodeCopy );
00453     
00454     //Copy contents specific to derived class here
00455     if (NodeCopy->InkPath.Initialise(InkPath.GetNumCoords(),12))
00456         NodeCopy->InkPath.CopyPathDataFrom(&InkPath);
00457 }

BOOL NodePath::CreateFromPath NodePath **  ppNewPath,
Path pSrcPath = NULL,
Operation pOp = NULL
[static]
 

Create and initialise a new NodePath, using the given path information if provided.

pSrcPath the path which the new NodePath will copy its data from. if NULL, then you just get back a fresh NodePath, ready for use.

pOp an Op ptr - if we run out of memory, then we can reclaim memory via this ptr; ok if this is NULL.

Parameters:
*pNewPath holds a new NodePath, if successful, NULL otherwise. [OUTPUTS]
Returns:
TRUE if success, FALSE otherwise.

Errors: ERROR2 with FALSE if ppNewPath is NULL.

Definition at line 2982 of file nodepath.cpp.

02983 {
02984     ERROR2IF(ppNewPath == NULL, FALSE, "NodePath::CreateFromPath; called with NULL param!");
02985 
02986     NodePath* pNewPath = NULL;
02987     ALLOC_WITH_FAIL(pNewPath, new NodePath, pOp);
02988     if (pNewPath != NULL)
02989     {
02990         if (pSrcPath != NULL)
02991         {
02992             BOOL    ok = pNewPath->InkPath.Initialise(pSrcPath->GetNumCoords(), 1);
02993             if (ok)
02994                 CALL_WITH_FAIL(pNewPath->InkPath.CopyPathDataFrom(pSrcPath), pOp, ok);
02995 
02996             if (!ok)
02997             {
02998                 delete pNewPath;
02999                 pNewPath = NULL;
03000             }
03001         }
03002         else
03003         {
03004             pNewPath->SetUpPath();
03005         }
03006     }
03007 
03008     *ppNewPath = pNewPath;
03009     return (pNewPath != NULL);
03010 }

String NodePath::Describe BOOL  Plural,
BOOL  Verbose
[virtual]
 

To return a description of the NodePath object in either the singular or the plural. This method is called by the DescribeRange method. The description will always begin with a lower case letter.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/6/93
Parameters:
Plural,: Flag indicating if the string description should be plural or [INPUTS] singular. Retuns: Description of the object
Returns:
Errors: A resource exception will be thrown if a problem occurs when loading the string resource.

Reimplemented from Node.

Definition at line 1130 of file nodepath.cpp.

01131 {     
01132     // if the first subpath is closed, this is a shape rather than a line
01133     if (InkPath.IsSubPathClosed(0))
01134     {
01135         if (Plural)
01136             return(String(_R(IDS_DESCRIBE_SHAPES)));  
01137         else
01138             return(String(_R(IDS_DESCRIBE_SHAPE))); 
01139     }
01140     else
01141     {
01142         if (Plural)
01143             return(String(_R(IDS_PATH_DESCRP)));  
01144         else
01145             return(String(_R(IDS_PATH_DESCRS))); 
01146     }
01147 }; 

void NodePath::DeSelect BOOL  ReDraw,
BOOL  bDeselectChildren = FALSE
[virtual]
 

When you select a NodePath we can to clear all the selection flags in the path before deselecting the node.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/1/95
Parameters:
ReDraw [INPUTS]
- [OUTPUTS]
Returns:
-
See also:
NodeRenderable::DeSelect

Reimplemented from NodeRenderable.

Definition at line 2199 of file nodepath.cpp.

02200 {
02201     if (ReDraw && GetApplication()->GetBlobManager()->GetCurrentInterest().Object)
02202         InkPath.RenderPathSelectedControlBlobs(FindParentSpread());
02203 
02204     InkPath.ClearSubSelection();
02205 
02206     // Now call the parent class
02207     NodeRenderableInk::DeSelect(ReDraw, bDeselectChildren);
02208 }

BOOL NodePath::DoBecomeA BecomeA pBecomeA  )  [virtual]
 

Actually tries to change the node into a different node type. This responds to BECOMEA_PASSBACK reason by making a duplicate NodePath and passing it to the pfnPassBack func provided in the pBecomeA class.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/10/94
Parameters:
pBecomeA = ptr to info class containing everything a node needs to be able [INPUTS] to become something else
- [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise

Errors: -

See also:
NodePath::CanBecomeA()

Reimplemented from Node.

Reimplemented in NodeBlendPath.

Definition at line 1388 of file nodepath.cpp.

01389 {
01390     // Check for a NULL entry param
01391     ERROR2IF_PF(pBecomeA == NULL,FALSE,("pBecomeA is NULL"));
01392 
01393     // This lump checks that the Reason is one that we understand
01394     // It also makes sure that we don't have a NULL UndoOp ptr
01395     BOOL ValidReason = (pBecomeA->GetReason() == BECOMEA_REPLACE || pBecomeA->GetReason() == BECOMEA_PASSBACK);
01396     ERROR2IF_PF(!ValidReason,FALSE,("Unkown BecomeA reason %d",pBecomeA->GetReason()));
01397 
01398     BOOL        Success = TRUE;         // Our success flag (Important that this defaults to TRUE)
01399     NodePath*   pNewNodePath = NULL;    // Ptr to a new NodePath, if we get to make one.
01400     
01401     if (pBecomeA->BAPath())
01402     {
01403         switch (pBecomeA->GetReason())
01404         {
01405             case BECOMEA_REPLACE:
01406                 // We do nothing as we are already a NodePath in the tree
01407                 // except tell the caller where we are in the tree...
01408                 pBecomeA->PassBack(this, this);
01409                 break;
01410 
01411             case BECOMEA_PASSBACK :
01412             {
01413                 // Make a copy of this NodePath
01414                 CALL_WITH_FAIL(((pNewNodePath = (NodePath*)SimpleCopy()) != NULL), pBecomeA->GetUndoOp(), Success);
01415 
01416                 // If successful, pass it back with my attribute map
01417                 if (Success) Success = pBecomeA->PassBack(pNewNodePath,this);
01418             }
01419             break;
01420             default: break;
01421         }
01422     }
01423 
01424     if (!Success)
01425     {
01426         if (pNewNodePath != NULL)
01427         {
01428             // Delete all the NodePath's children (if it has any) and unlink it from the tree (if it's linked)
01429             // This is all done by CascadeDelete()
01430             pNewNodePath->CascadeDelete(); 
01431             delete pNewNodePath;
01432             pNewNodePath = NULL;
01433         }
01434     }
01435 
01436     return Success;
01437 }

INT32 NodePath::EstimateNodeComplexity OpParam details  )  [virtual]
 

This function estimates a complexity value for the node. The complexity value is based upon the total length of all paths in the node.

Author:
Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/09/2000
Parameters:
details any data that should be used for the calculation [INPUTS]
- [OUTPUTS]
Returns:
an estimate of the nodes complexity
See Also: OpBlendNodes::DeterminBlendObjectsProcessorHit ()

Reimplemented from Node.

Definition at line 2426 of file nodepath.cpp.

02427 {
02428     return (InkPath.GetUsedSlots ());
02429 }

void NodePath::Extend const ExtendParams ExtParams  )  [virtual]
 

the path extends separately along each axis. if the path is asked to stretch, it scales along the corresponding axes. if the path is asked to extend, its control points translate, as described by ExtParams.

Returns:
Errors: See also: class Extender

Reimplemented from Node.

Definition at line 2850 of file nodepath.cpp.

02851 {
02852     TransformTranslateObject(ExtParams);
02853     TransformStretchObject(ExtParams);
02854 
02855     // do the base-class implementation to extend our children.
02856     Node::Extend(ExtParams);
02857 }

BOOL NodePath::GetAreaDetails XLONG pxlArea,
XLONG pxlPerimeter
[virtual]
 

Work out 2-dimensional properties of this node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/03/2005
Parameters:
xlArea [OUTPUTS] xlPerimeter
Returns:
TRUE if calcs succeeded

Reimplemented from NodeRenderableInk.

Definition at line 3060 of file nodepath.cpp.

03061 {
03062     BOOL bOK = TRUE;
03063 
03064     *pxlArea = InkPath.CalcArea();
03065     double dDistance = 0;
03066     bOK = InkPath.DistanceTo(InkPath.GetNumCoords()-1, 1, &dDistance);
03067     *pxlPerimeter = (INT32)dDistance;
03068 
03069     return TRUE;
03070 }

DocRect NodePath::GetBlobBoundingRect  )  [virtual]
 

This calculates the bounding box of the path and adds in the influence of the selection blobs. It does not consider if the blobs are visible or not, it just gives the bounding box that they would occupy if they were visible.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/02/94
Returns:
DocRect - Returns the bounding rect of the path and its blobs

Reimplemented from NodeRenderable.

Definition at line 1256 of file nodepath.cpp.

01257 {
01258     // Also, scan through all the points to find the bounds of the blobs
01259     PathVerb* Verbs = InkPath.GetVerbArray();
01260     PathFlags* Flags = InkPath.GetFlagArray();
01261     DocCoord* Coords = InkPath.GetCoordArray();
01262     INT32 NumCoords = InkPath.GetNumCoords();
01263 
01264     DocRect BlobRect;
01265     DocRect Rect;
01266 
01267     //Go get the blob manager and just return the bounding rect
01268     BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01269     if (BlobMgr==NULL)
01270         return GetBoundingRect();
01271 
01272     // loop through all the coords adding them to the bounding rect
01273     for (INT32 i=0; i<NumCoords; i++)
01274     {
01275         if (i==0)
01276         {
01277             // Set up initial rect to be just the first point
01278             Rect = DocRect(Coords[0].x,      Coords[0].y,
01279                            Coords[0].x + 1L, Coords[0].y + 1L);
01280         }
01281         else
01282         {
01283             // Expand the rectangle to include this point
01284             Rect.IncludePoint(Coords[i]);
01285         }
01286     }
01287 
01288     // Put blobs at the bottom-left and top-right corners, and include these in the rectangle
01289     BlobMgr->GetBlobRect(Rect.lo, &BlobRect);
01290     Rect = Rect.Union(BlobRect);
01291     BlobMgr->GetBlobRect(Rect.hi, &BlobRect);
01292     Rect = Rect.Union(BlobRect);
01293 
01294     // Now make sure we include any extra blobs dependent on the
01295     // blob type
01296 
01297     BlobStyle Blobs = BlobMgr->GetCurrentInterest(TRUE);
01298     if (Blobs.Pen)
01299     {
01300         // ok, if its the pen blobs, we need to do extra things over
01301         // and above the standard coord blobs. We need to add an extra
01302         // ghost point at the end of the path, if there is a curveto
01303 
01304         PathVerb LastVerb = Verbs[NumCoords-1];
01305         PathFlags LastFlag = Flags[NumCoords-1];
01306 
01307         if ((LastVerb == PT_BEZIERTO) && (LastFlag.IsRotate))
01308         {
01309             DocCoord Pt0 = Coords[NumCoords-2];
01310             DocCoord Pt1 = Coords[NumCoords-1];
01311 
01312             DocCoord GhostPt;
01313             GhostPt.x = Pt1.x - (Pt0.x - Pt1.x);
01314             GhostPt.y = Pt1.y - (Pt0.y - Pt1.y);
01315 
01316             BlobMgr->GetBlobRect(GhostPt,&BlobRect);
01317             Rect = Rect.Union(BlobRect);
01318         }
01319     }
01320 
01321     // Make sure we include the Bounds of our children
01322     IncludeChildrensBoundingRects(&Rect);
01323 
01324     // return the rectangle with the blobs included
01325     return Rect;
01326 }

DocRect NodePath::GetBoundingRect BOOL  DontUseAttrs = FALSE,
BOOL  HitTest = FALSE
[virtual]
 

returns the paths bounding rectangle and recalculates it if it is invalid

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/02/94
Parameters:
DontUseAttrs - TRUE if you don't want to use the nodes attrs to calculate [INPUTS] the bounding rect (defaults will be used). Defaults to FALSE. HitTest - TRUE if being called during HitTest
Returns:
The paths bounding rectangle.
See also:
NodePath::GetBlobBoundingRect; NodeRenderableBounded::GetBoundingRect

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeBlendPath, and NodeMouldPath.

Definition at line 1167 of file nodepath.cpp.

01168 {
01169     // go and recalculate the bounding rect if it is not known
01170     if (!IsBoundingRectValid || DontUseAttrs)
01171     {
01172         // a rect to put the new version of the bounding rect into
01173         DocRect NewBoundingRect;
01174 
01175         // Find out what the paths bounding rect is now
01176         if (!CalculatePathBoundingRect(InkPath, DontUseAttrs, &NewBoundingRect))
01177         {
01178             // GDraw failed to find out how big the bounding rect
01179             // we will have to make do with the bounding rect of the coords
01180             NewBoundingRect = InkPath.GetBoundingRect();
01181         }
01182 
01183         // If the line is vertical/horizontal with zero width then we will have a 0 width/height rect
01184         // Inflate this so rectangle calculations work.
01185         if (NewBoundingRect.Width() == 0)
01186             NewBoundingRect.hi.x++;
01187         if (NewBoundingRect.Height() == 0)
01188             NewBoundingRect.hi.y++;
01189 
01190         // we have a new bounding rect - decide what to do with it
01191         if (DontUseAttrs)
01192         {
01193             // but it is not the real bounding rect, so just return it
01194             return NewBoundingRect;
01195         }
01196         else
01197         {
01198             // We need to go though the attributes applied to this path,
01199             // and see if any of them effect the bounding rect
01200             // (eg. ArrowHeads)
01201             CCAttrMap AttribMap(30);
01202             if (FindAppliedAttributes(&AttribMap))
01203             {
01204                 void* pType;
01205                 void* pVal;
01206 
01207                 // iterating all (key, value) pairs
01208                 CCAttrMap::iterator end = AttribMap.GetEndPosition();
01209                 for( CCAttrMap::iterator Pos = AttribMap.GetStartPosition(); Pos != end; ++Pos )
01210                 {
01211                     // Get attr at position Pos
01212                     pType = Pos->first;
01213                     pVal = Pos->second;
01214 
01215                     if (pVal != NULL)
01216                     {
01217                         if ( ((NodeAttribute*)pVal)->EffectsParentBounds() )
01218                         {
01219                             // Get the bounds of the attribute and Union it with
01220                             // the path bounds
01221                             DocRect AttrBounds = 
01222                                 ((NodeAttribute*)pVal)->GetAttrBoundingRect(this, &AttribMap);
01223                             NewBoundingRect = NewBoundingRect.Union(AttrBounds);
01224                         }
01225                     }
01226                 }
01227             }
01228 
01229             // Update the Nodes bounding rectangle
01230             BoundingRectangle = NewBoundingRect;
01231 
01232             // Mark the rect as valid
01233             IsBoundingRectValid = TRUE;
01234         }
01235     }
01236 
01237     // return the current bounding rect
01238     return BoundingRectangle;
01239 }

void NodePath::GetDebugDetails StringBase Str  )  [virtual]
 

Displays debugging info of the tree For obtaining debug information about the Node.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/9/93
Parameters:
Str,: String giving debug info about the node [OUTPUTS]

Reimplemented from NodeRenderableBounded.

Definition at line 336 of file nodepath.cpp.

00337 {
00338 #ifdef _DEBUG
00339     // Call base class
00340     NodeRenderableInk::GetDebugDetails( Str );
00341     
00342     InkPath.FindStartOfPath();
00343     String_256 TempStr;
00344         
00345     (*Str) += TEXT( "\r\nPath Data Dump\r\n" );
00346     TempStr._MakeMsg( TEXT( "#1%ld bytes used\r\n"), InkPath.GetPathByteLength() );
00347     (*Str) += TempStr;
00348 
00349 #if !defined(EXCLUDE_FROM_RALPH)
00350     DocRect BlobRect = GetBlobBoundingRect();
00351     TempStr._MakeMsg( TEXT("Blob Bounding Rect :-\r\n\t#1%ld,\t#2%ld\r\n\t#3%ld,\t#4%ld\r\n"),
00352                       BlobRect.lo.x, BlobRect.lo.y, BlobRect.hi.x, BlobRect.hi.y );
00353     (*Str) += TempStr;
00354 #endif
00355 
00356     TempStr._MakeMsg(TEXT("The Path is #1%sFilled and #2%sStroked\r\n"), InkPath.IsFilled ? "" : "not ", InkPath.IsStroked ? "" : "not ");
00357     (*Str) += TempStr;
00358 
00359     (*Str) += TEXT( "\r\nNum\tType\tX Coord\tY Coord\r\n" );
00360     PathVerb* Verbs  = InkPath.GetVerbArray();
00361     DocCoord* Coords = InkPath.GetCoordArray();
00362     PathFlags* Flags = InkPath.GetFlagArray();
00363     INT32 numcoords = InkPath.GetNumCoords();
00364     for (INT32 i=0; i<numcoords; i++)
00365     {
00366         // Add the info to the string
00367         TempStr._MakeMsg( TEXT("#1%d.\t#2%d\t#3%ld,\t#4%ld\t"),
00368                           i, Verbs[i], Coords[i].x, Coords[i].y );
00369         
00370         // Add useful flags to the end of the string
00371         if (Flags[i].IsSmooth)
00372             TempStr += TEXT("S");
00373 
00374         if (Flags[i].IsRotate)
00375             TempStr += TEXT("R");
00376 
00377         if (Flags[i].IsEndPoint)
00378             TempStr += TEXT("E");
00379 
00380         if (Flags[i].IsSelected)
00381             TempStr += TEXT("(sel)");
00382 
00383         TempStr += TEXT("\r\n");
00384     
00385         (*Str) += TempStr;
00386 
00387     }
00388 #endif
00389 }

DocRect NodePath::GetExtendTargetBounds const ExtendParams ExtParams  )  [virtual]
 

Return a DocRect which contains the bounds of this node as defined and required by the Extending mechanism.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/06/2000
Parameters:
ExtParams const ref to an ExtendParams class describing the extension. [INPUTS]
[OUTPUTS] 
Returns:
The DocRect to treat as the bounding rect of this node when extending.
We treat x- and y- directions separately, and we always return our true bounds, unless we're extending in a direction, in which case we return the bounds of our extend control points, which are currently all of our inkpath's control points.
Returns:
Errors: See also: SliceHelper::BoundingNodeSize().

Reimplemented from NodeRenderableBounded.

Definition at line 2936 of file nodepath.cpp.

02937 {
02938     // think twice about using InkPath::GetTrueBoundingRect() here - using
02939     // NodePath::GetBoundingRect takes factors such as attributes into account.
02940     DocRect drBounds        = GetBoundingRect();
02941     DocRect drPointBounds   = InkPath.GetBoundingRect();
02942     if (ExtParams.fExtendFlags & X_EXTEND)
02943     {
02944         drBounds.lo.x = drPointBounds.lo.x;
02945         drBounds.hi.x = drPointBounds.hi.x;
02946     }
02947     if (ExtParams.fExtendFlags & Y_EXTEND)
02948     {
02949         drBounds.lo.y = drPointBounds.lo.y;
02950         drBounds.hi.y = drPointBounds.hi.y;
02951     }
02952 
02953     return drBounds;
02954 }

UINT32 NodePath::GetNodeSize  )  const [virtual]
 

For finding the size of the node.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/10/93
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The size of the path node in bytes
See also:
Node::GetSubtreeSize

Reimplemented from Node.

Definition at line 407 of file nodepath.cpp.

00408 {     
00409     return (sizeof(NodePath)+InkPath.GetPathByteLength());  
00410 }  

Path * NodePath::GetPathCopy  ) 
 

A quick'n'easy way to get a permanent copy of our path.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/2000
Returns:
ptr to a copy of our path if successful, NULL otherwise.
Notes: The copy is allocated on the heap, so it's *your* responsibility to dispose of it.

Definition at line 3029 of file nodepath.cpp.

03030 {
03031     Path* pResult = new Path;
03032     if (pResult != NULL)
03033     {
03034         if (!pResult->Initialise(InkPath.GetNumCoords()) ||
03035             !pResult->CloneFrom(InkPath))
03036         {
03037             delete pResult;
03038             pResult = NULL;
03039         }
03040     }
03041 
03042     return pResult;
03043 }

double NodePath::GetRotationAngle  )  [virtual]
 

The overridden function for determining the current angle of rotation of this path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/1/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The current angle of rotation of the path
See also:
NodeRenderableBounded::GetRotationAngle

Reimplemented from NodeRenderableBounded.

Definition at line 2178 of file nodepath.cpp.

02179 {
02180     return CurrentRotation;
02181 }

NodePath * NodePath::GetSmoothVariableWidthStrokePath  )  [virtual]
 

If we have a variable width stroke applied to us then this will get the path generated by that stroke. This base class version returns NULL, overridden versions must supply their own outline path.

Author:
Priestley (Xara Group Ltd) <camelotdev@xara.com> ripped from Diccon
Date:
18-11-2000
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
a nodepath containing the path that is generated by any variable width strokes that are applied to us, or NULL if there aren't any
THIS FUNCTION IS THE SAME AS THAT ABOVE, BUT JUST RETURNS THE SMOOTHED PATH

See also: NodePath::GetVariableWidthStrokePath, NodeRegularShape::GetVariableWidthStrokePath

Reimplemented from NodeRenderableInk.

Definition at line 1504 of file nodepath.cpp.

01505 {
01506     // first find out if we actually have a variable width applied to us, if not then we don't do anything
01507     AttrVariableWidth* pVarWidth = NULL;
01508     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth), (NodeAttribute**)&pVarWidth);
01509     if (pVarWidth && ((VariableWidthAttrValue*)pVarWidth->GetAttributeValue())->GetWidthFunction() == NULL)
01510         return NULL;
01511 
01512     // next find the stroke attribute that actually does the work
01513     AttrStrokeType* pStroke = NULL;
01514     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeType), (NodeAttribute**)&pStroke);
01515     
01516     NodePath* pRetNode = NULL;
01517     if (pStroke && pStroke->HasPathProcessor())
01518     {
01519         PathProcessorStroke* pPPS = pStroke->GetPathProcessor();
01520             
01521         pRetNode = pPPS->GetSmoothProcessedPath(&InkPath, this);
01522     }
01523         
01524     return pRetNode;    
01525 }

NodePath * NodePath::GetVariableWidthStrokePath  )  [virtual]
 

If we have a variable width stroke applied to us then this will get the path generated by that stroke. This base class version returns NULL, overridden versions must supply their own outline path.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
15-5-2000
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
a nodepath containing the path that is generated by any variable width strokes that are applied to us, or NULL if there aren't any
In this version we simply use our inkpath

See also: NodePath::GetVariableWidthStrokePath, NodeRegularShape::GetVariableWidthStrokePath

Reimplemented from NodeRenderableInk.

Definition at line 1460 of file nodepath.cpp.

01461 {
01462     // first find out if we actually have a variable width applied to us, if not then we don't do anything
01463     AttrVariableWidth* pVarWidth = NULL;
01464     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth), (NodeAttribute**)&pVarWidth);
01465     if (pVarWidth && ((VariableWidthAttrValue*)pVarWidth->GetAttributeValue())->GetWidthFunction() == NULL)
01466         return NULL;
01467 
01468     // next find the stroke attribute that actually does the work
01469     AttrStrokeType* pStroke = NULL;
01470     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeType), (NodeAttribute**)&pStroke);
01471     
01472     NodePath* pRetNode = NULL;
01473     if (pStroke && pStroke->HasPathProcessor())
01474     {
01475         PathProcessorStroke* pPPS = pStroke->GetPathProcessor();
01476             
01477         pRetNode = pPPS->GetProcessedPath(&InkPath, this);
01478     }
01479         
01480     return pRetNode;    
01481 }

void NodePath::HandleBlobClick DocCoord Coords,
PathFlags Flags,
INT32  Pos,
INT32  NumCoords,
BOOL  Adjust,
BOOL  Constrain
[private]
 

This will handle the selection and deselection of points on a path. For curve segments all the Bezier control points etc will be drawn in. This routine will also spot closed paths and select endpoints as well Scope: Private.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/11/93
Parameters:
Coords - The array of coordinates [INPUTS] Flags - The array of flags Pos - The item click on Adjust - TRUE if this is an Adjust click Constrain - TRIE if this is a Constrain click.
The values in the flags array are modified by this function [OUTPUTS]

Definition at line 971 of file nodepath.cpp.

00973 {
00974 #if !defined(EXCLUDE_FROM_RALPH)
00975     PathVerb* Verbs = InkPath.GetVerbArray();
00976     
00977     // clear the selection state of all the other selected objects in the tree (but not this one)
00978     if (!Adjust && !Constrain)
00979     {
00980         SelRange* Selected = GetApplication()->FindSelection();
00981         Node* pNode = Selected->FindFirst();
00982         while (pNode!=NULL)
00983         {
00984             if ((pNode!=this) && (pNode->IsKindOf(CC_RUNTIME_CLASS(NodePath))))
00985             {
00986                 // This node needs to get rid of all its selected control points
00987                 NodePath* pNodePath = (NodePath*) pNode;
00988                 if (pNodePath->InkPath.IsSubSelection())
00989                 {
00990                     Spread* pSpread = pNodePath->FindParentSpread();
00991                     ENSURE(pSpread!=NULL, "Node did not have a parent spread in NodePath::HandleBlobClick");
00992                     if (pSpread!=NULL)
00993                     {
00994                         pNodePath->InkPath.RenderPathSelectedControlBlobs(pSpread);
00995                         pNodePath->InkPath.ClearSubSelection();
00996                         pNodePath->InkPath.RenderPathSelectedControlBlobs(pSpread);
00997                     }
00998                 }
00999             }
01000 
01001             // Get the next selected node
01002             pNode = Selected->FindNext(pNode);
01003         }
01004     }
01005 
01006     // Find out what the current selection state is, so that we can toggle it
01007     // Selection state will hold the value we want to set
01008     BOOL NewSelState;
01009     BOOL OldSelState = Flags[Pos].IsSelected;
01010     if (OldSelState)
01011         NewSelState = FALSE;
01012     else
01013         NewSelState = TRUE;
01014 
01015     Spread *pSpread = FindParentSpread();
01016     ENSURE(pSpread != NULL, "NodePath does not have a parent spread");
01017 
01018     // Remove the current blobs from this path before we try and change selection
01019     InkPath.RenderPathSelectedControlBlobs(pSpread);
01020 
01021     // If we're not adjusting, clear the subselection in this path
01022     if (!Adjust && !Constrain)
01023         InkPath.ClearSubSelection();
01024 
01025     // if we are adjusting and constraining then (de)select all the endpoints on the path
01026     if (Adjust && Constrain)
01027     {
01028         BOOL NewSelState = !Flags[Pos].IsSelected;
01029         for (INT32 loop = 0; loop < InkPath.GetNumCoords(); loop++)
01030         {
01031             Flags[loop].IsSelected = NewSelState;
01032         }
01033     }
01034     else
01035     {
01036         // Now change the selection of this point
01037         Flags[Pos].IsSelected = NewSelState;
01038         // If the previous point is a control point then deal with it
01039         if ((Pos>0) && (!Flags[Pos-1].IsEndPoint))
01040         {
01041             // Change the control point's selection state
01042             Flags[Pos-1].IsSelected = NewSelState;
01043         }
01044 
01045         // If the next point is a control point then deal with it
01046         if ((Pos+1<NumCoords) && (!Flags[Pos+1].IsEndPoint))
01047         {
01048             // Change the control point's selection state
01049             Flags[Pos+1].IsSelected = NewSelState;
01050         }
01051     
01052         // Check for this being the first element in a closed subpath
01053         // If this element is a moveto, and the end of the path has the
01054         // CLOSEFIGURE flag set, we should select the endpoint as well
01055         if (Verbs[Pos] == PT_MOVETO)
01056         {
01057             INT32 j;
01058             // This for loop will find either the end of the path, or the next moveto
01059             for (j=Pos+1;j<NumCoords && Verbs[j] != PT_MOVETO;j++); // ; is intentional!
01060             j--;
01061             if (Verbs[j] & PT_CLOSEFIGURE)
01062             {
01063                 //HandleBlobClick(Coords,Flags,j,NumCoords,TRUE);
01064                 Flags[j].IsSelected = NewSelState;
01065                 // If the previous point is a control point then deal with it
01066                 if ((j>0) && (!Flags[j-1].IsEndPoint))
01067                 {
01068                     // Change the control point's selection state
01069                     Flags[j-1].IsSelected = NewSelState;
01070                 }
01071             }
01072 
01073         }
01074     }
01075 
01076     InkPath.RenderPathSelectedControlBlobs(pSpread);
01077 #endif
01078 }

BOOL NodePath::IsANodeBlendPath  )  [virtual]
 

virtual identifier function,will move to node.h/.cpp when i have time to wait for the rebuild

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
Returns:
FALSE;

Reimplemented in NodeBlendPath.

Definition at line 2790 of file nodepath.cpp.

02791 {
02792     return FALSE;
02793 }

BOOL NodePath::IsDifferent Node pOther  )  [virtual]
 

Determine if 2 nodes are considered different.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/2/97
Parameters:
pOther - The node to compare this one to [INPUTS]
Returns:
TRUE if this is considered different from pOther, FALSE if they are the same
Notes: **** IMPORTANT - May not function well enough for your needs! ****

This was written to allow the StrokeComponent class to merge stroke definitions which share identical clipart subtrees. Stroke subtrees are special in that they have had Make Shapes applied to them, and so only contain paths. Hence, I have only defined functions in Node, NodeRenderableBounded, and NodePath - most objects in the tree thus use base class functionality (are they of the same class, and do they have identical bounding boxes). This suffices for my needs, but you may need to implement this function for a lot more node types before it's of use to you.

NodePath checks that the 2 InkPaths contain the same set of Coords and Verbs - currently IGNOREs everything else

Reimplemented from NodeRenderableBounded.

Definition at line 2745 of file nodepath.cpp.

02746 {
02747     // First, check with the base class - this checks the classes are the same type
02748     if (NodeRenderableInk::IsDifferent(pOther))
02749         return(TRUE);
02750 
02751     ERROR3IF(GetRuntimeClass() != pOther->GetRuntimeClass(),
02752             "Node::IsDifferent base class method seems to have been broken");
02753 
02754     // Now, check the path info
02755     if (InkPath.GetNumCoords() != ((NodePath *)pOther)->InkPath.GetNumCoords())
02756         return(TRUE);
02757 
02758     // Check if all the coords and verbs are the same
02759     DocCoord *pCoord1 = InkPath.GetCoordArray();
02760     DocCoord *pCoord2 = ((NodePath *)pOther)->InkPath.GetCoordArray();
02761 
02762     PathVerb *pVerb1  = InkPath.GetVerbArray();
02763     PathVerb *pVerb2  = ((NodePath *)pOther)->InkPath.GetVerbArray();
02764 
02765     for (INT32 i = 0; i < InkPath.GetNumCoords(); i++)
02766     {
02767         if (pVerb1[i] != pVerb2[i] || pCoord1[i] != pCoord2[i])
02768             return(TRUE);
02769     }
02770 
02771     return(FALSE);
02772 }

BOOL NodePath::IsNodePath  )  const [virtual]
 

Override the node virtual function IsNodePath() and return TRUE as we definitely are one.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/03/95
Returns:
TRUE => This node is an instance of NodePath. FALSE => otherwise.

Reimplemented from Node.

Definition at line 271 of file nodepath.cpp.

00272 {
00273     return TRUE;
00274 }

BOOL NodePath::IsPathAllowable  )  [virtual]
 

This function following some operations on the path. It allows the path (and objects derived from NodePath) to say wether the operation has left them in an invalid state. For example, following a delete a closed path of one segment is not allowed. Further example, Mould paths can override this function to ensure there is at least four points on the path after a delete.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/4/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the path is valid FALSE if is not valid
See also:
-

Definition at line 2231 of file nodepath.cpp.

02232 {
02233     INT32 NumCoords = InkPath.GetNumCoords();
02234     PathVerb* Verbs = NULL;
02235     PathFlags* Flags = NULL;
02236     DocCoord* Coords = NULL;
02237     InkPath.GetPathArrays(&Verbs, &Coords, &Flags);
02238 
02239     // It's a moveto/lineto combination
02240     if ( (NumCoords == 2) && (Verbs[1] & PT_CLOSEFIGURE) && ((Verbs[1] & ~PT_CLOSEFIGURE) == PT_LINETO) )
02241     {
02242         ERROR3IF(Verbs[0] != PT_MOVETO,"Path didn't start with a moveto!");
02243         return FALSE;
02244     }
02245 
02246     // It's a moveto/curveto combination
02247     if ( (NumCoords == 4) && (Verbs[3] & PT_CLOSEFIGURE) && ((Verbs[3] & ~PT_CLOSEFIGURE) == PT_BEZIERTO) ) 
02248     {
02249         ERROR3IF(Verbs[0] != PT_MOVETO,"Path didn't start with a moveto!");
02250         ERROR3IF(Verbs[1] != PT_BEZIERTO,"Path didn't continue with a Bezierto!");
02251         return FALSE;
02252     }
02253 
02254     return TRUE;
02255 }

virtual BOOL NodePath::IsTypeExtendible  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 245 of file nodepath.h.

00245 { return TRUE; }

NodePath * NodePath::MakeNodePathFromAttributes double  Flatness = 750.0,
CCAttrMap pAttrMap = NULL,
BOOL  bIncludeClosedPaths = FALSE,
BOOL  IncludeWidth = TRUE
 

See returns.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/12/99
Parameters:
Flatness - The flatness to use in the stroking [INPUTS] pAttrMap - The attribute map to use (if NULL then use the attribute map applied to this object)
[OUTPUTS] 
Returns:
A new node path, stroked + with all line attributes applied to it (i.e. line width, dash patterns, arrowheads etc)

Errors: Scope: public

Definition at line 1547 of file nodepath.cpp.

01549 {
01550     // Find the applied attributes
01551     AttrLineWidth * pAttrLineWidth = NULL;
01552     AttrStartArrow * pAttrStartArrow = NULL;
01553     AttrEndArrow * pAttrEndArrow = NULL;
01554     AttrJoinType * pAttrJoinType = NULL;
01555     AttrStartCap * pAttrStartCap = NULL;
01556     AttrDashPattern * pAttrDashPattern = NULL;
01557     AttrStrokeColour* pAttrStrokeColour = NULL;
01558     AttrStrokeType* pAttrStrokeType = NULL;
01559     AttrVariableWidth* pAttrVariableWidth = NULL;
01560 
01561     if (!pAttrMap)
01562     {
01563         // get all the attributes out of the node
01564         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth),(NodeAttribute **)(&pAttrLineWidth));
01565         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStartArrow),(NodeAttribute **)(&pAttrStartArrow));
01566         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrEndArrow),(NodeAttribute **)(&pAttrEndArrow));
01567         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrJoinType),(NodeAttribute **)(&pAttrJoinType));
01568         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStartCap),(NodeAttribute **)(&pAttrStartCap));    
01569         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrDashPattern),(NodeAttribute **)(&pAttrDashPattern));  
01570         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour),(NodeAttribute **)(&pAttrStrokeColour));    
01571         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeType), (NodeAttribute **)(&pAttrStrokeType));
01572         FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth), (NodeAttribute **)(&pAttrVariableWidth));
01573     }
01574     else
01575     {
01576         // get all the attributes out of the attribute map
01577         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrLineWidth), (void *&)pAttrLineWidth );
01578         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStartArrow), (void *&)pAttrStartArrow );
01579         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrEndArrow), (void *&)pAttrEndArrow);
01580         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrJoinType), (void *&)pAttrJoinType);
01581         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStartCap), (void *&)pAttrStartCap);
01582         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrDashPattern), (void *&)pAttrDashPattern);
01583         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeColour), (void *&)pAttrStrokeColour);
01584         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeType), (void *&)pAttrStrokeType);
01585         pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrVariableWidth), (void *&)pAttrVariableWidth);
01586 
01587         if (!pAttrLineWidth)
01588             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth),(NodeAttribute **)(&pAttrLineWidth));
01589         
01590         if (!pAttrStartArrow)
01591             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStartArrow),(NodeAttribute **)(&pAttrStartArrow));
01592 
01593         if (!pAttrEndArrow)
01594             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrEndArrow), (NodeAttribute **)(&pAttrEndArrow));
01595         
01596         if (!pAttrJoinType)
01597             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrJoinType),(NodeAttribute **)(&pAttrJoinType));
01598         
01599         if (!pAttrStartCap)
01600             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStartCap),(NodeAttribute **)(&pAttrStartCap));
01601         
01602         if (!pAttrDashPattern)
01603             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrDashPattern),(NodeAttribute **)(&pAttrDashPattern));  
01604         
01605         if (!pAttrStrokeColour)
01606             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour),(NodeAttribute **)(&pAttrStrokeColour));    
01607 
01608         if (!pAttrStrokeType)
01609             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeType), (NodeAttribute **)(&pAttrStrokeType));
01610 
01611         if(!pAttrVariableWidth)
01612             FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth), (NodeAttribute **)(&pAttrVariableWidth));
01613     }
01614 
01615 // ********************************************************************************************
01616 // Matt 20/10/2000
01617 // At this point if stroke shapes are used, we may have a path consisting of a number of points
01618 // joined by lines - we can represent this much more efficiently as a path of a fewer number of
01619 // points joined by curves: This is achieved by smoothing the path with RetroSmooth
01620 // ********************************************************************************************
01621 
01622     // Mark Howitt 18/12/00 - I`ve now made it check to see if the Stroke colour is transparent, as
01623     // the outline of the last line width is returned which is not correct.
01624     // When the outline is made NONE it does not contribute to the objects outline.
01625     BOOL IsTransparentStroke = FALSE;
01626 
01627     if(pAttrStrokeColour)
01628     {
01629         DocColour* pCol = pAttrStrokeColour->Value.GetStartColour();
01630         IsTransparentStroke = pCol->IsTransparent();
01631     }
01632 
01633     // If this nodepath belongs to an object with a stroke type attribute, then we should smooth it...
01634     if (pAttrStrokeType && !IsTransparentStroke)
01635     {
01636         // Check to see if the Stroke is the default type by checking the Variable width Attribute
01637         // Width function pointer!
01638         if(pAttrVariableWidth && ((VariableWidthAttrValue*)pAttrVariableWidth->GetAttributeValue())->GetWidthFunction() != NULL)
01639         {
01640 //          double Smooth = 15.0;
01641 
01642 #ifdef CONVERTSTROKES  // vector stroking in here
01643 
01644             PathProcessorStroke* pPPS = pAttrStrokeType->GetPathProcessor();
01645             if (pPPS)
01646             {
01647                 BOOL OriginalIsClosed = InkPath.IsClosed();
01648 
01649                 Path UnStrokedPath;
01650                 UnStrokedPath.Initialise();
01651 
01652                 if(OriginalIsClosed)
01653                     UnStrokedPath.CloneFrom(InkPath);
01654 
01655                 // path processor stroke always wants stroked unfilled path
01656                 Path ClonePath;
01657                 ClonePath.Initialise();
01658                 ClonePath.CloneFrom(InkPath);
01659 
01660                 ClonePath.IsFilled = FALSE;
01661                 ClonePath.IsStroked = TRUE;
01662 
01663                 // Path processor makes a nodepath for us
01664                 NodePath* pNewNodePath = pPPS->GetSmoothProcessedPath(&ClonePath, this);
01665 
01666                 if (pNewNodePath == NULL)
01667                 {
01668                     ERROR3("Urk - Cannae get yer stroak path lassie");
01669                 }
01670                 else
01671                 {
01672                     double SFlat = pNewNodePath->InkPath.CalculateFlatnessValueFromPath(500.0,2.0,375.0);
01673                     double CFlat = UnStrokedPath.CalculateFlatnessValueFromPath(500.0,2.0,375.0);
01674                     DWORD ClipRule = OriginalIsClosed ? 7 : 3;
01675                     if(UnStrokedPath.ClipPathToPath(pNewNodePath->InkPath,&pNewNodePath->InkPath,ClipRule|CLIPPING_SOURCE_WINDING,20,SFlat,CFlat) < 0)
01676                     {
01677                         ERROR3("Urk - Cannae get yer stroak path lassie");
01678                     }
01679                 }
01680 
01681                 return pNewNodePath;
01682             }
01683 #else               
01684             if (RetroSmoothMe(Smooth))
01685             {
01686                 // make a copy to return
01687                 NodePath * pRetnNode = new NodePath;
01688                 ERROR2IF(!pRetnNode,NULL,"Failed to create a new Path Node!");
01689                 pRetnNode->InkPath.Initialise();
01690                 pRetnNode->InkPath.CloneFrom(InkPath);
01691                 return pRetnNode;
01692             }
01693 #endif
01694         }
01695     }
01696 
01697 // ********************************************************************************************
01698 // End of RetroSmoothing...
01699 // ********************************************************************************************
01700 
01701     // Make the return node and initialize it!
01702     NodePath * pRetnNode = new NodePath;
01703     ERROR2IF(!pRetnNode,NULL,"Failed to create a new Path Node!");
01704     pRetnNode->InkPath.Initialise();
01705     
01706     Path SrcPath;
01707     SrcPath.Initialise();
01708     SrcPath.CloneFrom(InkPath);
01709 
01710     DashPatternAttribute* pDashPattern = NULL;
01711     StartArrowAttribute* pStartArrow = NULL;
01712     LineWidthAttribute* pLineWidth = NULL;
01713     EndArrowAttribute* pEndArrow = NULL;
01714     JoinTypeAttribute* pJoinType = NULL;
01715     StartCapAttribute* pStartCap = NULL;
01716 
01717     // set up the attribute values
01718     if (pAttrLineWidth)
01719         pLineWidth = &(pAttrLineWidth->Value);
01720 
01721     if (pAttrStartArrow)
01722         pStartArrow = &(pAttrStartArrow->Value);
01723 
01724     if (pAttrEndArrow)
01725         pEndArrow = &(pAttrEndArrow->Value);
01726 
01727     if (pAttrJoinType)
01728         pJoinType = &(pAttrJoinType->Value);
01729 
01730     if (pAttrStartCap)
01731         pStartCap = &(pAttrStartCap->Value);
01732 
01733     if (pAttrDashPattern)
01734         pDashPattern = &(pAttrDashPattern->Value);
01735 
01736     // go through each path checking for non-closed paths
01737     INT32 StartIndex = 0;
01738     INT32 EndIndex = 0;
01739 
01740     Path SubPath;
01741     SubPath.Initialise();
01742 
01743     Path FlatPath;
01744     FlatPath.Initialise();
01745 
01746     UINT32 SubPathNum = 0;
01747     MILLIPOINT Width = 750;
01748     MILLIPOINT EndsWidth = 750;
01749 
01750     if(pLineWidth != NULL)
01751         Width = EndsWidth = pLineWidth->LineWidth;
01752 
01753     if(pAttrStrokeColour && pAttrStrokeColour->GetStartColour()->IsTransparent())
01754     {
01755         Width = 0;
01756         pDashPattern = NULL;
01757     }
01758 
01759     JoinStyles JoinS = JOIN_ROUND;
01760 
01761     if(pJoinType != NULL)
01762         JoinS = (pJoinType->JoinType == MitreJoin) ? JOIN_MITER : (pJoinType->JoinType == RoundJoin) ? JOIN_ROUND : JOIN_BEVEL;
01763 
01765     // Dash pattern - convert to Gavin-ness...
01766     DashType* pDashRec = NULL;
01767     DashType GavinDash;
01768     GavinDash.Length = 0;
01769     GavinDash.Offset = 0;
01770     GavinDash.Array[0] = 0;
01771 
01772     // Do do dash patten if there is one and the line width is greater than 0!
01773     if (pDashPattern && pDashPattern->DashPattern.Elements > 0 && pDashPattern->DashPattern.LineWidth > 0)
01774     {
01775         INT32 Length = pDashPattern->DashPattern.Elements;
01776 
01777         if (Length > 8) Length = 8;
01778 
01779         BOOL DoScale = pDashPattern->DashPattern.ScaleWithLineWidth;
01780         FIXED16 Scale = DoScale ? (double(Width) / double(pDashPattern->DashPattern.LineWidth)) : 1;
01781 
01782         GavinDash.Length = Length;
01783         GavinDash.Offset = LongMulFixed16(pDashPattern->DashPattern.DashStart, Scale);
01784 
01785         for (INT32 el = 0; el < Length; el++)
01786         {
01787             GavinDash.Array[el] = LongMulFixed16(pDashPattern->DashPattern.ElementData[el], Scale);
01788         }
01789     }
01790 
01791     // Set the dash pointer to the gavin dash structure!
01792     pDashRec = &GavinDash;
01793 
01795 
01796     // Make sure that we put the Width to a suitable value if we don`t require line widths in
01797     // the calculations
01798     if(!IncludeWidth && pAttrStrokeColour && !pAttrStrokeColour->GetStartColour()->IsTransparent())
01799         Width = 50;
01800     
01801     Path BlankPath;
01802     BlankPath.Initialise();
01803 
01804     Path StrokedPath;
01805     StrokedPath.Initialise();
01806 
01807     while (StartIndex < InkPath.GetNumCoords())
01808     {
01809         // get the end of the sub-path
01810         EndIndex = StartIndex;
01811         InkPath.FindEndElOfSubPath(&EndIndex);
01812         
01813         // only do this if the sub-path isn't closed
01814 //      if (!InkPath.IsSubPathClosed(StartIndex) || bIncludeClosedPaths)
01815         if (!InkPath.IsClosed() || bIncludeClosedPaths)
01816         {       
01817             // we have found the last element of the sub-path
01818             // therefore make a new path
01819             SubPath.ClearPath();
01820             InkPath.MakePathFromSubPath(SubPathNum, &SubPath);
01821             FlatPath.ClearPath();
01822             FlatPath.CloneFrom(SubPath);
01823             
01824             // first, stroke the path           
01825             SrcPath.IsFilled = FALSE;
01826             SrcPath.IsStroked = FALSE;
01827 
01828             if (pStartCap && pJoinType)
01829             {
01830                 SubPath.StrokePathToPath(Width,
01831                     pStartCap->StartCap,
01832                     pJoinType->JoinType,
01833                     pDashRec,
01834                     &StrokedPath,
01835                     Flatness,
01836                     FALSE);
01837             }
01838             else
01839             {
01840                 SubPath.StrokePathToPath(Width,
01841                     LineCapRound,
01842                     RoundJoin,
01843                     pDashRec,
01844                     &StrokedPath,
01845                     Flatness,
01846                     FALSE);
01847             }
01848 
01849             // ensure the validity of the path
01850             Path ClipPath;
01851             ClipPath.Initialise();
01852             ClipPath.CloneFrom(StrokedPath);
01853             StrokedPath.ClearPath();
01854 
01855             if(ClipPath.ClipPathToPath(BlankPath, &StrokedPath, 6 | CLIPPING_CLIP_WINDING,30, Flatness, Flatness) < 2)
01856                 StrokedPath.CloneFrom(ClipPath);
01857             
01858             // now, do the arrowheads
01859             INT32 Index = 0;
01860             DocCoord Centre;
01861             DocCoord Direction;
01862             Trans2DMatrix ArrowMatrix;
01863             
01864             Path ArrowPath;
01865             ArrowPath.Initialise();
01866             
01867             Path DestPathStartArrow;
01868             DestPathStartArrow.Initialise();
01869             
01870             Path DestPathEndArrow;
01871             DestPathEndArrow.Initialise();
01872 
01873             ClipPath.ClearPath();
01874 
01875             // do the start arrow
01876             if (pStartArrow)
01877             {
01878                 if (pStartArrow->StartArrow.GetArrowPath())
01879                 {
01880                     Centre = FlatPath.GetCoordArray()[0];
01881                     Direction = FlatPath.GetCoordArray()[1];
01882                     
01883                     pStartArrow->StartArrow.GetArrowMatrix(Centre, Direction,
01884                                         EndsWidth, &ArrowMatrix);
01885                     
01886                     // build the arrow's path and add it to the existing path
01887                     ArrowPath.ClearPath();
01888                     ArrowPath.CloneFrom(*pStartArrow->StartArrow.GetArrowPath());
01889                     
01890                     ArrowMatrix.Transform(ArrowPath.GetCoordArray(), ArrowPath.GetNumCoords());
01891                     
01892                     DestPathStartArrow.ClearPath();
01893                     ClipPath.CloneFrom(StrokedPath);
01894                     if(ClipPath.ClipPathToPath(ArrowPath,&StrokedPath, 7 | CLIPPING_SOURCE_WINDING,30, Flatness, Flatness) < 2)
01895                     {
01896                         TRACEUSER( "MarkH", _T("ClipFailed so copying path! NODEPATH\n"));
01897                     }
01898 
01899                     pRetnNode->InkPath.MergeTwoPaths(DestPathStartArrow);
01900                 }
01901             }
01902             
01903             // do the end arrow
01904             if (pEndArrow)
01905             {
01906                 if (pEndArrow->EndArrow.GetArrowPath())
01907                 {
01908                     Index = 0;
01909 
01910                     Centre = FlatPath.GetCoordArray()[FlatPath.GetNumCoords() - 1];
01911                     Direction.x = FlatPath.GetCoordArray()[FlatPath.GetNumCoords() - 1].x -
01912                         FlatPath.GetCoordArray()[FlatPath.GetNumCoords() - 2].x;
01913 
01914                     Direction.y = FlatPath.GetCoordArray()[FlatPath.GetNumCoords() - 1].y -
01915                         FlatPath.GetCoordArray()[FlatPath.GetNumCoords() - 2].y;
01916 
01917                     Direction.x = Centre.x - Direction.x;
01918                     Direction.y = Centre.y - Direction.y;
01919                     
01920                     pEndArrow->EndArrow.GetArrowMatrix(Centre, Direction,
01921                         EndsWidth, &ArrowMatrix);
01922                     
01923                     // build the arrow's path and add it to the existing path
01924                     ArrowPath.ClearPath();
01925                     ArrowPath.CloneFrom(*pEndArrow->EndArrow.GetArrowPath());
01926                     
01927                     ArrowMatrix.Transform(ArrowPath.GetCoordArray(), ArrowPath.GetNumCoords());
01928                     
01929                     DestPathEndArrow.ClearPath();
01930                     ClipPath.CloneFrom(StrokedPath);
01931                     if(ClipPath.ClipPathToPath(ArrowPath,&StrokedPath, 7 | CLIPPING_SOURCE_WINDING,30, Flatness, Flatness) < 2)
01932                     {
01933                         ArrowPath.CloneFrom(ClipPath);
01934                         TRACEUSER( "MarkH", _T("ClipFailed so copying path! NODEPATH\n"));
01935                     }
01936 
01937                     pRetnNode->InkPath.MergeTwoPaths(DestPathEndArrow);
01938                 }
01939             }
01940 
01941             if (pRetnNode->InkPath.GetBoundingRect().Union(StrokedPath.GetBoundingRect()).IsEmpty())
01942             {
01943                 pRetnNode->InkPath.MergeTwoPaths(StrokedPath);
01944             }
01945             else
01946             {
01947                 ClipPath.CloneFrom(pRetnNode->InkPath);
01948                 pRetnNode->InkPath.ClearPath();
01949                 if(StrokedPath.ClipPathToPath(ClipPath, &(pRetnNode->InkPath), 7 | CLIPPING_SOURCE_WINDING,30, Flatness, Flatness) < 2)
01950                 {
01951                     pRetnNode->InkPath.CloneFrom(ClipPath);
01952                     TRACEUSER( "MarkH", _T("ClipFailed so copying path! NODEPATH\n"));
01953                 }
01954             }
01955         }
01956         else
01957         {
01958             SubPath.ClearPath();
01959 
01960             // make sure that if we do require line widths to be taken into account then we need to stroke using the line width!
01961             if(IncludeWidth)
01962             {
01963                 // First do the clipping to make sure the windings come out correct!
01964                 SubPath.CloneFrom(InkPath);
01965                 if(BlankPath.ClipPathToPath(SubPath, &StrokedPath, 3, 10, Flatness, Flatness) < 2)
01966                 {
01967                     StrokedPath.CloneFrom(SubPath);
01968                     TRACEUSER( "MarkH", _T("ClipFailed so copying path! NODEPATH\n"));
01969                 }
01970 
01971                 // Now get the contour step for the full width!
01972                 StrokedPath.InitializeContourValues(Width,JoinS,true,Flatness);
01973                 if(StrokedPath.GetContourForStep(&pRetnNode->InkPath,1.0) < 2)
01974                 {
01975                     pRetnNode->InkPath.CloneFrom(StrokedPath);
01976                     TRACEUSER( "MarkH", _T("ClipFailed so copying path! NODEPATH\n"));
01977                 }
01978             }
01979             else
01980             {
01981                 // Just clone the original!
01982                 InkPath.MakePathFromSubPath(SubPathNum, &SubPath);
01983                 pRetnNode->InkPath.MergeTwoPaths(SubPath);
01984             }
01985         }                           
01986 
01987         StartIndex = EndIndex+1; 
01988         SubPathNum++;
01989     }
01990 
01991     if (pRetnNode)
01992     {
01993         pRetnNode->InkPath.IsFilled = TRUE;
01994         pRetnNode->InkPath.IsStroked = FALSE;
01995     }
01996 
01997     return pRetnNode;
01998 }

BOOL NodePath::NeedsToExport RenderRegion pRender,
BOOL  VisibleLayersOnly = FALSE,
BOOL  CheckSelected = FALSE
[virtual]
 

Virtual function - this version currently returns false if the path is an immediate child of a text story otherwise its always exportable.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/03/95
Parameters:
pRender - A pointer to the current export region [INPUTS] VisibleLayersOnly - TRUE => remove nodes which are on invisible layers
  • FALSE => export everything CheckSelected - TRUE => we check if object selected and only export selected bjects
  • FALSE => we don't bother checking for selection or not
    Returns:
    TRUE => please export me.

Reimplemented from NodeRenderable.

Definition at line 2275 of file nodepath.cpp.

02276 {
02277 #ifdef DO_EXPORT
02278     if (pRender->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
02279     {
02280         Node* pParent=FindParent();
02281         if (pParent!=NULL && IS_A(pParent,TextStory))
02282             return FALSE;
02283     }
02284 
02285     // If we have the check selection flag on then see if this node is:-
02286     // - selected or not = render it
02287     // - a child of the selection e.g. part of selected group where we are an item in the
02288     //   group and hence are not directly selected but still need to be exported
02289     // - a parent of the selected item e.g. selected inside item of group and we are at the
02290     //   group and hence need to include the group in the range 
02291     // Otherwise just return True as this is a path node and always needs to be exported
02292     // unless of course some node overrides this.
02293     if (CheckSelected)
02294         return (IsSelected() || IsChildOfSelected() || IsParentOfSelected());
02295     else
02296         return TRUE;
02297 #else
02298     return FALSE;
02299 #endif
02300 }

BOOL NodePath::OnBlobPopUp Spread pSpread,
DocCoord  PointerPos,
ContextMenu pMenu
[virtual]
 

Allows the Node to respond to pop up menu clicks on blobs.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/04/95
Parameters:
pSpread The spread in which things are happening [INPUTS] PointerPos The Location of the mouse pointer at the time of the click pMenu The menu to which items should be added
Returns:
BOOL - TRUE if the node claims the click as its own and FALSE if it is not interested in the click

Reimplemented from NodeRenderableInk.

Definition at line 873 of file nodepath.cpp.

00874 {
00875 #if !defined(EXCLUDE_FROM_RALPH)
00876     DocRect    BlobRect;
00877 //  DocCoord*  Coords = InkPath.GetCoordArray();
00878 //  PathFlags* Flags  = InkPath.GetFlagArray();
00879 //  PathVerb*  Verbs  = InkPath.GetVerbArray();
00880 
00881     // Should always be able to get selected view
00882     DocView *pDocView = DocView::GetSelected();
00883     ERROR3IF(pDocView == NULL, "NodePath::OnClick: Could not get selected DocView");
00884     if (pDocView == NULL)
00885         return FALSE;
00886 
00887     // If there are no selected points we won't put up our menu because its
00888     // items are entirely to do with points (a useful thing in a Blobs menu!).
00889     if (!InkPath.IsSubSelection())
00890         return FALSE;
00891 
00892 //  INT32 NumCoords = InkPath.GetNumCoords();
00893     INT32 i;
00894     if (InkPath.FindNearestPoint(   PointerPos, 
00895                                     POINTFLAG_ENDPOINTS | 
00896                                     POINTFLAG_CONTROLPOINTS | 
00897                                     POINTFLAG_ENDSFIRST,
00898                                     &i)
00899         )
00900     {
00901         pMenu->BuildCommand(TOOL_OPTOKEN_BEZTOOL, TRUE);
00902 
00903         pMenu->BuildCommand(OPTOKEN_MAKELINESOP);
00904         pMenu->BuildCommand(OPTOKEN_MAKECURVESOP, TRUE);
00905 
00906         pMenu->BuildCommand(OPTOKEN_DELETEPOINTSOP);
00907         pMenu->BuildCommand(OPTOKEN_BREAKATPOINTS, TRUE);
00908 
00909         pMenu->BuildCommand(OPTOKEN_SELECTALLPATHPOINTS);
00910         pMenu->BuildCommand(OPTOKEN_DESELECTALLPATHPOINTS, TRUE);
00911 
00912         return TRUE;
00913     }
00914 
00915 #endif
00916     // we do not want to claim the click, so return FALSE
00917     return FALSE;
00918 }

ChangeCode NodePath::OnChildChange ObjChangeParam pParam  )  [virtual]
 

It is now necessary to know when the nodepath has been updated because if it has a brush applied to it the brush needs to clear its cache.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/01/95
Parameters:
pParam = pointer to a object change parameter class [INPUTS]
Returns:
CC_OK

Reimplemented from Node.

Definition at line 640 of file nodepath.cpp.

00641 {
00642     // look for an applied brush attribute
00643     NodeAttribute* pAttr = NULL;
00644     AttrBrushType* pAttrBrush = NULL;
00645     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), &pAttr);
00646     if (pAttr!= NULL)
00647     {
00648         pAttrBrush = (AttrBrushType*)pAttr;
00649         
00650         // make an undoable action
00651         UpdateBrushAction* pAction;
00652         UndoableOperation* pOp = pParam->GetOpPointer();
00653         if (pOp != NULL)
00654             UpdateBrushAction::Init(pOp, pOp->GetUndoActionList(), this, &pAction);
00655     }
00656     return CC_OK;
00657 }

BOOL NodePath::OnClick DocCoord  PointerPos,
ClickType  Click,
ClickModifiers  ClickMods,
Spread pSpread
[virtual]
 

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 verion never gets called. Eg the NodePath class might claim the click if it happened over one of its unselected blobs.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/10/93
Parameters:
PointerPos - The Location of the mouse pointer at the time of the click [INPUTS] Click - The type of click received (single, double, drag etc) ClickMods - The modifiers to the click (eg shift, control etc )
Returns:
BOOL - TRUE if the node claims the click as its own and FLASE if it is not interested in the click

Reimplemented from NodeRenderableInk.

Definition at line 706 of file nodepath.cpp.

00708 {
00709 #ifndef STANDALONE
00710 
00711     DocRect    BlobRect;
00712     DocCoord*  Coords = InkPath.GetCoordArray();
00713     PathFlags* Flags  = InkPath.GetFlagArray();
00714 //  PathVerb*  Verbs  = InkPath.GetVerbArray();
00715 
00716     // Should always be able to get selected view
00717     DocView *pDocView = DocView::GetSelected();
00718     ERROR3IF(pDocView == NULL, "NodePath::OnClick: Could not get selected DocView");
00719     if (pDocView == NULL)
00720         return FALSE;
00721 
00722     // we only handle the click if we can confirm that object blobs are being displayed.
00723     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
00724     if (pBlobMgr == NULL)
00725         return FALSE;
00726     if (!pBlobMgr->GetCurrentInterest().Object)
00727         return FALSE;
00728 
00729     INT32 NumCoords = InkPath.GetNumCoords();
00730     INT32 i;
00731     if (InkPath.FindNearestPoint(   PointerPos, 
00732                                     POINTFLAG_ENDPOINTS | 
00733                                     POINTFLAG_CONTROLPOINTS | 
00734                                     POINTFLAG_ENDSFIRST,
00735                                     &i)
00736         )
00737     {
00738         // we had a hit on a blob, so do something with it
00739         if ( Click == CLICKTYPE_SINGLE )
00740         {
00741             // Clicks on control points have no effect
00742             // but clicks on endpoints do have an effect
00743             if (Flags[i].IsEndPoint)
00744             {
00745                 if (ClickMods.Adjust && ClickMods.Constrain)
00746                 {
00747                     HandleBlobClick(Coords, Flags, i, NumCoords, TRUE, TRUE);
00748                 }
00749                 else
00750                 {
00751                     if ((!Flags[i].IsSelected) || ((Flags[i].IsSelected) && (ClickMods.Adjust)))                           
00752                     {
00753                         HandleBlobClick(Coords, Flags, i, NumCoords, ClickMods.Adjust, FALSE);
00754                     }                                              
00755                     else
00756                     {
00757                         // In order to deselect all but the clicked on point and still have dragging of
00758                         // multiple points we need to start the drag op on the click and handle a click
00759                         // at the end of the drag
00760                         if (Flags[i].IsSelected && !ClickMods.Menu)
00761                         {
00762                             OpNodePathEditBlob* pOpNodePath = new OpNodePathEditBlob;
00763                             if (pOpNodePath == NULL)
00764                                 InformError();
00765                             else
00766                                 pOpNodePath->DoStartDragEdit(this, Coords[i], pSpread);
00767                         }
00768                     }
00769                 }
00770             }
00771             else
00772             {
00773                 // Detected single click on Control Point
00774             }
00775         }
00776 
00777         if ( Click == CLICKTYPE_DOUBLE)
00778         {
00779             // A point has been double-clicked. Only if it's selected and an endpoint can we
00780             // do anything about it. What we do is the toggle smooth operation
00781 
00782             if (Flags[i].IsSelected && Flags[i].IsEndPoint)
00783             {
00784                 // Try and create the toggle operation
00785                 OpToggleSmooth* pOpToggle = new OpToggleSmooth;
00786                 if (!pOpToggle)
00787                 {
00788                     // Inform the user that we are out of memory
00789                     InformError();
00790                 }
00791                 else
00792                 {
00793                     // Call the function that actually does something
00794                     pOpToggle->DoTogglePoint(this, i, pSpread, FALSE, !ClickMods.Constrain);    // invert constrain
00795                 }
00796             }
00797         }
00798 
00799         // Check for drags, but only when the click isn't due to a menu click.
00800         if ( Click == CLICKTYPE_DRAG && !ClickMods.Menu )
00801         {
00802             
00803             //if (Flags[i].IsSelected)
00804             {
00805                 if (Flags[i].IsEndPoint)
00806                 {
00807                     // Need to do a drag on the selected points,
00808                     // so we had better start an operation
00809                     OpNodePathEditBlob* pOpNodePath = new OpNodePathEditBlob;
00810                     if (pOpNodePath == NULL)
00811                     {
00812                         // Inform the user that we are out of memory
00813                         InformError();
00814                     }
00815                     else
00816                     {
00817                         // Start the drag operation and pass in the Anchor Point to the operation
00818 
00819                         // The anchor point MUST be the true coord of the path point for
00820                         // snapping to work correctly (Markn 30/9/94)
00821 
00822                         pOpNodePath->DoStartDragEdit(this, Coords[i], pSpread);
00823                     }
00824                 }
00825                 else
00826                 {
00827                     // This must be a drag on a control point, so start an operation to
00828                     // handle that situation
00829                     OpNodePathEditControlBlob* pOpNodePath = new OpNodePathEditControlBlob;
00830                     if (pOpNodePath==NULL)
00831                     {
00832                         // Failed to get the mem I needed
00833                         InformError();
00834                     }
00835                     else
00836                     {
00837                         // Start the drag operation and pass in the Anchor Point to the operation
00838 
00839                         // The anchor point MUST be the true coord of the path point for
00840                         // snapping to work correctly (Markn 30/9/94)
00841 
00842                         pOpNodePath->DoStartDragEdit(this, Coords[i], pSpread, i);
00843                     }
00844                 }
00845             }
00846         }                   
00847 
00848         return TRUE;
00849     }
00850 
00851 #endif
00852     // we do not want to claim the click, so return FALSE
00853     return FALSE;
00854 }

BOOL NodePath::OnNodePopUp Spread pSpread,
DocCoord  PointerPos,
ContextMenu pMenu
[virtual]
 

Allows the Node to respond to pop up menu clicks on it (rather than its blobs).

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/05/95
Parameters:
pSpread The spread in which things are happening [INPUTS] PointerPos The Location of the mouse pointer at the time of the click pMenu The menu to which items should be added
Returns:
BOOL - TRUE if the node claims the click as its own and FALSE if it is not interested in the click

Reimplemented from NodeRenderableInk.

Definition at line 936 of file nodepath.cpp.

00937 {
00938 #if !defined(EXCLUDE_FROM_RALPH)
00939     BOOL ok = TRUE;
00940     
00941     ok = ok && pMenu->BuildCommand(TOOL_OPTOKEN_BEZTOOL, TRUE);
00942 
00943     return ok;
00944 #else
00945     return FALSE;
00946 #endif
00947 }

void NodePath::PolyCopyNodeContents NodeRenderable pNodeCopy  )  [virtual]
 

Polymorphically copies the contents of this node to another.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/2003
Parameters:
- [OUTPUTS]
Returns:
Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 474 of file nodepath.cpp.

00475 {
00476     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
00477     ENSURE(IS_A(pNodeCopy, NodePath), "PolyCopyNodeContents given wrong dest node type");
00478 
00479     if (IS_A(pNodeCopy, NodePath))
00480         CopyNodeContents((NodePath*)pNodeCopy);
00481 }

void NodePath::Render RenderRegion pRender  )  [virtual]
 

Will render the path contained within the object to the given render region.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/5/93
Parameters:
Pointer to a render region [INPUTS]

Reimplemented from Node.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 496 of file nodepath.cpp.

00497 {
00498     // render the path.
00499     TRACEUSER( "Diccon", _T("Rendering nodepath\n"));
00500     pRender->DrawPath(&InkPath);
00501 }

void NodePath::RenderEorDrag RenderRegion pRender  )  [virtual]
 

Renders a version of the path for EORed dragging of shapes.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/10/93
Parameters:
pRender - A Pointer to the current RenderRegion [INPUTS]
See also:
NodePath::Render; NodeRenderableInk::RenderEorDrag

Reimplemented from NodeRenderableInk.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 517 of file nodepath.cpp.

00518 {
00519     // Currently this function performs an identical task to the
00520     // Render() function
00521     
00522     // render the path
00523     pRender -> DrawPath( &InkPath );
00524 }

void NodePath::RenderObjectBlobs RenderRegion pRender  )  [virtual]
 

Draws the paths object blobs into the render region supplied.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/8/94
Parameters:
pRender - The region to render the blobs into [INPUTS]

Reimplemented from NodeRenderable.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 539 of file nodepath.cpp.

00540 {
00541     // Find the parent spread
00542     Spread* pSpread = FindParentSpread();
00543     ENSURE(pSpread != NULL, "NodePath does not have a parent spread");
00544     
00545     // Render the blobs on the path
00546     if (pSpread!=NULL)
00547         InkPath.RenderPathBlobs(pRender);
00548 
00549     // New Diccon 13/6/2000 If we are a brush and we are selected then we want to 
00550     // render the path on top
00551     NodeAttribute* pAttr = NULL;
00552     FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), &pAttr);
00553     if (pAttr!= NULL)
00554     {
00555         if (((AttrBrushType*)pAttr)->GetBrushHandle() != BrushHandle_NoBrush)
00556         {
00557 
00558             // --- If the quality is set low enough, strokes are just rendered as centrelines
00559             // "low enough" is defined as the same point that Blends show their middle parts
00560             // BLOCK
00561             {
00562                 View* pRenderView = NULL;
00563                 pRenderView = pRender->GetRenderView();
00564                 if(pRenderView != NULL)
00565                 {
00566                     Quality viewQuality = pRenderView->RenderQuality;
00567                     if (viewQuality.GetBlendQuality() == Quality::FullBlend)
00568                     {
00569                         pRender->SetLineColour(COLOUR_BEZIERLINE);
00570                         pRender->SetFillColour(COLOUR_NONE);
00571                         pRender->DrawPath(&InkPath);
00572                     }
00573                 }
00574             }
00575         }
00576     }
00577 }

void NodePath::RenderPenBlobs RenderRegion pRender  )  [virtual]
 

Draws the paths pen blobs into the render region supplied.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/8/94
Parameters:
pRender - The region to render the blobs into [INPUTS]

Reimplemented from NodeRenderable.

Definition at line 590 of file nodepath.cpp.

00591 {
00592     // Find the parent spread
00593     Spread* pSpread = FindParentSpread();
00594     ENSURE(pSpread != NULL, "NodePath does not have a parent spread");
00595     
00596     // Render the blobs on the path
00597     if (pSpread!=NULL)
00598         InkPath.RenderPathPenBlobs(pSpread);
00599 }

void NodePath::RenderTinyBlobs RenderRegion pRender  )  [virtual]
 

Draws the paths Tiny blob into the render region supplied.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/8/94
Parameters:
pRender - The region to render the blobs into [INPUTS]

Reimplemented from NodeRenderable.

Reimplemented in NodeBrushPath.

Definition at line 613 of file nodepath.cpp.

00614 {
00615     // Set the line colours etc as we need them
00616     pRender->SetLineColour(COLOUR_NONE);
00617     pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
00618 
00619     // Render the blobs on the path
00620     DocCoord* Coords = InkPath.GetCoordArray();
00621     pRender->DrawBlob(Coords[0], BT_UNSELECTED);
00622 }

BOOL NodePath::RetroSmoothMe double  Smoothness  ) 
 

Use and abuse the retrosmoother to smooth our ink path. The Retrosmoother is normally activated from the gadget in the shape editor tool however we are hijacking it here for our purposes.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
Smoothness - the amount to smooth by [INPUTS]
[OUTPUTS] 
Returns:
TRUE if everything went ok, FALSE if not.

Errors: Scope: public

Definition at line 2019 of file nodepath.cpp.

02020 {
02021     if (Smoothness <= 0)
02022     {
02023         ERROR3("Zero smoothing value in NodePath::RetroSmoothMe");
02024         return TRUE;
02025     }
02026 
02027     Spread *pSpread = Document::GetSelectedSpread();
02028     ERROR2IF(pSpread == NULL, FALSE, "No spread in NodePath::RetroSmoothMe");
02029 
02030     //Make a retro smoother and tell it not to bother with EOR rendering on top
02031     RetroSmooth rSmoother;
02032     rSmoother.Initialise();
02033     rSmoother.SetRenderFlag(false);
02034 
02035     // all path points must be selected
02036     InkPath.SetAllSubSelection();
02037 
02038     // set the smoother to work
02039     rSmoother.Changing(this, pSpread, Smoothness);
02040     BOOL ok = rSmoother.FinishedNoUndo(this);
02041     
02042     InkPath.ClearSubSelection();
02043 
02044     return ok;
02045 }

BOOL NodePath::SetUpPath INT32  RequiredSize = 12,
INT32  BlockSize = 12
 

To initialise the Nodepath into a state that can be used, by allocating memory, setting up member variables properly and inserting an EndPath element into the path.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
04/5/93
Parameters:
RequiredSize - The size of the initial block of memory to be allocated to the [INPUTS] path. BlockSize - The size of the block asked for by the path object when it runs out of space.
Returns:
TRUE if the path was init'ed ok, FALSE otherwise

Definition at line 296 of file nodepath.cpp.

00297 {
00298     CurrentRotation = 0.0;
00299     return (InkPath.Initialise(RequiredSize, BlockSize)); 
00300 }

Node * NodePath::SimpleCopy void   )  [virtual]
 

Makes a copy of all the data in the node.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/5/93
Returns:
Pointer to a Node

Reimplemented from NodeRenderableInk.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 425 of file nodepath.cpp.

00426 {
00427 
00428     NodePath* NodeCopy = new NodePath();
00429     if (NodeCopy)
00430         CopyNodeContents(NodeCopy);
00431     
00432     return NodeCopy;
00433 }            

BOOL NodePath::Snap DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
[virtual]
 

Snaps the given rect to the nearest position 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). Scope: public.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/9/94
Parameters:
pDocCoord - the rectangle to snap [INPUTS] StartDrag - Start coord of drag EndDrag - End coord of drag
[OUTPUTS] 
Returns:
TRUE - the DocRect been snapped to the grid. FALSE - the DocRect has not been processed.

Reimplemented from NodeRenderableBounded.

Definition at line 2107 of file nodepath.cpp.

02108 {
02109 #if !defined(EXCLUDE_FROM_RALPH)
02110     TRACEUSER( "MarkN", _T("NodePath::Snap(DocRect)\n") );
02111 #endif
02112     return FALSE;
02113 }

BOOL NodePath::Snap DocCoord pDocCoord  )  [virtual]
 

Snaps to given coord to the nearest point on the path. If it is not appropriate to snap the coord to the path (at the moment this means the coord is too far awawy), then FALSE is returned.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocCoord = a coord in Spread coords [INPUTS]
[OUTPUTS] 
Returns:
TRUE - the DocCoord has been snapped to the path. FALSE - the DocCoord has not been processed.

Errors: Scope: public

Reimplemented from NodeRenderableBounded.

Definition at line 2071 of file nodepath.cpp.

02072 {
02073 #if !defined(EXCLUDE_FROM_RALPH)
02074     return CSnap::SnapCoordToPath(pDocCoord, &InkPath);
02075 #else
02076     return FALSE;
02077 #endif
02078 }

BOOL NodePath::SnapToCoords DocCoord pDocCoord  )  [virtual]
 

Snaps the point to all the magnetic points in a NodePath. These include all the endpoint in the path (ie MoveTos, LineTos and the last point in CurveTos). If it is close enough to any of these points in the path then the coord ischanged to match the point on the path and TRUE is returned. pDocCoord is not effected if it is not close enough to any of the points in the path.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/11/94
Parameters:
pDocCoord - the point to magnetically snap [INPUTS]
pDocCoord - if the point was able to magnetically snap to a coord then [OUTPUTS] it is changed to that coord
Returns:
TRUE if it snapped to a coord, FALSE if not
See also:
MagneticPointRadius; NodeRenderableBounded::SnapToCoords

Reimplemented from NodeRenderableBounded.

Definition at line 2138 of file nodepath.cpp.

02139 {
02140 #if !defined(EXCLUDE_FROM_RALPH)
02141     DocCoord* Coords = InkPath.GetCoordArray();
02142     PathFlags* Flags = InkPath.GetFlagArray();
02143     INT32 NumCoords = InkPath.GetNumCoords();
02144 
02145     // loop through all the coords in the path
02146     for (INT32 i=0; i<NumCoords; i++)
02147     {
02148         // Only test the endpoints
02149         if (Flags[i].IsEndPoint)
02150         {
02151             // Now test the coord to see if it is close
02152             if (IsMagneticallyClose(&Coords[i], pDocCoord))
02153                 return TRUE;
02154         }
02155     }
02156 #endif
02157     // Did not find a match
02158     return FALSE;
02159 }

void NodePath::Transform TransformBase Trans  )  [virtual]
 

Will Transform all the coords in the path with the transform provided.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/10/93
Parameters:
Trans - The transform to be applied to the path [INPUTS]
See also:
NodeRenderableInk::Transform()

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeBrushPath.

Definition at line 1097 of file nodepath.cpp.

01098 {
01099     // Change all the coords
01100     Trans.Transform( (DocCoord*)InkPath.GetCoordArray(), InkPath.GetNumCoords() );
01101 
01102     // and keep the bounding rectangle up to date.
01103     InvalidateBoundingRect();
01104 
01105     // Transform all the children...
01106     TransformChildren(Trans);
01107 
01108     // Also update our CurrentRotation variable
01109 
01110 }

void NodePath::TransformTranslateObject const ExtendParams ExtParams  )  [virtual]
 

Do an extend (as opposed to stretch) operation on this path, using ExtParams as the source of the extend data, together with the extend-centre of this path, defined in NodeRenderable::FindExtendCentre().

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
01/12/1999
Parameters:
ExtParams description of how this path should extend. [INPUTS]
This path's control points may be extended, depending on ExtParams' flags. [OUTPUTS]
This function does nothing unless ExtParams uses X_EXTEND or Y_EXTEND. See also: The Extender class; FindExtendCentre().

Reimplemented from NodeRenderable.

Definition at line 2875 of file nodepath.cpp.

02876 {
02877     // get the path's control points.
02878     INT32 numPoints = InkPath.GetNumCoords();
02879     DocCoord* doccArray = InkPath.GetCoordArray();
02880 
02881     // x-extension behaviour.
02882     if (ExtParams.fExtendFlags & X_EXTEND)
02883     {
02884         // translate the whole path by the offset from start- to end- centres.
02885         Trans2DMatrix baseXoffset(ExtParams.doccOffset.x, 0);
02886         Transform(baseXoffset);
02887 
02888         for (INT32 i = 0; i < numPoints; i ++)
02889         {
02890             if (doccArray[i].x > (ExtParams.doccEndCentre.x + ExtParams.xincExtendBuffer))
02891                 doccArray[i].x += ExtParams.xinc;
02892             else if (doccArray[i].x < (ExtParams.doccEndCentre.x - ExtParams.xdecExtendBuffer))
02893                 doccArray[i].x -= ExtParams.xdec;
02894         }
02895     }
02896 
02897     // y-extension behaviour.
02898     if (ExtParams.fExtendFlags & Y_EXTEND)
02899     {
02900         // translate the whole path by the offset from start- to end- centres.
02901         Trans2DMatrix baseYoffset(0, ExtParams.doccOffset.y);
02902         Transform(baseYoffset);
02903 
02904         for (INT32 i = 0; i < numPoints; i ++)
02905         {
02906             if (doccArray[i].y > (ExtParams.doccEndCentre.y + ExtParams.yincExtendBuffer))
02907                 doccArray[i].y += ExtParams.yinc;
02908             else if (doccArray[i].y < (ExtParams.doccEndCentre.y - ExtParams.ydecExtendBuffer))
02909                 doccArray[i].y -= ExtParams.ydec;
02910         }
02911     }
02912 }

DocRect NodePath::ValidateExtend const ExtendParams ExtParams  )  [virtual]
 

Tests to see whether this path's control points are positioned so as to make an extend operation irreversible.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/11/1999
Parameters:
ExtParams parameters describing the extension. [INPUTS]
[OUTPUTS] 
Returns:
TRUE if this path can validly extend, FALSE otherwise.

Errors: See also:

Reimplemented from Node.

Definition at line 2813 of file nodepath.cpp.

02814 {
02815     INT32 numPoints = InkPath.GetNumCoords();
02816     DocCoord* doccArray = InkPath.GetCoordArray();
02817     DocRect drMinExtend = Extender::ValidateControlPoints(numPoints, doccArray, ExtParams);
02818 
02819     // if we didn't invalidate the extension, we must call the base class
02820     // implementation, which will validate our children.
02821     if (drMinExtend.lo.x == INT32_MAX &&
02822         drMinExtend.lo.y == INT32_MAX &&
02823         drMinExtend.hi.x == INT32_MAX &&
02824         drMinExtend.hi.y == INT32_MAX)
02825         drMinExtend = Node::ValidateExtend(ExtParams);
02826 
02827     return drMinExtend;
02828 }

BOOL NodePath::WriteBeginChildRecordsNative BaseCamelotFilter pFilter  )  [virtual]
 

Begin to write out you child records, in the native format.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/8/96
Parameters:
pFilter [INPUTS]
Returns:
TRUE if ok, FALSE otherwise
This will write out a TAG_DOWN record, followed by a path flags record
See also:
-

Reimplemented from NodeRenderableInk.

Definition at line 2639 of file nodepath.cpp.

02640 {
02641 #ifdef DO_EXPORT
02642     ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
02643 
02644     BOOL ok = pFilter->WriteZeroSizedRecord(TAG_DOWN);
02645 
02646     if (ok)
02647     {
02648         INT32 NumCoords = InkPath.GetNumCoords();
02649         INT32 RecordSize = sizeof(BYTE)*NumCoords;
02650 
02651         CamelotFileRecord Rec(pFilter,TAG_PATH_FLAGS,RecordSize);
02652         ok = Rec.Init();
02653 
02654         PathFlags* pFlags = InkPath.GetFlagArray();
02655 
02656         if (ok && pFlags != NULL)
02657         {
02658             BYTE Flags;
02659             for (INT32 i=0; ok && i < NumCoords;i++)
02660             {
02661                 Flags = 0;
02662 
02663                 if (pFlags[i].IsSmooth)     Flags |= TAG_PATH_FLAGS_SMOOTH;
02664                 if (pFlags[i].IsRotate)     Flags |= TAG_PATH_FLAGS_ROTATE;
02665                 if (pFlags[i].IsEndPoint)   Flags |= TAG_PATH_FLAGS_ENDPOINT;
02666 
02667                 ok = Rec.WriteBYTE(Flags);
02668             }
02669 
02670             ok = pFilter->Write(&Rec);
02671         }
02672 
02673         if (ok)
02674         {
02675             if (pFilter->GetBoundsWriteLevel() >= BWL_ALL)
02676                 ok = WriteBoundsRecord(pFilter);
02677         }
02678     }
02679 
02680     return ok;
02681 #else
02682     return FALSE;
02683 #endif
02684 }

BOOL NodePath::WriteEndChildRecordsNative BaseCamelotFilter pFilter  )  [virtual]
 

End writing out you child records, in the native format.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
8/8/96
Parameters:
pFilter [INPUTS]
Returns:
TRUE if ok, FALSE otherwise
This will write out a TAG_UP record
See also:
-

Reimplemented from NodeRenderableInk.

Definition at line 2701 of file nodepath.cpp.

02702 {
02703 #ifdef DO_EXPORT
02704     ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
02705 
02706     return pFilter->WriteZeroSizedRecord(TAG_UP);
02707 #else
02708     return FALSE;
02709 #endif
02710 }

BOOL NodePath::WritePathRecord BaseCamelotFilter pFilter  )  [virtual]
 

Writes the path record to the filter.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/5/96
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Definition at line 2491 of file nodepath.cpp.

02492 {
02493 #ifdef DO_EXPORT
02494     ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
02495 
02496     INT32 RecordSize = CalcPathRecordSize();
02497 
02498     BOOL ok = TRUE;
02499 
02500     // Which type of path is it to be?
02501     UINT32 Tag = ChooseTagValue();
02502 
02503     CamelotFileRecord Rec(pFilter,Tag,RecordSize);
02504 
02505     ok = Rec.Init();
02506     if (ok) ok = WritePathToRecord(&Rec);
02507 
02508     UINT32 RecordNumber;
02509     if (ok) RecordNumber = pFilter->WriteDefinitionRecord(&Rec);
02510     if (ok) ok = (RecordNumber != 0);
02511     if (ok) pFilter->AddPathRecordRefToList(this,RecordNumber);
02512 
02513     if (!ok)
02514         pFilter->GotError(_R(IDE_FILE_WRITE_ERROR));
02515 
02516     return ok;
02517 #else
02518     return FALSE;
02519 #endif
02520 }

BOOL NodePath::WritePathRefRecord BaseCamelotFilter pFilter,
UINT32  SrcPathRecNum,
Matrix pTransform
[virtual]
 

Writes the path reference record to the filter.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/9/96
Parameters:
pFilter = ptr to the filter [INPUTS] SrcPathRecNum = the record that contains the path that's similar to this path pTransform = How to transform the path in SrcPathRecNum to get this path bac
Returns:
TRUE if record is written, FALSE if not
See also:
-

Definition at line 2537 of file nodepath.cpp.

02538 {
02539     ERROR2IF(pTransform == NULL,FALSE,"NULL transform matrix ptr");
02540 
02541     BOOL ok = TRUE;
02542 
02543     UINT32 Tag  = TAG_PATHREF_TRANSFORM;
02544     INT32  Size = TAG_PATHREF_TRANSFORM_SIZE;
02545 
02546     CamelotFileRecord Rec(pFilter,Tag,Size);
02547     if (ok) ok = Rec.Init();
02548     if (ok) ok = Rec.WriteReference(SrcPathRecNum);
02549     if (ok) ok = Rec.WriteMatrixTrans(*pTransform,0,0);
02550     if (ok) ok = (pFilter->Write(&Rec) != 0);
02551 
02552     return ok;
02553 }

BOOL NodePath::WritePathToRecord CamelotFileRecord pRecord  )  [virtual]
 

Central func writes out the correct path record.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/9/96
Parameters:
pRecord = ptr to a record to write to [INPUTS]
Returns:
TRUE if ok, FALSE otherwise
See also:
BaseCamelotFilter::WritePathsInRelativeFormat()

Definition at line 2468 of file nodepath.cpp.

02469 {
02470     ERROR2IF(pRecord == NULL,FALSE,"NULL record ptr");
02471 
02472     if (BaseCamelotFilter::WritePathsInRelativeFormat())
02473         return pRecord->WritePathRelative(&InkPath);
02474     else
02475         return pRecord->WritePath(&InkPath);
02476 }

BOOL NodePath::WritePreChildrenNative BaseCamelotFilter pFilter  )  [virtual]
 

Writes the path record to the filter.

> virtual BOOL NodePath::WritePreChildrenNative(BaseCamelotFilter* pFilter)

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/5/96
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Reimplemented from Node.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 2607 of file nodepath.cpp.

02608 {
02609 #ifdef DO_EXPORT
02610 
02611     // If it's the compact native filter (i.e. the non-minimal web format) OR the path
02612     // similarity check has been selected to apply to the native format,
02613     // do as you would for the web format.
02614     if (pFilter->IsCompactNativeFilter() || pFilter->GetNativeCheckSimilarPaths())
02615         return WritePreChildrenWeb(pFilter);
02616     else
02617         return WritePathRecord(pFilter);
02618 #else
02619     return FALSE;
02620 #endif
02621 }

BOOL NodePath::WritePreChildrenWeb BaseCamelotFilter pFilter  )  [virtual]
 

Writes the path record to the filter.

> virtual BOOL NodePath::WritePreChildrenWeb(BaseCamelotFilter* pFilter)

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/5/96
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Reimplemented from Node.

Reimplemented in NodeBlendPath, NodeBrushPath, and NodeMouldPath.

Definition at line 2569 of file nodepath.cpp.

02570 {
02571 #ifdef DO_EXPORT
02572 
02573     BOOL ok = TRUE;
02574     UINT32 SrcPathRecNum;
02575     Matrix Transform;
02576 
02577     INT32 RecordSize = CalcPathRecordSize();
02578 
02579     // Only call FindSimilarPath() if the path is bigger than the path reference record.
02580     // there's no point in creating a reference if the ref is bigger than the actual path
02581 
02582     if (RecordSize > TAG_PATHREF_TRANSFORM_SIZE && pFilter->FindSimilarPath(this,&SrcPathRecNum,&Transform))
02583         ok = WritePathRefRecord(pFilter,SrcPathRecNum,&Transform);
02584     else
02585         ok = WritePathRecord(pFilter);
02586 
02587     return ok;
02588 
02589 #else
02590     return FALSE;
02591 #endif
02592 }


Member Data Documentation

double NodePath::CurrentRotation [protected]
 

Definition at line 269 of file nodepath.h.

Path NodePath::InkPath
 

Definition at line 134 of file nodepath.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:57:02 2007 for Camelot by  doxygen 1.4.4