void CCAttrMap::ApplyAttributesToNode(NodeRenderableInk * pInk) { iterator pos = GetStartPosition(); while( pos != GetEndPosition() ) { CCRuntimeClass *pKey; void *pVal; GetNextAssoc(pos, pKey, pVal); NodeAttribute * pAttr = (NodeAttribute *)pVal; // copy the attribute if( pAttr->CanBeAppliedToObject() ) { NodeAttribute * pAttrCopy = NULL; pAttr->NodeCopy((Node **)(&pAttrCopy)); pAttrCopy->AttachNode(pInk, LASTCHILD); // nb now that GLAs have an independent flag to indicate when // they are copied from the default, it is safe to fix linkages // this ensures that GLA defaults get copied when BlendRefs are // made from complex nodes, and that they are found when MakeAppliedAttributes // calls FindAppliedAttributes on the unattached subtree // TODO?? // What about just copying compound node's Parent pointers to // pseudo attach the tree, rather than copying applied attrs to unattached tree // Just need to watch when deleting that it doesn't do anything to the // parents pointers - which it shouldn't surely? pAttrCopy->LinkToGeometry(pInk); } } }
/******************************************************************************************** > void CCAttrMap::Render(RenderRegion * pRegion, BOOL RenderOffscreenAttributes = TRUE) Author: David_McClarnon (Xara Group Ltd) <*****@*****.**> Created: 30/4/99 Inputs: pRegion render-region to render into. RenderOffscreenAttributes whether or not to render offscreen attributes, eg feathers. Outputs: - Returns: - Purpose: Renders the attribute map into the given render region Notes: Karim 15/11/2000 Modified so that I can render an attribute map *without* rendering any offscreen attributes contained therein. SeeAlso: - ********************************************************************************************/ void CCAttrMap::Render(RenderRegion * pRegion, BOOL RenderOffscreenAttributes) { // OK, we have found the full quota of attributes. Now render them all. iterator pos = GetStartPosition(); while( pos != GetEndPosition() ) { CCRuntimeClass *pKey; void *pVal; GetNextAssoc( pos, pKey, pVal ); NodeAttribute* pAttr = (NodeAttribute*)pVal; if ( pAttr->CanBeAppliedToObject() && pAttr->RenderSubtree(pRegion)==SUBTREE_ROOTONLY ) { // render all attributes, unless we've been specifically asked // not to render offscreen attributes. if (RenderOffscreenAttributes || !pAttr->IsAnOffscreenAttribute()) pAttr->Render(pRegion); } } }
BOOL NodeRenderableInk::MakeAttributeComplete(Node* Root, BOOL CheckForDuplicates, /* = TRUE */ AttrTypeSet* pAffectedAttrTypes, /* = NULL */ BOOL IncludeDefaults, /* = FALSE */ BOOL bIncludeEffectAttrs /* = FALSE */) { Node* Current = NULL; // Pointer to the current node in the tree NodeAttribute* CurAttr; CCRuntimeClass* AttrType; BOOL Exists; Node* PreFirstChild = FindFirstChild(); // Remember the FirstChild of the node before we add // any new attributes, this will come in handy if we // need to abort. // Loop until all attributes are copied, we are not interested in the defaults cos these are the // same for all docs !. if (bIncludeEffectAttrs) Current = NodeAttribute::FindFirstAppliedAttr(this, Root); else Current = NodeAttribute::FindPrevAppliedAttr(this, Root); while (Current && (IncludeDefaults || (!(IS_A(Current->FindParent(), NodeDocument)))) ) { // Find the next node, snaking up the tree if (Current->IsAnAttribute()) { CurAttr = (NodeAttribute*)Current; if (CurAttr->CanBeAppliedToObject() && CurAttr->ShouldBeOptimized()) { AttrType = CurAttr->GetAttributeType(); BOOL Required = RequiresAttrib(AttrType) || this->IsCompound(); // Is the attribute required ? if (Required && (!pAffectedAttrTypes || pAffectedAttrTypes->InSet(AttrType))) { Exists = FALSE; if (CheckForDuplicates) { // triggers can have duplicates if(!CurAttr->CanBeMultiplyApplied()) { // Does the node already have this child attribute Exists = (GetChildAttrOfType(AttrType) != NULL); } } #ifdef _DEBUG if (!CheckForDuplicates) { // If we feel there is no need to check for duplicates then there shouldn't be any ! if (!CurAttr->CanBeMultiplyApplied()) { NodeAttribute* pChildAttr = GetChildAttrOfType(AttrType); if ((pChildAttr != NULL)) { #if DEBUG_TREE DebugTreeDlg::DumpSubTree(this, 4); #endif TRACE(_T("Duplicate Attr found at %x %s\n"), pChildAttr, pChildAttr->GetRuntimeClass()->m_lpszClassName); } // ERROR3IF((pChildAttr != NULL), "MakeAttributeComplete: Duplicate attr found !"); } } #endif if (!Exists) { // Make a copy of the attribute NodeAttribute* NewAttr = (NodeAttribute*)CurAttr->SimpleCopy(); if (NewAttr == NULL) { goto OutOfMemory; } // Now add the attribute to this node NewAttr->AttachNode(this, FIRSTCHILD, TRUE, FALSE); } } } } Current = NodeAttribute::FindPrevAppliedAttr(Current, Root); // in order to copy brush ink nodes we need to break if the parent is NULL, else is violates if (Current!=NULL && Current->FindParent() == NULL) break; } return TRUE; OutOfMemory: // Delete any new attributes added to the node Current = FindFirstChild(); Node* Next; while (Current != PreFirstChild) { ENSURE(Current != NULL, "PreFirstChild could not be found"); ENSURE(Current->IsAnAttribute(), "Should be a NodeAttribute"); Next = Current->FindNext(); // Delete the attribute Current->CascadeDelete(); delete Current; Current = Next; } return FALSE; }