00001 // $Id: nodeattr.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 /* 00100 */ 00101 00102 #include "camtypes.h" 00103 //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "mario.h" 00105 //#include "simon.h" 00106 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "doccolor.h" 00109 #include "colcomp.h" 00110 //#include "basedoc.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "blendatt.h" 00112 //#include "ink.h" // for EffectsParentBounds(NodeRenderableInk*) - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "nodedoc.h" 00114 //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 //#include "undoop.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 #include "layer.h" 00117 00118 DECLARE_SOURCE("$Revision: 1282 $"); 00119 00120 CC_IMPLEMENT_DYNAMIC(NodeAttribute, NodeRenderable) 00121 00122 /******************************************************************************************** 00123 00124 > NodeAttribute::NodeAttribute() 00125 00126 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00127 Created: 21/6/93 00128 Inputs: - 00129 Outputs: - 00130 Returns: - 00131 Purpose: Default constructor for Node Attribute class 00132 Errors: - 00133 SeeAlso: - 00134 00135 ********************************************************************************************/ 00136 00137 NodeAttribute::NodeAttribute() : NodeRenderable() 00138 { 00139 } 00140 00141 /******************************************************************************************** 00142 00143 > NodeAttribute::NodeAttribute(Node* ContextNode, 00144 AttachNodeDirection Direction, 00145 BOOL Locked, 00146 BOOL Mangled, 00147 BOOL Marked, 00148 BOOL Selected 00149 ): Node(ContextNode, Direction, Locked, Mangled, Marked, Selected, TRUE) 00150 00151 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 21/6/93 00153 Inputs: - 00154 Outputs: - 00155 Returns: - 00156 Purpose: Who knows ? 00157 Errors: - 00158 SeeAlso: - 00159 00160 ********************************************************************************************/ 00161 00162 NodeAttribute::NodeAttribute(Node* ContextNode, 00163 AttachNodeDirection Direction, 00164 BOOL Locked, 00165 BOOL Mangled, 00166 BOOL Marked, 00167 BOOL Selected 00168 ): NodeRenderable(ContextNode, Direction, Locked, Mangled, Marked, Selected) 00169 { 00170 } 00171 00172 00173 /********************************************************************************************* 00174 00175 > BOOL NodeAttribute::IsAnAttribute(void) const 00176 00177 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00178 Created: 19/4/93 00179 Inputs: - 00180 Outputs: - 00181 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00182 Purpose: Virtual function for determining if the node is an attribute 00183 Errors: 00184 00185 **********************************************************************************************/ 00186 00187 BOOL NodeAttribute::IsAnAttribute() const 00188 { 00189 return TRUE; 00190 } 00191 00192 00193 /******************************************************************************************** 00194 00195 > virtual BOOL NodeAttribute::IsOrHidesAnAttribute() const 00196 00197 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00198 Created: 12/6/95 00199 Returns: TRUE, as this is an attribute 00200 Purpose: To see if this node is an attribute, or is hiding an attribute (NodeHiddens) 00201 00202 ********************************************************************************************/ 00203 00204 BOOL NodeAttribute::IsOrHidesAnAttribute() const 00205 { 00206 return TRUE; 00207 } 00208 00209 00210 /********************************************************************************************* 00211 00212 > BOOL NodeAttribute::IsAValueChange(void) const 00213 00214 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00215 Created: 13/2/95 00216 Inputs: - 00217 Outputs: - 00218 Returns: TRUE if the node is an AttrValueChange, will return TRUE 00219 Purpose: Virtual function for determining if the node is a value change attribute 00220 Errors: 00221 00222 **********************************************************************************************/ 00223 00224 BOOL NodeAttribute::IsAValueChange() const 00225 { 00226 return FALSE; 00227 } 00228 00229 /********************************************************************************************* 00230 00231 > BOOL NodeAttribute::IsAColourFill(void) const 00232 00233 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00234 Created: 13/2/95 00235 Inputs: - 00236 Outputs: - 00237 Returns: TRUE if the node is a AttrColourFill, will return TRUE 00238 Purpose: Virtual function for determining if the node is a Colour Fill attribute 00239 Errors: 00240 00241 **********************************************************************************************/ 00242 00243 BOOL NodeAttribute::IsAColourFill() const 00244 { 00245 return FALSE; 00246 } 00247 00248 /********************************************************************************************* 00249 00250 > BOOL NodeAttribute::IsATranspFill(void) const 00251 00252 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00253 Created: 13/2/95 00254 Inputs: - 00255 Outputs: - 00256 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00257 Purpose: Virtual function for determining if the node is an attribute 00258 Errors: 00259 00260 **********************************************************************************************/ 00261 00262 BOOL NodeAttribute::IsATranspFill() const 00263 { 00264 return FALSE; 00265 } 00266 00267 /********************************************************************************************* 00268 00269 > BOOL NodeAttribute::IsAStrokeColour(void) const 00270 00271 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00272 Created: 13/2/95 00273 Inputs: - 00274 Outputs: - 00275 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00276 Purpose: Virtual function for determining if the node is an attribute 00277 Errors: 00278 00279 **********************************************************************************************/ 00280 00281 BOOL NodeAttribute::IsAStrokeColour() const 00282 { 00283 return FALSE; 00284 } 00285 00286 /********************************************************************************************* 00287 00288 > BOOL NodeAttribute::IsAStrokeTransp(void) const 00289 00290 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00291 Created: 13/2/95 00292 Inputs: - 00293 Outputs: - 00294 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00295 Purpose: Virtual function for determining if the node is an attribute 00296 Errors: 00297 00298 **********************************************************************************************/ 00299 00300 BOOL NodeAttribute::IsAStrokeTransp() const 00301 { 00302 return FALSE; 00303 } 00304 00305 /********************************************************************************************* 00306 00307 > BOOL NodeAttribute::IsAFlatFill(void) const 00308 00309 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00310 Created: 13/2/95 00311 Inputs: - 00312 Outputs: - 00313 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00314 Purpose: Virtual function for determining if the node is an attribute 00315 Errors: 00316 00317 **********************************************************************************************/ 00318 00319 BOOL NodeAttribute::IsAFlatFill() const 00320 { 00321 return FALSE; 00322 } 00323 /********************************************************************************************* 00324 00325 > BOOL NodeAttribute::IsAGradFill(void) const 00326 00327 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00328 Created: 13/2/95 00329 Inputs: - 00330 Outputs: - 00331 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00332 Purpose: Virtual function for determining if the node is an attribute 00333 Errors: 00334 00335 **********************************************************************************************/ 00336 00337 BOOL NodeAttribute::IsAGradFill() const 00338 { 00339 return FALSE; 00340 } 00341 00342 /********************************************************************************************* 00343 00344 > BOOL NodeAttribute::IsABitmapFill(void) const 00345 00346 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00347 Created: 13/2/95 00348 Inputs: - 00349 Outputs: - 00350 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00351 Purpose: Virtual function for determining if the node is an attribute 00352 Errors: 00353 00354 **********************************************************************************************/ 00355 00356 BOOL NodeAttribute::IsABitmapFill() const 00357 { 00358 return FALSE; 00359 } 00360 /********************************************************************************************* 00361 00362 > BOOL NodeAttribute::IsAFractalFill(void) const 00363 00364 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00365 Created: 13/2/95 00366 Inputs: - 00367 Outputs: - 00368 Returns: TRUE if the node is a NodeAttribute, will return TRUE 00369 Purpose: Virtual function for determining if the node is an attribute 00370 Errors: 00371 00372 **********************************************************************************************/ 00373 00374 BOOL NodeAttribute::IsAFractalFill() const 00375 { 00376 return FALSE; 00377 } 00378 00379 /********************************************************************************************* 00380 00381 > BOOL NodeAttribute::IsALineWidthAttr() const 00382 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00383 Created: 13/2/95 00384 Inputs: - 00385 Outputs: - 00386 Returns: TRUE if the node is a line width attribute, will return TRUE 00387 Purpose: Virtual function for determining if the node is a line width attribute 00388 Errors: 00389 00390 *************************************************************************************************/ 00391 00392 BOOL NodeAttribute::IsALineWidthAttr() const 00393 { 00394 return FALSE; 00395 } 00396 00397 /********************************************************************************************* 00398 00399 > virtual BOOL NodeAttribute::NeedsToRenderAtEachBrushStroke() 00400 00401 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00402 Created: 29/11/99 00403 Inputs: - 00404 Outputs: - 00405 Returns: TRUE if this attribute should be rendered at every step of a brush stroke 00406 Purpose: So that don't have to keep re-rendering attributes whilst drawing a brush, this 00407 identifies whether or not the attribute need to be rendered at each step, 00408 e.g. radial fills. 00409 Errors: 00410 See Also; Brush code (ndbrshmk.cpp) 00411 00412 **********************************************************************************************/ 00413 00414 BOOL NodeAttribute::NeedsToRenderAtEachBrushStroke() const 00415 { 00416 return FALSE; 00417 } 00418 00419 00420 00421 /********************************************************************************************* 00422 00423 > BOOL NodeAttribute::EffectsParentBounds() const 00424 00425 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00426 Created: 4/4/95 00427 Inputs: - 00428 Outputs: - 00429 Returns: TRUE if the node will effect the bounds of it's parent. 00430 Purpose: Virtual function for determining if the node will effect it's parent bounds. 00431 eg. ArrowHeads. 00432 SeeAlso: NodeAttribute::GetAttrBoundingRect 00433 00434 **********************************************************************************************/ 00435 00436 BOOL NodeAttribute::EffectsParentBounds() 00437 { 00438 return FALSE; 00439 } 00440 00441 /********************************************************************************************* 00442 00443 > DocRect NodeAttribute::GetAttrBoundingRect(NodeRenderableInk* pParent) 00444 00445 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00446 Created: 4/4/95 00447 Inputs: pParent, the parent Ink node that this attribute will effect. 00448 Outputs: - 00449 Returns: The Bounding rect of the attribute (NULL rectangle is it doesn't have any). 00450 Purpose: Virtual function for determining the bounding rect of an attribute. 00451 eg. ArrowHeads. 00452 SeeAlso: NodeAttribute::EffectsParentBounds 00453 00454 **********************************************************************************************/ 00455 00456 DocRect NodeAttribute::GetAttrBoundingRect(NodeRenderableInk* pParent, CCAttrMap* pAttribMap) 00457 { 00458 return DocRect(0,0,0,0); 00459 } 00460 00461 /******************************************************************************************** 00462 00463 > BOOL NodeAttribute::NeedsToRender( RenderRegion *pRender ) 00464 00465 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00466 Created: 07/02/94 00467 Inputs: pRender - A pointer to the current render region 00468 Returns: TRUE => This node should be rendered, 00469 FALSE => This node does not need to be rendered. 00470 Purpose: Virtual function - this version always returns TRUE, which indicates to 00471 the caller that we always want to render nodes of this type if we have 00472 encountered them. 00473 SeeAlso: Node::NeedsToRender 00474 00475 ********************************************************************************************/ 00476 00477 SubtreeRenderState NodeAttribute::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip) 00478 { 00479 // If we've found an attribute node, then we always want to render it. 00480 return SUBTREE_ROOTONLY; 00481 } 00482 00483 /******************************************************************************************** 00484 00485 > BOOL NodeAttribute::NeedsToExport(RenderRegion* pRender, BOOL VisibleLayersOnly = FALSE, 00486 BOOL CheckSelected = FALSE) 00487 00488 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00489 Created: 23/03/94 00490 Inputs: pRender - A pointer to the current export region 00491 VisibleLayersOnly - TRUE => remove nodes which are on invisible layers 00492 - FALSE => export everything 00493 CheckSelected - TRUE => we check if object selected and only export selected bjects 00494 - FALSE => we don't bother checking for selection or not 00495 Returns: TRUE => please export me. 00496 Purpose: Virtual function - this version always returns TRUE, because we always 00497 want to export attributes. 00498 SeeAlso: NodeAttribute::NeedsToRender 00499 00500 ********************************************************************************************/ 00501 00502 BOOL NodeAttribute::NeedsToExport(RenderRegion* pRender, BOOL VisibleLayersOnly, 00503 BOOL CheckSelected) 00504 { 00505 return TRUE; 00506 } 00507 00508 /*********************************************************************************************** 00509 > Node* NodeAttribute::SimpleCopy() 00510 00511 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00512 Created: 21/6/93 00513 00514 Inputs: - 00515 Outputs: 00516 Returns: A copy of the node, or NULL if memory runs out 00517 00518 Purpose: This method returns a shallow copy of the node with all Node pointers NULL. 00519 The function is virtual, and must be defined for all derived classes. 00520 00521 Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory 00522 error and the function returns NULL. 00523 00524 Scope: protected 00525 ***********************************************************************************************/ 00526 00527 Node* NodeAttribute::SimpleCopy() 00528 { 00529 NodeAttribute* NodeCopy = new NodeAttribute(); 00530 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); 00531 CopyNodeContents(NodeCopy); 00532 00533 return NodeCopy; 00534 } 00535 00536 /******************************************************************************************** 00537 00538 > INT32 NodeAttribute::operator==(const NodeAttribute& Attrib) 00539 00540 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00541 Created: 9/2/94 00542 Inputs: Atrib: The attribute to compare 00543 Outputs: - 00544 Returns: - 00545 Purpose: This function is slightly weird. Unlike most definitions of operator== it's 00546 virtual. 00547 00548 To see why it's required, consider the following 00549 00550 NodeAttribute* A,B; 00551 00552 A = X; 00553 B = Y; 00554 00555 where X and Y are pointers to instances of derived 00556 classes of NodeAttribute. 00557 00558 if X->GetRuntimeClass() == Y->GetRuntimeClass() then we should be 00559 able to compare X and Y. But if we had defined a normal operator== 00560 fn then we find we cannot do this, because there is no way of casting 00561 to a type which is unknown at compile time. 00562 00563 The implementation of operator== in all derived classes of NodeAttribute 00564 should look something like this. 00565 00566 INT32 DerivedClass::operator==(const NodeAttribute& Attrib) 00567 { 00568 DerivedClass* Attr = (DerivedClass*) &Attrib; 00569 00570 // Compare member vars with Attr 00571 } 00572 00573 Before calling this function you must be sure that the attributes 00574 have the same runtime class. 00575 00576 The function needs to be defined in all derived classes of NodeAttribute 00577 00578 Errors: If this function is called on an instance of a derived class of 00579 NodeAttribute, and the function has not been defined for the derived 00580 class, then an ENSURE failure will result. 00581 00582 SeeAlso: - 00583 00584 ********************************************************************************************/ 00585 00586 INT32 NodeAttribute::operator==(const NodeAttribute& Attrib) 00587 { 00588 ENSURE(FALSE, "the pure virtual operator== fn has not been defined"); 00589 return (FALSE); 00590 } 00591 00592 00593 00594 /******************************************************************************************** 00595 00596 > virtual BOOL NodeAttribute::IsDifferent(Node *pOther) 00597 00598 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00599 Created: 28/2/97 00600 00601 Inputs: pOther - The node to compare this one to 00602 00603 Returns: TRUE if this is considered different from pOther, 00604 FALSE if they are the same 00605 00606 Purpose: Determine if 2 nodes are considered different. 00607 00608 Notes: NodeAttribute uses its own (and derived class) operator== method 00609 to determine if the nodes are different. This will work for ANY 00610 derived attribute class. 00611 00612 ********************************************************************************************/ 00613 00614 BOOL NodeAttribute::IsDifferent(Node *pOther) 00615 { 00616 // First, check with the base class - this checks the classes are the same type 00617 if (NodeRenderable::IsDifferent(pOther)) 00618 return(TRUE); 00619 00620 ERROR3IF(GetRuntimeClass() != pOther->GetRuntimeClass(), 00621 "Node::IsDifferent base class method seems to have been broken"); 00622 00623 // Check if different using the operator== which is defined from NodeAttribute onwards 00624 if (*this == *((NodeAttribute *)pOther) ) 00625 return(FALSE); 00626 00627 return(TRUE); 00628 } 00629 00630 00631 00632 /******************************************************************************************** 00633 00634 > virtual UINT32 NodeAttribute::GetAttrNameID(void) 00635 00636 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00637 Created: 22/2/94 00638 Inputs: - 00639 Outputs: - 00640 Returns: Attribute description ID 00641 Purpose: Returns back a string resource ID describing the attribute, this base 00642 class function returns the resource _R(IDS_ATTRIBUTE). 00643 00644 Errors: - 00645 SeeAlso: - 00646 00647 ********************************************************************************************/ 00648 00649 UINT32 NodeAttribute::GetAttrNameID(void) 00650 { 00651 return (_R(IDS_ATTRIBUTE)); 00652 } 00653 00654 /*********************************************************************************************** 00655 > void NodeAttribute::CopyNodeContents(NodeAttribute* NodeCopy) 00656 00657 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00658 Created: 28/4/93 00659 00660 Inputs: 00661 Outputs: A copy of this node 00662 Returns: - 00663 00664 Purpose: This method copies the node's contents to the node pointed to by NodeCopy. 00665 00666 Errors: An assertion failure will occur if NodeCopy is NULL 00667 00668 Scope: protected 00669 00670 ***********************************************************************************************/ 00671 00672 void NodeAttribute::CopyNodeContents( NodeAttribute* NodeCopy) 00673 { 00674 NodeRenderable::CopyNodeContents( NodeCopy ); 00675 } 00676 00677 00678 #ifdef _DEBUG 00679 /*********************************************************************************************** 00680 00681 > void NodeAttribute::ShowDebugTreeDetails() const 00682 00683 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00684 Created: 21/6/93 00685 Purpose: Displays debugging info of the tree 00686 00687 ***********************************************************************************************/ 00688 00689 void NodeAttribute::ShowDebugTreeDetails() const 00690 { 00691 // Display a bit of debugging info 00692 // For now, we will just call the base class version 00693 Node::ShowDebugTreeDetails(); 00694 } 00695 #endif 00696 00697 00698 /******************************************************************************************** 00699 00700 > DocColour *NodeAttribute::EnumerateColourFields(UINT32 Context) 00701 00702 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00703 Created: 19/07/94 00704 Inputs: Context - indicates which colour field should be returned next. 00705 Returns: Pointer to the next colour field - this may well be altered by the caller. 00706 Purpose: Enumerates all the colour fields used by an attribute. This enables the 00707 colour manager to scan the tree and process any attribute it finds to carry 00708 out operations such as turning indexed colours into immediate colours, and 00709 so on. 00710 The Context parameter indicates which colour field should be returned 00711 next. It is 0 initially, then it will be 1, then 2, etc. The NodeAttribute 00712 object should use this to deduce how far it has got through its colour 00713 fields, and return the next one, or NULL if there are no more. 00714 The order in which the colours are returned is not important, as long 00715 as EVERY colour in the attribute is returned ONCE and ONLY once. Other 00716 than this stipulation, the NodeAttribute can amuse itself in whatever 00717 foul and depraved manner it deems appropriate. 00718 00719 ********************************************************************************************/ 00720 00721 DocColour *NodeAttribute::EnumerateColourFields(UINT32 Context) 00722 { 00723 // No colours in a standard NodeAttribute. 00724 return NULL; 00725 } 00726 00727 /******************************************************************************************** 00728 00729 > virtual BOOL NodeAttribute::CopyComponentData(BaseDocument* SrcDoc, BaseDocument* NodesDoc) 00730 00731 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00732 Created: 12/9/94 00733 Inputs: SrcDoc: The document from where this node was copied 00734 NodesDoc: The document where this node lives 00735 Outputs: - 00736 Returns: FALSE if unable to copy data 00737 Purpose: If the attribute contains any DocColours which are indexed then a copy 00738 of the indexed colour is made and added to the NodesDoc 00739 ColourListComponent. 00740 Errors: - 00741 SeeAlso: NodeRenderable::CopyComponentData 00742 00743 ********************************************************************************************/ 00744 00745 00746 BOOL NodeAttribute::CopyComponentData(BaseDocument* SrcDoc, BaseDocument* NodesDoc) 00747 { 00748 // Ask the base class to copy its data 00749 if (!NodeRenderable::CopyComponentData(SrcDoc, NodesDoc)) 00750 { 00751 return FALSE; // Failed 00752 } 00753 // Get the colour list component 00754 ColourListComponent *pComponent = 00755 (ColourListComponent *) NodesDoc->GetDocComponent(CC_RUNTIME_CLASS(ColourListComponent)); 00756 00757 ENSURE (pComponent != NULL, "Could not find ColourListComponent"); 00758 00759 // Copy across all DocColours 00760 for (INT32 i=0;;i++) 00761 { 00762 DocColour* pDocCol = EnumerateColourFields(i); 00763 if (pDocCol == NULL) 00764 { 00765 // there are no more colours to copy 00766 break; 00767 } 00768 // Copy the colour across 00769 if (pComponent->CopyColourAcross(pDocCol) == CCCOPY_FAILED) 00770 { 00771 return FALSE; // Failed to copy colour info 00772 } 00773 } 00774 return TRUE; 00775 } 00776 00777 00778 00779 00780 /******************************************************************************************** 00781 > static NodeAttribute* NodeAttribute::FindFirstAppliedAttr(Node* pContextNode, Node* pRoot = NULL) 00782 00783 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00784 Created: 06/01/2005 00785 Inputs: - 00786 Outputs: - 00787 Returns: Pointer to attribute which is closest in scope to the context node. 00788 Purpose: Find the attribute which is closest in attribute scope to the context node. 00789 Use in conjunction with FindPrevAppliedAtt. 00790 Note! 00791 This routine and FindPrevAppliedAttr will return "Effect Attributes" that 00792 only apply to pContextNode, and not its children. You should test for them 00793 using IsEffectAttribute outside this function if you don't want to find them. 00794 Errors: - 00795 SeeAlso: NodeAttribute::FindPrevAppliedAtt 00796 ********************************************************************************************/ 00797 00798 NodeAttribute* NodeAttribute::FindFirstAppliedAttr(Node* pContextNode, Node* pRoot) 00799 { 00800 ERROR2IF(pContextNode == NULL, NULL, "FindFirstAppliedAttr() called on NULL"); 00801 Node* pNode = NULL; 00802 00803 // Begin the attribute search from the right-most child of "this" node. 00804 // (So that Effect Attributes are picked up) 00805 pNode = pContextNode->FindLastChild(); 00806 if (pNode == NULL) pNode = pContextNode; 00807 00808 // If the very first node is an attribute, great, return that... 00809 if (pNode->IsAnAttribute() && !pNode->IsAClipViewAttr()) 00810 return ((NodeAttribute*) pNode); 00811 00812 // Otherwise must search in reverse render order for an attribute... 00813 return FindPrevAppliedAttr(pNode, pRoot); 00814 } 00815 00816 00817 00818 00819 /******************************************************************************************** 00820 > static NodeAttribute* NodeAttribute::FindPrevAppliedAttr(Node* pContextNode, Node* pRoot = NULL) 00821 00822 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00823 Created: 06/01/2005 00824 Inputs: - 00825 Outputs: - 00826 Returns: A pointer to the attribute which occurs "previous" to this node. 00827 Purpose: Finds the previous attribute in the tree, from this node, by searching 00828 backwards and up (along Previous and Parent links), or null if there is no 00829 such attribute. 00830 Note! 00831 This routine and FindFirstAppliedAttr will return "Effect Attributes" that 00832 only apply to pContextNode, and not its children. You should test for them 00833 using IsEffectAttribute outside this function if you don't want to find them. 00834 Errors: - 00835 SeeAlso: - 00836 ********************************************************************************************/ 00837 00838 NodeAttribute* NodeAttribute::FindPrevAppliedAttr(Node* pContextNode, Node* pRoot) 00839 { 00840 ERROR2IF(pContextNode == NULL, NULL, "FindPrevAppliedAttr() called on NULL"); 00841 00842 // We are going to start from this attribute node. 00843 // All attributes are collected together as the first nodes in a sub-tree, so we can 00844 // call FindPrevious here as the previous node will either be NULL or another attribute. 00845 Node* pNode = pContextNode; 00846 00847 // Search for the next attribute 00848 do 00849 { 00850 // Get the previous node 00851 if (pNode->FindPrevious()) 00852 pNode = pNode->FindPrevious(); 00853 else 00854 { 00855 // Move up to sibling list above 00856 pNode = pNode->FindParent(); 00857 00858 // -------------------------------------- 00859 // Optimisation! 00860 // There are often a small number of attributes at the start of a large sibling 00861 // list. So it's often quicker to skip to the start and then skip forward from there 00862 // (This clause can be removed without changing the basic operation of this 00863 // function.) 00864 if (pNode==pRoot) return NULL; 00865 00866 // Quick test to see whether attr is readily available in new sibling list 00867 // (Assume that paper node tree section is quicker to scan the obvious way) 00868 Node* pTestNode = pNode->FindPrevious(); 00869 if (!(pNode->IsPaper() || (pTestNode && pTestNode->IsOrHidesAnAttribute()))) 00870 { 00871 Node* pAttr = NULL; // Init the attr pointer we're searching for 00872 pTestNode = pNode; 00873 while (pTestNode && pAttr==NULL) // Start looping up through sibling lists til we find an attr 00874 { 00875 Node* pParent = pTestNode->FindParent(); // Find first node in this sibling list 00876 pTestNode = pParent ? pParent->FindFirstChild() : NULL; 00877 00878 while (pTestNode && pTestNode->IsOrHidesAnAttribute()) // Loop through nodes in this sib list until find a non-attr 00879 { 00880 pAttr = pTestNode; // Remember the last attr we've found 00881 pTestNode = pTestNode->FindNext(); // Test next node in this sibling list 00882 } 00883 00884 pTestNode = pParent; // Find parent sibling list 00885 } 00886 00887 if (pAttr) // If we found an attribute 00888 pNode = pAttr; // return it 00889 // (otherwise leave pNode unchanged and allow normal 00890 // algorithm to work out how to handle it) 00891 } 00892 // -------------------------------------- 00893 } 00894 00895 if (pNode && pNode->IsAnAttribute() && !pNode->IsAClipViewAttr()) 00896 return ((NodeAttribute*) pNode); 00897 } 00898 while (pNode!=pRoot); 00899 00900 return NULL; 00901 } 00902 00903 00904 /******************************************************************************************** 00905 > BOOL NodeAttribute::HasEquivalentDefaultValue(BOOL bAppearance = FALSE) 00906 00907 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00908 Created: 22/03/2005 00909 Inputs: - 00910 Outputs: - 00911 Returns: TRUE if this node has a value equivalent to the relevant 00912 FALSE otherwise 00913 Purpose: Determine whether this attribute has the default value or not 00914 Errors: - 00915 SeeAlso: - 00916 ********************************************************************************************/ 00917 00918 BOOL NodeAttribute::HasEquivalentDefaultValue(BOOL bAppearance) 00919 { 00920 AttributeValue* pDefaultAttrVal = NULL; 00921 // CCRuntimeClass* AttrType = GetAttributeType(); 00922 00923 // Look for the default attr directly 00924 // (But this doesn't work for those attrs which are grouped together 00925 // and share a common default value - e.g. fills) 00926 AttrIndex attrid = GetAttributeIndex(); 00927 if (attrid!=ATTR_BAD_ID && attrid<ATTR_FIRST_FREE_ID) 00928 pDefaultAttrVal = AttributeManager::GetDefaultAttributeVal(attrid); 00929 00930 if (pDefaultAttrVal && !GetAttributeValue()->IsDifferent(pDefaultAttrVal)) 00931 { 00932 // Just allow the node to be hidden 00933 return TRUE; 00934 } 00935 00936 return FALSE; 00937 } 00938 00939 00940 00941 00942 /******************************************************************************************** 00943 > BOOL NodeAttribute::Blend(BlendAttrParam* pBlendParam) 00944 00945 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00946 Created: 25/10/94 00947 Inputs: pBlendParam = ptr to a blend attr class object 00948 Outputs: - 00949 Returns: TRUE if successful, FALSE otherwise 00950 Purpose: This will blend this attribute using the data held in pBlendParam. 00951 This base version does this: 00952 If the blend ratio <= 50%, this attr is copied 00953 If the blend ratio > 50%, the other attr is copied 00954 Errors: - 00955 SeeAlso: - 00956 ********************************************************************************************/ 00957 00958 BOOL NodeAttribute::Blend(BlendAttrParam* pBlendParam) 00959 { 00960 // Check NULL entry param 00961 ERROR3IF(pBlendParam == NULL,"pBlendParam == NULL"); 00962 if (pBlendParam == NULL) return FALSE; 00963 00964 // Make a copy of this node, and make this the blended attribute 00965 NodeAttribute* pBlendedAttr = NULL; 00966 NodeAttribute* pAttrToCopy = NULL; 00967 00968 if (pBlendParam->GetBlendRatio() <= 0.5) 00969 pAttrToCopy = this; 00970 else 00971 pAttrToCopy = pBlendParam->GetOtherAttr(); 00972 00973 if (pAttrToCopy != NULL) 00974 { 00975 pBlendedAttr = (NodeAttribute*) pAttrToCopy->SimpleCopy(); 00976 pBlendParam->SetBlendedAttr(pBlendedAttr); 00977 } 00978 00979 // Return TRUE if we were able to make a copy of this node 00980 return (pBlendedAttr != NULL); 00981 } 00982 00983 00984 /******************************************************************************************** 00985 00986 > BOOL NodeAttribute::IsADefaultAttr() 00987 00988 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00989 Created: 28/9/95 00990 Returns: TRUE if attribute is a default attribute. i.e. it's parent is a NodeDocument 00991 Purpose: Simple but useful fn to determine if the attribute (which must be in the tree) 00992 is a default attribute 00993 00994 ********************************************************************************************/ 00995 00996 00997 BOOL NodeAttribute::IsADefaultAttr() 00998 { 00999 return (IS_A(FindParent(), NodeDocument)); 01000 } 01001 01002 01003 /******************************************************************************************** 01004 01005 > BOOL NodeAttribute::IsEffectAttribute() const 01006 01007 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01008 Created: 05/01/2005 01009 Returns: TRUE if attribute is an Effect attribute. i.e. it's not in the usual place 01010 in the tree, it's at the end of a child list with bounded nodes ahead of it. 01011 01012 ********************************************************************************************/ 01013 01014 BOOL NodeAttribute::IsEffectAttribute() const 01015 { 01016 // Node* pSibling = FindPrevious(CC_RUNTIME_CLASS(NodeRenderableBounded)); 01017 Node* pSibling = FindPrevious(); 01018 while (pSibling && !pSibling->IsBounded()) 01019 pSibling = pSibling->FindPrevious(); 01020 01021 return (pSibling!=NULL); 01022 } 01023 01024 01025 /******************************************************************************************** 01026 01027 > BOOL NodeAttribute::ShouldBecomeCurrent() 01028 01029 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 01030 Created: 14/6/96 01031 Returns: TRUE if this attribute should become current. 01032 01033 FALSE if the user must deliberately apply this attribute to an object 01034 every time he wants to use it. 01035 01036 Purpose: The attribute manager calls this function before making an attribute current. 01037 01038 There are some attributes - like this URL Hot Link attribute I'm about 01039 to put in - that the user probably won't want to become current. 01040 For example, if a user puts a HotLink on an object and happens to have 01041 the Give Other Objects Most Recent Attributes option on, all his new objects are 01042 going to have HotLinks. That's not good. 01043 01044 So those attributes will override this function and return FALSE. 01045 01046 ********************************************************************************************/ 01047 01048 01049 BOOL NodeAttribute::ShouldBecomeCurrent() 01050 { 01051 //Yes, we'd like this attribute to be passed to other objects. 01052 return TRUE; 01053 } 01054 01055 01056 01057 /******************************************************************************************** 01058 > NodeAttribute* NodeAttribute::FindNextAttr(TypeFunc pfnTest) const 01059 01060 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01061 Created: 27/1/95 01062 Inputs: pfnTest --- pointer to a member-function of Node:- 01063 typedef BOOL (Node::*TypeFunc)() const; 01064 that returns TRUE for the attribute being 01065 searched for and FALSE otherwise 01066 Returns: The next attribute of the given type from this one that applies to the 01067 object Node::FindFirstAttr was called for, or null if there 01068 isn't one. 01069 Purpose: Finds the next attribute of the given type that applies to the object. 01070 SeeAlso: Node::FindFirstAttr 01071 ********************************************************************************************/ 01072 01073 NodeAttribute* NodeAttribute::FindNextAttr(TypeFunc pfnTest) const 01074 { 01075 // Search for the class in the previous sibling nodes, then the parent's siblings, 01076 // then the parent siblings of the parent of ... etc. 01077 const Node* pNode = this; 01078 do { 01079 // Work out the next node in the search order. 01080 if (pNode->FindPrevious() != 0) 01081 { 01082 // The next node is the previous sibling. 01083 pNode = pNode->FindPrevious(); 01084 } 01085 else 01086 { 01087 // The next node is the parent, if there is one. 01088 pNode = pNode->FindParent(); 01089 if (pNode == 0) break; 01090 } 01091 } while (!(pNode->*pfnTest)()); 01092 01093 // Return the attribute, or null if none was found. 01094 return (NodeAttribute*) pNode; 01095 } 01096 01098 // New extensions to the attribute system - initially created to support feathering attribute 01100 01101 01102 /******************************************************************************************** 01103 > virtual BOOL NodeAttribute::IsLinkedToNodeGeometry() 01104 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01105 Created: 3/5/00 01106 Inputs: 01107 Outputs: 01108 Returns: 01109 Purpose: This test determines whether the attribute is linked to the geometry of the 01110 objects it has been applied to. This condition is an important precursor before 01111 performing extra initialisation tests, and passing operation messages around to 01112 ensure that the attribute is up to date. 01113 ********************************************************************************************/ 01114 BOOL NodeAttribute::IsLinkedToNodeGeometry() 01115 { 01116 return FALSE; 01117 } 01118 01119 01120 /******************************************************************************************** 01121 > virtual BOOL NodeAttribute::IsLinkedToThisNode(Node* pNode) 01122 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01123 Created: 3/5/00 01124 Inputs: 01125 Outputs: 01126 Returns: 01127 Purpose: This test determines whether the attribute is linked to the geometry of the 01128 supplied object 01129 ********************************************************************************************/ 01130 BOOL NodeAttribute::IsLinkedToThisNode(Node* pNode) 01131 { 01132 return FALSE; 01133 } 01134 01135 /******************************************************************************************** 01136 > virtual BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, Path* InkPath, 01137 CCRuntimeClass* pCreatorClass) 01138 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01139 Created: 27/4/00 01140 Inputs: pMap - the attr map which contains the dynamically generated attribute 01141 we are trying to initialise 01142 InkPath - the inkpath we are going to render in this blend/contour step 01143 - NB also have a Node* version below 01144 pCreatorClass - Allows the attribute to modify it's behaviour depending on 01145 which complex node has asked to create a dynamic attr 01146 Outputs: 01147 Returns: 01148 Purpose: Blends and contours create attribute maps which are dynamically blended 01149 when the compound is rendered. 01150 Certain attributes cannot function correctly without having links to the 01151 objects which they apply to. 01152 eg feather attributes need the path outline of the objects in order to create 01153 a silhouette image from which the feather bitmap is created 01154 In order for these attributes to do their job they require an extra initialisation 01155 step after dynamic creation. 01156 NB only required when NodeAttributes in an CCAttrMap is copied or blended (ie 01157 dynamically created) 01158 NOT required if the attribute is going to be inserted into the tree before being 01159 rendered (because then it can acquire all the information it needs, about the node 01160 it is attached to, via the NodeAttribute which contains in - NB this assertion 01161 requires the associated NodeAttribute's Render() function to feed the attribute 01162 this information before asking it to render (ie by calling NodeAttribute::Render())). 01163 Errors: May return FALSE if memory allocations fail. 01164 In this case the attribute will not be able to acheive it's affect. 01165 The caller must be careful not to ask the attribute to render (eg by removing it from the 01166 CCAttrMap before calling pMap->Render()) 01167 SeeAlso: NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, ___Node* pNode____, 01168 CCRuntimeClass* pCreatorClass) 01169 ********************************************************************************************/ 01170 BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, 01171 Path* InkPath, 01172 CCRuntimeClass* pCreatorClass) 01173 { 01174 return TRUE; 01175 } 01176 01177 /******************************************************************************************** 01178 > virtual BOOL NodeAttribute::PostDynCreateInit( CCAttrMap* pMap, 01179 Node* pNode, 01180 CCRuntimeClass* pCreatorClass) 01181 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01182 Created: 27/4/00 01183 Inputs: as above except:- 01184 pNode - This variety allows the caller to supply the attr with a node which it 01185 would like the attribute to apply itself to 01186 Outputs: 01187 Returns: 01188 Purpose: 01189 Errors: 01190 SeeAlso: NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, ___Path* InkPath____, 01191 CCRuntimeClass* pCreatorClass) 01192 ********************************************************************************************/ 01193 BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, 01194 Node* pNode, 01195 CCRuntimeClass* pCreatorClass) 01196 { 01197 return TRUE; 01198 } 01199 01200 /******************************************************************************************** 01201 > virtual void NodeAttribute::PostDynCreateDeInit() 01202 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01203 Created: 27/4/00 01204 Inputs: 01205 Outputs: 01206 Returns: 01207 Purpose: Free memory allocated by PostDynCreateInit(..) functions 01208 Errors: No memory needs to be allocated so cannot fail. 01209 SeeAlso: - 01210 ********************************************************************************************/ 01211 void NodeAttribute::PostDynCreateDeInit() 01212 { 01213 } 01214 01215 /******************************************************************************************** 01216 > virtual BOOL NodeAttribute::LinkedNodeGeometryHasChanged(UndoableOperation* pOp) 01217 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01218 Created: 27/4/00 01219 Inputs: pOp - the operation that has caused the children nodes to change their 01220 geometry 01221 Outputs: 01222 Returns: 01223 Purpose: Attributes which are linked to the geometry of the objects which they affect, 01224 need to receive notification when these objects are changed by other 01225 operations 01226 eg if a group of objects is featherd, then the feather attribute applied at 01227 group level needs to be informed when any operations are performed on the 01228 children which will change their outline 01229 Tech Notes: NB NB NB 01230 This function gets called as part of the AllowOp process where an operation 01231 informs the rest of the tree that it is about to make a modification of some 01232 kind. 01233 Because of the structure of the AllowOp process we can only pass in a pointer to 01234 the operation which is causing the change 01235 It is important that you understand where this function is being used and also 01236 to use the Op pointer to make any changes UndoAble 01237 Order in which this function gets called is dependent on where the attribute 01238 appears in the tree ie ensure that work you do in this function is not order 01239 dependent. 01240 Also, this is called during the permission stage of the operation, ie it is 01241 merely trying to find out if it can go ahead and perform its actions, 01242 ie NO CHANGES HAVE BEEN MADE YET! 01243 This means you have to treat this function as a flag to reinit yourself at a 01244 later stage - ie delaying recalculation till the next time you are asked to 01245 render is one way to ensure all changes made by pOp have been performed. 01246 Errors: may need to allocate memory so can fail (return FALSE) 01247 SeeAlso: Node::AllowOp(..) and other AllowOp's 01248 ********************************************************************************************/ 01249 BOOL NodeAttribute::LinkedNodeGeometryHasChanged(UndoableOperation* pOp) 01250 { 01251 return TRUE; 01252 } 01253 01254 /******************************************************************************************** 01255 > virtual void NodeAttribute::NewlyCreatedDefaultAttr(NodeDocument* pNode) 01256 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01257 Created: 27/4/00 01258 Inputs: 01259 Outputs: 01260 Returns: 01261 Purpose: Attributes which are linked to the geometry of the objects which they affect, 01262 may not be able to perform a useful function if attached directly to the 01263 NodeDocument node (ie a default attribute). This function allows a default 01264 attribute of this type to perform an extra initialisation step so that the 01265 Render() function can handle 01266 Errors: 01267 SeeAlso: - 01268 ********************************************************************************************/ 01269 void NodeAttribute::NewlyCreatedDefaultAttr(NodeDocument* pNode) 01270 { 01271 } 01272 01273 // geometry linked attributes should use the nodes inkpath as required 01274 BOOL NodeAttribute::LinkToGeometry(Node* pContext) 01275 { 01276 return TRUE; 01277 } 01278 01279 /******************************************************************************************** 01280 > virtual BOOL NodeAttribute::ContainsAttributeValue(AttributeValue* pVal) 01281 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 01282 Created: 7/6/00 01283 Inputs: 01284 Outputs: 01285 Returns: 01286 Purpose: To check if this NodeAttribute contains a the AttributeValue 01287 NB needs to be implemented in a manner specific to the way in which 01288 the derived NodeAttribute class stores the AttributeValue 01289 Errors: 01290 SeeAlso: OffscreenAttrValue::DoesOffscreenBmpRequireTransp 01291 AttrFeather::ContainsAttributeValue 01292 ********************************************************************************************/ 01293 BOOL NodeAttribute::ContainsAttributeValue(AttributeValue* pVal) 01294 { 01295 return FALSE; 01296 }