Пример #1
0
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; 
}
Пример #2
0
BOOL NodeRenderableInk::FindCommonAttributesToFactorOut(CommonAttrSet* CommonAttributeSet)
{
	CommonAttributeItem* CommonAttrItem;
	CommonAttributeItem* NextCommonAttrItem;

	// Place all attributes in the CommonAttributeSet
	if (!CommonAttributeSet->AddAllTypesToSet())
	{
		return FALSE; // ERROR already called 
	}

	// Scan all grouped objects
	for (Node* CurrentObject = FindFirstChild();  
		 CurrentObject != NULL;
		 CurrentObject = CurrentObject->FindNext())
	{
		if (CurrentObject->IsAnObject())
		{
			
			// Scan all attributes in the CommonAttributeSet in turn
			CommonAttrItem = (CommonAttributeItem*)CommonAttributeSet->GetHead();

			while(CommonAttrItem != NULL)
			{
				// Hand over hand cos we may well delete the CommonAttrItem
				NextCommonAttrItem = (CommonAttributeItem*)(CommonAttributeSet->GetNext(CommonAttrItem));

				// Does CurrentObject require the attribute	to render
				if ( (((NodeRenderableInk*)CurrentObject)->RequiresAttrib(CommonAttrItem->AttrType)) || CurrentObject->IsCompound())
				{
					BOOL DeleteCommonAttr = FALSE; // Until we know better
            
					// Ok the current object requires the attribute
					// Does the CurrentObject have a child attribute of this type ?
					NodeAttribute* pAttrNode = 
						((NodeRenderableInk*)CurrentObject)->GetChildAttrOfType(CommonAttrItem->AttrType);
					if (pAttrNode != NULL && pAttrNode->ShouldBeOptimized())
					{
						// Ok it has an attribute of this type
						if (CommonAttrItem->pAttr == NULL)
						{
							// The attribute becomes a common attribute
							CommonAttrItem->pAttr = pAttrNode;
							CommonAttrItem->Status = Range::ATTR_COMMON; 
						}
						else if(CommonAttrItem->pAttr->GetRuntimeClass() ==
							    pAttrNode->GetRuntimeClass())
						{
							// Ok they are the same runtime class but are they equal
							if (!((*pAttrNode)==(*(CommonAttrItem->pAttr))))
							{
								// They are not equal so remove CommonAttrItem from the
								// common attribute set.
								DeleteCommonAttr = TRUE; 
							}
							// DY 12/5/2000 AttrBrushTypes cannot be factored because they 
							// may contain caches of pressure or timestamp data which apply
							// to a specific node only.
							// They no longer contain this data so factor them like normal!
							//if (pAttrNode->IsKindOf(CC_RUNTIME_CLASS(AttrBrushType)))
							//	DeleteCommonAttr = TRUE;
						}
						else 
						{
							// They cannot be the same value cos they are different runtime types
							DeleteCommonAttr = TRUE; 
						}
					}
					else 
					{
						// The CurrentObject does not have an attribute of this type so it
						// cannot be common
						DeleteCommonAttr = TRUE; 
					}

					if (DeleteCommonAttr)
					{
						delete(CommonAttributeSet->RemoveItem(CommonAttrItem)); 
					}
				}

				CommonAttrItem = NextCommonAttrItem;
			}
		}
		// Removed because there are circumstances where certain attributes have 
		// already been factored out eg. Corel filter
		//else 
		//{
		//	ENSURE(CurrentObject->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeHidden), 
		//				"It's not an object, it's not a hidden node, so what is it ??");
		//}
	} 	
	// Delete all NULL items in the CommonAttributeSet
	CommonAttrItem = (CommonAttributeItem*)CommonAttributeSet->GetHead();
	while (CommonAttrItem != NULL)
	{
		CommonAttributeItem* Next = (CommonAttributeItem*)CommonAttributeSet->GetNext(CommonAttrItem);
		if (CommonAttrItem->pAttr == NULL)
		{
			// Item is a non required attribute so zap it
			delete (CommonAttributeSet->RemoveItem(CommonAttrItem)); 
		}
		CommonAttrItem = Next; 
	}
	
	return TRUE; // Job done
}