ConvertPathToShapesBecomeA Class Reference

The become A structure for the above operation Adds a node into the tree which is the stroked path of the particular node passed into the PassBack function Notes: When stepping through, you MUST store the next node before calling DoBecomeA - since the tree will be changed when PassBack is called in this class. More...

#include <opcntr.h>

Inheritance diagram for ConvertPathToShapesBecomeA:

BecomeA List of all members.

Public Member Functions

 ConvertPathToShapesBecomeA (BecomeAReason Reason, CCRuntimeClass *pClass, UndoableOperation *pOp, BOOL Sel)
 Constructor (initialises the path).
virtual BOOL PassBack (NodeRenderableInk *pNewNode, NodeRenderableInk *pCreatedByNode, CCAttrMap *pAttrMap=NULL)
void GetSummedPath (Path *pPath)
NodeRenderableInkGetContextNode ()
 Having potentially converted brushes or strokes to shapes we need to retrieve them. This can take a couple of forms, depending on what was converted: 1 brush will return one group containing nodepaths of the brush objects >1 brush will return a group, with group children containing the brushes 1 or more brushes + 1 or more strokes will return a group Strokes ONLY - will return a nodepath, which will contain any other strokes as its siblings.

Private Attributes

Path m_SummedPath
NodeGroupm_pContextNode

Detailed Description

The become A structure for the above operation Adds a node into the tree which is the stroked path of the particular node passed into the PassBack function Notes: When stepping through, you MUST store the next node before calling DoBecomeA - since the tree will be changed when PassBack is called in this class.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com> Mc
Date:
10/2/2000

Definition at line 833 of file opcntr.h.


Constructor & Destructor Documentation

ConvertPathToShapesBecomeA::ConvertPathToShapesBecomeA BecomeAReason  Reason,
CCRuntimeClass pClass,
UndoableOperation pOp,
BOOL  Sel
 

Constructor (initialises the path).

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/2/2000
Parameters:
See base class [INPUTS]

Definition at line 4644 of file opcntr.cpp.

04647                               : BecomeA(Reason, pClass, pOp, Sel)
04648 {
04649     m_SummedPath.Initialise();
04650     m_pContextNode = NULL;
04651     
04652 }


Member Function Documentation

NodeRenderableInk * ConvertPathToShapesBecomeA::GetContextNode  ) 
 

Having potentially converted brushes or strokes to shapes we need to retrieve them. This can take a couple of forms, depending on what was converted: 1 brush will return one group containing nodepaths of the brush objects >1 brush will return a group, with group children containing the brushes 1 or more brushes + 1 or more strokes will return a group Strokes ONLY - will return a nodepath, which will contain any other strokes as its siblings.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Parameters:
- [INPUTS]
The context node that was generated to hold brushes or strokes converted to [OUTPUTS] shapes, or NULL if there isn't one
Date:
10/2/2000

Definition at line 4903 of file opcntr.cpp.

04904 {
04905     if (m_pContextNode == NULL)
04906         return NULL;
04907 
04908     NodeRenderableInk* pRetNode = m_pContextNode;
04909 
04910     // if the context node has no children then we have no brushes, only strokes, so return the first sibling
04911     if (pRetNode->FindFirstChild() == NULL)
04912     {
04913         // we will have inserted any strokes as siblings to the context node
04914         pRetNode = static_cast<NodeRenderableInk*>(pRetNode->FindNext());
04915         if (pRetNode == NULL)
04916         {
04917             ERROR3("Urk, we don't seem to have anything to return in ConvertPathToShapesBecomeA::GetContextNode");
04918         }
04919         // unhook the context node and delete it
04920         m_pContextNode->CascadeDelete();
04921         delete m_pContextNode;
04922     }
04923     m_pContextNode = NULL;
04924     return pRetNode;
04925 }

void ConvertPathToShapesBecomeA::GetSummedPath Path pPath  )  [inline]
 

Definition at line 843 of file opcntr.h.

00843 { pPath->CloneFrom(m_SummedPath); }

BOOL ConvertPathToShapesBecomeA::PassBack NodeRenderableInk pNewNode,
NodeRenderableInk pCreatedByNode,
CCAttrMap pAttrMap = NULL
[virtual]
 

DY 28/11/2000 This has been changed to deal with what gets passed back by brush and stroke attributes. So basically there are three cases:

1) No brush or stroke attributes applied: Easy, we just add the paths to the summed path that we are storing. 2) Stroke attribute applied: We ask the stroke for its stroked path and store it as a sibling to our context node. 3) Brush applied: Somewhat more complex - the BrushBecomeAGroup does pretty much what its name suggests, and we store the returned group under the context node. Recall that if both a brush and a stroke are applied then the stroke acts as a pressure provider to the brush.

Reimplemented from BecomeA.

Definition at line 4679 of file opcntr.cpp.

04682 {
04683     // continuity checks
04684     if (!pNewNode || !pCreatedByNode)
04685     {
04686         ERROR3("The new node or the created by node is NULL");
04687         return FALSE;
04688     }
04689 
04690     if (!pNewNode->IsNodePath())
04691     {
04692         ERROR3("New node isn't a node path");
04693         return FALSE;
04694     }
04695 
04696 //  if (!GetUndoOp())
04697 //  {
04698 //      ERROR3("No operation defined");
04699 //      return FALSE;
04700 //  }
04701 
04702     // first, if we've not been given an attribute map, then create one
04703     if (!pAttrMap)
04704     {
04705         CCAttrMap * pXMap = CCAttrMap::MakeAppliedAttrMap(pCreatedByNode);
04706         
04707         pAttrMap = pXMap->Copy();
04708 
04709         delete pXMap;
04710 
04711         // exit if we don't have an attribute map
04712         if (!pAttrMap)
04713         {
04714             pNewNode->DeleteChildren(pNewNode->FindFirstChild());
04715             delete pNewNode;
04716             ERROR3("Couldn't create attribute map");
04717             return FALSE;
04718         }
04719     }
04720     NodePath * pPathNode = NULL;
04721     // Pre release bodge - DY 15/11 Brush attributes should really be catered for in MakeNodePathFromAttributes
04722     // but that has too many potential knock-on effects for me to test now
04723     AttrBrushType* pAttrBrush = NULL;
04724     pAttrMap->Lookup(CC_RUNTIME_CLASS(AttrBrushType), (void*&)pAttrBrush);
04725     if (pAttrBrush && pAttrBrush->GetBrushHandle() != BrushHandle_NoBrush)
04726     {
04727         //Turn the brush into a group with lots of nodepaths
04728         BrushBecomeAGroup BecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), GetUndoOp());
04729         pAttrBrush->DoBecomeA(&BecomeA, pCreatedByNode);
04730         
04731         // the brush will create a group out of itself and we want to retrieve that
04732         NodeGroup* pBrushGroup = BecomeA.GetNodeGroup();
04733         if (pBrushGroup != NULL)
04734         {
04735             if (m_pContextNode == NULL)
04736             {
04737                 m_pContextNode = pBrushGroup;
04738             }
04739             else
04740             {
04741                 // insert as the last sibling
04742                 Node* pNode = m_pContextNode;
04743                 Node* pNext = NULL;
04744                 while (pNode)
04745                 {
04746                     pNext = pNode->FindNext();
04747                     if (pNext == NULL)
04748                         pBrushGroup->AttachNode(pNode, NEXT);
04749                     pNode = pNext;
04750                 }
04751             }
04752         }
04753         else
04754             ERROR3("Failed to create node group!");
04755 
04756         pAttrMap->DeleteAttributes();
04757         delete pAttrMap;
04758         delete pNewNode;
04759         return TRUE;
04760     }
04761 
04762     // likewise if we have an active stroke attribute
04763     AttrStrokeType* pStroke = NULL;
04764     pAttrMap->Lookup(CC_RUNTIME_CLASS(AttrStrokeType), (void*&)pStroke);
04765     AttrVariableWidth* pVarWidth = NULL;
04766     pAttrMap->Lookup(CC_RUNTIME_CLASS(AttrVariableWidth), (void*&)pVarWidth);
04767     
04768     if (pStroke && pStroke->HasPathProcessor() && pVarWidth && pVarWidth->HasActiveValueFunction())
04769     {
04770         PathProcessorStroke* pPPS = pStroke->GetPathProcessor();
04771         Path* pPath = &((NodePath*)pNewNode)->InkPath;
04772         NodePath* pStrokedPath = pPPS->GetSmoothProcessedPath(pPath, pCreatedByNode);
04773 
04774         if (pStrokedPath)
04775         {
04776             // if we don't have a context node then make one
04777             if (m_pContextNode == NULL)
04778             {
04779                 ALLOC_WITH_FAIL(m_pContextNode, new NodeGroup, GetUndoOp());
04780                 if (m_pContextNode == NULL)
04781                 {
04782                     delete pStrokedPath;
04783                     return FALSE;
04784                 }
04785             }
04786 
04787             // Karim 05/12/2000
04788             // process the returned stroke, to change its working
04789             // winding rule from non-zero to even-odd.
04790             Path* pInkStrokePath = &(pStrokedPath->InkPath);
04791             double Flatness = pInkStrokePath->CalculateFlatnessValueFromPath(750.0, 2.0, 375.0);
04792             pInkStrokePath->ClipPathToPath(*pInkStrokePath, pInkStrokePath, 3 | 0x10, 20, Flatness, Flatness);
04793 
04794             // bit of a hack here, but it avoids some code duplication.  Basically OpConvertPathToShapes
04795             // has a really handy function doing all the things you need to do when converting a stroked shape
04796             // to a path, so we're going to assume that our undo op is definitely an OpConvertPathToShapes.
04797             UndoableOperation* pOp = GetUndoOp();
04798             if (pOp == NULL || pOp->IsKindOf(CC_RUNTIME_CLASS(OpConvertPathToShapes)))
04799             {
04800                 OpConvertPathToShapes* pConvert = (OpConvertPathToShapes*)pOp;
04801         
04802                 OpConvertPathToShapes::AdjustStrokeAndFillAttrs(pConvert, pStrokedPath, NULL, pAttrMap);
04803             }
04804             // insert as the last sibling
04805             Node* pNode = m_pContextNode;
04806             Node* pNext = NULL;
04807             while (pNode)
04808             {
04809                 pNext = pNode->FindNext();
04810                 if (pNext == NULL)
04811                     pStrokedPath->AttachNode(pNode, NEXT);
04812                 pNode = pNext;
04813             }
04814             pAttrMap->DeleteAttributes();
04815             delete pAttrMap;
04816             delete pNewNode;
04817             return TRUE;
04818         }
04819     }
04820 
04821 
04822 
04823     // This deals with the case if we have neither a brush or stroke attribute, 
04824     // simply sum the paths.
04825 
04826     double Flatness = ((NodePath *)pNewNode)->InkPath.CalculateFlatnessValueFromPath(750.0, 1.0, 375.0);
04827     pPathNode = ((NodePath *)pNewNode)->MakeNodePathFromAttributes(Flatness, pAttrMap, TRUE);
04828 
04829         // ensure that the path is correct by clipping it
04830     Path BlankPath;
04831     BlankPath.Initialise();
04832     
04833     Path ClipPath;
04834     ClipPath.Initialise();
04835 
04836     // delete the new node
04837     pNewNode->DeleteChildren(pNewNode->FindFirstChild());
04838     delete pNewNode;
04839 
04840     pAttrMap->DeleteAttributes();
04841     delete pAttrMap;
04842 
04843     if (!pPathNode)
04844     {
04845         return FALSE;
04846     }
04847 /*
04848     // smooth the new node's path
04849     double Error = SMOOTH_MIN + (SMOOTH_MAX - SMOOTH_MIN)*pow((35/100), 3.0);
04850 
04851     FitCurveNoChangeGeometry::SmoothPath(&(pPathNode->InkPath), Error);
04852 */  
04853     DocRect dr1(0,0,0,0);
04854     DocRect dr2(0,0,0,0);
04855 
04856     m_SummedPath.GetTrueBoundingRect(&dr1);
04857     pPathNode->InkPath.GetTrueBoundingRect(&dr2);
04858 
04859     // now, let's add this node to the become A path
04860 //  if (m_SummedPath.GetBoundingRect().IsIntersectedWith(pPathNode->InkPath.GetBoundingRect())) MRH 19/5/00
04861     if (dr1.IsIntersectedWith(dr2))
04862     {
04863         Path OrigPath;
04864         OrigPath.Initialise();
04865         OrigPath.CloneFrom(m_SummedPath);
04866         
04867         m_SummedPath.ClearPath();
04868         
04869         OrigPath.ClipPathToPath(pPathNode->InkPath, &m_SummedPath, 7 | CLIPPING_CLIP_WINDING,
04870             50, 50, 50);
04871     }
04872     else
04873     {
04874         m_SummedPath.MergeTwoPaths(pPathNode->InkPath);
04875     }
04876 
04877     delete pPathNode;
04878 
04879     return TRUE;
04880 }


Member Data Documentation

NodeGroup* ConvertPathToShapesBecomeA::m_pContextNode [private]
 

Definition at line 848 of file opcntr.h.

Path ConvertPathToShapesBecomeA::m_SummedPath [private]
 

Definition at line 847 of file opcntr.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:53:11 2007 for Camelot by  doxygen 1.4.4