Esempio n. 1
0
void NodeRenderableInk::NormaliseAttributes()
{

	NodeAttribute* ChildAttribute;	   
	NodeAttribute* GlobalAttribute;

	Node* LocalScan;
	Node* NextLocal;  
	
	// Scan the child attribute block
	LocalScan = FindFirstChild();
	// Stop if we hit an object or if there are no more children 
	// NOTE: Stopping scanning when we find the first RendereblInk node prevents
	// Effect attributes being Normalised. THIS IS DELIBERATE!
	while((LocalScan != NULL) && (!LocalScan->IsAnObject())) 
	{
		// Hand over hand (LocalScan may get deleted)
		NextLocal = LocalScan->FindNext();
		if(LocalScan->IsAnAttribute() && ((NodeAttribute*)LocalScan)->ShouldBeOptimized())	// cos it could be a NodeHidden
		{
			ChildAttribute = (NodeAttribute*)LocalScan;  
			// We now need to search up the tree to see if ChildAttribute is redundant
//		   	Node* GlobalScan = FindPreviousEffectiveNode();
			Node* GlobalScan = NodeAttribute::FindPrevAppliedAttr(this);
			// Search until we can go no higher
			while (GlobalScan != NULL)
			{
				if (GlobalScan->IsAnAttribute())
				{
					GlobalAttribute = (NodeAttribute*)GlobalScan; 
					// An attribute has been found, is it the same class as ChildAttribute ?
					if(GlobalAttribute->GetRuntimeClass() ==
					   ChildAttribute->GetRuntimeClass())
					{
						// Yes it is, so let's check if they are equal
						if ((*GlobalAttribute)==(*ChildAttribute))
						{
							// They are equal so we can nuke the child object because it's 
							// redundant
							ChildAttribute->CascadeDelete();
							delete ChildAttribute;
						}
						break;	 // don't search any further
					}

				}
//				GlobalScan = GlobalScan->FindPreviousEffectiveNode(); // climb higher
				GlobalScan = NodeAttribute::FindPrevAppliedAttr(GlobalScan);
			} 
		}
		LocalScan = NextLocal; // Get the next child 
	}    

}
Esempio n. 2
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; 
}
Esempio n. 3
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
}
Esempio n. 4
0
BOOL OpChangeLineAttribOpDesc::SetCurrentSelectedAttrib()
{
	// Nothing to do if no current document.
	if (Document::GetCurrent() == NULL)
	{
/*		TRACEUSER( "JustinF", _T("No current document in OpChangeLineAttribOpDesc")
							 "::SetCurrentSelectedAttrib\n");
*/		
		// There is no document so blank all gadgets.
		SetGadgetText(String(_T("")));
		return TRUE;
	}

	// Determine if there is a common attribute.
	NodeAttribute* pAttr;
	SelRange::CommonAttribResult eResult;
	eResult = GetApplication()->
				 FindSelection()->
					 FindCommonAttribute(GetAttribRuntimeClass(), &pAttr);

	// Work out what to put in the combo-box according to the returned result.
	UINT32 nTxtID;
	switch (eResult)
	{
		case SelRange::ATTR_COMMON:
		case SelRange::ATTR_NONE:
		{
			// If there isn't an attribute we just return (this logic is copied from the
			// line-width combo OpDescriptor code).
			if (pAttr == NULL)
			{
/*				TRACEUSER( "JustinF", _T("No attribute in OpChangeLineAttribOpDesc")
									 "::SetCurrentSelectedAttrib\n");
*/				return TRUE;
			}

			// Check for something screwy.
			ERROR3IF(pAttr->GetRuntimeClass() != GetAttribRuntimeClass(),
					 "Wrong kind of attribute in OpChangeLineAttribOpDesc"
					 "::SetCurrentSelectedAttrib");

			// There is, so call the derived class to provide some text.
			nTxtID = ConvertAttribToStringID(pAttr);
			if (nTxtID == 0)
			{
				ERROR3("Unexpected attribute type in OpChangeLineAttribOpDesc"
					   "::SetCurrentSelectedAttrib!");
				return FALSE;
			}
			break; 
		}

		case SelRange::ATTR_MANY:
			nTxtID = _R(IDS_MANY);
			break;

		default:
			ERROR3("Unexpected case in OpChangeLineAttribOpDesc::SetCurrentSelectedAttrib!");
			return FALSE;
	}

	// Set the gadget's text.
	SetGadgetText(String(nTxtID));
	return TRUE;
}
Esempio n. 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;	
}