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); } } }
BOOL NodeRenderableInk::FactorOutCommonChildAttrHelper(BOOL Global, AttrTypeSet* pAffectedAttrTypes) { // This function should only ever get called on a compound object ENSURE(IsCompound(), "FactorOutCommonChildAttributes called on a non compound object"); CommonAttrSet CommonAttributeSet; // A list of CommonAttributeItems if (!FindCommonAttributesToFactorOut(&CommonAttributeSet)) // Ignores attr discard nodes { return FALSE; } NodeAttribute* pFactoredOutAttr; // Ok let's add the common attributes to the first child of the group CommonAttributeItem* pCommonAttr; for (pCommonAttr = (CommonAttributeItem*)CommonAttributeSet.GetHead(); pCommonAttr != NULL; pCommonAttr = (CommonAttributeItem*)CommonAttributeSet.GetNext(pCommonAttr)) { // Is the common attribute an attribute which should be factored out ? if (!pAffectedAttrTypes || (pAffectedAttrTypes->InSet(pCommonAttr->pAttr->GetAttributeType())) ) { //pCommonAttr->pAttr->MoveNode(this, FIRSTCHILD); // Take a copy of the node and insert it as a first child pFactoredOutAttr = (NodeAttribute*)(pCommonAttr->pAttr->SimpleCopy()); if (!pFactoredOutAttr) return FALSE; pFactoredOutAttr->AttachNode(this, FIRSTCHILD, TRUE, FALSE); } } // The CommonAttributeSet is no longer required CommonAttributeSet.DeleteAll(); // Do we need to factor out the parents attributes ? if (Global) { Node* pParent = FindParent(); if (pParent && (pParent->IsCompound())) { // We need to localise the parent's attributes first (Recursive bit) if (!(((NodeRenderableInk*)pParent)->FactorOutCommonChildAttrHelper(TRUE, pAffectedAttrTypes))) { return FALSE; // Failed } } } return TRUE; // Success }
BOOL BitmapExportDocument::Init(KernelBitmap* pBitmap, const DocRect& RectToExport) { // Don't attach any CCamDoc. if (!Document::Init(0)) return(FALSE); Node *pSpread = FindFirstSpread(); ERROR3IF(pSpread == NULL, "No Spread in document!"); Node *pLayer = pSpread->FindFirstChild(); ERROR3IF(pLayer == NULL, "No Spread-child in document!"); // Store away the rectangle ExportRect = RectToExport; // Now scan the children of the first spread until we find a layer, or run out of nodes while (pLayer != NULL && !pLayer->IsLayer()) pLayer = pLayer->FindNext(); if (pLayer == NULL) // No Layer, so we'd better add one for ourselves { String_256 LayerID = String_256(_R(IDS_K_CLIPINT_LAYERNAME)); pLayer = new Layer(pSpread, LASTCHILD, LayerID); if (pLayer == NULL) return(InitFailed()); } // Create a new NodeRect NodeRect* pRectNode = new NodeRect(pLayer, FIRSTCHILD); // Failed so cleanup and exit if (pRectNode == NULL) return(InitFailed()); // Initilaise the node if (!pRectNode->SetUpPath(6,6)) return(InitFailed()); // Create the rectangle pRectNode->CreateShape(ExportRect); // Give the rectangle a line colour #if 0 // This memory leaks a StrokeColourAttribute StrokeColourAttribute* pAttrValue = new StrokeColourAttribute(DocColour(COLOUR_TRANS)); if (pAttrValue == NULL) return(InitFailed()); NodeAttribute* pAttr = pAttrValue->MakeNode(); if (pAttr == NULL) return(InitFailed()); // Attach the attribute to the rectangle pAttr->AttachNode(pRectNode, FIRSTCHILD); #else // Do what ApplyDefaultBitmapAttrs does Node* pLineColAttr = new AttrStrokeColour(); if (pLineColAttr == NULL) return(InitFailed()); DocColour none(COLOUR_NONE); ((AttrFillGeometry*)pLineColAttr)->SetStartColour(&none); pLineColAttr->AttachNode(pRectNode, FIRSTCHILD); #endif // Create a NodeBitmap (don't attach it to the tree straight away 'cos we // have to put the attributes on it first) pBitmapNode = new NodeBitmap(); if (pBitmapNode == NULL) return(InitFailed()); if (!pBitmapNode->SetUpPath(6,6)) return(InitFailed()); pBitmapNode->CreateShape(ExportRect); if (!SetBitmap(pBitmap)) return(InitFailed()); // Set the bitmap's attributes // This must be done before the NodeBitmap is inserted into the tree if (!pBitmapNode->ApplyDefaultBitmapAttrs(NULL)) return(InitFailed()); // Attach it to the tree as the next sibling of the rectangle pBitmapNode->AttachNode(pRectNode, NEXT); // Success... return(TRUE); }
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; }