00001 // $Id: brshbeca.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // Implementation of BrushBecomeA classes 00100 00101 #include "camtypes.h" 00102 #include "brshbeca.h" 00103 //#include "becomea.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "undoop.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 #include "attrmap.h" 00107 #include "nodepath.h" 00108 #include "nodebldr.h" 00109 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 #include "ophist.h" 00111 00112 CC_IMPLEMENT_MEMDUMP(HandleBrushBecomeA, CC_CLASS_MEMDUMP); 00113 CC_IMPLEMENT_MEMDUMP(BrushBecomeA, BecomeA); 00114 CC_IMPLEMENT_MEMDUMP(SimpleBecomeA, BecomeA); 00115 CC_IMPLEMENT_MEMDUMP(BrushBecomeAGroup, BecomeA); 00116 00117 /*********************************************************************************************** 00118 00119 > HandleBrushBecomeA::HandleBrushBecomeA() 00120 00121 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00122 Created: 7/12/99 00123 Inputs: - 00124 Outputs: - 00125 Returns: - 00126 Purpose: Default constructor 00127 00128 ***********************************************************************************************/ 00129 00130 HandleBrushBecomeA::HandleBrushBecomeA() 00131 { 00132 m_pContextNode = NULL; 00133 m_pCreatedByNode = NULL; 00134 m_pNodeGroup = NULL; 00135 m_pBecomeA = NULL; 00136 m_LastStep = -1; 00137 m_NumBlendPaths = 0; 00138 m_bFirst = TRUE; 00139 m_bSecondary = FALSE; 00140 } 00141 00142 00143 /*********************************************************************************************** 00144 00145 > HandleBrushBecomeA::~HandleBrushBecomeA() 00146 00147 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00148 Created: 4/3/2000 00149 Inputs: - 00150 Outputs: - 00151 Returns: - 00152 Purpose: destructor 00153 00154 ***********************************************************************************************/ 00155 00156 HandleBrushBecomeA::~HandleBrushBecomeA() 00157 { 00158 if (m_pContextNode != NULL) 00159 { 00160 m_pContextNode->CascadeDelete(); 00161 delete m_pContextNode; 00162 m_pContextNode = NULL; 00163 } 00164 } 00165 00166 00167 /*********************************************************************************************** 00168 00169 > BOOL HandleBrushBecomeA::Initialise(BecomeA* pBecomeA, Node* pContextNode, Node* pCreatedBy) 00170 00171 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00172 Created: 4/3/2000 00173 Inputs: pContextNode - the position in the tree to insert new nodes 00174 pCreatedBy - the node that created these objects 00175 pBecomeA - the BecomeA object that tells us what to do and receives any passbacks 00176 Outputs: - 00177 Returns: TRUE, unless you pass in a duff pointer 00178 Purpose: initialises the HBecA object ready for use 00179 00180 ***********************************************************************************************/ 00181 00182 BOOL HandleBrushBecomeA::Initialise(BecomeA* pBecomeA, Node* pContextNode, Node* pCreatedBy) 00183 { 00184 ERROR2IF(pBecomeA == NULL, FALSE, "BecomeA pointer is NULL in HandleBrushBecomeA::Initialise"); 00185 ERROR2IF(pCreatedBy == NULL, FALSE, "Parent node is NULL in HandleBrushBecomeA::Initialise"); 00186 // if we are replacing a node in the tree then we need to ha 00187 if (pBecomeA->GetReason() == BECOMEA_REPLACE) 00188 ERROR2IF(pContextNode == NULL, FALSE, "Context Node is NULL in HandleBrushBecomeA::Initialise"); 00189 00190 m_pBecomeA = pBecomeA; 00191 m_pContextNode = pContextNode; 00192 m_pCreatedByNode = pCreatedBy; 00193 return TRUE; 00194 } 00195 00196 00197 /*********************************************************************************************** 00198 00199 > BOOL HandleBrushBecomeA::PassBack(BlendPath* pBlendPath, AttrMap* pAttrMap, UINT32 StepNum)) 00200 00201 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00202 Created: 4/3/2000 00203 Inputs: pBlendPath - a blendpath that has been generated by the brush 00204 pAttrMap - the attributes that apply to the blendpath 00205 StepNum - the step counter of the brush 00206 Outputs: - 00207 Returns: TRUE, unless something goes wrong 00208 Purpose: This takes a path and an attribute map generated by a PathProcessorBrush, 00209 and generates a NodePath object, if it wants to become a path object 00210 If pBecomeA->Reason == BECOMEA_REPLACE, the NodePath and attributes are added to the tree. 00211 If pBecomeA->Reason == BECOMEA_PASSBACK, the NodePath is passed to the routine. 00212 00213 SeeAlso: This routine is based upon the HandleBecomeA routine in nodebldr.cpp 00214 ***********************************************************************************************/ 00215 00216 BOOL HandleBrushBecomeA::Passback(Path* pPath, CCAttrMap* pAttrMap, UINT32 StepNum) 00217 { 00218 ERROR2IF(pPath == NULL, FALSE, "pPath is NULL in HandleBecomeA::Passback"); 00219 ERROR2IF(pAttrMap == NULL, FALSE, "pAttrMap is NULL in HandleBecomeA::Passback"); 00220 ERROR2IF(m_pBecomeA == NULL, FALSE, "BecomeA is NULL in HandleBecomeA::Passback"); 00221 00222 BOOL ValidReason = (m_pBecomeA->GetReason() == BECOMEA_REPLACE || m_pBecomeA->GetReason() == BECOMEA_PASSBACK); 00223 ERROR3IF_PF(!ValidReason,("Unkown BecomeA reason %d",m_pBecomeA->GetReason())); 00224 if (!ValidReason) return FALSE; 00225 00226 if (m_pBecomeA->GetReason()== BECOMEA_REPLACE) 00227 ERROR2IF(m_pContextNode == NULL, FALSE, "Context Node is NULL in HandleBrushBecomeA::Passback"); 00228 00229 BOOL Success = FALSE; 00230 NodePath* pNewNodePath = NULL; 00231 if (m_pBecomeA->BAPath()) 00232 { 00233 // We need to create a new NodePath, no matter what the reason. 00234 00235 // Allocate a new NodePath node 00236 ALLOC_WITH_FAIL(pNewNodePath, (new NodePath), m_pBecomeA->GetUndoOp()); 00237 Success = (pNewNodePath != NULL); 00238 00239 // Initialise the path 00240 if (Success) CALL_WITH_FAIL(pNewNodePath->InkPath.Initialise(pPath->GetNumCoords(),12), m_pBecomeA->GetUndoOp(), Success); 00241 if (Success) CALL_WITH_FAIL(pNewNodePath->InkPath.CopyPathDataFrom(pPath), m_pBecomeA->GetUndoOp(), Success); 00242 00243 // If Success is TRUE, then we now have a new NodePath object that contains this shape's path 00244 00245 // By default, attach the new path as the previous child of the context node 00246 Node* pAttachNode = m_pContextNode; 00247 AttachNodeDirection AttachDir = NEXT; 00248 00249 // if this is the very first item then insert at first child 00250 if (m_bFirst) 00251 { 00252 AttachDir = LASTCHILD; 00253 m_bFirst = FALSE; 00254 } 00255 00256 00257 // By default, create a hide node action for the new path we're attaching to the tree 00258 // note - I've Changed my mind - because brushes can contain so many objects, by inserting an action 00259 // for each one we're eating up tons of unneccessary space. Instead call HideNode when 00260 // you're done so ou only do it once. 00261 BOOL HideNode = TRUE; 00262 Node* pNodeToHide = pNewNodePath; 00263 00264 00265 // Should we be placing all created paths inside a group? 00266 if (MakeGroupForThisStep()) 00267 { 00268 // Do we need to create a new group? I.e. is this the first path created for this step of the blend? 00269 if (StepNum == 1) 00270 { 00271 // Create a new group and place it in the tree next to the context node 00272 m_pNodeGroup = new NodeGroup; 00273 Success = (m_pNodeGroup != NULL); 00274 if (Success) 00275 { 00276 // attach group to our context node 00277 m_pNodeGroup->AttachNode(m_pContextNode,LASTCHILD); 00278 00279 // Make a hide node action for this group 00280 HideNode = TRUE; 00281 pNodeToHide = m_pNodeGroup; 00282 } 00283 } 00284 else 00285 { 00286 pAttachNode = m_pNodeGroup; 00287 HideNode = FALSE; // We created a hide node action when this group was created 00288 } 00289 00290 // If we have a group node, make sure the new path gets placed in the tree as the 00291 // group's last child 00292 if (Success) 00293 { 00294 pAttachNode = m_pNodeGroup; 00295 AttachDir = LASTCHILD; 00296 } 00297 } 00298 else 00299 AttachDir = LASTCHILD; 00300 00301 00302 if (Success) 00303 { 00304 switch (m_pBecomeA->GetReason()) 00305 { 00306 case BECOMEA_REPLACE : 00307 { 00308 // It's a BECOMEA_REPLACE, so put the new NodePath in the tree in an undoable way 00309 00310 // Can't do it in an undoable way without an Undo Op 00311 // ERROR2IF_PF(m_pBecomeA->GetUndoOp() == NULL,FALSE,("GetUndoOp() returned NULL")); 00312 00313 if (Success) 00314 { 00315 ERROR2IF(pAttachNode == NULL,FALSE,"The attach node is NULL!!!"); 00316 00317 // Insert the new NodePath into the tree 00318 pNewNodePath->AttachNode(pAttachNode,AttachDir); 00319 00320 // Apply all the attributes to the new path 00321 pNewNodePath->ApplyAttributes(pAttrMap,TRUE); 00322 00323 if (m_pBecomeA->GetUndoOp()) 00324 { 00325 // Set the bounds 00326 pNewNodePath->ValidateBoundingRect(); 00327 pNewNodePath->InvalidateBoundingRect(); 00328 00329 // Create a hide node action to hide the node when we undo 00330 if (HideNode) 00331 { 00332 ERROR2IF(pNodeToHide == NULL,FALSE,"pNodeToHide is NULL"); 00333 00334 HideNodeAction* UndoHideNodeAction; 00335 Success = (HideNodeAction::Init(m_pBecomeA->GetUndoOp(), 00336 m_pBecomeA->GetUndoOp()->GetUndoActionList(), 00337 pNodeToHide, 00338 TRUE, // Include subtree size 00339 ( Action**)(&UndoHideNodeAction)) 00340 != AC_FAIL); 00341 } 00342 } 00343 } 00344 00345 // We need to create a copy of the blended attributes to give to the caller 00346 // as they don't exist in the tree, and the ones in pAttrMap will be 00347 // deleted eventually. 00348 ERROR2IF(m_pCreatedByNode == NULL, FALSE, "Parent node is NULL in HandleBrushBecomeA::Passback"); 00349 CCAttrMap* pNewAttrMap = pAttrMap->Copy(); // was causing memory leaks 00350 if (pNewAttrMap != NULL) 00351 m_pBecomeA->PassBack(pNewNodePath,(NodeRenderableInk*)m_pCreatedByNode,pNewAttrMap); 00352 } 00353 break; 00354 00355 case BECOMEA_PASSBACK : 00356 { 00357 if (Success) 00358 { 00359 ERROR2IF(pAttachNode == NULL,FALSE,"The attach node is NULL!!!"); 00360 00361 // Insert the new NodePath into the tree 00362 pNewNodePath->AttachNode(pAttachNode,AttachDir); 00363 00364 // Apply all the attributes to the new path 00365 pNewNodePath->ApplyAttributes(pAttrMap,TRUE); 00366 00367 // Set the bounds 00368 pNewNodePath->ValidateBoundingRect(); 00369 pNewNodePath->InvalidateBoundingRect(); 00370 } 00371 00372 // We need to create a copy of the blended attributes to give to the caller 00373 // as they don't exist in the tree, and the ones in pAttrMap will be 00374 // deleted eventually. 00375 ERROR2IF(m_pCreatedByNode == NULL, FALSE, "Parent node is NULL in HandleBrushBecomeA::Passback"); 00376 CCAttrMap* pNewAttrMap = pAttrMap->Copy(); // was causing memory leaks 00377 if (pNewAttrMap != NULL) 00378 Success = m_pBecomeA->PassBack(pNewNodePath,(NodeRenderableInk*)m_pCreatedByNode,pNewAttrMap); 00379 else 00380 Success = FALSE; 00381 } 00382 break; 00383 00384 case BECOMEA_TEST : 00385 ERROR3("This case wasn't handled by the switch and generated a warning"); 00386 break; 00387 } // end switch 00388 00389 } //end if 00390 else //not success so delete our nodepath 00391 { 00392 if (pNewNodePath != NULL) 00393 delete pNewNodePath; 00394 } 00395 } // end if pBecomeA->BAPath() 00396 00397 return Success; 00398 } 00399 00400 00401 /*********************************************************************************************** 00402 00403 > BOOL HandleBrushBecomeA::HideContextNode() 00404 00405 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00406 Created: 4/3/2000 00407 Inputs: - 00408 Outputs: - 00409 Returns: TRUE if successful, etc. 00410 Purpose: inserts an action to hide the context node 00411 00412 ***********************************************************************************************/ 00413 00414 BOOL HandleBrushBecomeA::HideContextNode() 00415 { 00416 ERROR2IF(m_pBecomeA == NULL, FALSE, "BecomeA is NULL in HandleBecomeA::HideContextNode"); 00417 ERROR2IF(m_pContextNode == NULL, FALSE, "Context node is NULL in HandleBecomeA::HideContextNode"); 00418 ERROR2IF(m_pBecomeA->GetUndoOp() == NULL,FALSE,"GetUndoOp() returned NULL in HandleBecomeA::HideContextNode"); 00419 00420 UndoableOperation* pUndoOp = m_pBecomeA->GetUndoOp(); 00421 00422 return pUndoOp->DoHideNode(m_pContextNode, TRUE); 00423 00424 00425 } 00426 00427 00428 /*********************************************************************************************** 00429 00430 > BOOL HandleBrushBecomeA::HideCreatedByNode() 00431 00432 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00433 Created: 4/3/2000 00434 Inputs: - 00435 Outputs: - 00436 Returns: TRUE if successful, etc. 00437 Purpose: inserts an action to hide the context node 00438 00439 ***********************************************************************************************/ 00440 00441 BOOL HandleBrushBecomeA::HideCreatedByNode() 00442 { 00443 ERROR2IF(m_pBecomeA == NULL, FALSE, "BecomeA is NULL in HandleBecomeA::HideContextNode"); 00444 ERROR2IF(m_pCreatedByNode == NULL, FALSE, "Context node is NULL in HandleBecomeA::HideContextNode"); 00445 // ERROR2IF(m_pBecomeA->GetUndoOp() == NULL,FALSE,"GetUndoOp() returned NULL in HandleBecomeA::HideContextNode"); 00446 00447 // set the context node selected 00448 if (m_pContextNode) 00449 m_pContextNode->SetSelected(TRUE); 00450 00451 m_pContextNode = NULL; // so our destructor doesn't delete it 00452 00453 UndoableOperation* pUndoOp = m_pBecomeA->GetUndoOp(); 00454 00455 if (!m_bSecondary) 00456 { 00457 if (pUndoOp) 00458 return pUndoOp->DoHideNode(m_pCreatedByNode, TRUE); 00459 00460 m_pCreatedByNode->CascadeDelete(); 00461 delete m_pCreatedByNode; 00462 } 00463 00464 return(TRUE); 00465 } 00466 00467 00468 00469 /*********************************************************************************************** 00470 00471 > BOOL HandleBrushBecomeA::FinishPassback() 00472 00473 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00474 Created: 4/3/2000 00475 Inputs: - 00476 Outputs: - 00477 Returns: TRUE if successful, etc. 00478 Purpose: Somewhat devious this, and to be used with care. Basically after we have completed 00479 all our passbacks we have accumulated a nodegroup containiing all the brush objects 00480 converted to nodepaths. This function indicates that we have finished and can then 00481 passback this nodegroup to our becomeA object. 00482 This is a bit bad as we're never supposed to pass nodegroups back, so you must 00483 make sure your becomeA object can handle it. 00484 It also nulls the group pointer so that it doesn't get deleted on destruction 00485 ***********************************************************************************************/ 00486 00487 BOOL HandleBrushBecomeA::FinishPassback() 00488 { 00489 ERROR2IF(m_pBecomeA == NULL, FALSE, "BecomeA is NULL in HandleBecomeA::FinishPassback"); 00490 ERROR2IF(m_pContextNode == NULL, FALSE, "Context node is NULL in HandleBecomeA::FinishPassback"); 00491 00492 if (m_pBecomeA->GetReason() == BECOMEA_REPLACE) 00493 { 00494 // Select the newly created node 00495 if (m_pContextNode) 00496 m_pContextNode->SetSelected(TRUE); 00497 } 00498 00499 if (m_pBecomeA->GetReason() == BECOMEA_REPLACE) 00500 { 00501 // Select the newly created node 00502 if (m_pContextNode) 00503 m_pContextNode->SetSelected(TRUE); 00504 } 00505 00506 // We really shouldn't be passing this group back to anyone apart from our special becomeA 00507 if (!m_pBecomeA->IsBrushBecomeAGroup()) 00508 { 00509 m_pContextNode = NULL; 00510 return TRUE; 00511 } 00512 00513 BOOL ok = m_pBecomeA->PassBack((NodeRenderableInk*)m_pContextNode,(NodeRenderableInk*)m_pCreatedByNode,NULL); 00514 00515 if (ok) 00516 m_pContextNode = NULL; 00517 00518 return ok; 00519 } 00520 00521 00522 00523 /*------------------------------------------------------------------------------------------------ 00524 --------------------------BrushBecomeA implementation--------------------------------------------- 00525 -------------------------------------------------------------------------------------------------*/ 00526 00527 00528 /*********************************************************************************************** 00529 00530 > BrushBecomeA::BrushBecomeA() 00531 00532 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00533 Created: 7/12/99 00534 Inputs: Reason - our reason for being 00535 pClass - the class to generate 00536 pOp - the operation we are part of 00537 pBlendRef - the blendref that created us 00538 Outputs: - 00539 Returns: - 00540 Purpose: constructor 00541 00542 ***********************************************************************************************/ 00543 00544 BrushBecomeA::BrushBecomeA(BecomeAReason Reason, CCRuntimeClass* pClass, UndoableOperation* pOp, 00545 BlendRef* pBlendRef) : BecomeA(Reason, pClass, pOp) 00546 { 00547 m_pBlendRef = pBlendRef; 00548 } 00549 00550 00551 /*********************************************************************************************** 00552 00553 > bool BrushBecomeA::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, CCAttrMap* pAttrMap) 00554 00555 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00556 Created: 7/12/99 00557 Inputs: pNewNode - the node that was generated 00558 pCreatedByNode - the node that created the node that was generated 00559 pAttrMap - the applied attributes 00560 Outputs: - 00561 Returns: TRUE if successful, FALSE otherwise 00562 Purpose: the money function, takes the nodepaths that are generated and makes blendpaths 00563 out of them. Note that for this to work pNewNode MUST be a nodepath. 00564 00565 ***********************************************************************************************/ 00566 00567 BOOL BrushBecomeA::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, CCAttrMap* pAttrMap) 00568 { 00569 ERROR2IF(pNewNode == NULL || pCreatedByNode == NULL, FALSE, "Input pointers are NULL in BrushBecomeA::PassBack"); 00570 00571 if (!pNewNode->IsNodePath()) 00572 { 00573 ERROR3("New node is not NodePath in BrushBecomeA::PassBack"); 00574 return FALSE; 00575 } 00576 00577 Path* pInkPath = &(((NodePath*)pNewNode)->InkPath); 00578 00579 //Node * pPathNode = (NodePath *)pNewNode; 00580 00581 //INT32 NumCoords = pInkPath->GetNumCoords(); 00582 //INT32 StartIndex=0,EndIndex=0; 00583 //UINT32 NumSubPaths=0; 00584 00585 // Create a new NodePath for this subpath 00586 NodePath* pNewNodePath = new NodePath; 00587 BOOL ok = (pNewNodePath != NULL); 00588 if (ok) 00589 { 00590 // Copy the subpath in TempPath into the new NodePath's path object 00591 Path* pNewPath = &(pNewNodePath->InkPath); 00592 ok = pNewPath->Initialise(pInkPath->GetNumCoords()); 00593 00594 if (ok) ok = pNewPath->CopyPathDataFrom(pInkPath); 00595 00596 if (ok) 00597 { 00598 // Create a new BlendPath obect 00599 BlendPath* pBlendPath = new BlendPath; 00600 ok = (pBlendPath != NULL); 00601 00602 // Initialise the BlendPath object with the generated NodePath 00603 // and add the BlendPath to the BlendRef 00604 if (ok) ok = pBlendPath->Initialise(pNewNodePath, 0, pCreatedByNode, 1, 0, pAttrMap, FALSE); 00605 if (ok) ok = m_pBlendRef->AddBlendPath(pBlendPath); 00606 00607 } 00608 } 00609 00610 00611 if (ok) 00612 { 00613 //pBlendRef->SetAWComplex(NumSubPaths > 1); // This is the 'complex' flag used when exporting to AW EPS 00614 pNewNode->CascadeDelete(); 00615 delete pNewNode; 00616 pNewNode = NULL; 00617 } 00618 00619 return ok; 00620 } 00621 00622 00623 00624 /*------------------------------------------------------------------------------------------------ 00625 --------------------------BrushBecomeA implementation--------------------------------------------- 00626 -------------------------------------------------------------------------------------------------*/ 00627 00628 00629 /*********************************************************************************************** 00630 00631 > SimpleBecomeA::SimpleBecomeA(BecomeAReason, CCRuntimeClass* pClass, UndoableOperation* pOp) 00632 00633 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00634 Created: 7/12/99 00635 Inputs: Reason - our reason for being 00636 pClass - the class to generate 00637 pOp - the operation we are part of 00638 Outputs: - 00639 Returns: - 00640 Purpose: constructor 00641 00642 ***********************************************************************************************/ 00643 00644 SimpleBecomeA::SimpleBecomeA(BecomeAReason Reason, CCRuntimeClass* pClass, UndoableOperation* pOp) 00645 :BecomeA(Reason, pClass, pOp) 00646 { 00647 m_pNodePath = NULL; 00648 } 00649 00650 00651 /*********************************************************************************************** 00652 00653 > BOOL SimpleBecomeA::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, CCAttrMap* pAttrMap) 00654 00655 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00656 Created: 7/12/99 00657 Inputs: pNewNode - the node that was generated 00658 pCreatedByNode - the node that created the node that was generated 00659 pAttrMap - the applied attributes 00660 Outputs: - 00661 Returns: TRUE if successful, FALSE otherwise 00662 Purpose: the money function, takes the nodepath and assigns it to our member so it can 00663 be retrieved using GetNodePath 00664 00665 ***********************************************************************************************/ 00666 00667 BOOL SimpleBecomeA::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, CCAttrMap* pAttrMap) 00668 { 00669 ERROR2IF(pNewNode == NULL, FALSE, "Node is NULL in SimpleBecomeA::PassBack"); 00670 ERROR2IF(!pNewNode->IsNodePath(), FALSE, "New node is not nodepath in SimpleBecomeA::PassBack"); 00671 00672 m_pNodePath = (NodePath*)pNewNode; 00673 00674 return TRUE; 00675 } 00676 00677 00678 00679 /*********************************************************************************************** 00680 00681 > NodePath* SimpleBecomeA::GetNodePath() 00682 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00683 Created: 7/12/99 00684 Inputs: - 00685 Outputs: - 00686 Returns: the nodepath that we receieved from the passback 00687 Purpose: as above 00688 ***********************************************************************************************/ 00689 00690 NodePath* SimpleBecomeA::GetNodePath() 00691 { 00692 return m_pNodePath; 00693 } 00694 00695 00696 00697 00698 /*------------------------------------------------------------------------------------------------ 00699 --------------------------BrushBecomeAGroup implementation--------------------------------------------- 00700 -------------------------------------------------------------------------------------------------*/ 00701 00702 00703 /*********************************************************************************************** 00704 00705 > BrushBecomeAGroup::BrushBecomeAGroup(BecomeAReason, CCRuntimeClass* pClass, UndoableOperation* pOp) 00706 00707 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00708 Created: 7/12/99 00709 Inputs: Reason - our reason for being 00710 pClass - the class to generate 00711 pOp - the operation we are part of 00712 Outputs: - 00713 Returns: - 00714 Purpose: constructor 00715 00716 ***********************************************************************************************/ 00717 00718 BrushBecomeAGroup::BrushBecomeAGroup(BecomeAReason Reason, CCRuntimeClass* pClass, UndoableOperation* pOp) 00719 :BecomeA(Reason, pClass, pOp) 00720 { 00721 m_pNodeGroup = NULL; 00722 } 00723 00724 00725 00726 /*********************************************************************************************** 00727 00728 > NodeGroup* BrushBecomeAGroup::GetNodeGroup() 00729 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00730 Created: 7/12/99 00731 Inputs: - 00732 Outputs: - 00733 Returns: the nodepath that we receieved from the passback 00734 Purpose: as above, nulls the group so we don't delete it 00735 ***********************************************************************************************/ 00736 00737 BrushBecomeAGroup::~BrushBecomeAGroup() 00738 { 00739 if (m_pNodeGroup != NULL) 00740 { 00741 m_pNodeGroup->CascadeDelete(); 00742 delete m_pNodeGroup; 00743 } 00744 } 00745 00746 /*********************************************************************************************** 00747 00748 > BOOL BrushBecomeAGroup::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, CCAttrMap* pAttrMap) 00749 00750 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00751 Created: 7/12/99 00752 Inputs: pNewNode - the node that was generated 00753 pCreatedByNode - the node that created the node that was generated 00754 pAttrMap - the applied attributes 00755 Outputs: - 00756 Returns: TRUE if successful, FALSE otherwise 00757 Purpose: Curiously enough we're only interested in receiving nodegroups here 00758 00759 ***********************************************************************************************/ 00760 00761 BOOL BrushBecomeAGroup::PassBack(NodeRenderableInk* pNewNode, NodeRenderableInk* pCreatedByNode, 00762 CCAttrMap* pAttrMap) 00763 { 00764 ERROR2IF(pNewNode == NULL || pCreatedByNode == NULL, FALSE, "Input pointers are NULL in BrushBecomeA::PassBack"); 00765 00766 // we don't care about the attr maps 00767 if (pAttrMap != NULL) 00768 { 00769 pAttrMap->DeleteAttributes(); 00770 delete pAttrMap; 00771 pAttrMap = NULL; 00772 } 00773 00774 if (pNewNode->IsAGroup()) 00775 { 00776 if (m_pNodeGroup != NULL) 00777 ERROR3("Whats going on here? We've already got a nodegroup!"); 00778 m_pNodeGroup = (NodeGroup*)pNewNode; 00779 } 00780 return TRUE; 00781 } 00782 00783 00784 /*********************************************************************************************** 00785 00786 > NodeGroup* BrushBecomeAGroup::GetNodeGroup() 00787 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00788 Created: 7/12/99 00789 Inputs: - 00790 Outputs: - 00791 Returns: the nodepath that we receieved from the passback 00792 Purpose: as above, nulls the group so we don't delete it 00793 ***********************************************************************************************/ 00794 00795 NodeGroup* BrushBecomeAGroup::GetNodeGroup() 00796 { 00797 NodeGroup* Temp = m_pNodeGroup; 00798 m_pNodeGroup = NULL; 00799 return Temp; 00800 }