PathBecomeA Class Reference

Converts nodes to paths. More...

#include <pbecomea.h>

Inheritance diagram for PathBecomeA:

BecomeA ContourBecomeA2 List of all members.

Public Types

enum  OutlineRules { STRIP_OUTLINES, ADD_OUTLINES, IGNORE_OUTLINES }

Public Member Functions

 PathBecomeA (BecomeAReason baReason, CCRuntimeClass *pClass, UndoableOperation *pUndoOp, BOOL bSel, Path *pResultPath, enum OutlineRules OutlineRule=IGNORE_OUTLINES)
 ~PathBecomeA ()
virtual BOOL PassBack (NodeRenderableInk *pNewNode, NodeRenderableInk *pCreatedByNode, CCAttrMap *pAttrMap=NULL)
 Called by DoBecomeA when a node is asked to convert itself to another type of node. The passed-in new node is expected to be a NodePath. We extract its actual Path, and add it to the path referenced by a pointer we were given at construction.

Protected Attributes

Pathm_pResultPath

Private Member Functions

PathExtractOutlineAsPath (NodePath *pSrcNodePath, CCAttrMap *pAttrMap)
 Given a NodePath and an attribute map, construct the Path which delineates the NodePath's outline. If the line width of the path is 0pt, you'll get a NULL ptr back.

Private Attributes

enum OutlineRules m_OutlineRule
UINT32 m_ClipPathRule

Detailed Description

Converts nodes to paths.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
10 February 2000
Notes: Karim 31/10/2000 Moved into its own source files from nodeclip.h/.cpp, as it really isn't related to NodeClipView et al.

Definition at line 122 of file pbecomea.h.


Member Enumeration Documentation

enum PathBecomeA::OutlineRules
 

Enumerator:
STRIP_OUTLINES 
ADD_OUTLINES 
IGNORE_OUTLINES 

Definition at line 129 of file pbecomea.h.

00130 {
00131     STRIP_OUTLINES,     //  remove areas covered by outline from the final path.
00132     ADD_OUTLINES,       //  add areas covered by outline to the final path.
00133     IGNORE_OUTLINES     //  don't worry about outlines at all.
00134 };


Constructor & Destructor Documentation

PathBecomeA::PathBecomeA BecomeAReason  baReason,
CCRuntimeClass pClass,
UndoableOperation pUndoOp,
BOOL  bSel,
Path pResultPath,
enum OutlineRules  OutlineRule = IGNORE_OUTLINES
 

fRemoveOutlines if set, then we strip the area obscured by any object outlines, from the resultant path.

Parameters:
After a call to DoBecomeA with this parameter object, baReason set to [OUTPUTS] BECOMEA_PASSBACK and pClass set to NodePath, pResultPath should contain the outline(s) of whatever node was asked to DoBecomeA.
Notes: It is up to the caller to create, initialise and destroy the Path object pointed to by pResultPath. All we do is fill the path object with the required information.

Outline rules - as an example, imagine processing two overlapping circles with 20pt line width: IGNORE_OUTLINES the default; result - the path which would enclose both circles if their line widths were set to 0.

STRIP_OUTLINES the path which would result if you drew the circles, then erased the areas covered by their thick line widths.

ADD_OUTLINES the path which would result if you drew the circles, complete with thick line widths.

Definition at line 160 of file pbecomea.cpp.

00163                             : BecomeA(baReason, pClass, pUndoOp, bSel)
00164 {
00165     // initialise our pointer to the result-path.
00166     m_pResultPath = pResultPath;
00167 
00168     // initialise our outlines behaviour.
00169     m_OutlineRule = OutlineRule;
00170     if (m_OutlineRule == STRIP_OUTLINES)
00171         m_ClipPathRule = 4;
00172     else if (m_OutlineRule == ADD_OUTLINES)
00173         m_ClipPathRule = 7;
00174 }

PathBecomeA::~PathBecomeA  ) 
 

Definition at line 178 of file pbecomea.cpp.

00179 {
00180     // empty our pointer to the result-path.
00181     m_pResultPath = NULL;
00182 }


Member Function Documentation

Path * PathBecomeA::ExtractOutlineAsPath NodePath pSrcNodePath,
CCAttrMap pAttrMap
[private]
 

Given a NodePath and an attribute map, construct the Path which delineates the NodePath's outline. If the line width of the path is 0pt, you'll get a NULL ptr back.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/11/2000
Parameters:
pSrcNodePath a NodePath whose outline we're going to extract. [INPUTS] pAttrMap the attribute map from which we'll get line attributes, eg width, cap style, join style etc.
Returns:
A ptr to a path if successful, NULL otherwise.
Notes: This method returns a Path allocated on the heap - it's *your* responsibility to delete it!

Either input can be NULL, in which case you'll get a NULL ptr back.

This method should really just take a pure Path* for flexibility, however we make use of MakeNodePathFromAttributes(), which is a NodePath method. I'm fed up of rewriting other people's code at the moment and I don't want to potentially destabilise the code base before a release. If you want to rewrite MakeNodePath... and this method to take a pure Path*, be my guest :o)

Definition at line 374 of file pbecomea.cpp.

00375 {
00376     // we can accept NULL inputs - we just don't do any processing for them.
00377     if (pAttrMap == NULL || pSrcNodePath == NULL)
00378         return NULL;
00379 
00380     const INT32 Flatness = NodeClipViewController::EstimatePathFlatness();
00381 
00382     Path* pFillPath     = &( pSrcNodePath->InkPath );
00383     Path* pStrokePath   = NULL;
00384 
00385     // we only need to generate an outline path if the path has non-transparent line colour.
00386     BOOL bHaveAnOutline = FALSE;
00387     AttrStrokeColour* pAttrStrokeColour = NULL;
00388     pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeColour), (void*&)pAttrStrokeColour );
00389     if (pAttrStrokeColour != NULL)
00390     {
00391         DocColour* pLineColour = pAttrStrokeColour->GetStartColour();
00392         if (pLineColour != NULL && !pLineColour->IsTransparent())
00393         {
00394             bHaveAnOutline = TRUE;
00395         }
00396     }
00397 
00398     // ok, if we don't have an outline, then go home now.
00399     if (!bHaveAnOutline)
00400         return NULL;
00401 
00402     // if the line is stroked, then use the stroke's path-processor to give us the outline.
00403     AttrStrokeType* pAttrStrokeType = NULL;
00404     pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStrokeType), (void*&)pAttrStrokeType );
00405     if (pAttrStrokeType != NULL && pAttrStrokeType->HasPathProcessor())
00406     {
00407         PathProcessorStroke* pPPS = pAttrStrokeType->GetPathProcessor();
00408         if (pPPS != NULL)
00409         {
00410             pStrokePath = pPPS->GetProcessedPath(pFillPath, pAttrMap);
00411             pStrokePath->ClipPathToPath(*pStrokePath, pStrokePath, 3 | 0x10, 20, 75, 75);
00412         }
00413     }
00414 
00415     // if it's a simple line, then use DavidMc's MakeNodePath... method.
00416     else
00417     {
00418         NodePath* pNodeOutline = NULL;
00419         pNodeOutline = pSrcNodePath->MakeNodePathFromAttributes(Flatness,
00420                                                                 pAttrMap,
00421                                                                 TRUE);
00422         if (pNodeOutline != NULL)
00423         {
00424             pStrokePath = pNodeOutline->GetPathCopy();
00425             delete pNodeOutline;
00426             pNodeOutline = NULL;
00427         }
00428     }
00429 
00430     return pStrokePath;
00431 }

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

Called by DoBecomeA when a node is asked to convert itself to another type of node. The passed-in new node is expected to be a NodePath. We extract its actual Path, and add it to the path referenced by a pointer we were given at construction.

Returns:
TRUE if successful, FALSE otherwise.
Notes: The possible node tree pointed to by pNewNode, together with pAttrMap, must both be destroyed by this function - no-one else is going to do it.

Returns:
Errors: ERROR2 with FALSE if pNewNode is NULL or is not a path. See also: BecomeA::PassBack()

Reimplemented from BecomeA.

Reimplemented in ContourBecomeA2.

Definition at line 212 of file pbecomea.cpp.

00215 {
00216     // validate inputs.
00217     ERROR2IF(   pNewNode == NULL || !pNewNode->IsNodePath(),
00218                 FALSE,
00219                 "PathBecomeA::PassBack; Passed back node was NULL, or not a path" );
00220 
00221     ERROR2IF(   m_pResultPath == NULL, FALSE,
00222                 "PathBecomeA::PassBack; NULL result path!"  );
00223 
00224     BOOL fDeleteAttributes  = TRUE;
00225     BOOL fDeleteFillPath    = FALSE;
00226 
00227     const INT32 Flatness = NodeClipViewController::EstimatePathFlatness();
00228 
00229     // try to get an attribute map for converting the outline to shapes.
00230     if (pAttrMap == NULL)
00231     {
00232         fDeleteAttributes = FALSE;
00233         pAttrMap = CCAttrMap::MakeAppliedAttrMap(pCreatedByNode);
00234     }
00235 
00236     NodePath* pNewNodePath = (NodePath*)pNewNode;
00237 
00238     Path* pFillPath = &( pNewNodePath->InkPath );
00239     Path* pLinePath = NULL;
00240 
00241     // ok, first try to get the node's outline as a closed path.
00242     // we obviously won't get anything unless the outline's non-transparent.
00243     pLinePath = ExtractOutlineAsPath(pNewNodePath, pAttrMap);
00244 
00245     // providing the fill-path is filled, we'll use it as is.
00246     if (pFillPath->IsFilled)
00247     {
00248         if (pFillPath->GetNumCoords() < 3)
00249             pFillPath->ClearPath();
00250     }
00251 
00252     // if the fill-path is open, then we'll use the line path instead.
00253     else
00254     {
00255         fDeleteFillPath = TRUE;
00256         pFillPath = pLinePath;
00257         pLinePath = NULL;
00258     }
00259 
00260     // provided it exists, add the fill-path to the results path.
00261     if (pFillPath != NULL && pFillPath->GetNumCoords() > 0)
00262     {
00263         // if our results path is empty, just plonk the fill path in it.
00264         if (m_pResultPath->GetNumCoords() == 0)
00265             m_pResultPath->CloneFrom(*pFillPath);
00266 
00267         // otherwise, add our fill path to the current results path.
00268         // there's a slight optimisation here - if the bounds of the two paths don't overlap,
00269         // then the path union can be done simply by merging them together.
00270         else
00271         {
00272             BOOL fBoundsOverlap = FALSE;
00273             DocRect drResultPath(0, 0, 0, 0);
00274             DocRect drFillPath(0, 0, 0, 0);
00275             if (m_pResultPath->GetTrueBoundingRect(&drResultPath))
00276                 if (pFillPath->GetTrueBoundingRect(&drFillPath))
00277                     if (drFillPath.IsIntersectedWith(drResultPath))
00278                         fBoundsOverlap = TRUE;
00279 
00280             if (!fBoundsOverlap)
00281                 m_pResultPath->MergeTwoPaths(*pFillPath);
00282 
00283             else
00284             {
00285                 m_pResultPath->ClipPathToPath(  *pFillPath, m_pResultPath, 7,
00286                                                 NodeClipViewController::CLIPVIEW_TOLERANCE,
00287                                                 Flatness,
00288                                                 Flatness );
00289 
00290                 // there is a bug here somewhere.  If pCreatedByNode just happens to have a stroke
00291                 // applied to it, then the above call to ClipPathToPath seems to invert the path!
00292                 // I'm not sure what to do about this, so for now it going to have to be left ....
00293                 // NOTE:  to observe the bug, group two (overlapping) quickshapes, apply a stroke to
00294                 // the group and slice with a line.
00295             }
00296         }
00297     }
00298 
00299     // if we're not ignoring outlines and we have a valid outline,
00300     // then throw it into the soup.
00301     if (m_OutlineRule != IGNORE_OUTLINES)
00302     {
00303         if (pLinePath != NULL)
00304         {
00305             m_pResultPath->ClipPathToPath(  *pLinePath, m_pResultPath, m_ClipPathRule | 0x10,
00306                                             NodeClipViewController::CLIPVIEW_TOLERANCE,
00307                                             Flatness,
00308                                             Flatness );
00309         }
00310 
00311         // a side-effect of the ClipPathToPath call above is that it ensures the path is tidy.
00312         // this ClipPathToPath call does the same thing.
00313         else
00314             m_pResultPath->ClipPathToPath(*m_pResultPath, m_pResultPath, 3, 20, 75, 75);
00315     }
00316 
00317     // PathBecomeA tries to return closed paths, so ensure our results path is marked so.
00318     if (!m_pResultPath->IsFilled)
00319         m_pResultPath->IsFilled = TRUE;
00320 
00321     // clear away all our temporary info.
00322     // no NULL assignments required, as these vars are all about to go out of scope.
00323     if (pLinePath != NULL)
00324         delete pLinePath;
00325 
00326     if (fDeleteFillPath && pFillPath != NULL)
00327         delete pFillPath;
00328 
00329     if (pAttrMap != NULL)
00330     {
00331         if (fDeleteAttributes)
00332             pAttrMap->DeleteAttributes();
00333 
00334         delete pAttrMap;
00335     }
00336 
00337     pNewNode->CascadeDelete();
00338     delete pNewNode;
00339 
00340     return TRUE;
00341 }


Member Data Documentation

UINT32 PathBecomeA::m_ClipPathRule [private]
 

Definition at line 159 of file pbecomea.h.

enum OutlineRules PathBecomeA::m_OutlineRule [private]
 

Definition at line 155 of file pbecomea.h.

Path* PathBecomeA::m_pResultPath [protected]
 

Definition at line 149 of file pbecomea.h.


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