// $Id: nodeattr.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ /* */ #include "camtypes.h" //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "mario.h" //#include "simon.h" //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "doccolor.h" #include "colcomp.h" //#include "basedoc.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "blendatt.h" //#include "ink.h" // for EffectsParentBounds(NodeRenderableInk*) - in camtypes.h [AUTOMATICALLY REMOVED] #include "nodedoc.h" //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "undoop.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "layer.h" DECLARE_SOURCE("$Revision: 1282 $"); CC_IMPLEMENT_DYNAMIC(NodeAttribute, NodeRenderable) /******************************************************************************************** > NodeAttribute::NodeAttribute() Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Inputs: - Outputs: - Returns: - Purpose: Default constructor for Node Attribute class Errors: - SeeAlso: - ********************************************************************************************/ NodeAttribute::NodeAttribute() : NodeRenderable() { } /******************************************************************************************** > NodeAttribute::NodeAttribute(Node* ContextNode, AttachNodeDirection Direction, BOOL Locked, BOOL Mangled, BOOL Marked, BOOL Selected ): Node(ContextNode, Direction, Locked, Mangled, Marked, Selected, TRUE) Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Inputs: - Outputs: - Returns: - Purpose: Who knows ? Errors: - SeeAlso: - ********************************************************************************************/ NodeAttribute::NodeAttribute(Node* ContextNode, AttachNodeDirection Direction, BOOL Locked, BOOL Mangled, BOOL Marked, BOOL Selected ): NodeRenderable(ContextNode, Direction, Locked, Mangled, Marked, Selected) { } /********************************************************************************************* > BOOL NodeAttribute::IsAnAttribute(void) const Author: Simon_Maneggio (Xara Group Ltd) Created: 19/4/93 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAnAttribute() const { return TRUE; } /******************************************************************************************** > virtual BOOL NodeAttribute::IsOrHidesAnAttribute() const Author: Rik_Heywood (Xara Group Ltd) Created: 12/6/95 Returns: TRUE, as this is an attribute Purpose: To see if this node is an attribute, or is hiding an attribute (NodeHiddens) ********************************************************************************************/ BOOL NodeAttribute::IsOrHidesAnAttribute() const { return TRUE; } /********************************************************************************************* > BOOL NodeAttribute::IsAValueChange(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is an AttrValueChange, will return TRUE Purpose: Virtual function for determining if the node is a value change attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAValueChange() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAColourFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a AttrColourFill, will return TRUE Purpose: Virtual function for determining if the node is a Colour Fill attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAColourFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsATranspFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsATranspFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAStrokeColour(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAStrokeColour() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAStrokeTransp(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAStrokeTransp() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAFlatFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAFlatFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAGradFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAGradFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsABitmapFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsABitmapFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsAFractalFill(void) const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a NodeAttribute, will return TRUE Purpose: Virtual function for determining if the node is an attribute Errors: **********************************************************************************************/ BOOL NodeAttribute::IsAFractalFill() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::IsALineWidthAttr() const Author: Will_Cowling (Xara Group Ltd) Created: 13/2/95 Inputs: - Outputs: - Returns: TRUE if the node is a line width attribute, will return TRUE Purpose: Virtual function for determining if the node is a line width attribute Errors: *************************************************************************************************/ BOOL NodeAttribute::IsALineWidthAttr() const { return FALSE; } /********************************************************************************************* > virtual BOOL NodeAttribute::NeedsToRenderAtEachBrushStroke() Author: Diccon_Yamanaka (Xara Group Ltd) Created: 29/11/99 Inputs: - Outputs: - Returns: TRUE if this attribute should be rendered at every step of a brush stroke Purpose: So that don't have to keep re-rendering attributes whilst drawing a brush, this identifies whether or not the attribute need to be rendered at each step, e.g. radial fills. Errors: See Also; Brush code (ndbrshmk.cpp) **********************************************************************************************/ BOOL NodeAttribute::NeedsToRenderAtEachBrushStroke() const { return FALSE; } /********************************************************************************************* > BOOL NodeAttribute::EffectsParentBounds() const Author: Will_Cowling (Xara Group Ltd) Created: 4/4/95 Inputs: - Outputs: - Returns: TRUE if the node will effect the bounds of it's parent. Purpose: Virtual function for determining if the node will effect it's parent bounds. eg. ArrowHeads. SeeAlso: NodeAttribute::GetAttrBoundingRect **********************************************************************************************/ BOOL NodeAttribute::EffectsParentBounds() { return FALSE; } /********************************************************************************************* > DocRect NodeAttribute::GetAttrBoundingRect(NodeRenderableInk* pParent) Author: Will_Cowling (Xara Group Ltd) Created: 4/4/95 Inputs: pParent, the parent Ink node that this attribute will effect. Outputs: - Returns: The Bounding rect of the attribute (NULL rectangle is it doesn't have any). Purpose: Virtual function for determining the bounding rect of an attribute. eg. ArrowHeads. SeeAlso: NodeAttribute::EffectsParentBounds **********************************************************************************************/ DocRect NodeAttribute::GetAttrBoundingRect(NodeRenderableInk* pParent, CCAttrMap* pAttribMap) { return DocRect(0,0,0,0); } /******************************************************************************************** > BOOL NodeAttribute::NeedsToRender( RenderRegion *pRender ) Author: Tim_Browse (Xara Group Ltd) Created: 07/02/94 Inputs: pRender - A pointer to the current render region Returns: TRUE => This node should be rendered, FALSE => This node does not need to be rendered. Purpose: Virtual function - this version always returns TRUE, which indicates to the caller that we always want to render nodes of this type if we have encountered them. SeeAlso: Node::NeedsToRender ********************************************************************************************/ SubtreeRenderState NodeAttribute::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip) { // If we've found an attribute node, then we always want to render it. return SUBTREE_ROOTONLY; } /******************************************************************************************** > BOOL NodeAttribute::NeedsToExport(RenderRegion* pRender, BOOL VisibleLayersOnly = FALSE, BOOL CheckSelected = FALSE) Author: Tim_Browse (Xara Group Ltd) Created: 23/03/94 Inputs: pRender - A pointer to the current export region VisibleLayersOnly - TRUE => remove nodes which are on invisible layers - FALSE => export everything CheckSelected - TRUE => we check if object selected and only export selected bjects - FALSE => we don't bother checking for selection or not Returns: TRUE => please export me. Purpose: Virtual function - this version always returns TRUE, because we always want to export attributes. SeeAlso: NodeAttribute::NeedsToRender ********************************************************************************************/ BOOL NodeAttribute::NeedsToExport(RenderRegion* pRender, BOOL VisibleLayersOnly, BOOL CheckSelected) { return TRUE; } /*********************************************************************************************** > Node* NodeAttribute::SimpleCopy() Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Inputs: - Outputs: Returns: A copy of the node, or NULL if memory runs out Purpose: This method returns a shallow copy of the node with all Node pointers NULL. The function is virtual, and must be defined for all derived classes. Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory error and the function returns NULL. Scope: protected ***********************************************************************************************/ Node* NodeAttribute::SimpleCopy() { NodeAttribute* NodeCopy = new NodeAttribute(); ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); CopyNodeContents(NodeCopy); return NodeCopy; } /******************************************************************************************** > INT32 NodeAttribute::operator==(const NodeAttribute& Attrib) Author: Simon_Maneggio (Xara Group Ltd) Created: 9/2/94 Inputs: Atrib: The attribute to compare Outputs: - Returns: - Purpose: This function is slightly weird. Unlike most definitions of operator== it's virtual. To see why it's required, consider the following NodeAttribute* A,B; A = X; B = Y; where X and Y are pointers to instances of derived classes of NodeAttribute. if X->GetRuntimeClass() == Y->GetRuntimeClass() then we should be able to compare X and Y. But if we had defined a normal operator== fn then we find we cannot do this, because there is no way of casting to a type which is unknown at compile time. The implementation of operator== in all derived classes of NodeAttribute should look something like this. INT32 DerivedClass::operator==(const NodeAttribute& Attrib) { DerivedClass* Attr = (DerivedClass*) &Attrib; // Compare member vars with Attr } Before calling this function you must be sure that the attributes have the same runtime class. The function needs to be defined in all derived classes of NodeAttribute Errors: If this function is called on an instance of a derived class of NodeAttribute, and the function has not been defined for the derived class, then an ENSURE failure will result. SeeAlso: - ********************************************************************************************/ INT32 NodeAttribute::operator==(const NodeAttribute& Attrib) { ENSURE(FALSE, "the pure virtual operator== fn has not been defined"); return (FALSE); } /******************************************************************************************** > virtual BOOL NodeAttribute::IsDifferent(Node *pOther) Author: Jason_Williams (Xara Group Ltd) Created: 28/2/97 Inputs: pOther - The node to compare this one to Returns: TRUE if this is considered different from pOther, FALSE if they are the same Purpose: Determine if 2 nodes are considered different. Notes: NodeAttribute uses its own (and derived class) operator== method to determine if the nodes are different. This will work for ANY derived attribute class. ********************************************************************************************/ BOOL NodeAttribute::IsDifferent(Node *pOther) { // First, check with the base class - this checks the classes are the same type if (NodeRenderable::IsDifferent(pOther)) return(TRUE); ERROR3IF(GetRuntimeClass() != pOther->GetRuntimeClass(), "Node::IsDifferent base class method seems to have been broken"); // Check if different using the operator== which is defined from NodeAttribute onwards if (*this == *((NodeAttribute *)pOther) ) return(FALSE); return(TRUE); } /******************************************************************************************** > virtual UINT32 NodeAttribute::GetAttrNameID(void) Author: Simon_Maneggio (Xara Group Ltd) Created: 22/2/94 Inputs: - Outputs: - Returns: Attribute description ID Purpose: Returns back a string resource ID describing the attribute, this base class function returns the resource _R(IDS_ATTRIBUTE). Errors: - SeeAlso: - ********************************************************************************************/ UINT32 NodeAttribute::GetAttrNameID(void) { return (_R(IDS_ATTRIBUTE)); } /*********************************************************************************************** > void NodeAttribute::CopyNodeContents(NodeAttribute* NodeCopy) Author: Simon_Maneggio (Xara Group Ltd) Created: 28/4/93 Inputs: Outputs: A copy of this node Returns: - Purpose: This method copies the node's contents to the node pointed to by NodeCopy. Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected ***********************************************************************************************/ void NodeAttribute::CopyNodeContents( NodeAttribute* NodeCopy) { NodeRenderable::CopyNodeContents( NodeCopy ); } #ifdef _DEBUG /*********************************************************************************************** > void NodeAttribute::ShowDebugTreeDetails() const Author: Will_Cowling (Xara Group Ltd) Created: 21/6/93 Purpose: Displays debugging info of the tree ***********************************************************************************************/ void NodeAttribute::ShowDebugTreeDetails() const { // Display a bit of debugging info // For now, we will just call the base class version Node::ShowDebugTreeDetails(); } #endif /******************************************************************************************** > DocColour *NodeAttribute::EnumerateColourFields(UINT32 Context) Author: Tim_Browse (Xara Group Ltd) Created: 19/07/94 Inputs: Context - indicates which colour field should be returned next. Returns: Pointer to the next colour field - this may well be altered by the caller. Purpose: Enumerates all the colour fields used by an attribute. This enables the colour manager to scan the tree and process any attribute it finds to carry out operations such as turning indexed colours into immediate colours, and so on. The Context parameter indicates which colour field should be returned next. It is 0 initially, then it will be 1, then 2, etc. The NodeAttribute object should use this to deduce how far it has got through its colour fields, and return the next one, or NULL if there are no more. The order in which the colours are returned is not important, as long as EVERY colour in the attribute is returned ONCE and ONLY once. Other than this stipulation, the NodeAttribute can amuse itself in whatever foul and depraved manner it deems appropriate. ********************************************************************************************/ DocColour *NodeAttribute::EnumerateColourFields(UINT32 Context) { // No colours in a standard NodeAttribute. return NULL; } /******************************************************************************************** > virtual BOOL NodeAttribute::CopyComponentData(BaseDocument* SrcDoc, BaseDocument* NodesDoc) Author: Simon_Maneggio (Xara Group Ltd) Created: 12/9/94 Inputs: SrcDoc: The document from where this node was copied NodesDoc: The document where this node lives Outputs: - Returns: FALSE if unable to copy data Purpose: If the attribute contains any DocColours which are indexed then a copy of the indexed colour is made and added to the NodesDoc ColourListComponent. Errors: - SeeAlso: NodeRenderable::CopyComponentData ********************************************************************************************/ BOOL NodeAttribute::CopyComponentData(BaseDocument* SrcDoc, BaseDocument* NodesDoc) { // Ask the base class to copy its data if (!NodeRenderable::CopyComponentData(SrcDoc, NodesDoc)) { return FALSE; // Failed } // Get the colour list component ColourListComponent *pComponent = (ColourListComponent *) NodesDoc->GetDocComponent(CC_RUNTIME_CLASS(ColourListComponent)); ENSURE (pComponent != NULL, "Could not find ColourListComponent"); // Copy across all DocColours for (INT32 i=0;;i++) { DocColour* pDocCol = EnumerateColourFields(i); if (pDocCol == NULL) { // there are no more colours to copy break; } // Copy the colour across if (pComponent->CopyColourAcross(pDocCol) == CCCOPY_FAILED) { return FALSE; // Failed to copy colour info } } return TRUE; } /******************************************************************************************** > static NodeAttribute* NodeAttribute::FindFirstAppliedAttr(Node* pContextNode, Node* pRoot = NULL) Author: Phil_Martin (Xara Group Ltd) Created: 06/01/2005 Inputs: - Outputs: - Returns: Pointer to attribute which is closest in scope to the context node. Purpose: Find the attribute which is closest in attribute scope to the context node. Use in conjunction with FindPrevAppliedAtt. Note! This routine and FindPrevAppliedAttr will return "Effect Attributes" that only apply to pContextNode, and not its children. You should test for them using IsEffectAttribute outside this function if you don't want to find them. Errors: - SeeAlso: NodeAttribute::FindPrevAppliedAtt ********************************************************************************************/ NodeAttribute* NodeAttribute::FindFirstAppliedAttr(Node* pContextNode, Node* pRoot) { ERROR2IF(pContextNode == NULL, NULL, "FindFirstAppliedAttr() called on NULL"); Node* pNode = NULL; // Begin the attribute search from the right-most child of "this" node. // (So that Effect Attributes are picked up) pNode = pContextNode->FindLastChild(); if (pNode == NULL) pNode = pContextNode; // If the very first node is an attribute, great, return that... if (pNode->IsAnAttribute() && !pNode->IsAClipViewAttr()) return ((NodeAttribute*) pNode); // Otherwise must search in reverse render order for an attribute... return FindPrevAppliedAttr(pNode, pRoot); } /******************************************************************************************** > static NodeAttribute* NodeAttribute::FindPrevAppliedAttr(Node* pContextNode, Node* pRoot = NULL) Author: Phil_Martin (Xara Group Ltd) Created: 06/01/2005 Inputs: - Outputs: - Returns: A pointer to the attribute which occurs "previous" to this node. Purpose: Finds the previous attribute in the tree, from this node, by searching backwards and up (along Previous and Parent links), or null if there is no such attribute. Note! This routine and FindFirstAppliedAttr will return "Effect Attributes" that only apply to pContextNode, and not its children. You should test for them using IsEffectAttribute outside this function if you don't want to find them. Errors: - SeeAlso: - ********************************************************************************************/ NodeAttribute* NodeAttribute::FindPrevAppliedAttr(Node* pContextNode, Node* pRoot) { ERROR2IF(pContextNode == NULL, NULL, "FindPrevAppliedAttr() called on NULL"); // We are going to start from this attribute node. // All attributes are collected together as the first nodes in a sub-tree, so we can // call FindPrevious here as the previous node will either be NULL or another attribute. Node* pNode = pContextNode; // Search for the next attribute do { // Get the previous node if (pNode->FindPrevious()) pNode = pNode->FindPrevious(); else { // Move up to sibling list above pNode = pNode->FindParent(); // -------------------------------------- // Optimisation! // There are often a small number of attributes at the start of a large sibling // list. So it's often quicker to skip to the start and then skip forward from there // (This clause can be removed without changing the basic operation of this // function.) if (pNode==pRoot) return NULL; // Quick test to see whether attr is readily available in new sibling list // (Assume that paper node tree section is quicker to scan the obvious way) Node* pTestNode = pNode->FindPrevious(); if (!(pNode->IsPaper() || (pTestNode && pTestNode->IsOrHidesAnAttribute()))) { Node* pAttr = NULL; // Init the attr pointer we're searching for pTestNode = pNode; while (pTestNode && pAttr==NULL) // Start looping up through sibling lists til we find an attr { Node* pParent = pTestNode->FindParent(); // Find first node in this sibling list pTestNode = pParent ? pParent->FindFirstChild() : NULL; while (pTestNode && pTestNode->IsOrHidesAnAttribute()) // Loop through nodes in this sib list until find a non-attr { pAttr = pTestNode; // Remember the last attr we've found pTestNode = pTestNode->FindNext(); // Test next node in this sibling list } pTestNode = pParent; // Find parent sibling list } if (pAttr) // If we found an attribute pNode = pAttr; // return it // (otherwise leave pNode unchanged and allow normal // algorithm to work out how to handle it) } // -------------------------------------- } if (pNode && pNode->IsAnAttribute() && !pNode->IsAClipViewAttr()) return ((NodeAttribute*) pNode); } while (pNode!=pRoot); return NULL; } /******************************************************************************************** > BOOL NodeAttribute::HasEquivalentDefaultValue(BOOL bAppearance = FALSE) Author: Phil_Martin (Xara Group Ltd) Created: 22/03/2005 Inputs: - Outputs: - Returns: TRUE if this node has a value equivalent to the relevant FALSE otherwise Purpose: Determine whether this attribute has the default value or not Errors: - SeeAlso: - ********************************************************************************************/ BOOL NodeAttribute::HasEquivalentDefaultValue(BOOL bAppearance) { AttributeValue* pDefaultAttrVal = NULL; // CCRuntimeClass* AttrType = GetAttributeType(); // Look for the default attr directly // (But this doesn't work for those attrs which are grouped together // and share a common default value - e.g. fills) AttrIndex attrid = GetAttributeIndex(); if (attrid!=ATTR_BAD_ID && attridIsDifferent(pDefaultAttrVal)) { // Just allow the node to be hidden return TRUE; } return FALSE; } /******************************************************************************************** > BOOL NodeAttribute::Blend(BlendAttrParam* pBlendParam) Author: Mark_Neves (Xara Group Ltd) Created: 25/10/94 Inputs: pBlendParam = ptr to a blend attr class object Outputs: - Returns: TRUE if successful, FALSE otherwise Purpose: This will blend this attribute using the data held in pBlendParam. This base version does this: If the blend ratio <= 50%, this attr is copied If the blend ratio > 50%, the other attr is copied Errors: - SeeAlso: - ********************************************************************************************/ BOOL NodeAttribute::Blend(BlendAttrParam* pBlendParam) { // Check NULL entry param ERROR3IF(pBlendParam == NULL,"pBlendParam == NULL"); if (pBlendParam == NULL) return FALSE; // Make a copy of this node, and make this the blended attribute NodeAttribute* pBlendedAttr = NULL; NodeAttribute* pAttrToCopy = NULL; if (pBlendParam->GetBlendRatio() <= 0.5) pAttrToCopy = this; else pAttrToCopy = pBlendParam->GetOtherAttr(); if (pAttrToCopy != NULL) { pBlendedAttr = (NodeAttribute*) pAttrToCopy->SimpleCopy(); pBlendParam->SetBlendedAttr(pBlendedAttr); } // Return TRUE if we were able to make a copy of this node return (pBlendedAttr != NULL); } /******************************************************************************************** > BOOL NodeAttribute::IsADefaultAttr() Author: Simon_Maneggio (Xara Group Ltd) Created: 28/9/95 Returns: TRUE if attribute is a default attribute. i.e. it's parent is a NodeDocument Purpose: Simple but useful fn to determine if the attribute (which must be in the tree) is a default attribute ********************************************************************************************/ BOOL NodeAttribute::IsADefaultAttr() { return (IS_A(FindParent(), NodeDocument)); } /******************************************************************************************** > BOOL NodeAttribute::IsEffectAttribute() const Author: Phil_Martin (Xara Group Ltd) Created: 05/01/2005 Returns: TRUE if attribute is an Effect attribute. i.e. it's not in the usual place in the tree, it's at the end of a child list with bounded nodes ahead of it. ********************************************************************************************/ BOOL NodeAttribute::IsEffectAttribute() const { // Node* pSibling = FindPrevious(CC_RUNTIME_CLASS(NodeRenderableBounded)); Node* pSibling = FindPrevious(); while (pSibling && !pSibling->IsBounded()) pSibling = pSibling->FindPrevious(); return (pSibling!=NULL); } /******************************************************************************************** > BOOL NodeAttribute::ShouldBecomeCurrent() Author: Graham_Walmsley (Xara Group Ltd) Created: 14/6/96 Returns: TRUE if this attribute should become current. FALSE if the user must deliberately apply this attribute to an object every time he wants to use it. Purpose: The attribute manager calls this function before making an attribute current. There are some attributes - like this URL Hot Link attribute I'm about to put in - that the user probably won't want to become current. For example, if a user puts a HotLink on an object and happens to have the Give Other Objects Most Recent Attributes option on, all his new objects are going to have HotLinks. That's not good. So those attributes will override this function and return FALSE. ********************************************************************************************/ BOOL NodeAttribute::ShouldBecomeCurrent() { //Yes, we'd like this attribute to be passed to other objects. return TRUE; } /******************************************************************************************** > NodeAttribute* NodeAttribute::FindNextAttr(TypeFunc pfnTest) const Author: Justin_Flude (Xara Group Ltd) Created: 27/1/95 Inputs: pfnTest --- pointer to a member-function of Node:- typedef BOOL (Node::*TypeFunc)() const; that returns TRUE for the attribute being searched for and FALSE otherwise Returns: The next attribute of the given type from this one that applies to the object Node::FindFirstAttr was called for, or null if there isn't one. Purpose: Finds the next attribute of the given type that applies to the object. SeeAlso: Node::FindFirstAttr ********************************************************************************************/ NodeAttribute* NodeAttribute::FindNextAttr(TypeFunc pfnTest) const { // Search for the class in the previous sibling nodes, then the parent's siblings, // then the parent siblings of the parent of ... etc. const Node* pNode = this; do { // Work out the next node in the search order. if (pNode->FindPrevious() != 0) { // The next node is the previous sibling. pNode = pNode->FindPrevious(); } else { // The next node is the parent, if there is one. pNode = pNode->FindParent(); if (pNode == 0) break; } } while (!(pNode->*pfnTest)()); // Return the attribute, or null if none was found. return (NodeAttribute*) pNode; } ///////////////////////////////////////////////////////////////////////////////////////////// // New extensions to the attribute system - initially created to support feathering attribute ///////////////////////////////////////////////////////////////////////////////////////////// /******************************************************************************************** > virtual BOOL NodeAttribute::IsLinkedToNodeGeometry() Author: Ilan_Copelyn (Xara Group Ltd) Created: 3/5/00 Inputs: Outputs: Returns: Purpose: This test determines whether the attribute is linked to the geometry of the objects it has been applied to. This condition is an important precursor before performing extra initialisation tests, and passing operation messages around to ensure that the attribute is up to date. ********************************************************************************************/ BOOL NodeAttribute::IsLinkedToNodeGeometry() { return FALSE; } /******************************************************************************************** > virtual BOOL NodeAttribute::IsLinkedToThisNode(Node* pNode) Author: Ilan_Copelyn (Xara Group Ltd) Created: 3/5/00 Inputs: Outputs: Returns: Purpose: This test determines whether the attribute is linked to the geometry of the supplied object ********************************************************************************************/ BOOL NodeAttribute::IsLinkedToThisNode(Node* pNode) { return FALSE; } /******************************************************************************************** > virtual BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, Path* InkPath, CCRuntimeClass* pCreatorClass) Author: Ilan_Copelyn (Xara Group Ltd) Created: 27/4/00 Inputs: pMap - the attr map which contains the dynamically generated attribute we are trying to initialise InkPath - the inkpath we are going to render in this blend/contour step - NB also have a Node* version below pCreatorClass - Allows the attribute to modify it's behaviour depending on which complex node has asked to create a dynamic attr Outputs: Returns: Purpose: Blends and contours create attribute maps which are dynamically blended when the compound is rendered. Certain attributes cannot function correctly without having links to the objects which they apply to. eg feather attributes need the path outline of the objects in order to create a silhouette image from which the feather bitmap is created In order for these attributes to do their job they require an extra initialisation step after dynamic creation. NB only required when NodeAttributes in an CCAttrMap is copied or blended (ie dynamically created) NOT required if the attribute is going to be inserted into the tree before being rendered (because then it can acquire all the information it needs, about the node it is attached to, via the NodeAttribute which contains in - NB this assertion requires the associated NodeAttribute's Render() function to feed the attribute this information before asking it to render (ie by calling NodeAttribute::Render())). Errors: May return FALSE if memory allocations fail. In this case the attribute will not be able to acheive it's affect. The caller must be careful not to ask the attribute to render (eg by removing it from the CCAttrMap before calling pMap->Render()) SeeAlso: NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, ___Node* pNode____, CCRuntimeClass* pCreatorClass) ********************************************************************************************/ BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, Path* InkPath, CCRuntimeClass* pCreatorClass) { return TRUE; } /******************************************************************************************** > virtual BOOL NodeAttribute::PostDynCreateInit( CCAttrMap* pMap, Node* pNode, CCRuntimeClass* pCreatorClass) Author: Ilan_Copelyn (Xara Group Ltd) Created: 27/4/00 Inputs: as above except:- pNode - This variety allows the caller to supply the attr with a node which it would like the attribute to apply itself to Outputs: Returns: Purpose: Errors: SeeAlso: NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, ___Path* InkPath____, CCRuntimeClass* pCreatorClass) ********************************************************************************************/ BOOL NodeAttribute::PostDynCreateInit(CCAttrMap* pMap, Node* pNode, CCRuntimeClass* pCreatorClass) { return TRUE; } /******************************************************************************************** > virtual void NodeAttribute::PostDynCreateDeInit() Author: Ilan_Copelyn (Xara Group Ltd) Created: 27/4/00 Inputs: Outputs: Returns: Purpose: Free memory allocated by PostDynCreateInit(..) functions Errors: No memory needs to be allocated so cannot fail. SeeAlso: - ********************************************************************************************/ void NodeAttribute::PostDynCreateDeInit() { } /******************************************************************************************** > virtual BOOL NodeAttribute::LinkedNodeGeometryHasChanged(UndoableOperation* pOp) Author: Ilan_Copelyn (Xara Group Ltd) Created: 27/4/00 Inputs: pOp - the operation that has caused the children nodes to change their geometry Outputs: Returns: Purpose: Attributes which are linked to the geometry of the objects which they affect, need to receive notification when these objects are changed by other operations eg if a group of objects is featherd, then the feather attribute applied at group level needs to be informed when any operations are performed on the children which will change their outline Tech Notes: NB NB NB This function gets called as part of the AllowOp process where an operation informs the rest of the tree that it is about to make a modification of some kind. Because of the structure of the AllowOp process we can only pass in a pointer to the operation which is causing the change It is important that you understand where this function is being used and also to use the Op pointer to make any changes UndoAble Order in which this function gets called is dependent on where the attribute appears in the tree ie ensure that work you do in this function is not order dependent. Also, this is called during the permission stage of the operation, ie it is merely trying to find out if it can go ahead and perform its actions, ie NO CHANGES HAVE BEEN MADE YET! This means you have to treat this function as a flag to reinit yourself at a later stage - ie delaying recalculation till the next time you are asked to render is one way to ensure all changes made by pOp have been performed. Errors: may need to allocate memory so can fail (return FALSE) SeeAlso: Node::AllowOp(..) and other AllowOp's ********************************************************************************************/ BOOL NodeAttribute::LinkedNodeGeometryHasChanged(UndoableOperation* pOp) { return TRUE; } /******************************************************************************************** > virtual void NodeAttribute::NewlyCreatedDefaultAttr(NodeDocument* pNode) Author: Ilan_Copelyn (Xara Group Ltd) Created: 27/4/00 Inputs: Outputs: Returns: Purpose: Attributes which are linked to the geometry of the objects which they affect, may not be able to perform a useful function if attached directly to the NodeDocument node (ie a default attribute). This function allows a default attribute of this type to perform an extra initialisation step so that the Render() function can handle Errors: SeeAlso: - ********************************************************************************************/ void NodeAttribute::NewlyCreatedDefaultAttr(NodeDocument* pNode) { } // geometry linked attributes should use the nodes inkpath as required BOOL NodeAttribute::LinkToGeometry(Node* pContext) { return TRUE; } /******************************************************************************************** > virtual BOOL NodeAttribute::ContainsAttributeValue(AttributeValue* pVal) Author: Ilan_Copelyn (Xara Group Ltd) Created: 7/6/00 Inputs: Outputs: Returns: Purpose: To check if this NodeAttribute contains a the AttributeValue NB needs to be implemented in a manner specific to the way in which the derived NodeAttribute class stores the AttributeValue Errors: SeeAlso: OffscreenAttrValue::DoesOffscreenBmpRequireTransp AttrFeather::ContainsAttributeValue ********************************************************************************************/ BOOL NodeAttribute::ContainsAttributeValue(AttributeValue* pVal) { return FALSE; }