NodeLiveEffect Class Reference

Bitmap effects nodes are type of Post-Processors. They process the bitmap output of their child nodes. They are "Live" in that as soon as their children change they re-process the output. More...

#include <nodeliveeffect.h>

Inheritance diagram for NodeLiveEffect:

NodeBitmapEffect NodeEffect NodeCompound NodeRenderableInk NodeRenderableBounded NodeRenderable Node CCObject SimpleCCObject NodeFeatherEffect List of all members.

Public Member Functions

 NodeLiveEffect ()
 Note:.
 ~NodeLiveEffect ()
 Destructor Note:.
 NodeLiveEffect (Node *ContextNode, AttachNodeDirection Direction, BOOL Locked=FALSE, BOOL Mangled=FALSE, BOOL Marked=FALSE, BOOL Selected=FALSE)
 This constructor initialises the nodes flags and links it to ContextNode in the direction specified by Direction. All neccesary tree links are updated. Note: SetUpShape() must be called before the NodeRegularShape is in a state in which it can be used.
virtual SubtreeRenderState RenderSubtree (RenderRegion *pRender, Node **ppNextNode=NULL, BOOL bClip=TRUE)
 Do clever stuff on the way into a subtree, possibly modifying rendering behaviour.
virtual String Describe (BOOL Plural, BOOL Verbose)
 To return a description of the Group object in either the singular or the plural. This method is called by the DescribeRange method.
virtual NodeSimpleCopy ()
 This method returns a shallow copy of the node with all Node pointers NULL. The function is virtual, and must be defined for all derived classes.
virtual UINT32 GetNodeSize () const
 For finding the size of the node.
virtual void PolyCopyNodeContents (NodeRenderable *pNodeCopy)
 Polymorphically copies the contents of this node to another.
virtual DocRect GetBoundingRect (BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
 Get the bounding rect of the cached processed bitmap or the original bitmap if the processed isn't set yet... or the children if neither is set yet...
virtual void Transform (TransformBase &Trans)
 Transforms the LiveEffect node.
virtual BOOL ReleaseCached (BOOL bAndParents=TRUE, BOOL bAndChildren=TRUE, BOOL bSelf=TRUE, BOOL bAndDerived=TRUE)
 Protected Helper function Use the CaptureManager to capture the results of rendering, cache them and associate them with this Ink node.
virtual BOOL WritePreChildrenWeb (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
virtual BOOL WritePreChildrenNative (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
virtual NodeRenderableInkFindNodeAtPointHelper (const Spread *pSpread, const DocCoord dcPoint)
 Allows a node class to control hit detection and selection of itself.
virtual BOOL CanSelectAsCompoundParent ()
 Ask a node whether or not it's prepared to become selected when one of it's children is clicked on. This function is called in the FindSimple/Compound routines when they are following parent links up the tree from a node which has been "hit". This virtual function should be overridden in derived classes to alter its behaviour.
virtual BOOL PromoteHitTestOnChildrenToMe () const
virtual BOOL ShouldITransformWithChildren () const
virtual BOOL AllowSelectInside () const
virtual BOOL GetProcessedBitmap (BOOL bDirect, LPBITMAPINFO *plpInfo, LPBYTE *plpBits, DocRect *pRect)
 

virtual DocRect SetProcessedBitmap (LPBITMAPINFO lpInfo, LPBYTE lpBits, DocRect rect, INT32 width, INT32 height, double xOffset, double yOffset, double dPixelWidth=0, Matrix *pmatTransform=NULL)
 

virtual BOOL IsLockedEffect ()
virtual KernelBitmapGetKernelBitmap (DocCoord *pCoords, BOOL bRetainCached=FALSE)
 Allows a bitmap effect to create a permanent kernel bitmap version of itself.
void RemoveBitmapFromCache ()
 Remove the bitmap from the cache but don't vape the bitmap itself from memory.

Protected Member Functions

virtual BOOL WriteLiveEffect (BaseCamelotFilter *pFilter)
 Writes the path record to the filter.
void CopyNodeContents (NodeLiveEffect *pCopyOfNode)
 Copies the data from this node to pCopyOfNode by first calling the base class to get it to copy its stuff, and then copying its own stuff Scope: protected.

Private Member Functions

 CC_DECLARE_DYNCREATE (NodeLiveEffect)

Private Attributes

DocRect m_rectEstimatedBounds
MILLIPOINT m_lMaxBorder

Friends

class LiveEffectRecordHandler

Detailed Description

Bitmap effects nodes are type of Post-Processors. They process the bitmap output of their child nodes. They are "Live" in that as soon as their children change they re-process the output.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004

Definition at line 293 of file nodeliveeffect.h.


Constructor & Destructor Documentation

NodeLiveEffect::NodeLiveEffect  ) 
 

Note:.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
See also:

Definition at line 1891 of file nodeliveeffect.cpp.

01891                                : NodeBitmapEffect()
01892 {
01893     m_rectEstimatedBounds = DocRect(0,0,0,0);
01894     m_lMaxBorder = 0;
01895     m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLivePixelsPerInch;
01896 }

NodeLiveEffect::~NodeLiveEffect  ) 
 

Destructor Note:.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
See also:

Definition at line 1912 of file nodeliveeffect.cpp.

01913 {
01914     m_pEditsDoc = NULL;             // m_pEditsDoc is a smart pointer so NULLing it Releases the COM interface
01915                                     // and releases any memory
01916     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01917     if (pBitmapCache!=NULL)
01918     {
01919         CBitmapCacheKey inky(this, 42);
01920         pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
01921     }
01922 }

NodeLiveEffect::NodeLiveEffect Node ContextNode,
AttachNodeDirection  Direction,
BOOL  Locked = FALSE,
BOOL  Mangled = FALSE,
BOOL  Marked = FALSE,
BOOL  Selected = FALSE
 

This constructor initialises the nodes flags and links it to ContextNode in the direction specified by Direction. All neccesary tree links are updated. Note: SetUpShape() must be called before the NodeRegularShape is in a state in which it can be used.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Parameters:
ContextNode,: Pointer to a node which this node is to be attached to. [INPUTS] MonoOn Direction: MonoOff Specifies the direction in which the node is to be attached to the ContextNode. The values this variable can take are as follows:
PREV : Attach node as a previous sibling of the context node NEXT : Attach node as a next sibling of the context node FIRSTCHILD: Attach node as the first child of the context node LASTCHILD : Attach node as a last child of the context node

BoundingRect: Bounding rectangle

The remaining inputs specify the status of the node:

Locked: Is node locked ? Mangled: Is node mangled ? Marked: Is node marked ? Selected: Is node selected ?

See also:
NodeRegularShape::SetUpShape
Returns:
Errors: An ENSURE will occur if ContextNode is NULL

Definition at line 1864 of file nodeliveeffect.cpp.

01870                 : NodeBitmapEffect(ContextNode, Direction, Locked, Mangled, Marked, Selected )
01871 {                         
01872     m_rectEstimatedBounds = DocRect(0,0,0,0);
01873     m_lMaxBorder = 0;
01874     m_dPixelsPerInch = (double)NodeBitmapEffect::DefaultLivePixelsPerInch;
01875 }                        


Member Function Documentation

virtual BOOL NodeLiveEffect::AllowSelectInside  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 331 of file nodeliveeffect.h.

00331 {return TRUE;}                  // TRUE if normal effect

virtual BOOL NodeLiveEffect::CanSelectAsCompoundParent  )  [inline, virtual]
 

Ask a node whether or not it's prepared to become selected when one of it's children is clicked on. This function is called in the FindSimple/Compound routines when they are following parent links up the tree from a node which has been "hit". This virtual function should be overridden in derived classes to alter its behaviour.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/01/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the node will allow itself to be selected when one of it's children has been "hit" FALSE otherwise

Errors: -

See also:
NodeRenderableInk::FindSimpleAtPoint; NodeRenderableInk::FindCompoundAtPoint

Reimplemented from NodeRenderableInk.

Definition at line 328 of file nodeliveeffect.h.

00328 {return FALSE;}                 // FALSE if normal effect

NodeLiveEffect::CC_DECLARE_DYNCREATE NodeLiveEffect   )  [private]
 

void NodeLiveEffect::CopyNodeContents NodeLiveEffect pCopyOfNode  )  [protected]
 

Copies the data from this node to pCopyOfNode by first calling the base class to get it to copy its stuff, and then copying its own stuff Scope: protected.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/09/2004
Parameters:
pCopyOfNode - The node to copy data to [INPUTS]
- [OUTPUTS]
Returns:
-
See also:
NodeGroup::CopyNodeContents

Definition at line 2355 of file nodeliveeffect.cpp.

02356 {
02357     NodeBitmapEffect::CopyNodeContents(pCopyOfNode);
02358 
02359     // Copy member vars here
02360     if (m_pEditsDoc)
02361     {
02362 PORTNOTETRACE("other","NodeLiveEffect::CopyNodeContents - not copying XML data");
02363 #ifndef EXCLUDE_FROM_XARALX
02364         pCopyOfNode->m_pEditsDoc = CXMLUtils::NewDocument(m_pEditsDoc);
02365 #endif
02366     }
02367     else
02368         pCopyOfNode->m_pEditsDoc = NULL;
02369     pCopyOfNode->m_dPixelsPerInch = m_dPixelsPerInch;
02370     pCopyOfNode->m_strDisplayName = m_strDisplayName;
02371     pCopyOfNode->m_rectEstimatedBounds = m_rectEstimatedBounds;
02372     pCopyOfNode->m_lMaxBorder = m_lMaxBorder;
02373     pCopyOfNode->m_rectDirectBitmap = m_rectDirectBitmap;
02374 
02375     // If this node cannot remake it's associated bitmap
02376     // Then we need to copy the cached bitmaps into the new node
02377     CopyCached(pCopyOfNode, GetPixelWidth(), 1);    // Copy cached bitmaps, options 0 and 1 (original and processed)
02378 }

String NodeLiveEffect::Describe BOOL  Plural,
BOOL  Verbose
[virtual]
 

To return a description of the Group object in either the singular or the plural. This method is called by the DescribeRange method.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Parameters:
Plural,: Flag indicating if the string description should be plural or [INPUTS] singular.
- [OUTPUTS] Retuns: Description of the group node
The description will always begin with a lower case letter.

Returns:
Errors: (Need to do this)
See also:
-

Reimplemented from Node.

Reimplemented in NodeFeatherEffect.

Definition at line 2299 of file nodeliveeffect.cpp.

02300 {
02301     if (Plural)
02302         return(String(_R(IDS_LIVEEFFECT_DESCRP)));
02303     else
02304         return(String(_R(IDS_LIVEEFFECT_DESCRS)));
02305 };

NodeRenderableInk * NodeLiveEffect::FindNodeAtPointHelper const Spread pSpread,
const DocCoord  dcPoint
[virtual]
 

Allows a node class to control hit detection and selection of itself.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/09/2004
Parameters:
pSpread - pointer to relevant spread (should be our ancestor somewhere) [INPUTS] dcPoint - point on spread under consideration
Returns:
Pointer to node that should become selected as result of hit detection at this point
See also:
-

Reimplemented from NodeRenderableInk.

Definition at line 2700 of file nodeliveeffect.cpp.

02701 {
02702     // Non-destructive LiveEffects should be invisible to selection...
02703     // But they do render into the hit-detection bitmap so that the user can click
02704     // them where they are bigger than the original object
02705     // So skip down the tree until we hit a "real" object
02706     // NOTE! We assume that a non-destructive LiveEffect only contains one renderablechild
02707     NodeRenderableInk* pNode = this;
02708     while (pNode!=NULL && pNode->IsCompoundClass() && !(pNode->CanSelectAsCompoundParent() && pNode->PromoteHitTestOnChildrenToMe()))
02709     {
02710         pNode = ((NodeCompound*)pNode)->GetInkNodeFromController();
02711     }
02712 
02713     return pNode;
02714 }

DocRect NodeLiveEffect::GetBoundingRect BOOL  DontUseAttrs = FALSE,
BOOL  HitTest = FALSE
[virtual]
 

Get the bounding rect of the cached processed bitmap or the original bitmap if the processed isn't set yet... or the children if neither is set yet...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/09/2004
Returns:
The bounding box of the live effect

Reimplemented from NodeRenderableBounded.

Definition at line 1940 of file nodeliveeffect.cpp.

01941 {
01942     // Let sanity prevail!
01943     BOOL bIncludeAttrs = !DontUseAttrs;
01944 
01945     // Optimise this function by returning fast cached info if we know it's valid.
01946     if (IsBoundingRectValid && bIncludeAttrs)
01947         return BoundingRectangle;
01948 
01949     // Else work it out by looking up the cached bitmaps
01950     // and failing that by scanning our children
01951     if (bIncludeAttrs)
01952     {
01953         // We can check the bounds of our whacky effects bitmap
01954         CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01955         if (pBitmapCache!=NULL)
01956         {
01957             // Look for cached processed bitmap
01958             CBitmapCacheKey inky(this, GetPixelWidth(), 1);             // Get cached BMP for this node at our dpi
01959             CCachedBitmap cbmp;
01960             BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
01961             if (bFound)
01962             {
01963                 BoundingRectangle = cbmp.GetCachedRect();
01964                 IsBoundingRectValid = TRUE;
01965                 return BoundingRectangle;
01966             }
01967         }
01968     }
01969 
01970     // If we get here, we don't know what the bounds of the effect bitmap
01971     // or what they might be...
01972     // Make a best guess using previous knowledge if we have it
01973     //      m_rectEstimatedBounds
01974     //      m_lMaxBorder
01975     // and factor in an arbitrary border to allow the effect to create
01976     // a bigger bitmap than the original data.
01977     //
01978     DocRect brect = GetChildBoundingRect(bIncludeAttrs);                // Note - don't set IsBoundingRectValid yet
01979 
01980     if (bIncludeAttrs)
01981     {
01982         brect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
01983 
01984         // Inflate by the previously known border width
01985         brect.Inflate((INT32)m_lMaxBorder);
01986 
01987         // NOTE! There's a possible optimisation to be had here:
01988         // If the border is known (not just default value) and is zero then we know that
01989         // the effect will not spread the bounds and so we don't need to expand the bounds
01990         // by 50 pixels to cope with it!
01991         //
01992         // Expand bounds to account for as yet unknown size increases that effects might apply
01993         brect.Inflate((INT32)GetPixelWidth()*50);
01994 
01995         // Include transformed bounds of last known bounding rect
01996         if (!m_rectEstimatedBounds.IsEmpty())
01997             brect = brect.Union(m_rectEstimatedBounds);
01998     }
01999 
02000     return brect;
02001 }

KernelBitmap * NodeLiveEffect::GetKernelBitmap DocCoord pCoords,
BOOL  bRetainCached = FALSE
[virtual]
 

Allows a bitmap effect to create a permanent kernel bitmap version of itself.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/02/2005
Parameters:
bRetainCached - TRUE to retain the cached version when making the permanent bitmap [INPUTS]
pCoords - Array of coords filled in with 3 points defining parallelogram [OUTPUTS]
Returns:
Pointer to new KernelBitmap
See also:
-

Reimplemented from NodeBitmapEffect.

Definition at line 2733 of file nodeliveeffect.cpp.

02734 {
02735     // Get bitmap out of cache (hope it's still in there!)
02736     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02737     CBitmapCacheKey inky(this, GetPixelWidth(), 1);                     // Get cached BMP for this PROCESSED node at our dpi
02738     CCachedBitmap cbmp;
02739     BOOL bFoundCached = pBitmapCache->Lookup(inky, cbmp);
02740     if (!bFoundCached)
02741         return NULL;
02742 
02743     CWxBitmap          *wBitmap     = new CWxBitmap(cbmp.pbmpInfo, cbmp.pbmpBits);
02744     if (wBitmap==NULL)
02745         return NULL;
02746 
02747     wBitmap->SetHidden(TRUE);                                           // We don't want the user to see this bitmap in the gallery
02748     KernelBitmap* kBitmap   = new KernelBitmap(wBitmap);
02749     if (kBitmap==NULL)
02750     {
02751         delete wBitmap;
02752         return NULL;
02753     }
02754     Document* pDoc = Document::GetCurrent();
02755     BitmapList* pBmpList = pDoc->GetBitmapList();
02756     kBitmap->Attach(pBmpList);
02757 PORTNOTE("xpe", "NodeLiveEffect::GetKernelBitmap - removed use of XPE")
02758 #if !defined(EXCLUDE_FROM_XARALX)
02759     XPEHost::GetEffectDetails(m_strPostProID, &m_strDisplayName);
02760 #endif
02761     String_256 name(m_strDisplayName);
02762     kBitmap->SetName(name);
02763 
02764     if (pCoords)
02765     {
02766         pCoords[0] = cbmp.coord0;
02767         pCoords[1] = cbmp.coord1;
02768         pCoords[2] = cbmp.coord2;
02769     }
02770 
02771     if (!bRetainCached)
02772         pBitmapCache->RemoveBitmap(inky);
02773 
02774     return kBitmap;
02775 }

UINT32 NodeLiveEffect::GetNodeSize  )  const [virtual]
 

For finding the size of the node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/09/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The size of the node in bytes
See also:
Node::GetSubtreeSize

Reimplemented from Node.

Reimplemented in NodeFeatherEffect.

Definition at line 2422 of file nodeliveeffect.cpp.

02423 {     
02424     return sizeof(NodeLiveEffect);
02425 }  

BOOL NodeLiveEffect::GetProcessedBitmap BOOL  bDirect,
LPBITMAPINFO plpInfo,
LPBYTE plpBits,
DocRect pRect
[virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/09/2004
Parameters:
bDirect - TRUE to get bounding rect in DirectBitmap space [INPUTS] FALSE to get bounding rect in Drawing space
plpInfo - pointer to LPBITMAPINFO pointer to be written to for bitmap info [OUTPUTS] plpBits - pointer to LPBYTE pointer to be written to for bitmap data pRect - pointer to DocRect describing bitmap bounds

Reimplemented from NodeBitmapEffect.

Definition at line 2124 of file nodeliveeffect.cpp.

02125 {
02126     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02127     if (pBitmapCache==NULL)
02128         return FALSE;
02129 
02130     CBitmapCacheKey inky(this, GetPixelWidth(), 1);                     // Get cached BMP for this node at our dpi
02131 
02132     // Look for a cached bitmap at the appropriate pixel size...
02133     CCachedBitmap       cbmp;
02134     BOOL                bFound = pBitmapCache->Lookup(inky, cbmp);
02135     if (bFound)
02136     {
02137         if (plpInfo)
02138             *plpInfo = cbmp.pbmpInfo;
02139         if (plpBits)
02140             *plpBits = cbmp.pbmpBits;
02141         if (pRect)
02142         {
02143             if (bDirect)
02144                 *pRect = m_rectDirectBitmap;
02145             else
02146                 *pRect = cbmp.GetCachedRect();
02147         }
02148         return TRUE;
02149     }
02150 
02151     if (plpInfo)
02152         *plpInfo = NULL;
02153     if (plpBits)
02154         *plpBits = NULL;
02155 
02156     return FALSE;
02157 }

virtual BOOL NodeLiveEffect::IsLockedEffect  )  [inline, virtual]
 

Reimplemented from NodeBitmapEffect.

Definition at line 345 of file nodeliveeffect.h.

00345 {return FALSE;}

void NodeLiveEffect::PolyCopyNodeContents NodeRenderable pNodeCopy  )  [virtual]
 

Polymorphically copies the contents of this node to another.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/09/2004
Parameters:
- [OUTPUTS]
Returns:
Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected

Reimplemented from NodeEffect.

Reimplemented in NodeFeatherEffect.

Definition at line 2395 of file nodeliveeffect.cpp.

02396 {
02397     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
02398     ENSURE(IS_A(pNodeCopy, NodeLiveEffect), "PolyCopyNodeContents given wrong dest node type");
02399 
02400     if (IS_A(pNodeCopy, NodeLiveEffect))
02401         CopyNodeContents((NodeLiveEffect*)pNodeCopy);
02402 }

virtual BOOL NodeLiveEffect::PromoteHitTestOnChildrenToMe  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 329 of file nodeliveeffect.h.

00329 {return FALSE;}     // FALSE if normal effect

BOOL NodeLiveEffect::ReleaseCached BOOL  bAndParents = TRUE,
BOOL  bAndChildren = TRUE,
BOOL  bSelf = TRUE,
BOOL  bAndDerived = TRUE
[virtual]
 

Protected Helper function Use the CaptureManager to capture the results of rendering, cache them and associate them with this Ink node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/06/2004
Returns:
TRUE if captured data was cached
See also:
NodeRenderableInk::RenderCached, CaptureCached

Reimplemented from NodeRenderableBounded.

Definition at line 2537 of file nodeliveeffect.cpp.

02538 {
02539     // Don't release cached data if the release request is the result of transformation
02540     // re-rendering because we can transform our cached data!
02541     if (!IsDragged())
02542     {
02543         CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02544         if (pBitmapCache!=NULL && bSelf)
02545         {
02546             CBitmapCacheKey inky(this, 42);
02547             pBitmapCache->RemoveAllOwnedBitmaps(inky, FALSE, CACHEPRIORITY_PERMANENT);
02548             m_rectDirectBitmap = DocRect(0,0,0,0);
02549         }
02550     }
02551 
02552     // If we should release our children's caches as well...
02553     if (bAndChildren)
02554     {
02555         Node* pChild = FindFirstChild();
02556         while (pChild)
02557         {
02558             if (pChild->IsBounded())
02559                 ((NodeRenderableBounded*)pChild)->ReleaseCached(FALSE, TRUE, TRUE, TRUE);
02560 
02561             pChild = pChild->FindNext();
02562         }
02563     }
02564 
02565     // If I can't be cached, neither can my parent...
02566     if (bAndParents && FindParent() && FindParent()->IsBounded())
02567         ((NodeRenderableBounded*)FindParent())->ReleaseCached(TRUE, FALSE, TRUE, TRUE);
02568 
02569     return TRUE;
02570 }

void NodeLiveEffect::RemoveBitmapFromCache  ) 
 

Remove the bitmap from the cache but don't vape the bitmap itself from memory.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/06/2005
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
See also:
-

Definition at line 2794 of file nodeliveeffect.cpp.

02795 {
02796     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02797     CBitmapCacheKey inky(this, GetPixelWidth(), 1);         // Get cached BMP for this PROCESSED node at our dpi
02798     pBitmapCache->RemoveBitmap(inky);
02799 }

SubtreeRenderState NodeLiveEffect::RenderSubtree RenderRegion pRender,
Node **  ppNextNode = NULL,
BOOL  bClip = TRUE
[virtual]
 

Do clever stuff on the way into a subtree, possibly modifying rendering behaviour.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/09/2004
Parameters:
pRender - The region render into (or use as context for decisions about subtree) [INPUTS] ppNextNode - Address of node pointer for next node to render or run to after this bClip - flag indicating whether to clip or not

Reimplemented from NodeEffect.

Definition at line 2020 of file nodeliveeffect.cpp.

02021 {
02022     BOOL bRendered = FALSE;
02023 
02024     if (pRender == NULL)                            // If no render region supplied, assume we need to be rendered
02025         return SUBTREE_ROOTANDCHILDREN;
02026 
02027     // Let children render themselves directly if we're not showing filled paths so the user can
02028     // see their outlines
02029     if (pRender->RRQuality.GetFillQuality() <= Quality::Solid)
02030         return SUBTREE_ROOTANDCHILDREN;
02031 
02032     // Live effects need to be rendered in the complex bitmap stages of printing
02033     if (pRender->IsKindOf(CC_RUNTIME_CLASS(ScanningRenderRegion)))
02034     {
02035         ScanningRenderRegion* pScanner = (ScanningRenderRegion*)pRender;
02036         pScanner->ComplexShapeFoundWrapper();
02037         return SUBTREE_NORENDER;    // Don't render any of our children
02038     }
02039 
02040     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02041     if (pBitmapCache==NULL)
02042         return SUBTREE_NORENDER;
02043 
02044     // Find out whether we have a cached processed bitmap for this node...
02045     BOOL bFoundCached = FindCachedEffect(pBitmapCache);
02046 
02047     // Go find out about my bounding rectangle
02048     // If we don't have a cached bitmap then expand the bounding rect to ensure it will cover an expansion caused by the effect
02049     // If we do have a cached bitmap then use the bounding rect stored with the processed bitmap
02050     DocRect BoundingRect = GetBoundingRect();
02051     if (!BoundingRect.IsValid())
02052         return SUBTREE_ROOTANDCHILDREN;
02053 
02054     if (!bFoundCached)
02055         BoundingRect.Inflate((INT32)(GetPixelWidth()*150));     // Bodge to ensure LE is rendered before it grows
02056     DocRect ClipRect = pRender->GetClipRect();
02057 
02058     if (bClip && !ClipRect.IsIntersectedWith(BoundingRect))     // If not within the clipping rect then
02059         return SUBTREE_NORENDER;                                // Don't render us or our children
02060 
02061     // No need to check BackmostChanged node here because we never capture
02062     // our background in a 24BPP bitmap we always capture at 32BPP using cfLOCKEDTRANSPARENT
02063 
02064     // Now ask our derived classes to render what they need to render
02065     bRendered = RenderCachedEffect(pBitmapCache, pRender);
02066 
02067     if (bRendered)
02068         return SUBTREE_NORENDER;
02069 
02070     // If this region is "immediate rendering" then we should always render
02071     // Else try to avoid rendering to keep the user experience smooth...
02072     if (!pRender->GetImmediateRender())
02073     {
02074         // Any sort of drag prevents new cacheing (to keep drags running smoothly)
02075         if (GetQuickRender())
02076             return SUBTREE_ROOTANDCHILDREN;
02077 
02078         // XPE editing op can prevent new cacheing (to keep XPE edits running smoothly)
02079 PORTNOTE("xpe", "NodeLiveEffect::RenderSubtree - removed use of XPE")
02080 #if !defined(EXCLUDE_FROM_XARALX)
02081         if (!XPEHost::EnableLERendering(this))
02082             return SUBTREE_ROOTANDCHILDREN;                         // But allow children to render
02083 #endif
02084     }
02085 
02086     // If we couldn't find or render a cached bitmap then try to cache a new one
02087     // Only cache if it's worth it!
02088     if (CanGenerateBitmap())
02089     {
02090         DocRect CaptureRect = GetChildBoundingRect();           // Make sure we get our child bound not result of processing!
02091         CaptureRect.Inflate(CAPTURE_BORDER*(INT32)GetPixelWidth());
02092 
02093         // If child node can supply a bitmap directly then we'll have it!
02094         // Note that RenderAfterSubtree will only do anything if it finds this capture
02095         // (This is crucial because RenderCallback filtering might prevent RenderSubtree being
02096         //  called but it does not then also prevent RenderAfterSubtree being called for the
02097         //  same node)
02098         CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfFULLCOVERAGE | cfUNCLIP | (EnableDirectCapture() ? cfALLOWDIRECT : cfNONE));
02099         double dResolution = GetPixelsPerInch();
02100         //Capture* pCapture =
02101         pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, dResolution, GetInkNodeFromController());
02102 //      if (pCapture && pCapture->IsDirect())
02103 //          return SUBTREE_ROOTONLY;                            // Capture gets bitmap directly from child so child does not need to be rendered
02104     }
02105 
02106     return SUBTREE_ROOTANDCHILDREN;                             // We must render ourselves and our children
02107 }

DocRect NodeLiveEffect::SetProcessedBitmap LPBITMAPINFO  lpInfo,
LPBYTE  lpBits,
DocRect  rect,
INT32  width,
INT32  height,
double  xOffset,
double  yOffset,
double  dPixelWidth = 0,
Matrix pmatTransform = NULL
[virtual]
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/09/2004
Parameters:
- [INPUTS]
lpInfo - reference to LPBITMAPINFO pointer for bitmap info [OUTPUTS] lpBits - reference to LPBYTE pointer for bitmap data

Reimplemented from NodeBitmapEffect.

Definition at line 2175 of file nodeliveeffect.cpp.

02176 {
02177     BOOL bWasInvalidBounds = !IsBoundingRectValid;
02178     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02179     if (pBitmapCache==NULL)
02180         return rect;
02181 
02182     if (dPixelWidth==0)
02183         dPixelWidth = GetPixelWidth();
02184 
02185     if (rect.IsEmpty())
02186     {
02187         rect = GetChildBoundingRect();
02188         rect.Inflate(CAPTURE_BORDER*(INT32)dPixelWidth);
02189     }
02190 
02191     CBitmapCacheKey inky(this, dPixelWidth, 1);                     // Get cached BMP for this node at our dpi
02192     DocRect crect = AdjustPixelOffsets(rect, width, height, xOffset, yOffset, dPixelWidth);
02193     DocRect uprect = crect;
02194 
02195     // If we have a transform, then we must transform our coords before rendering
02196     DocCoord coords[3];
02197     coords[0] = crect.lo;
02198     coords[1] = DocCoord(crect.hi.x, crect.lo.y);
02199     coords[2] = DocCoord(crect.lo.x, crect.hi.y);
02200     if (pmatTransform)
02201         pmatTransform->transform(coords, 3);
02202 
02203     // Deallocate any cached DIB here
02204     CCachedBitmap cbmp;
02205     BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
02206     if (bFound)
02207     {
02208         pBitmapCache->RemoveBitmap(inky);
02209         cbmp.Release();
02210         m_rectDirectBitmap = DocRect(0,0,0,0);
02211     }
02212 
02213     if (lpInfo!=NULL && lpBits!=NULL)
02214     {
02215         cbmp.pbmpInfo = lpInfo;
02216         cbmp.pbmpBits = lpBits;
02217 //      cbmp.SetCachedRect(crect);
02218         cbmp.SetCachedParallelogram(coords, 3);
02219         cbmp.nPriority = CACHEPRIORITY_PERMANENT;
02220 
02221         pBitmapCache->StoreBitmap(inky, cbmp);
02222 
02223         m_rectDirectBitmap = crect;         // "Cache" rectangle in DirectBitmap space for GetProcessedBitmap
02224 
02225         uprect = cbmp.GetCachedRect();
02226 
02227         IsBoundingRectValid = TRUE;         // URGH! Force InvalidateBoundingRect to go up parent links!
02228         InvalidateBoundingRect();           // Tell our parents that our bounds have changed
02229         BoundingRectangle = uprect;         // But we know our bounding rectangle now
02230         IsBoundingRectValid = TRUE;         // And we know that it's valid
02231 
02232         // Store some data about the bounds while we know it
02233         m_rectEstimatedBounds = uprect;
02234 
02235         // Store max border created by this effect so we can redraw correctly after scaling
02236         // rect is in DirectBitmap space, crect is in Drawing space, so we must get a version of rect
02237         // in Drawing space before we can compare the two rects to get m_lMaxBorder measured in
02238         // Drawing space dimensions...
02239         //
02240         // Transform rect into Drawing space...
02241         DocCoord OrigCoords[4];
02242         OrigCoords[0] = rect.lo;
02243         OrigCoords[1] = DocCoord(rect.lo.x, rect.hi.y);
02244         OrigCoords[2] = DocCoord(rect.hi.x, rect.lo.y);
02245         OrigCoords[3] = rect.hi;
02246         if (pmatTransform)
02247             pmatTransform->transform(OrigCoords, 4);
02248         // Form upright rect enclosing transformed coords...
02249         DocRect OrigRect(OrigCoords[0], OrigCoords[0]);
02250         OrigRect.IncludePoint(OrigCoords[1]);
02251         OrigRect.IncludePoint(OrigCoords[2]);
02252         OrigRect.IncludePoint(OrigCoords[3]);
02253         // Compare upright original rect against new upright rect to find max offset in Drawing space...
02254         m_lMaxBorder = max(OrigRect.lo.x-uprect.lo.x, OrigRect.lo.y-uprect.lo.y);
02255         m_lMaxBorder = max(uprect.hi.x-OrigRect.hi.x, m_lMaxBorder);
02256         m_lMaxBorder = max(uprect.hi.y-OrigRect.hi.y, m_lMaxBorder);
02257         // Safety check
02258         if ( !Error::IsUserName("Gavin") )
02259             ERROR3IF(m_lMaxBorder<0, "m_lMaxBorder has become negative!");
02260         m_lMaxBorder = 0;
02261 
02262         // If the processed bitmap is bigger than the original we must ensure the bounds are updated
02263         // (Compare two rects in DirectBitmap space)
02264         if (rect!=crect || bWasInvalidBounds)
02265         {
02266             DocView* pView = DocView::GetCurrent();
02267             if (pView)
02268                 pView->NotifyBoundsChanged();
02269         }
02270     }
02271 
02272     // Note! Leave bounds alone if setting processed bitmap to NULL in the hope they will persist...
02273     return uprect;
02274 }

virtual BOOL NodeLiveEffect::ShouldITransformWithChildren  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 330 of file nodeliveeffect.h.

00330 {return TRUE;}

Node * NodeLiveEffect::SimpleCopy void   )  [virtual]
 

This method returns a shallow copy of the node with all Node pointers NULL. The function is virtual, and must be defined for all derived classes.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/09/2004
Parameters:
- [INPUTS]
[OUTPUTS] 
Returns:
A copy of the node, or NULL if memory has run out

Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory error and the function returns NULL.

Reimplemented from NodeEffect.

Reimplemented in NodeFeatherEffect.

Definition at line 2327 of file nodeliveeffect.cpp.

02328 {
02329     NodeLiveEffect* NodeCopy; 
02330     NodeCopy = new NodeLiveEffect();
02331     ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); 
02332     CopyNodeContents(NodeCopy);         
02333     return (NodeCopy);
02334 }   

void NodeLiveEffect::Transform TransformBase Trans  )  [virtual]
 

Transforms the LiveEffect node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/09/2004
Parameters:
Trans - The transform Object [INPUTS]
See also:
NodeRenderableInk::Transform()

Reimplemented from NodeRenderableBounded.

Definition at line 2442 of file nodeliveeffect.cpp.

02443 {
02444     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
02445     ERROR3IF(pBitmapCache==NULL, "Can't find BitmapCache");
02446 
02447     // Transform the cached bitmaps
02448     CCachedBitmap cbmp;
02449     CBitmapCacheKey inky(this, GetPixelWidth(), 0);                     // Get cached BMP for this ORIGINAL node at our dpi
02450     BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
02451     if (bFound)
02452     {
02453         cbmp.Transform(Trans);
02454         pBitmapCache->StoreBitmap(inky, cbmp);
02455     }
02456 
02457     CBitmapCacheKey inky1(this, GetPixelWidth(), 1);                    // Get cached BMP for this PROCESSED node at our dpi
02458     bFound = pBitmapCache->Lookup(inky1, cbmp);
02459     if (bFound)
02460     {
02461         cbmp.Transform(Trans);
02462         pBitmapCache->StoreBitmap(inky1, cbmp);
02463     }
02464     else
02465     {
02466         Trans.bHaveTransformedCached = FALSE;
02467         Trans.bTransformYourChildren = TRUE;
02468     }
02469 
02470     // No need to transform Option 2, processed/rendered bitmap because it is only
02471     // an intermediate stage for producing other cached bitmaps
02472     // and exists outside the drawing geometry domain anyway
02473 
02474     // Transform the estimated bounds
02475     DocCoord t[3];
02476     t[0] = m_rectEstimatedBounds.lo;
02477     t[1] = DocCoord(m_rectEstimatedBounds.hi.x, m_rectEstimatedBounds.lo.y);
02478     t[2] = DocCoord(m_rectEstimatedBounds.lo.x, m_rectEstimatedBounds.hi.y);
02479 
02480     Trans.Transform(t, 3);
02481 
02482     m_rectEstimatedBounds = DocRect(t[0], t[0]);
02483     m_rectEstimatedBounds.IncludePoint(t[1]);
02484     m_rectEstimatedBounds.IncludePoint(t[2]);
02485     m_rectEstimatedBounds.IncludePoint(DocCoord(t[2].x+t[1].x-t[0].x, t[2].y+t[1].y-t[0].y));
02486 
02487     // Note that we don't scale the m_lMaxBorder field here so that, if m_rectEstimatedBounds
02488     // gets smaller, m_lMaxBorder won't and will generate a better guess at the resulting
02489     // bounds in GetBoundingRect
02490 
02491     InvalidateBoundingRect();
02492 
02493     // Preserve current state of transformed cache flag
02494     BOOL bTransCache = Trans.bHaveTransformedCached;
02495 
02496     // Transform all the children...
02497     // No need to transfom children if we are being dragged and we have successfully transformed our cached bitmap
02498 //  if (!(IsDragged() && bFound))
02499     if (Trans.bTransformYourChildren)
02500         TransformChildren(Trans);
02501     else
02502     {
02503         TransformEffectAttrs(Trans);
02504         Trans.bHaveTransformedChildren = FALSE;
02505     }
02506 
02507     // If the current transform is a translation then we have successfully
02508     // transformed our cached info so don't allow our children to modify the state of
02509     // bHaveTransformedCached
02510     Trans.bHaveTransformedCached = bTransCache;
02511 //  if (bTransCache && Trans.IsTranslation())
02512 //  {
02513 //      Trans.bHaveTransformedCached = TRUE;
02514 //  } 
02515 }

BOOL NodeLiveEffect::WriteLiveEffect BaseCamelotFilter pFilter  )  [protected, virtual]
 

Writes the path record to the filter.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/09/2004
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Definition at line 2647 of file nodeliveeffect.cpp.

02648 {
02649 #ifdef DO_EXPORT
02650     ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
02651 
02652     BOOL ok = TRUE;
02653     BYTE Flags = 0;
02654 
02655     UINT32 Tag = TAG_LIVE_EFFECT;
02656 
02657     CXaraFileRecord Rec(Tag);
02658 
02659 PORTNOTETRACE("other","NodeLiveEffect::WriteLiveEffect - removed use of XML");
02660 #ifndef EXCLUDE_FROM_XARALX
02661     BSTR bstrValue;
02662     HRESULT hr;
02663     hr = m_pEditsDoc->get_xml(&bstrValue);
02664     ok = (SUCCEEDED(hr));
02665 #endif
02666     if (ok) ok = Rec.Init();
02667     if (ok) ok = Rec.WriteBYTE(Flags);                  // flags
02668     if (ok) ok = Rec.WriteDOUBLE(m_dPixelsPerInch);     // Resolution
02669     if (ok) ok = Rec.WriteUnicode(m_strPostProID);      // Effect ID
02670     if (ok) ok = Rec.WriteUnicode(m_strDisplayName);    // Display Name
02671     if (ok) ok = Rec.WriteUTF16STR(m_vstrEdits);        // UNICODE xml string edits list
02672 
02673     // Write the record
02674     if (ok) ok = pFilter->Write(&Rec);
02675 
02676     return ok;
02677 #else
02678     return FALSE;
02679 #endif
02680 }

BOOL NodeLiveEffect::WritePreChildrenNative BaseCamelotFilter pFilter  )  [virtual]
 

Writes the path record to the filter.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/09/2004
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Reimplemented from Node.

Reimplemented in NodeFeatherEffect.

Definition at line 2616 of file nodeliveeffect.cpp.

02617 {
02618 #ifdef DO_EXPORT
02619 
02620     BOOL ok = TRUE;
02621 
02622     ok = WriteLiveEffect(pFilter);
02623 
02624     return ok;
02625 
02626 #else
02627     return FALSE;
02628 #endif
02629 }

BOOL NodeLiveEffect::WritePreChildrenWeb BaseCamelotFilter pFilter  )  [virtual]
 

Writes the path record to the filter.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/09/2004
Parameters:
pFilter = ptr to the filter [INPUTS]
Returns:
TRUE if record is written, FALSE if not
See also:
-

Reimplemented from Node.

Reimplemented in NodeFeatherEffect.

Definition at line 2588 of file nodeliveeffect.cpp.

02589 {
02590 #ifdef DO_EXPORT
02591 
02592     BOOL ok = TRUE;
02593 
02594     ok = WriteLiveEffect(pFilter);
02595 
02596     return ok;
02597 
02598 #else
02599     return FALSE;
02600 #endif
02601 }


Friends And Related Function Documentation

friend class LiveEffectRecordHandler [friend]
 

Reimplemented from NodeBitmapEffect.

Reimplemented in NodeFeatherEffect.

Definition at line 298 of file nodeliveeffect.h.


Member Data Documentation

MILLIPOINT NodeLiveEffect::m_lMaxBorder [private]
 

Definition at line 357 of file nodeliveeffect.h.

DocRect NodeLiveEffect::m_rectEstimatedBounds [private]
 

Definition at line 356 of file nodeliveeffect.h.


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