00001 // $Id: ndmldpth.cpp 1315 2006-06-14 09:51:34Z 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 // NodeMouldPath implementation. This file controls the tree node 'mouldpath' 00099 // which is the shape of the mould for perspective and envelope shapes. 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 #include "ndmldpth.h" 00106 #include "nodepath.h" 00107 #include "nodemold.h" 00108 #include "nodemldr.h" 00109 #include "moldshap.h" 00110 #include "aw_eps.h" 00111 #include "nativeps.h" // The old style EPS native filter, used in v1.1 00112 #include "blobs.h" 00113 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "tim.h" 00115 //#include "ngcore.h" // NameGallery, for stretching functionality 00116 00117 #include "cxftags.h" 00118 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 //#include "camfiltr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 00121 DECLARE_SOURCE("$Revision: 1315 $"); 00122 00123 CC_IMPLEMENT_DYNCREATE( NodeMouldPath, NodePath ) 00124 00125 // Declare smart memory handling in Debug builds 00126 #define new CAM_DEBUG_NEW 00127 00128 00129 /********************************************************************************************* 00130 00131 > NodeMouldPath::NodeMouldPath() 00132 00133 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00134 Created: 16/01/95 00135 Purpose: This constructor creates a NodeMouldPath linked to no other, with all status 00136 flags false and an uninitialised bounding rectangle. 00137 00138 **********************************************************************************************/ 00139 00140 NodeMouldPath::NodeMouldPath(): NodePath() 00141 { 00142 } 00143 00144 00145 /*********************************************************************************************** 00146 00147 > void NodeMouldPath::NodeMouldPath 00148 ( 00149 Node* ContextNode, 00150 AttachNodeDirection Direction, 00151 BOOL Locked = FALSE, 00152 BOOL Mangled = FALSE, 00153 BOOL Marked = FALSE, 00154 BOOL Selected = FALSE, 00155 ) 00156 00157 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00158 Created: 16/01/95 00159 Inputs: ContextNode: Pointer to a node which this node is to be attached to. 00160 00161 Direction: 00162 00163 Specifies the direction in which this node is to be attached to the 00164 ContextNode. The values this variable can take are as follows: 00165 00166 PREV : Attach node as a previous sibling of the context node 00167 NEXT : Attach node as a next sibling of the context node 00168 FIRSTCHILD: Attach node as the first child of the context node 00169 LASTCHILD : Attach node as a last child of the context node 00170 00171 The remaining inputs specify the status of the node: 00172 00173 Locked: Is node locked ? 00174 Mangled: Is node mangled ? 00175 Marked: Is node marked ? 00176 Selected: Is node selected ? 00177 00178 Outputs: - 00179 Returns: - 00180 Purpose: This method initialises the node and links it to ContextNode in the 00181 direction specified by Direction. All necessary tree links are 00182 updated. 00183 00184 Errors: An assertion error will occur if ContextNode is NULL 00185 00186 00187 ***********************************************************************************************/ 00188 00189 NodeMouldPath::NodeMouldPath(Node* ContextNode, 00190 AttachNodeDirection Direction, 00191 BOOL Locked, 00192 BOOL Mangled, 00193 BOOL Marked, 00194 BOOL Selected 00195 ):NodePath(ContextNode, Direction, Locked, Mangled, Marked, Selected) 00196 { 00197 } 00198 00199 /********************************************************************************************* 00200 00201 > NodeMouldPath::~NodeMouldPath() 00202 00203 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00204 Created: 16/01/95 00205 Purpose: Destructor for Node MouldPath. This does nothing at present. 00206 00207 **********************************************************************************************/ 00208 00209 NodeMouldPath::~NodeMouldPath() 00210 { 00211 } 00212 00213 00214 /*********************************************************************************************** 00215 00216 > virtual Node* NodeMouldPath::SimpleCopy() 00217 00218 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00219 Created: 16/01/95 00220 Returns: Pointer to a Node 00221 Purpose: Makes a copy of all the data in the node 00222 00223 ***********************************************************************************************/ 00224 00225 Node* NodeMouldPath::SimpleCopy() 00226 { 00227 NodeMouldPath* NodeCopy = new NodeMouldPath(); 00228 if (NodeCopy) 00229 CopyNodeContents(NodeCopy); 00230 00231 return NodeCopy; 00232 } 00233 00234 00235 /*********************************************************************************************** 00236 00237 > void NodeMouldPath::CopyNodeContents(NodeMouldPath* NodeCopy) 00238 00239 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00240 Created: 17/5/95 00241 Inputs: NodeCopy - The node to copy 00242 Purpose: Copies the data in the node by first calling the base class to get it to 00243 copy its stuff, and then copying its own stuff 00244 Scope: protected 00245 SeeAlso: NodeRenderableInk::CopyNodeContents 00246 00247 ***********************************************************************************************/ 00248 00249 void NodeMouldPath::CopyNodeContents( NodeMouldPath* NodeCopy) 00250 { 00251 NodePath::CopyNodeContents( NodeCopy ); 00252 //Copy contents specific to derived class here 00253 } 00254 00255 00256 00257 /*********************************************************************************************** 00258 > void NodeMouldPath::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00259 00260 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00261 Created: 18/12/2003 00262 Outputs: - 00263 Purpose: Polymorphically copies the contents of this node to another 00264 Errors: An assertion failure will occur if NodeCopy is NULL 00265 Scope: protected 00266 00267 ***********************************************************************************************/ 00268 00269 void NodeMouldPath::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00270 { 00271 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node"); 00272 ENSURE(IS_A(pNodeCopy, NodeMouldPath), "PolyCopyNodeContents given wrong dest node type"); 00273 00274 if (IS_A(pNodeCopy, NodeMouldPath)) 00275 CopyNodeContents((NodeMouldPath*)pNodeCopy); 00276 } 00277 00278 00279 00280 /*********************************************************************************************** 00281 00282 > virtual void NodeMouldPath::Render(RenderRegion* pRRegion) 00283 00284 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00285 Created: 16/01/95 00286 Inputs: Pointer to a render region 00287 Purpose: Overrides inherited function to do nothing. 00288 00289 ***********************************************************************************************/ 00290 00291 void NodeMouldPath::Render(RenderRegion* pRender) 00292 { 00293 if (!InsideMould()) 00294 NodePath::Render(pRender); 00295 } 00296 00297 00298 /******************************************************************************************** 00299 00300 > virtual void NodeMouldPath::RenderEorDrag( RenderRegion* pRender ) 00301 00302 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00303 Created: 16/01/95 00304 Inputs: pRender - A Pointer to the current RenderRegion 00305 Purpose: Overrides inherited function to do nothing. 00306 00307 ********************************************************************************************/ 00308 00309 void NodeMouldPath::RenderEorDrag( RenderRegion* pRender ) 00310 { 00311 #if !defined(EXCLUDE_FROM_RALPH) 00312 //if (!InsideMould()) 00313 BlobManager* pBlobMan = GetApplication()->GetBlobManager(); 00314 BlobStyle CurrBlobs = pBlobMan->GetCurrentInterest(); 00315 if (CurrBlobs.Object) 00316 NodePath::RenderEorDrag(pRender); 00317 #endif 00318 } 00319 00320 00321 /******************************************************************************************** 00322 00323 > virtual void NodeMouldPath::RenderObjectBlobs(RenderRegion* pRender) 00324 00325 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00326 Created: 23/8/94 00327 Inputs: pRender - The region to render the blobs into 00328 Purpose: Draws the paths object blobs into the render region supplied 00329 00330 ********************************************************************************************/ 00331 00332 void NodeMouldPath::RenderObjectBlobs(RenderRegion* pRender) 00333 { 00334 #if !defined(EXCLUDE_FROM_RALPH) 00335 if (!InsideMould()) 00336 NodePath::RenderObjectBlobs(pRender); 00337 else 00338 { 00339 // set our eor colour. 00340 pRender->SetLineColour(BLACK); 00341 // render the path 00342 pRender->DrawPath(&InkPath); 00343 // call the parent class render function 00344 NodePath::RenderObjectBlobs(pRender); 00345 } 00346 #endif 00347 } 00348 00349 00350 00351 /******************************************************************************************** 00352 00353 > DocRect NodeMouldPath::GetBoundingRect(BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE) 00354 00355 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00356 Created: 17/01/95 00357 Inputs: DontUseAttrs - TRUE if you don't want to use the nodes attrs to calculate 00358 the bounding rect (defaults will be used). Defaults to FALSE. 00359 HitTest - TRUE if being called during HitTest 00360 Returns: A null rectangle 00361 Purpose: Returns a completely null rectangle 00362 00363 ********************************************************************************************/ 00364 00365 DocRect NodeMouldPath::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest) 00366 { 00367 /* Tricky problems: 00368 (1) When importing, the importer translates the imported picture to centre around 00369 the drop point. Unfortunately it calls us to find our bbox. We don't have a 00370 bbox until the moulder nodes are built, which is not until PostImport time so 00371 the importer does a Translate = (Drop - Center) which is X = (0 - C), BAD. 00372 So we must return a bbox if their is no moulder in the mould! Nasty Showstopper fix */ 00373 00374 if (InsideMould()) 00375 { 00376 // if there is a moulder node to contribute a bbox 00377 if (FindNext(CC_RUNTIME_CLASS(NodeMoulder))) 00378 { 00379 // Then we dont contribute anything! 00380 DocRect Rect; 00381 return Rect; 00382 } 00383 } 00384 // Otherwise we do. 00385 return NodePath::GetBoundingRect(DontUseAttrs); 00386 } 00387 00388 00389 /******************************************************************************************** 00390 00391 > BOOL NodeMouldPath::InsideMould() 00392 00393 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00394 Created: 09/02/95 00395 Inputs: - 00396 Returns: TRUE if this mould path is inside a mould object ie its immediate parent 00397 is a mould object 00398 Purpose: Determins whether the immediate parent of this node mould path object is 00399 a mould object. 00400 00401 ********************************************************************************************/ 00402 00403 BOOL NodeMouldPath::InsideMould() 00404 { 00405 Node* p = FindParent(); 00406 if (p) 00407 { 00408 if (IS_A(p, NodeMould)) 00409 return TRUE; 00410 if (IS_A(p, NodeHidden)) 00411 return TRUE; 00412 } 00413 return FALSE; 00414 } 00415 00416 00417 00418 /********************************************************************************************* 00419 00420 > BOOL NodeMouldPath::ExportRender(RenderRegion* pRegion) 00421 00422 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00423 Created: 14/03/95 00424 Inputs: pRegion = ptr to the export render region to export to 00425 Outputs: 00426 Returns: TRUE if ok, FALSE if something went wrong 00427 Purpose: Called after this node and all of its children have been rendered to the 00428 export region. This outputs the "end mould" command. 00429 Supports ArtWorks EPS and Camelot EPS 00430 Errors: 00431 00432 **********************************************************************************************/ 00433 00434 BOOL NodeMouldPath::ExportRender(RenderRegion* pRegion) 00435 { 00436 #ifdef DO_EXPORT 00437 if (pRegion->IS_KIND_OF(NativeRenderRegion)) 00438 return ExportCAMEPS(pRegion); 00439 00440 if (pRegion->IS_KIND_OF(ArtWorksEPSRenderRegion)) 00441 return ExportAWEPS(pRegion); 00442 #endif 00443 return FALSE; 00444 } 00445 00446 00447 /********************************************************************************************* 00448 00449 BOOL NodeMouldPath::ExportCAMEPS(RenderRegion* pRegion) 00450 00451 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00452 Created: 14/03/95 00453 Inputs: pRegion = a pointer to a Camelot EPS render region 00454 Returns: TRUE if we've rendered the object 00455 FALSE if we want the caller to render the object 00456 Purpose: Export delimiter tokens for this particular object. 00457 The format is defined as 00458 csmp 00459 path description 00460 cemp 00461 00462 **********************************************************************************************/ 00463 00464 BOOL NodeMouldPath::ExportCAMEPS(RenderRegion* pRegion) 00465 { 00466 #ifdef DO_EXPORT 00467 EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC(); 00468 00469 // If we're hanging around in a mould then export the correct tokens 00470 if (!InsideMould()) 00471 { 00472 NodePath::Render(pRegion); 00473 } 00474 else 00475 { 00476 pDC->OutputToken(_T("csmp")); // Camelot "start mould path" token 00477 pDC->OutputNewLine(); 00478 00479 // Call the parent class 00480 NodePath::Render(pRegion); 00481 00482 pDC->OutputToken(_T("cemp")); // Camelot "start mould path" token 00483 pDC->OutputNewLine(); 00484 } 00485 #endif 00486 return TRUE; 00487 } 00488 00489 00490 00491 00492 /********************************************************************************************* 00493 00494 BOOL NodeMouldPath::ExportAWEPS(RenderRegion* pRegion) 00495 00496 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00497 Created: 14/03/95 00498 Inputs: pRegion = a pointer to a Camelot EPS render region 00499 Returns: TRUE if we've rendered the object 00500 FALSE if we want the caller to render the object 00501 Purpose: Overrides the standard call to Obj->Render so we can render the path 00502 as we would like 00503 00504 **********************************************************************************************/ 00505 00506 BOOL NodeMouldPath::ExportAWEPS(RenderRegion* pRegion) 00507 { 00508 // just return false for the moment until we write our 00509 // proper random AWEPS path render function 00510 return FALSE; 00511 } 00512 00513 00514 /******************************************************************************************** 00515 00516 > virtual INT32 NodeMouldPath::ComplexCopy(CopyStage Stage, Range& RangeToCopy, Node** pOutput) 00517 00518 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00519 Created: 3/5/95 00520 Inputs: Stage - COPYOBJECT if we should make a copy 00521 - COPYFINISHED once the entire copy operation has completed 00522 RangeToCopy - Describes the range which is currently being copied. 00523 pOutput - a pointer to a pointer to a node. Set this pointer to point 00524 at the tree copy 00525 Returns: -1 = The routine failed to make a copy. 00526 0 = No copy has been made. 00527 +1 = pOutput points to the copy. 00528 Purpose: If the copystage is COPYOBJECT, 00529 The node has been called to copy itself and do what ever it needs to to 00530 make a sensible copy of other items such as attributes. 00531 The caller (CopyObjects) will not deep copy this node (as this is a complex 00532 copy and it expects the handler to know what its doing). In this case the 00533 NodeMouldPath object needs to turn itself into a node path. 00534 SeeAlso Node::ComplexCopy(), CopyObjects() 00535 00536 ********************************************************************************************/ 00537 00538 INT32 NodeMouldPath::ComplexCopy(CopyStage Stage, Range& RangeToCopy, Node** pOutput) 00539 { 00540 ERROR2IF(pOutput==NULL,FALSE,"NodeMouldPath::ComplexCopy() called with NULL output pointer!"); 00541 00542 switch (Stage) 00543 { 00544 case COPYOBJECT: 00545 { 00546 // we've been asked to make a copy of ourselves 00547 NodePath* NodeCopy = new NodePath; 00548 BOOL ok = (NodeCopy!=NULL); 00549 if (ok) 00550 { 00551 NodePath::CopyNodeContents(NodeCopy); 00552 // Copy contents specific to derived class here 00553 NodeCopy->InkPath.IsFilled = TRUE; 00554 } 00555 00556 if (ok) 00557 { 00558 (*pOutput) = NodeCopy; 00559 return 1; 00560 } 00561 else 00562 return -1; 00563 } 00564 break; 00565 00566 case COPYFINISHED: 00567 return 0; 00568 break; 00569 00570 default: 00571 return -1; 00572 break; 00573 } 00574 } 00575 00576 /******************************************************************************************** 00577 00578 > virtual BOOL NodeMouldPath::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00579 00580 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00581 Created: 19/7/96 00582 Inputs: pFilter = ptr to the filter 00583 Returns: TRUE if record is written, FALSE if not 00584 Purpose: Writes the mould path record to the filter 00585 SeeAlso: - 00586 00587 ********************************************************************************************/ 00588 00589 BOOL NodeMouldPath::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00590 { 00591 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 00592 00593 INT32 NumCoords = InkPath.GetNumCoords(); 00594 INT32 RecordSize = sizeof(INT32)+(sizeof(PathVerb)*NumCoords)+(sizeof(DocCoord)*NumCoords); 00595 00596 CamelotFileRecord Rec(pFilter,TAG_MOULD_PATH,RecordSize); 00597 00598 BOOL ok = Rec.Init(); 00599 00600 if (ok) ok = Rec.WritePath(&InkPath); 00601 if (ok) ok = pFilter->Write(&Rec); 00602 00603 if (!ok) 00604 pFilter->GotError(_R(IDE_FILE_WRITE_ERROR)); 00605 00606 return ok; 00607 } 00608 00609 //-------------------------------------------------------------- 00610 // See NodeMouldPath::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00611 // 00612 BOOL NodeMouldPath::WritePreChildrenNative(BaseCamelotFilter* pFilter) 00613 { 00614 return WritePreChildrenWeb(pFilter); 00615 } 00616 00617