#include <nodepath.h>
Inheritance diagram for NodePath:
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 Node * | SimpleCopy () |
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. | |
NodePath * | MakeNodePathFromAttributes (double Flatness=750.0, CCAttrMap *pAttrMap=NULL, BOOL bIncludeClosedPaths=FALSE, BOOL IncludeWidth=TRUE) |
See returns. | |
virtual NodePath * | GetVariableWidthStrokePath () |
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 NodePath * | GetSmoothVariableWidthStrokePath () |
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. | |
Path * | GetPathCopy () |
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. |
Definition at line 128 of file nodepath.h.
|
This constructor creates a NodePath linked to no other with all status flags false and an uninitialized bounding rectangle.
Definition at line 251 of file nodepath.cpp. 00251 : NodeRenderableInk() 00252 { 00253 CurrentRotation = 0.0; 00254 }
|
|
|
|
To get node paths inside text objects to reformat themselves correctly when their paths change. Also see: TextStory::AllowOp().
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 }
|
|
This func is the centre point at which the size of the record that will contain the path is calculated.
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 }
|
|
Interrogation routine to see if a node can be changed into a different node type. Returns TRUE if pClass is a NodePath, FALSE otherwise.
Also, the entry value of *pNumObjects cannot be assumed to be 0.
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 }
|
|
Writes the path record to the filter.
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 }
|
|
Clears the paths sub-selection and re-draws the blobs to show this.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 };
|
|
When you select a NodePath we can to clear all the selection flags in the path before deselecting the node.
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 }
|
|
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.
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 }
|
|
This function estimates a complexity value for the node. The complexity value is based upon the total length of all paths in the node.
Reimplemented from Node. Definition at line 2426 of file nodepath.cpp. 02427 { 02428 return (InkPath.GetUsedSlots ()); 02429 }
|
|
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.
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 }
|
|
Work out 2-dimensional properties of this node.
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 }
|
|
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.
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 }
|
|
returns the paths bounding rectangle and recalculates it if it is invalid
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 }
|
|
Displays debugging info of the tree For obtaining debug information about the Node.
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 }
|
|
Return a DocRect which contains the bounds of this node as defined and required by the Extending mechanism.
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 }
|
|
For finding the size of the node.
Reimplemented from Node. Definition at line 407 of file nodepath.cpp. 00408 { 00409 return (sizeof(NodePath)+InkPath.GetPathByteLength()); 00410 }
|
|
A quick'n'easy way to get a permanent copy of our path.
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 }
|
|
The overridden function for determining the current angle of rotation of this path.
Reimplemented from NodeRenderableBounded. Definition at line 2178 of file nodepath.cpp. 02179 { 02180 return CurrentRotation; 02181 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
virtual identifier function,will move to node.h/.cpp when i have time to wait for the rebuild
Reimplemented in NodeBlendPath. Definition at line 2790 of file nodepath.cpp. 02791 { 02792 return FALSE; 02793 }
|
|
Determine if 2 nodes are considered different.
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 }
|
|
Override the node virtual function IsNodePath() and return TRUE as we definitely are one.
Reimplemented from Node. Definition at line 271 of file nodepath.cpp. 00272 { 00273 return TRUE; 00274 }
|
|
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.
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 }
|
|
Reimplemented from Node. Definition at line 245 of file nodepath.h. 00245 { return TRUE; }
|
|
See returns.
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 }
|
|
Virtual function - this version currently returns false if the path is an immediate child of a text story otherwise its always exportable.
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 }
|
|
Allows the Node to respond to pop up menu clicks on blobs.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Allows the Node to respond to pop up menu clicks on it (rather than its blobs).
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 }
|
|
Polymorphically copies the contents of this node to another.
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 }
|
|
Will render the path contained within the object to the given render region.
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 }
|
|
Renders a version of the path for EORed dragging of shapes.
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 }
|
|
Draws the paths object blobs into the render region supplied.
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 }
|
|
Draws the paths pen blobs into the render region supplied.
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 }
|
|
Draws the paths Tiny blob into the render region supplied.
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 }
|
|
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.
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 }
|
|
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.
Definition at line 296 of file nodepath.cpp. 00297 { 00298 CurrentRotation = 0.0; 00299 return (InkPath.Initialise(RequiredSize, BlockSize)); 00300 }
|
|
Makes a copy of all the data in the 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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Will Transform all the coords in the path with the transform provided.
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 }
|
|
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().
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 }
|
|
Tests to see whether this path's control points are positioned so as to make an extend operation irreversible.
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 }
|
|
Begin to write out you child records, in the native format.
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 }
|
|
End writing out you child records, in the native format.
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 }
|
|
Writes the path record to the filter.
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 }
|
|
Writes the path reference record to the filter.
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 }
|
|
Central func writes out the correct path record.
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 }
|
|
Writes the path record to the filter. > virtual BOOL NodePath::WritePreChildrenNative(BaseCamelotFilter* pFilter)
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 }
|
|
Writes the path record to the filter. > virtual BOOL NodePath::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
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 }
|
|
Definition at line 269 of file nodepath.h. |
|
Definition at line 134 of file nodepath.h. |