Beispiel #1
0
CCAttrMap* CCAttrMap::Copy()
{
	CCAttrMap		   *pNewAttrMap = new CCAttrMap( GetCount() );
	if( pNewAttrMap != NULL )
	{
		// iterating all (key, value) pairs
		for( iterator Pos = GetStartPosition(); Pos != GetEndPosition(); )
		{
			CCRuntimeClass *pType;
			void	   *pVal;
			GetNextAssoc( Pos, pType, pVal );

			// Get the attribute value of this attribute
			NodeAttribute* pAttr = (NodeAttribute*)pVal;

			// Copy the attribute
			NodeAttribute* pNewAttr = (NodeAttribute*) (pAttr->SimpleCopy());

			// Stick the new attr into the new attr map
			if (pNewAttr != NULL)
				pNewAttrMap->SetAt(pNewAttr->GetAttributeType(),pNewAttr);
		}
	}

	pNewAttrMap->attrMapCreator = attrMapCreator;

	return pNewAttrMap;
}
Beispiel #2
0
/********************************************************************************************

>	static CCAttrMap * CCAttrMap::MakeAttrMapFromRenderRegion(RenderRegion * pRegion)

	Author:		David_McClarnon (Xara Group Ltd) <*****@*****.**>
	Created:	24/2/2000
	Inputs:		The render region to get the attribute map from
	Outputs:	An attribute map (copied) from the render region
	Returns:	-
	Purpose:	Makes an attribute out of the render region's current attribute state
	Notes:		You MUST call DeleteAttributes afterwards to release memory - delete is
				not sufficient
	SeeAlso:	-

********************************************************************************************/
CCAttrMap * CCAttrMap::MakeAttrMapFromRenderRegion(RenderRegion * pRegion)
{
	CCAttrMap * pMap = new CCAttrMap;
	ENSURE(pMap,"No mem for attrmap");
	if(!pMap)
		return NULL;

	// let's get every attribute in the render region
	AttributeValue * pAttrVal = NULL;
	NodeAttribute * pNewAttr = NULL;

	for (UINT32 i = 0; i < ATTR_FIRST_FREE_ID; i++)
	{
		pAttrVal = pRegion->GetCurrentAttribute(i);

		// make a new node out of this attribute value
		pNewAttr = pAttrVal->MakeNode();
		
		// Karim 12/04/2000
		// AttributeValues _do_not_have_to_have_ a corresponding NodeAttribute,
		// so can we please *check* that MakeNode didn't just return NULL!
		if (pNewAttr != NULL)
		{
			if(!pNewAttr->IsLinkedToNodeGeometry())
				pMap->SetAt(pNewAttr->GetAttributeType(),pNewAttr);
			else
			{
				delete pNewAttr;
				pNewAttr = AttributeManager::GetDefaultAttribute((AttrIndex) i);
				if(pNewAttr)
				{
					ENSURE(pNewAttr->IsLinkedToNodeGeometry(),"Incorrect NodeAttribute returned by GetDefaultAttribute");
					pMap->SetAt(pNewAttr->GetAttributeType(), pNewAttr);
				}
				else
					return NULL;
			}
		}
	}

	pMap->attrMapCreator = NULL;

	return pMap;
}
Beispiel #3
0
void NodeRenderableInk::DeleteFactoredOutAttribs(BOOL Global, AttrTypeSet* pAffectedAttrTypes)
{
	Node* pGroupNode = FindFirstChild(); 
	while(pGroupNode!=NULL)
	{
		// Karim 30/08/2000
		// Non-optimisable attributes, like feathers and names,
		// must not be automatically deleted - only automatically delete optimisable ones.
		if (pGroupNode->IsAnAttribute() && ((NodeAttribute*)pGroupNode)->ShouldBeOptimized())
		{
			NodeAttribute* pGroupAttr = (NodeAttribute*)pGroupNode;
			CCRuntimeClass* GrouptAttrType = pGroupAttr->GetAttributeType();
			if (pAffectedAttrTypes==NULL || pAffectedAttrTypes->InSet(GrouptAttrType))
			{
				// delete this group attr type from all child objects of this group
				// BUT if obj discards child attrs only delete attr if it also has same value
				for (Node* pNode=FindFirstChild(); pNode!=NULL; pNode=pNode->FindNext())
				{
					if (pNode->IsAnObject())
					{
						NodeRenderableInk* pObject = (NodeRenderableInk*)pNode;
						NodeAttribute* pDeadAttr = pObject->GetChildAttrOfType(GrouptAttrType);
						if (pDeadAttr!=NULL)
						{
							// This code used to only test the attribute for equality if pObject
							// returned TRUE from DiscardsAttributeChildren, otherwise it would 
							// just assume that they are identical and delete it.
							// The DiscardAttributeChildren checks are now done elsewhere so 
							// this code now just assumes it can delete any attributes that have 
							// got this far.
							// This optimisation relies on the tree being in a "legal" state 
							// at the start (i.e. correctly optimised) and also helps to correct 
							// problems where attributes may have been incorrectly left on children
							// (though such "corrections" may change the appearance of the document).

							pDeadAttr->CascadeDelete(); 
							delete pDeadAttr;	
						}
					}
				}
			}
		}
		pGroupNode = pGroupNode->FindNext(); 		
	}

	// Do we need to delete any parent compound's attributes
	if (Global)
	{
		Node* pParent = FindParent(); 
		if (pParent && (pParent->IsCompound()))
		{
			// We need to delete the parent's attributes first  (Recursive bit)
			((NodeRenderableInk*)pParent)->DeleteFactoredOutAttribs(Global, pAffectedAttrTypes); 
		}
	}
} 
Beispiel #4
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; 
}
Beispiel #5
0
/********************************************************************************************

>	BOOL BlendHelpers::BlendAttributes(BlendNodeParam * pParam, CCAttrMap* pBlendedAttrMap)

	Author:		David_McClarnon (Xara Group Ltd) <*****@*****.**> based on blender code
	Created:	21/2/2000
	Inputs:		pParam	-	the blend node param
	Outputs:	-
	Returns:	TRUE if successful, FALSE otherwise
	Purpose:	Blends the attributes of the two BlendPath objects by the amount specified in BlendRatio
	SeeAlso:	-

********************************************************************************************/
BOOL BlendHelpers::BlendAttributes(BlendNodeParam * pParam, CCAttrMap* pBlendedAttrMap)
{
	// Check entry params
	double BlendRatio = pParam->GetAttrBlendRatio();

	BOOL ok = (pParam != NULL && pBlendedAttrMap != NULL);
	ERROR3IF(!ok,"One or more NULL entry params");
	if (!ok) return FALSE;

	// Find the attributes that are applied to the blend paths

	BlendPath * pBlendPathStart = pParam->GetStartBlendPath();
	BlendPath * pBlendPathEnd   = pParam->GetEndBlendPath();
	ok = (pBlendPathStart != NULL && pBlendPathEnd != NULL);
	ERROR3IF(!ok, "Blend paths are NULL");
	if (!ok) return FALSE;

	ok = (pBlendPathStart->GetCreatedByNode() != NULL && 
		pBlendPathEnd->GetCreatedByNode() != NULL);
	ERROR3IF(!ok, "Blend path created by nodes are NULL");
	if (!ok) return FALSE;

	BOOL startExludeGLAs = TRUE, endExcludeGLAs = TRUE;

	NodeAttribute			* pAttr				= NULL;
	if(pBlendPathStart->GetCreatedByNode()->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrFeather),&pAttr))
	{
		startExludeGLAs = FALSE;
	}
	if(pBlendPathEnd->GetCreatedByNode()->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrFeather),&pAttr))
	{
		endExcludeGLAs = FALSE;
	}

	CCAttrMap* pAttrMapStart = CCAttrMap::MakeAppliedAttrMap(pBlendPathStart->GetCreatedByNode(), startExludeGLAs);
	CCAttrMap* pAttrMapEnd   = CCAttrMap::MakeAppliedAttrMap(pBlendPathEnd->GetCreatedByNode(), endExcludeGLAs);

	if (!pAttrMapStart || !pAttrMapEnd)
		return FALSE;

	// find the attributes on the nodes
	
	if (pParam->GetNodeBlendPath() != NULL)
	{
		Trans2DMatrix* pRotateStart = GetRotateMatrix(pParam->GetNodeStart(),
			360.0 - pParam->GetAngleStart());
		Trans2DMatrix* pRotateEnd   = GetRotateMatrix(pParam->GetNodeEnd(),
			360.0 - pParam->GetAngleEnd());
		if (pRotateStart)	pAttrMapStart->Transform(*pRotateStart);
		if (pRotateEnd)		pAttrMapEnd  ->Transform(*pRotateEnd);

		if (pRotateStart)
			delete pRotateStart;

		if (pRotateEnd)
			delete pRotateEnd;
	}

	// These vars are used as params to the CCAttrMap funcs
	CCRuntimeClass	   *pTypeStart; 
	void			   *pValStart;
	void			   *pValEnd;
	double				OldBlendRatio = pParam->GetBlendRatio();
	// Process each attribute in turn
	CCAttrMap::iterator	PosStart = pAttrMapStart->GetStartPosition();
	CCAttrMap::iterator	EndStart = pAttrMapStart->GetEndPosition();
	for (;PosStart != EndStart;)
	{
		// Get a ptr to the attr at position PosStart in the start node's attr map
		pAttrMapStart->GetNextAssoc(PosStart,pTypeStart,pValStart);
		NodeAttribute* pNodeAttrStart = (NodeAttribute *)pValStart;
	
		BlendRatio = OldBlendRatio;	
		// Diccon 10/99 When using non-linear profiles for the objects those attributes
		// that make use of control points were not being profiled, making the objects look strange.
		// to avoid this those attributes now share the same profiles as the objects.
		if (pNodeAttrStart->IsAGradFill())
		{
		
			if (!((AttrFillGeometry*)pNodeAttrStart)->IsAColourFill())
			{
				
				BlendRatio = pParam->GetObjectRatio();
			
			}
			else
			{
				BlendRatio = pParam->GetInvertedAttributeRatio();
			
			}

		}
		if (pNodeAttrStart->IsAFlatFill() || (pNodeAttrStart->GetRuntimeClass() == CC_RUNTIME_CLASS(AttrLineWidth)))
		{
			BlendRatio = pParam->GetInvertedAttributeRatio();
		}
			
		// Get a blended attribute
		NodeAttribute* pBlendedNodeAttr = NULL;

		// Find an attr of the same type in the end object's attr list,
		// and blend the two attrs together
		pValEnd = NULL;

		if (pAttrMapEnd->Lookup(pTypeStart,pValEnd))
		{
			// We've found a matching end attr, so try to blend it with the start attr

			// Set up the param object to pass to the start attr's blend method
			BlendAttrParam BlendParam;

			NodeAttribute * pEndAttr = (NodeAttribute *)pValEnd;

			// Initialise the BlendParam with the end attr and blend ratio
			if (BlendParam.Init(pParam->GetRenderRegion(),
								pEndAttr,BlendRatio,
								pParam->GetColourBlendType(),
								pAttrMapStart, pAttrMapEnd))
			{
				// Successfully initialised, so now try blending the attributes
				if (pNodeAttrStart->Blend(&BlendParam))
				{
					// Attrs successfully blended, now get a ptr to the new attr.
					// Once we get the blended attr ptr, it belongs to us, so we have
					// to delete it when it is not needed
					pBlendedNodeAttr = BlendParam.GetBlendedAttr();
				}
			}
		}

		// If we have a blended attr, pBlendedNodeAttr != NULL
		if (pBlendedNodeAttr != NULL)
		{
			// Get the type of the blended attr
			CCRuntimeClass *pTypeBlend = pBlendedNodeAttr->GetAttributeType();
			void* pValBlend;

			// If we already have an attr in the blended attr map of the same type,
			// remove it and delete it, before inserting a new attr of this type
			if (pBlendedAttrMap->Lookup(pTypeBlend,pValBlend))
			{
				if (pValBlend != NULL)
				{
					pBlendedAttrMap->RemoveKey(pTypeBlend);
					delete (NodeAttribute*)pValBlend;
				}
			}
			// add it to the blend map
			pBlendedAttrMap->SetAt(pTypeBlend,pBlendedNodeAttr);
		}
	}

	if (pParam->GetNodeBlendPath() != NULL)
	{
		Trans2DMatrix* pRotateStart = GetRotateMatrix(pParam->GetNodeStart(),
			pParam->GetAngleStart());
		Trans2DMatrix* pRotateEnd   = GetRotateMatrix(pParam->GetNodeEnd(),
			pParam->GetAngleEnd()  );
		if (pRotateStart)	pAttrMapStart->Transform(*pRotateStart);
		if (pRotateEnd)		pAttrMapEnd	 ->Transform(*pRotateEnd);

		if (pRotateStart)
			delete pRotateStart;
		
		if (pRotateEnd)
			delete pRotateEnd;
	}

	delete pAttrMapStart;
	delete pAttrMapEnd;

	return TRUE;	
}