#include <ppstroke.h>
Inheritance diagram for PathProcessorStroke:
Public Member Functions | |
PathProcessorStroke () | |
Constructor. | |
virtual void | ProcessPath (Path *pPath, RenderRegion *pRender, PathShape ShapePath=PATHSHAPE_PATH) |
Called by the RenderRegion to apply the path processing operation to the given path. | |
virtual BOOL | WillChangeFillAndStrokeSeparately (void) |
Called by the RenderRegion to determine if this PathProcessorStroke affects the "fill" and "stroke" portions of the path separately. (Generally speaking, only fill/stroke providers will cause these two different "bits" of a path to be rendered separately). This call is made BEFORE this Processor's ProcessPath function will be called. | |
virtual BOOL | IsDifferent (PathProcessorStroke *pOther) |
Equality operator. | |
virtual PathProcessorStroke * | Clone (void) |
To copy PathProcessorStroke or derived-class object. | |
virtual BOOL | NeedsTransparency () const |
virtual BOOL | DoBecomeA (BecomeA *pBecomeA, Path *pPath, Node *pParent) |
To return the processed path to a BecomeA object. Does pretty much the same as process path but withot rendering anything. | |
virtual BOOL | DoesActuallyDoAnything (RenderRegion *pRender) |
Allows the render region to know whether this PPS will do anything, if not then it can DrawPath normally allowing Dash patterns to be applied to nodes with constant VarWidth attributes applied to them. | |
virtual BOOL | IsAPathProcessorStroke () |
NodePath * | GetProcessedPath (Path *pPath, Node *pParent) |
To return the stroked path. | |
Path * | GetProcessedPath (Path *pPath, CCAttrMap *pAttrMap) |
This is a rehash of Diccon's GetProcessedPath method, except you needn't worry about any nodes but the four NodeAttributes below, which must live in the supplied attr-map. | |
NodePath * | GetSmoothProcessedPath (Path *pPath, Node *pParent) |
Protected Member Functions | |
TrapsList * | PrepareTrapsForStroke (Path *pPath, RenderRegion *pRender, INT32 LineWidth) |
Precalculation function to be used in tandem with CreateVarWidthStroke(). If you want to create several strokes along the same path, then precalculating the trapezoids will give a large performance improvement. | |
Path * | CreateVarWidthStroke (Path *pPath, RenderRegion *pRender, INT32 LineWidth, TrapsList *pTrapezoids=NULL) |
Strokes the given path according to variable width parameters in the given render region, producing a new path representing the outline of a variable-width stroke. | |
BOOL | GetRequiredAttributes (CCAttrMap *pAttrMap, INT32 *pLineWidth, LineCapType *pLineCap, ValueFunction **ppValFunc, JointType *pJoinStyle) |
Extracts the following values, required for path stroking, from the supplied attribute map: Line width. Line start-cap - eg square or round end. Pointer to any applied width function - may be NULL. Join style - eg bevelled, mitred, round. | |
Path * | CreateSmoothVarWidthStroke (Path *pPath, RenderRegion *pRender, INT32 LineWidth, TrapsList *pTrapezoids=NULL) |
Private Member Functions | |
CC_DECLARE_DYNAMIC (PathProcessorStroke) | |
Friends | |
class | RenderRegion |
This can be used to "filter" almost any rendering, but is mainly intended for use by stroke and fill providers, which replace input paths with more suitable shapes to be rendered.
Definition at line 134 of file ppstroke.h.
|
Constructor.
Definition at line 142 of file ppstroke.cpp.
|
|
|
|
To copy PathProcessorStroke or derived-class object.
Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 577 of file ppstroke.cpp. 00578 { 00579 // Clone this object - this can be done by just creating a new one 00580 PathProcessorStroke *pClone = new PathProcessorStroke; 00581 00582 // And copy the (base class) parent-attribute pointer so we know when our 00583 // parent attribute is "current" in the render region. 00584 if (pClone != NULL) 00585 pClone->SetParentAttr(GetParentAttr()); 00586 00587 return(pClone); 00588 }
|
|
Definition at line 1076 of file ppstroke.cpp. 01078 { 01079 ERROR3IF(pPath == NULL || pRender == NULL, "Illegal NULL Params"); 01080 ERROR3IF(!pPath->IsStroked, "PathProcessor expects to be given a stroked path"); 01081 01082 // --- Ignore infinitely thin strokes 01083 if (LineWidth < 1) 01084 return(NULL); 01085 01086 // --- Create a new path to be rendered in place of the provided path 01087 // Note that I use a large allocation size so that reallocation need not be done 01088 // frequently, which also helps reduce memory fragmentation. 01089 Path *pOutput = new Path; 01090 if (pOutput == NULL) 01091 return(NULL); 01092 01093 pOutput->Initialise(128, 128); 01094 01095 // --- Get the current cap style from the render region 01096 // In case of failure, we initialise with suitable defaults 01097 LineCapType LineCap = LineCapButt; 01098 // BLOCK 01099 { 01100 StartCapAttribute *pCapAttr = (StartCapAttribute *) pRender->GetCurrentAttribute(ATTR_STARTCAP); 01101 if (pCapAttr != NULL) 01102 LineCap = pCapAttr->StartCap; 01103 } 01104 01105 // --- Get the variable line width descriptor from the render region 01106 ValueFunction *pValFunc = NULL; 01107 // BLOCK 01108 { 01109 VariableWidthAttrValue *pVarWidthAttr = (VariableWidthAttrValue *) pRender->GetCurrentAttribute(ATTR_VARWIDTH); 01110 if (pVarWidthAttr != NULL) 01111 pValFunc = pVarWidthAttr->GetWidthFunction(); 01112 01113 // If it is a constant width stroke, we'll just get GDraw to stroke it for us, 01114 // as that code is optimised assembler, and need not worry about variable width, 01115 // and as a result is about 4 times faster! 01116 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant)) 01117 { 01118 // Get the current line join style from the render region 01119 JointType JoinStyle = RoundJoin; 01120 JoinTypeAttribute *pJoinAttr = (JoinTypeAttribute *) pRender->GetCurrentAttribute(ATTR_JOINTYPE); 01121 if (pJoinAttr != NULL) 01122 JoinStyle = pJoinAttr->JoinType; 01123 01124 pPath->StrokePathToPath(LineWidth, LineCap, JoinStyle, NULL, pOutput); 01125 01126 pOutput->IsFilled = TRUE; 01127 pOutput->IsStroked = FALSE; 01128 return(pOutput); 01129 } 01130 } 01131 01132 // --- If none were passed in, generate the set of trapezoids for the dest path 01133 BOOL MustDeleteTraps = FALSE; 01134 if (pTrapezoids == NULL) 01135 { 01136 MustDeleteTraps = TRUE; 01137 pTrapezoids = PrepareTrapsForStroke(pPath, pRender, LineWidth); 01138 if (pTrapezoids == NULL) 01139 return(NULL); 01140 } 01141 01142 // --- Stroke the trapezoids into a variable-width path 01143 PathStroker Stroker(pValFunc, LineWidth, LineCap); 01144 01145 // our new option allows us to only get the forward mapped path 01146 01147 if (!Stroker.StrokeSmoothPath(pTrapezoids, pOutput)) 01148 { 01149 if (MustDeleteTraps) 01150 delete pTrapezoids; 01151 return(NULL); 01152 } 01153 01154 01155 if (MustDeleteTraps) 01156 delete pTrapezoids; 01157 01158 return(pOutput); 01159 }
|
|
Strokes the given path according to variable width parameters in the given render region, producing a new path representing the outline of a variable-width stroke.
pTrapezoids - NULL (in which case this function will generate the TrapList for itself), or a pointer to a precalculated trapezoid list (this should be generated by calling PathProcessorStroke::PrepareTrapsForStroke, and should be used if you are generating multiple strokes from one source (e.g. see the Airbrush stroker - ppairbsh.cpp)). (NOTE that using one TrapsList for multiple strokes will also give more consistent positioning of width/pattern elements along the path length)
Definition at line 737 of file ppstroke.cpp. 00739 { 00740 ERROR3IF(pPath == NULL || pRender == NULL, "Illegal NULL Params"); 00741 ERROR3IF(!pPath->IsStroked, "PathProcessor expects to be given a stroked path"); 00742 00743 // --- Ignore infinitely thin strokes 00744 if (LineWidth < 1) 00745 return(NULL); 00746 00747 // --- Create a new path to be rendered in place of the provided path 00748 // Note that I use a large allocation size so that reallocation need not be done 00749 // frequently, which also helps reduce memory fragmentation. 00750 Path *pOutput = new Path; 00751 if (pOutput == NULL) 00752 return(NULL); 00753 00754 pOutput->Initialise(128, 128); 00755 00756 // --- Get the current cap style from the render region 00757 // In case of failure, we initialise with suitable defaults 00758 LineCapType LineCap = LineCapButt; 00759 // BLOCK 00760 { 00761 StartCapAttribute *pCapAttr = (StartCapAttribute *) pRender->GetCurrentAttribute(ATTR_STARTCAP); 00762 if (pCapAttr != NULL) 00763 LineCap = pCapAttr->StartCap; 00764 } 00765 00766 // --- Get the variable line width descriptor from the render region 00767 ValueFunction *pValFunc = NULL; 00768 // BLOCK 00769 { 00770 VariableWidthAttrValue *pVarWidthAttr = (VariableWidthAttrValue *) pRender->GetCurrentAttribute(ATTR_VARWIDTH); 00771 if (pVarWidthAttr != NULL) 00772 pValFunc = pVarWidthAttr->GetWidthFunction(); 00773 00774 // If it is a constant width stroke, we'll just get GDraw to stroke it for us, 00775 // as that code is optimised assembler, and need not worry about variable width, 00776 // and as a result is about 4 times faster! 00777 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant)) 00778 { 00779 // Get the current line join style from the render region 00780 JointType JoinStyle = RoundJoin; 00781 JoinTypeAttribute *pJoinAttr = (JoinTypeAttribute *) pRender->GetCurrentAttribute(ATTR_JOINTYPE); 00782 if (pJoinAttr != NULL) 00783 JoinStyle = pJoinAttr->JoinType; 00784 00785 pPath->StrokePathToPath(LineWidth, LineCap, JoinStyle, NULL, pOutput); 00786 00787 pOutput->IsFilled = TRUE; 00788 pOutput->IsStroked = FALSE; 00789 return(pOutput); 00790 } 00791 } 00792 00793 // --- If none were passed in, generate the set of trapezoids for the dest path 00794 BOOL MustDeleteTraps = FALSE; 00795 if (pTrapezoids == NULL) 00796 { 00797 MustDeleteTraps = TRUE; 00798 pTrapezoids = PrepareTrapsForStroke(pPath, pRender, LineWidth); 00799 if (pTrapezoids == NULL) 00800 return(NULL); 00801 } 00802 00803 // --- Stroke the trapezoids into a variable-width path 00804 PathStroker Stroker(pValFunc, LineWidth, LineCap); 00805 00806 // our new option allows us toonly get the forward mapped path 00807 00808 if (!Stroker.StrokePath(pTrapezoids, pOutput)) 00809 { 00810 if (MustDeleteTraps) 00811 delete pTrapezoids; 00812 return(NULL); 00813 } 00814 00815 if (MustDeleteTraps) 00816 delete pTrapezoids; 00817 00818 return(pOutput); 00819 }
|
|
To return the processed path to a BecomeA object. Does pretty much the same as process path but withot rendering anything.
25/10/2000 Extra note: We are now working out a mechanism which uses GetProcessedPath and GetOutlinePath, so this function may become obsolete Reimplemented from PathProcessor. Definition at line 325 of file ppstroke.cpp. 00326 { 00327 ERROR2IF(pBecomeA == NULL, FALSE, "BecomeA pointer is NULL in PathProcessorStroke::DoBecomeA"); 00328 ERROR2IF(pParent == NULL, FALSE, "Parent is NULL in PathProcessorStroke::DoBecomeA"); 00329 ERROR2IF(pPath == NULL, FALSE, "Path is NULL in PathProcessorStroke::DoBecomeA"); 00330 00331 00332 // we need to make a new nodepath 00333 NodePath* pNewNode = GetSmoothProcessedPath(pPath, pParent); 00334 00335 if (pNewNode == FALSE) 00336 return FALSE; 00337 00338 BOOL Success = FALSE; 00339 // now what we do depends on what type of BecomeA we've got 00340 if (pBecomeA->BAPath()) 00341 { 00342 switch (pBecomeA->GetReason()) 00343 { 00344 case BECOMEA_REPLACE: 00345 { 00346 UndoableOperation* pUndoOp = pBecomeA->GetUndoOp(); 00347 ERROR2IF(pUndoOp == NULL, FALSE, "No op pointer in PathProcessorStroke::DoBecomeA"); 00348 // apply attributes to our new node 00349 // Get the attributes 00350 CCAttrMap AttribMap(30); 00351 if (!((NodeRenderableInk*)pParent)->FindAppliedAttributes(&AttribMap)) 00352 break; 00353 00354 // another bodge: this time if we have a stroked path that is not closed and 00355 // we have given it a stroke colour then we want this stroke colour to become 00356 // the fill colour of the new shape 00357 AttrStrokeColour * pColour = NULL; 00358 // if (!pParent->IsNodePath() && ((NodePath*)pParent)->InkPath.IsClosed()) 00359 { 00360 // look up the stroke colour attribute 00361 00362 //AttribMap.Lookup((void *)CC_RUNTIME_CLASS(AttrStrokeColour), 00363 // (void *&)pColour); 00364 ((NodeRenderableInk*)pParent)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), (NodeAttribute**)&pColour); 00365 // make a new flat fill attribute and apply this to the node 00366 if (pColour) 00367 { 00368 StrokeColourAttribute * pAttrVal = (StrokeColourAttribute *)pColour->GetAttributeValue(); 00369 00370 if (pAttrVal) 00371 { 00372 AttrFlatColourFill *pFill = NULL; 00373 // create and insert at first child 00374 ALLOC_WITH_FAIL(pFill, new AttrFlatColourFill(pNewNode, FIRSTCHILD), pUndoOp); 00375 00376 pFill->SetStartColour(&(pAttrVal->Colour)); 00377 // remove from the map so we don't duplicate 00378 AttribMap.RemoveKey(pFill->GetAttributeType()); 00379 } 00380 } 00381 00382 } 00383 00384 if (!pNewNode->ApplyAttributes(&AttribMap)) 00385 break; 00386 00387 // insert the new node and delete the original 00388 BOOL ok = TRUE; 00389 // If we don't own the parent node, we should insert after (on top of) it 00390 if (pBecomeA->IsSecondary()) 00391 ok = pUndoOp->DoInsertNewNode(pNewNode,pParent,NEXT,FALSE,FALSE,FALSE,FALSE); 00392 else 00393 { 00394 ok = pUndoOp->DoInsertNewNode(pNewNode,pParent,PREV,FALSE,FALSE,FALSE,FALSE); 00395 // If this BecomeA is a primary, then delete the source node 00396 if (ok) 00397 ok = pUndoOp->DoHideNode((NodeRenderableInk*)pParent, TRUE); 00398 } 00399 00400 if (!ok) 00401 break; 00402 00403 00404 if (!pBecomeA->IsCombineBecomeA()) 00405 { 00406 // pass it back then 00407 pBecomeA->PassBack(pNewNode,(NodeRenderableInk*)pParent); 00408 } 00409 else 00410 { 00411 CombineBecomeA* pPassback = (CombineBecomeA*) pBecomeA; 00412 00413 pPassback->SetStrokeCreatedPassbackPath(TRUE); 00414 pBecomeA->PassBack(pNewNode,(NodeRenderableInk*)pParent); 00415 pPassback->SetStrokeCreatedPassbackPath(FALSE); 00416 } 00417 Success = TRUE; 00418 } 00419 break; 00420 00421 case BECOMEA_PASSBACK : 00422 { 00423 if (!pBecomeA->IsCombineBecomeA ()) 00424 { 00425 // pass it back then 00426 Success = pBecomeA->PassBack(pNewNode,(NodeRenderableInk*)pParent); 00427 } 00428 else 00429 { 00430 CombineBecomeA* pPassback = (CombineBecomeA*) pBecomeA; 00431 00432 pPassback->SetStrokeCreatedPassbackPath(TRUE); 00433 Success = pBecomeA->PassBack(pNewNode,(NodeRenderableInk*)pParent); 00434 pPassback->SetStrokeCreatedPassbackPath(FALSE); 00435 } 00436 } 00437 break; 00438 00439 default: 00440 break; 00441 } 00442 } 00443 00444 00445 if (!Success) 00446 delete pNewNode; 00447 00448 return Success; 00449 }
|
|
Allows the render region to know whether this PPS will do anything, if not then it can DrawPath normally allowing Dash patterns to be applied to nodes with constant VarWidth attributes applied to them.
Reimplemented from PathProcessor. Definition at line 607 of file ppstroke.cpp. 00608 { 00609 ERROR2IF(pRender == NULL, FALSE, "RenderRegion is NULL in PathProcessorStroke::DoesActuallyDoAnything"); 00610 00611 if (IsDisabled()) 00612 return FALSE; 00613 00614 // Get the value function from the render region and have a look at it 00615 ValueFunction *pValFunc = NULL; 00616 00617 VariableWidthAttrValue *pVarWidthAttr = (VariableWidthAttrValue *) pRender->GetCurrentAttribute(ATTR_VARWIDTH); 00618 if (pVarWidthAttr != NULL) 00619 pValFunc = pVarWidthAttr->GetWidthFunction(); 00620 00621 // If it is a constant width stroke, then we don't really do anything 00622 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant)) 00623 return FALSE; 00624 00625 // likewise if we have a brush don't do anything either, because we will use the stroke to 00626 // generate a pressure curve for the brush 00627 BrushAttrValue* pBrush = (BrushAttrValue*) pRender->GetCurrentAttribute(ATTR_BRUSHTYPE); 00628 if (pBrush != NULL && pBrush->GetBrushHandle() != BrushHandle_NoBrush) 00629 return FALSE; 00630 00631 return TRUE; 00632 }
|
|
This is a rehash of Diccon's GetProcessedPath method, except you needn't worry about any nodes but the four NodeAttributes below, which must live in the supplied attr-map.
Notes: The following valid NodeAttributes must live in the attr-map: AttrLineWidth AttrStartCap AttrVariableWidth AttrJoinType
Definition at line 853 of file ppstroke.cpp. 00854 { 00855 ERROR2IF(pPath == NULL || pAttrMap == NULL, NULL, 00856 "PathProcessorStroke::GetProcessedPath; NULL input parameters!"); 00857 00858 INT32 LineWidth; 00859 LineCapType LineCap; 00860 ValueFunction* pValFunc; 00861 JointType JoinStyle; 00862 00863 if (!GetRequiredAttributes(pAttrMap, &LineWidth, &LineCap, &pValFunc, &JoinStyle)) 00864 return NULL; 00865 00866 if (LineWidth < 1) 00867 return NULL; 00868 00869 // Create a path to hold our stroking exploits! 00870 // We'll prob'ly be generating loads of data, so be generous with our path's 00871 // initialisation, so it's not continually reallocating memory as it runs out. 00872 Path* pStroke = new Path; 00873 if (pStroke == NULL) 00874 return NULL; 00875 if (!pStroke->Initialise(128, 128)) 00876 { 00877 delete pStroke; 00878 return NULL; 00879 } 00880 00881 // if it's a constant-width stroke, ask GDraw to stroke it - it's 00882 // quicker and if it goes wrong, it's Gavin's fault (only joking ;o) 00883 if (pValFunc == NULL || IS_A(pValFunc, ValueFunctionConstant)) 00884 { 00885 pPath->StrokePathToPath(LineWidth, LineCap, JoinStyle, NULL, pStroke); 00886 pStroke->IsFilled = TRUE; 00887 pStroke->IsStroked = TRUE; 00888 return pStroke; 00889 } 00890 00891 // ok, GDraw didn't deal with it, so let's get down to business. 00892 00893 // Generate the set of trapezoids for the dest path. 00894 ProcessPathToTrapezoids GenerateTraps(64); 00895 TrapsList *pTrapezoids = new TrapsList; 00896 BOOL ok = (pTrapezoids != NULL); 00897 if (ok) ok = GenerateTraps.Init(pPath, pTrapezoids); 00898 if (ok) 00899 { 00900 // Flags are: Flatten, QuantiseLines, QuantiseAll 00901 ProcessFlags PFlags(TRUE, FALSE, FALSE); 00902 ok = GenerateTraps.Process(PFlags, TrapTravel_Parametric, JoinStyle); 00903 } 00904 00905 // Stroke the trapezoids into a variable-width path. 00906 if (ok) 00907 { 00908 PathStroker Stroker(pValFunc, LineWidth, LineCap); 00909 ok = Stroker.StrokeSmoothPath(pTrapezoids, pStroke); 00910 } 00911 00912 // tidy up temporary info. 00913 if (pTrapezoids != NULL) 00914 { 00915 delete pTrapezoids; 00916 pTrapezoids = NULL; 00917 } 00918 00919 // tidy up the path and pass it out. 00920 if (pStroke != NULL) 00921 { 00922 if (ok) 00923 { 00924 if (!pStroke->IsClosed()) 00925 pStroke->TryToClose(); 00926 } 00927 else 00928 { 00929 delete pStroke; 00930 pStroke = NULL; 00931 } 00932 } 00933 00934 return pStroke; 00935 }
|
|
To return the stroked path.
Definition at line 467 of file ppstroke.cpp. 00468 { 00469 // we need to fake a renderregion as our helper functions need one, 00470 // luckily FormatRegion is on hand from the text stuff 00471 FormatRegion FakeRender; 00472 00473 if (!FakeRender.Init((NodeRenderableInk*)pParent)) // init renders all applied attributes into the region 00474 return NULL; 00475 00476 00477 // From here copied from ProcessPath: 00478 // --- Get the current line width, cap style, and join style from the render region 00479 // In case of failure, we initialise with suitable defaults 00480 INT32 LineWidth = 5000; 00481 00482 // BLOCK 00483 { 00484 LineWidthAttribute *pWidthAttr = (LineWidthAttribute *) FakeRender.GetCurrentAttribute(ATTR_LINEWIDTH); 00485 if (pWidthAttr != NULL) 00486 LineWidth = pWidthAttr->LineWidth; 00487 } 00488 00489 // --- Create a stroke outline by calling our helper function 00490 Path *pOutput = CreateVarWidthStroke(pPath, &FakeRender, LineWidth); 00491 if (pOutput == NULL) 00492 return FALSE; 00493 00494 if (!pOutput->IsClosed()) 00495 pOutput->TryToClose(); 00496 00497 // we need to make a new nodepath 00498 NodePath* pNewNode = new NodePath; 00499 00500 if (pNewNode == NULL) 00501 { 00502 delete pOutput; 00503 return FALSE; 00504 } 00505 00506 // initialise the path 00507 if (!pNewNode->InkPath.Initialise(pOutput->GetNumCoords(), 128)) 00508 { 00509 delete pOutput; 00510 delete pNewNode; 00511 return FALSE; 00512 } 00513 00514 // Copy our path data into it 00515 //CALL_WITH_FAIL(!pNewNode->InkPath.CopyPathDataFrom(pOutput), pUndoOp, Success) 00516 if (!pNewNode->InkPath.CopyPathDataFrom(pOutput)) 00517 { 00518 delete pOutput; 00519 delete pNewNode; 00520 return FALSE; 00521 } 00522 // don't need that path anymore 00523 delete pOutput; 00524 pOutput = NULL; 00525 00526 return pNewNode; 00527 }
|
|
Extracts the following values, required for path stroking, from the supplied attribute map: Line width. Line start-cap - eg square or round end. Pointer to any applied width function - may be NULL. Join style - eg bevelled, mitred, round.
Definition at line 977 of file ppstroke.cpp. 00982 { 00983 AttrLineWidth* pAttrWidth = NULL; 00984 AttrStartCap* pAttrCap = NULL; 00985 AttrVariableWidth* pAttrVarWidth = NULL; 00986 AttrJoinType* pAttrJoinType = NULL; 00987 00988 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrLineWidth), (void*&)pAttrWidth); 00989 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrStartCap), (void*&)pAttrCap); 00990 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrVariableWidth),(void*&)pAttrVarWidth); 00991 pAttrMap->Lookup( CC_RUNTIME_CLASS(AttrJoinType), (void*&)pAttrJoinType); 00992 00993 if (pAttrWidth == NULL || pAttrCap == NULL || 00994 pAttrVarWidth == NULL || pAttrJoinType == NULL) 00995 { 00996 TRACEALL( _T("PathProcessorStroke::GetProcessedPath; AttrMap doesn't contain the required attrs!") ); 00997 *pLineWidth = 0; 00998 *pLineCap = LineCapButt; 00999 *ppValFunc = NULL; 01000 *pJoinStyle = RoundJoin; 01001 return FALSE; 01002 } 01003 01004 *pLineWidth = pAttrWidth->Value.LineWidth; 01005 *pLineCap = pAttrCap->Value.StartCap; 01006 *ppValFunc = pAttrVarWidth->Value.GetWidthFunction(); 01007 *pJoinStyle = pAttrJoinType->Value.JoinType; 01008 01009 return TRUE; 01010 }
|
|
Definition at line 1014 of file ppstroke.cpp. 01015 { 01016 // we need to fake a renderregion as our helper functions need one, 01017 // luckily FormatRegion is on hand from the text stuff 01018 FormatRegion FakeRender; 01019 01020 if (!FakeRender.Init((NodeRenderableInk*)pParent)) // init renders all applied attributes into the region 01021 return FALSE; 01022 01023 // From here copied from ProcessPath: 01024 // --- Get the current line width, cap style, and join style from the render region 01025 // In case of failure, we initialise with suitable defaults 01026 INT32 LineWidth = 5000; 01027 01028 // BLOCK 01029 { 01030 LineWidthAttribute *pWidthAttr = (LineWidthAttribute *) FakeRender.GetCurrentAttribute(ATTR_LINEWIDTH); 01031 if (pWidthAttr != NULL) 01032 LineWidth = pWidthAttr->LineWidth; 01033 } 01034 01035 // --- Create a stroke outline by calling our helper function 01036 Path *pOutput = CreateSmoothVarWidthStroke(pPath, &FakeRender, LineWidth); 01037 if (pOutput == NULL) 01038 return FALSE; 01039 01040 if (!pOutput->IsClosed()) 01041 pOutput->TryToClose(); 01042 01043 // we need to make a new nodepath 01044 NodePath* pNewNode = new NodePath; 01045 01046 if (pNewNode == NULL) 01047 { 01048 delete pOutput; 01049 return FALSE; 01050 } 01051 01052 // initialise the path 01053 if (!pNewNode->InkPath.Initialise(pOutput->GetNumCoords(), 128)) 01054 { 01055 delete pOutput; 01056 delete pNewNode; 01057 return FALSE; 01058 } 01059 01060 // Copy our path data into it 01061 //CALL_WITH_FAIL(!pNewNode->InkPath.CopyPathDataFrom(pOutput), pUndoOp, Success) 01062 if (!pNewNode->InkPath.CopyPathDataFrom(pOutput)) 01063 { 01064 delete pOutput; 01065 delete pNewNode; 01066 return FALSE; 01067 } 01068 // don't need that path anymore 01069 delete pOutput; 01070 pOutput = NULL; 01071 01072 return pNewNode; 01073 }
|
|
Reimplemented from PathProcessor. Definition at line 162 of file ppstroke.h. 00162 {return TRUE;}
|
|
Equality operator.
Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 550 of file ppstroke.cpp. 00551 { 00552 ERROR3IF(pOther == NULL, "Illegal NULL param"); 00553 00554 if (GetRuntimeClass() != pOther->GetRuntimeClass()) 00555 return(TRUE); 00556 00557 // Assume that we're the same, as the base class is very simple 00558 return(FALSE); 00559 }
|
|
Reimplemented from PathProcessor. Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 155 of file ppstroke.h. 00155 {return FALSE;};
|
|
Precalculation function to be used in tandem with CreateVarWidthStroke(). If you want to create several strokes along the same path, then precalculating the trapezoids will give a large performance improvement.
Definition at line 662 of file ppstroke.cpp. 00663 { 00664 LineCapType LineCap = LineCapButt; 00665 JointType JoinStyle = RoundJoin; 00666 00667 // BLOCK 00668 { 00669 // --- Get the current line cap style from the render region 00670 StartCapAttribute *pCapAttr = (StartCapAttribute *) pRender->GetCurrentAttribute(ATTR_STARTCAP); 00671 if (pCapAttr != NULL) 00672 LineCap = pCapAttr->StartCap; 00673 00674 // --- Get the current line join style from the render region 00675 JoinTypeAttribute *pJoinAttr = (JoinTypeAttribute *) pRender->GetCurrentAttribute(ATTR_JOINTYPE); 00676 if (pJoinAttr != NULL) 00677 JoinStyle = pJoinAttr->JoinType; 00678 } 00679 00680 ProcessPathToTrapezoids GenerateTraps(64); 00681 TrapsList *pTrapezoids = new TrapsList; 00682 00683 if (pTrapezoids != NULL && GenerateTraps.Init(pPath, pTrapezoids)) 00684 { 00685 // Flags are: Flatten, QuantiseLines, QuantiseAll 00686 ProcessFlags PFlags(TRUE, FALSE, FALSE); 00687 if (!GenerateTraps.Process(PFlags, TrapTravel_Parametric, JoinStyle)) 00688 { 00689 delete pTrapezoids; 00690 pTrapezoids = NULL; 00691 } 00692 } 00693 00694 return pTrapezoids; 00695 }
|
|
Called by the RenderRegion to apply the path processing operation to the given path.
Notes: * When rendering a path, always pass in your 'this' pointer to RenderRegion::DrawPath, so that you don't start an infinite recursion! To stop rendering of the path, simply return without calling the RR To render this path unchanged, simply call directly back to the RR: pRender->DrawPath(pPath, this); Only affect the fill of this path if pPath->IsFilled Only affect the stroke of this path if pPath->IsStroked If converting a path into a "filled path" for stroking, the output path should be rendered with IsStroked=FALSE or it'll get a line around the outside! Implements PathProcessor. Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 212 of file ppstroke.cpp. 00215 { 00216 TRACEUSER( "Diccon", _T("Rendering stroke\n")); 00217 ERROR3IF(pPath == NULL || pRender == NULL, "Illegal NULL Params"); 00218 00219 // --- If the provided path is not stroked, then we'll just pass it straight through 00220 // We also don't touch it if we're doing EOR rendering 00221 if (!pPath->IsStroked || pRender->DrawingMode != DM_COPYPEN) 00222 { 00223 pRender->DrawPath(pPath, this, ShapePath); 00224 return; 00225 } 00226 00227 // --- If the quality is set low, strokes are just rendered as centrelines 00228 // BLOCK 00229 { 00230 QualityAttribute *pQuality = (QualityAttribute *) pRender->GetCurrentAttribute(ATTR_QUALITY); 00231 if (pQuality != NULL && pQuality->QualityValue.GetLineQuality() != Quality::FullLine) 00232 { 00233 pRender->DrawPath(pPath, this, ShapePath); 00234 return; 00235 } 00236 } 00237 00238 // --- If the attribute which created us is not the current StrokeType attribute, then 00239 // we have been overridden by a different stroke type, so we do nothing. 00240 // BLOCK 00241 { 00242 StrokeTypeAttrValue *pTypeAttr = (StrokeTypeAttrValue *) pRender->GetCurrentAttribute(ATTR_STROKETYPE); 00243 if (pTypeAttr != NULL && pTypeAttr != GetParentAttr()) 00244 { 00245 pRender->DrawPath(pPath, this); 00246 return; 00247 } 00248 } 00249 00250 // --- We don't expect the input path to be stroked AND filled on entry 00251 ERROR3IF(pPath->IsFilled, "PathProcessor expected RenderRegion to handle IsFilled case"); 00252 00253 // --- Get the current line width, cap style, and join style from the render region 00254 // In case of failure, we initialise with suitable defaults 00255 INT32 LineWidth = 5000; 00256 00257 // BLOCK 00258 { 00259 LineWidthAttribute *pWidthAttr = (LineWidthAttribute *) pRender->GetCurrentAttribute(ATTR_LINEWIDTH); 00260 if (pWidthAttr != NULL) 00261 LineWidth = pWidthAttr->LineWidth; 00262 } 00263 00264 // --- Create a stroke outline by calling our helper function 00265 00266 // (ChrisG 4/11/00) - Use smoothed paths with AIExport. This is only done for the export, as the smooth 00267 // path creation function is about five times slower than the non-smoothed one. 00268 Path * pOutput = NULL; 00269 if (pRender->IsKindOf (CC_RUNTIME_CLASS (AIEPSRenderRegion))) 00270 { 00271 pOutput = CreateSmoothVarWidthStroke(pPath, pRender, LineWidth); 00272 } 00273 else 00274 { 00275 pOutput = CreateVarWidthStroke(pPath, pRender, LineWidth); 00276 } 00277 00278 if (pOutput == NULL) 00279 { 00280 pRender->DrawPath(pPath, this); 00281 return; 00282 } 00283 00284 // --- Finally, render the new stroke outline path in place of the one we were given 00285 pRender->SaveContext(); 00286 00287 // !!!!****ToDo - for now, strokes always render flat-filled with the stroke colour 00288 StrokeColourAttribute *pStrokeColour = (StrokeColourAttribute *) pRender->GetCurrentAttribute(ATTR_STROKECOLOUR); 00289 if (pStrokeColour != NULL) 00290 pRender->SetFillColour(pStrokeColour->Colour); 00291 00292 pRender->SetWindingRule(NonZeroWinding); 00293 pRender->DrawPath(pOutput, this); 00294 00295 pRender->RestoreContext(); 00296 00297 // --- And clean up 00298 delete pOutput; 00299 }
|
|
Called by the RenderRegion to determine if this PathProcessorStroke affects the "fill" and "stroke" portions of the path separately. (Generally speaking, only fill/stroke providers will cause these two different "bits" of a path to be rendered separately). This call is made BEFORE this Processor's ProcessPath function will be called.
Notes: Base class implementation returns FALSE. Derived Stroke and Fill processors (such as this one) override this method to return TRUE. Reimplemented from PathProcessor. Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 171 of file ppstroke.cpp. 00172 { 00173 return(TRUE); 00174 }
|
|
Reimplemented from PathProcessor. Reimplemented in PathProcessorStrokeAirbrush, and PathProcessorStrokeVector. Definition at line 136 of file ppstroke.h. |