NodeGroup Class Reference

Group Node. More...

#include <group.h>

Inheritance diagram for NodeGroup:

NodeCompound NodeRenderableInk NodeRenderableBounded NodeRenderable Node CCObject SimpleCCObject NodeBlend NodeBrush NodeClipViewController NodeContourController NodeMould NodeMoulder NodeMouldGroup List of all members.

Public Member Functions

 NodeGroup ()
 This constructor creates a NodeGroup linked to no other, with all status flags false and an uninitialised bounding rectangle.
 NodeGroup (Node *ContextNode, AttachNodeDirection Direction, BOOL Locked=FALSE, BOOL Mangled=FALSE, BOOL Marked=FALSE, BOOL Selected=FALSE)
 This method initialises the node and links it to ContextNode in the direction specified by Direction. All necessary tree links are updated.
virtual BOOL IsAGroup () const
virtual DocRect GetBoundingRect (BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
 If the groups bounding rect is known then it is returned. If not, it is re-calculated.
virtual DocRect GetBlobBoundingRect ()
 Finds the bounding rect of the group along with its blobs. Its main use is to determine which areas of the document to invalidate.
virtual DocRect GetEorDragBoundingRect ()
 Gets the eor drag bounding rect for all my children.
virtual void Transform (TransformBase &)
 Transforms the group object and all its children.
virtual void PreExportRender (RenderRegion *pRender)
 Perform any rendering required when exporting to a file, and this node is being 'passed by' during the tree searching. For example, a group node being exported to EPS would output a "start group" token, and then its ExportRender function would output a "end group" token. By default, it does nothing. Nodes wishing to do special export processing should override this function (and ExportRender).
virtual BOOL ExportRender (RenderRegion *pRender)
 Custom export code for nodes derived from NodeRenderableInk. So far there is only code for the VectorFileRenderRegion (which is a superclass for the EPS, CMX, and Flash render regions) to allow for the export of stroked shapes.
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 void RenderAfterSubtree (RenderRegion *pRender)
 For determining quickly if the node is a compound object Capture the group as a cached bitmap.
virtual void RenderObjectBlobs (RenderRegion *pRender)
 Will render the group iff we have it cached - for hit detection reasonsRenders the object blobs.
virtual void RenderTinyBlobs (RenderRegion *pRender)
 Renders the tiny blobs for a group (A Single blob on the topmost child object in the group).
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.
void CopyNodeContents (NodeGroup *NodeCopy)
 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.
virtual void PolyCopyNodeContents (NodeRenderable *pNodeCopy)
 Polymorphically copies the contents of this node to another.
virtual UINT32 GetNodeSize () const
 This method outputs a 'deep' copy of the node. It is the same as CopyNode except that the copy is not linked into the tree. Override if your class can interpret the lightweight flagFor finding the size of the node.
virtual ChangeCode OnChildChange (ObjChangeParam *pParam)
 This function should be overridden in derived object classes. Composite objects can use this function to respond to one of their children undergoing a change. They should return CC_FAIL whenever they are unable to cope with the change.
virtual BOOL OnClick (DocCoord, ClickType, ClickModifiers, Spread *)
 Determines if the user has started a drag on one of the groups blobs. If they have then it starts the groups resize operation.
virtual BOOL WritePreChildrenWeb (BaseCamelotFilter *pFilter)
 Writes the group record to the filter.
virtual BOOL WritePreChildrenNative (BaseCamelotFilter *pFilter)
virtual BOOL WriteBoundsRecord (BaseCamelotFilter *pFilter)
 Write out a record containing the bounds of this object.
virtual BOOL WillWriteBounds (BaseCamelotFilter *pFilter)
 Determines if the down/up pair need to be written.
virtual BOOL AreYouSafeToRender ()
 Begin to write out your child records, in the native formatBegin to write out you child records, in the native formatGroup nodes are always safe to render, but derived group nodes (such as blends and text, etc) are not safe until their post import functions have been called.
virtual BOOL RenderTight (RenderRegion *pRender)
 Protected Helper function Allow this node to render itself using cached data if it has it and for that cached data to represent an arbitrary section of the document (usually a subtree but can be more).
virtual BOOL CaptureTight (RenderRegion *pRender)
 Protected Helper function Use the CaptureManager to capture the results of rendering, cache them and associate them with this Ink node.
virtual double GetTightGroupPixelsPerInch (RenderRegion *pRender=NULL) const
 Get width of pixels for use in capturing this group as a tight group bitmap.
virtual double GetTightGroupPixelWidth (RenderRegion *pRender=NULL) const
virtual void TransformTight (TransformBase &Trans, double dTestPixelWidth)
 Transform all the cached bitmaps associated with this node.
virtual BOOL IsValidEffectAttr (NodeAttribute *pAttr) const
 Get width of pixels for use in capturing this group as a tight group bitmapDetermine whether this type of attribute can be an effect attribute On this node at this time.Determine whether this attribute instance can be an effect attribute On this node at this time.
virtual BOOL GroupCanTransformCached (TransformBase &Trans) const

Detailed Description

Group Node.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/93

Definition at line 122 of file group.h.


Constructor & Destructor Documentation

NodeGroup::NodeGroup  ) 
 

This constructor creates a NodeGroup linked to no other, with all status flags false and an uninitialised bounding rectangle.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/5/93
Parameters:
- [INPUTS]
[OUTPUTS] 
Returns:
-

Errors:

Definition at line 164 of file group.cpp.

00164                     : NodeCompound()
00165 {
00166     blenderNode = NULL;
00167 }

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

This method initialises the node and links it to ContextNode in the direction specified by Direction. All necessary tree links are updated.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/10/93
Parameters:
ContextNode,: Pointer to a node which this node is to be attached to. [INPUTS]
Direction:

Specifies the direction in which this 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

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 ?

Parameters:
- [OUTPUTS]
Returns:
-

Errors: An assertion error will occur if ContextNode is NULL

Definition at line 214 of file group.cpp.

00220                 :NodeCompound(ContextNode, Direction, Locked, Mangled, Marked, 
00221                 Selected) 
00222 {
00223     blenderNode = NULL;
00224 } 


Member Function Documentation

BOOL NodeGroup::AreYouSafeToRender  )  [virtual]
 

Begin to write out your child records, in the native formatBegin to write out you child records, in the native formatGroup nodes are always safe to render, but derived group nodes (such as blends and text, etc) are not safe until their post import functions have been called.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/9/96
Parameters:
- [INPUTS]
Returns:
TRUE if safe to render, FALSE otherwise
See also:
-

Reimplemented from NodeRenderableInk.

Definition at line 1842 of file group.cpp.

01843 {
01844     if (IS_A(this,NodeGroup))
01845         return TRUE;
01846     else
01847         return NodeRenderableInk::AreYouSafeToRender();
01848 }

BOOL NodeGroup::CaptureTight RenderRegion pRender  )  [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:
11/01/2005
Returns:
TRUE if captured data was cached
See also:
NodeRenderableBounded::RenderCached

Definition at line 525 of file group.cpp.

00526 {
00527     // If the caller wants his bitmap to respond to Effect Attributes
00528     // Then we have to behave quite differently than a normal cache/capture sequence
00529     // We must grab the bitmap regardless of the cache-enabling flag
00530     // We must grab at a controlled resolution
00531     // We must grab the whole thing
00532     // We must grab at 32BPP RGBT
00533     Capture* pCapture = pRender->GetTopCapture();
00534     if (pCapture==NULL)                                         // If nothing was captured
00535         return FALSE;                                           // Then do nothing
00536 
00537     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00538     if (pBitmapCache==NULL)
00539     {
00540         return FALSE;
00541     }
00542 
00543 //  ERROR3IF(IsDragged() || m_bCachedBitmapShared, "CaptureTight asked to capture when its dragged");
00544 //  ERROR3IF(IsDragged(), "CaptureTight asked to capture when its dragged");
00545 
00546     // Only stop the capture if we started it
00547     // (means we only capture whole subtrees at the mo.)
00548     BOOL bCached = FALSE;
00549     if (pCapture->GetOwner()==this)
00550     {
00551         // End this capture:
00552         // Blit capture to screen
00553         // Retain bitmap because we will release it ourselves onyl if we fail to cache it
00554         LPBITMAPINFO lpInfo = NULL;
00555         LPBYTE lpBits = NULL;
00556         DocRect CaptureRect = GetBoundingRect();                // Set maximum size we allow
00557         BOOL bFullCoverage = pCapture->HasFullCoverage();
00558         pRender->StopCapture(this, FALSE, FALSE, &lpInfo, &lpBits, &CaptureRect);
00559 
00560         // If the capture gave us back a bitmap, try to cache it
00561         if (lpInfo && lpBits && CaptureRect.IsValid())
00562         {
00563 //TRACEUSER("Phil", _T("Ending TightGroup Capture SUCCEEDED %x, %f\n"), this, GetTightGroupPixelWidth(pRender));
00564             // Cache the ORIGINAL bitmap as Option 0
00565             // See also, SetOriginalBitmap
00566             double PixelWidth = GetTightGroupPixelWidth(pRender);
00567             CBitmapCacheKey inky(this, PixelWidth, 0);
00568 
00569             CCachedBitmap cbmp;
00570 
00571             cbmp.pbmpBits = lpBits;
00572             cbmp.pbmpInfo = lpInfo;
00573             cbmp.SetCachedRect(CaptureRect);
00574             cbmp.nPriority = CACHEPRIORITY_TEMPBITMAP_HIGH;
00575             cbmp.bFullCoverage = bFullCoverage;
00576 
00577             if ( cbmp.IsValid() 
00578                  && !pRender->IsKindOf(CC_RUNTIME_CLASS(PrintingMaskedRenderRegion))
00579                 )
00580             {
00581                 pBitmapCache->StoreBitmap(inky, cbmp);
00582                 MayBeCached = TRUE;
00583                 bCached = TRUE;
00584             }
00585 
00586             // Render the bitmap taking effect attrs into account...
00587             if (lpInfo && lpBits)
00588                 pRender->RenderBits(lpInfo, lpBits, CaptureRect, TRUE, this);
00589         }
00590 
00591         // If we failed to cache the captured bitmap then release it
00592         if (lpInfo!=NULL && lpBits!=NULL && !bCached)
00593         {
00594 //TRACEUSER("Phil", _T("Ending TightGroup Capture FAILED %x, %f\n"), this, GetTightGroupPixelWidth(pRender));
00595             FreeDIB(lpInfo, lpBits, NULL, FALSE);
00596         }
00597     }
00598 
00599     return bCached;
00600 }

void NodeGroup::CopyNodeContents NodeGroup 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.

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

Definition at line 1368 of file group.cpp.

01369 {
01370     NodeRenderableInk::CopyNodeContents(pCopyOfNode);
01371     pCopyOfNode->m_bBlendStartNode = m_bBlendStartNode;         // NodeController?
01372     pCopyOfNode->m_bBlendEndNode   = m_bBlendEndNode;               // NodeController?
01373     pCopyOfNode->m_pBlendCreatedByNode = m_pBlendCreatedByNode; // NodeController?
01374     CopyCached(pCopyOfNode);                            // Copy cached bitmaps
01375 }

String NodeGroup::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:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/6/93
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 NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1316 of file group.cpp.

01317 {     
01318     if (Plural)
01319         return(String(_R(IDS_GROUP_DESCRP)));  
01320     else
01321         return(String(_R(IDS_GROUP_DESCRS))); 
01322 }; 

BOOL NodeGroup::ExportRender RenderRegion pRegion  )  [virtual]
 

Custom export code for nodes derived from NodeRenderableInk. So far there is only code for the VectorFileRenderRegion (which is a superclass for the EPS, CMX, and Flash render regions) to allow for the export of stroked shapes.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/11/00
Parameters:
pRender - A pointer to the render region being used for the export. [INPUTS]
Returns:
TRUE - The node was exported using this function. FALSE - There is no custom export code for this node type.

Reimplemented from NodeRenderableInk.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeMoulder, and NodeMould.

Definition at line 251 of file group.cpp.

00252 {
00253 #ifdef DO_EXPORT
00254     if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
00255     {
00256         // Output "end group" token
00257         EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
00258         pDC->OutputToken(_T("U"));
00259         pDC->OutputNewLine();
00260         
00261         // Tell caller we rendered ourselves ok
00262         return TRUE;
00263     }
00264 PORTNOTE("cmx", "Removed use of CMXRenderRegion")
00265 #ifndef EXCLUDE_FROM_XARALX
00266     else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
00267     {
00268         // mark start of a group...
00269         CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
00270         pDC->EndGroup();
00271 
00272         return TRUE;
00273     }
00274 #endif
00275 #endif
00276     // Render thid node in the normal way
00277     return FALSE;
00278 }

DocRect NodeGroup::GetBlobBoundingRect  )  [virtual]
 

Finds the bounding rect of the group along with its blobs. Its main use is to determine which areas of the document to invalidate.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> (re-written)
Date:
29/6/95
Returns:
DocRect - The bounding rect of the group and its blobs

Reimplemented from NodeRenderable.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1248 of file group.cpp.

01249 {
01250     DocRect NewRect = DocRect(0,0,0,0);
01251 
01252 #if !defined(EXCLUDE_FROM_RALPH)
01253     // Find the Blob manager
01254     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
01255     if (pBlobMgr!= NULL)
01256     {
01257         BlobStyle VisibleBlobs = pBlobMgr->GetCurrentInterest(TRUE);
01258         if (VisibleBlobs.Object)
01259         {
01260             DocRect BoundingRect = GetBoundingRect();
01261 
01262             // Object blobs are visible, so include blob in each
01263             // corner of the group bounds
01264             DocRect BlobSize;
01265 
01266             // Find out where the blobs will be drawn
01267             DocCoord Low  = BoundingRect.LowCorner();
01268             DocCoord High = BoundingRect.HighCorner();
01269 
01270             // Include the object blob in each corner
01271             pBlobMgr->GetBlobRect(Low, &BlobSize);
01272             NewRect = NewRect.Union(BlobSize);
01273             pBlobMgr->GetBlobRect(High, &BlobSize);
01274             NewRect = NewRect.Union(BlobSize);
01275             pBlobMgr->GetBlobRect(DocCoord(Low.x, High.y), &BlobSize);
01276             NewRect = NewRect.Union(BlobSize);
01277             pBlobMgr->GetBlobRect(DocCoord(High.x, Low.y), &BlobSize);
01278             NewRect = NewRect.Union(BlobSize);
01279         }
01280     }
01281 
01282     Node* pNode=FindFirstChild();
01283     while (pNode!=NULL)
01284     {
01285         if (pNode->IsBounded())
01286             NewRect = NewRect.Union(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect());
01287         pNode = pNode->FindNext();
01288     }
01289 
01290     IncludeChildrensBoundingRects(&NewRect);
01291 #endif
01292     return NewRect;
01293 }

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

If the groups bounding rect is known then it is returned. If not, it is re-calculated.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/6/94
Parameters:
DontUseAttrs - TRUE if the attrs associated with the node should be [INPUTS] ignored. defaults to FALSE HitTest - TRUE if being called during HitTest
Returns:
The Groups bounding rect

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, and NodeMoulder.

Definition at line 1162 of file group.cpp.

01163 {
01164     if (!IsBoundingRectValid || DontUseAttrs)
01165     {
01166         // Optimisation:
01167         // If we're holding cached data that is a full representation of our children
01168         //  And we're being dragged
01169         //  And the bounding box should include attrs (the cached data includes attrs)
01170         //
01171         // Then we can avoid calling our children recursively to get their bounding
01172         // rectangles because the info is all contained in our cached data's bounding
01173         // rectangle.
01174         //
01175         if (MayBeCached && IsDragged() && !DontUseAttrs)
01176         {
01177             CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01178             CCachedBitmap cbmp;
01179             BOOL bFound = FALSE;
01180             if (HasEffectAttrs())
01181             {
01182                 CBitmapCacheKey inky(this, GetTightGroupPixelWidth());
01183                 bFound = pBitmapCache->Lookup(inky, cbmp);
01184                 bFound = bFound && cbmp.bFullCoverage;
01185             }
01186             else
01187             {
01188                 View* pCurrentView = View::GetCurrent();
01189                 if (pCurrentView)
01190                 {
01191                     // Note! View::GetScaledPixelWidth returns an unrounded fractional value where
01192                     // RenderRegion::GetScaledPixelWidth return a rounded integer!!!
01193                     CBitmapCacheKey inky(this, (MILLIPOINT)(pCurrentView->GetScaledPixelWidth().MakeDouble()+0.5));
01194                     bFound = pBitmapCache->Lookup(inky, cbmp);
01195                     bFound = bFound && cbmp.bFullCoverage;
01196                 }
01197             }
01198             if (bFound)
01199             {
01200                 BoundingRectangle = cbmp.GetCachedRect();
01201                 IsBoundingRectValid = TRUE;
01202                 return BoundingRectangle;
01203             }
01204         }
01205 
01206         // Find the groups first child
01207         DocRect NewRect(0,0,0,0);
01208         Node* pNode = FindFirstChild();
01209         
01210         while (pNode!=NULL)
01211         {
01212             // if this node is bounded, union its bounds with the others
01213             if (pNode->IsBounded())
01214                 NewRect = NewRect.Union(((NodeRenderableBounded*)pNode)->GetBoundingRect(DontUseAttrs));
01215 
01216             // Get the next node in the list
01217             pNode = pNode->FindNext();
01218         }
01219 
01220         if (DontUseAttrs)
01221         {
01222             // just return this rectangle as it is not the nodes true bounding rect
01223             return NewRect;
01224         }
01225 
01226         // copy the new docrect into the node bounding rect
01227         BoundingRectangle = NewRect;
01228 
01229         // Mark the bounding rect as valid
01230         IsBoundingRectValid = TRUE;
01231     }
01232 
01233     // Return the resulting bounding rect
01234     return BoundingRectangle;
01235 }

DocRect NodeGroup::GetEorDragBoundingRect  )  [virtual]
 

Gets the eor drag bounding rect for all my children.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/1/2000
Parameters:
None [INPUTS]
Returns:
The eor drag bounding rect for all of my children
See also:
-

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeClipViewController, and NodeMouldGroup.

Definition at line 1128 of file group.cpp.

01129 {
01130     Node * pChild = FindFirstChild();
01131 
01132     DocRect dr(0,0,0,0);
01133 
01134     while (pChild)
01135     {
01136         if (pChild->IsBounded())
01137         {
01138             dr = dr.Union(((NodeRenderableBounded *)pChild)->GetEorDragBoundingRect());
01139         }
01140 
01141         pChild = pChild->FindNext();
01142     }
01143 
01144     return dr;
01145 }

UINT32 NodeGroup::GetNodeSize  )  const [virtual]
 

This method outputs a 'deep' copy of the node. It is the same as CopyNode except that the copy is not linked into the tree. Override if your class can interpret the lightweight flagFor finding the size of the node.

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

Reimplemented from Node.

Reimplemented in NodeClipViewController, NodeMouldGroup, NodeBlend, NodeMoulder, and NodeMould.

Definition at line 1470 of file group.cpp.

01471 {     
01472     return (sizeof(NodeGroup)); 
01473 }  

double NodeGroup::GetTightGroupPixelsPerInch RenderRegion pRender = NULL  )  const [virtual]
 

Get width of pixels for use in capturing this group as a tight group bitmap.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/01/2005
Parameters:
- [INPUTS]
Returns:
pixel width for capturing

Definition at line 614 of file group.cpp.

00615 {
00616     double dPPI = 0.0;
00617 
00618     if (NodeBitmapEffect::GroupPixelsPerInch==0)
00619     {
00620         // 0 means automatic
00621         // Automatic means get resolution in context
00622         // Context means either respond to a fixed resolution above us in the tree
00623         // or get resolution from current view
00624         double dViewPPI = 96.0;
00625         double dViewScaledPPI = 96.0;
00626         if (pRender==NULL)
00627         {
00628             View* pView = View::GetCurrent();
00629             if (pView)
00630                 dViewPPI = 72000.0 / pView->GetPixelWidth().MakeDouble();
00631                 dViewScaledPPI = 72000.0 / pView->GetScaledPixelWidth().MakeDouble();
00632         }
00633         else
00634         {
00635             dViewPPI = pRender->GetPixelsPerInch();
00636             dViewScaledPPI = 72000.0 / pRender->GetScaledPixelWidth();
00637         }
00638 
00639         Node* pParent = this->FindParent();
00640         while (pParent && !pParent->IsLayer())
00641         {
00642             if (pParent->IsBitmapEffect())
00643             {
00644                 dPPI = ((NodeBitmapEffect*)pParent)->GetPixelsPerInchValue();
00645                 if (dPPI!=0)
00646                     break;
00647 
00648                 // If we found an effect at all then ensure we use default effect PPI
00649                 dPPI = dViewPPI;
00650             }
00651 
00652             pParent = pParent->FindParent();
00653         }
00654 
00655         // If we found no effects above us then try to operate at zoomed view res
00656         // for best results on screen.
00657         if (dPPI==0)
00658         {
00659             // See also OpEffectLock::DoEffectNodeOp
00660             // We should capture at at least 200dpi for printing
00661             // We should capture at a size that's at least as good as the current zoomed pixel size
00662             // (We rely on the capture being clipped to keep bitmap sizes under control at high zoom factors)
00663             // (We should reduce the resolution if the bitmap will be huge...)
00664             dPPI = dViewScaledPPI;
00665         }
00666     }
00667 
00668     // Try to limit bitmap size if dpi is getting large inside a wrapped
00669     // RenderRegion.
00670     // Without this restriction, tight groups inside shadows become a problem
00671     // because this function does not pick up the reduced resolution of the
00672     // offscreen render region used by the shadow to create its silhouette.
00673     if (pRender && pRender->IsWrappedRender() && dPPI>480)
00674     {
00675         dPPI = 480;
00676     }
00677 
00678     if (dPPI==0)
00679         dPPI = NodeBitmapEffect::GroupPixelsPerInch;
00680 
00681     if (dPPI==0)
00682     {
00683         // Shouldn't ever reach this clause but just in case...
00684         ERROR3("GetPixelsPerInch can't get sensible PPI so defaulting to 96");
00685         dPPI = 96.0;
00686     }
00687 
00688 TRACEUSER("Phil", _T("GTGPPI %f\n"), dPPI);
00689     return dPPI;
00690 }

virtual double NodeGroup::GetTightGroupPixelWidth RenderRegion pRender = NULL  )  const [inline, virtual]
 

Definition at line 184 of file group.h.

00184 {return 72000.0/GetTightGroupPixelsPerInch(pRender);}

virtual BOOL NodeGroup::GroupCanTransformCached TransformBase Trans  )  const [inline, virtual]
 

Reimplemented in NodeContourController, NodeClipViewController, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 189 of file group.h.

00189 {return TRUE;}

virtual BOOL NodeGroup::IsAGroup  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 139 of file group.h.

00139 { return TRUE; }

BOOL NodeGroup::IsValidEffectAttr NodeAttribute pAttr  )  const [virtual]
 

Get width of pixels for use in capturing this group as a tight group bitmapDetermine whether this type of attribute can be an effect attribute On this node at this time.Determine whether this attribute instance can be an effect attribute On this node at this time.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/01/2005
Parameters:
Attribute [INPUTS]
Returns:
TRUE if the attr is a valid effect attr

Reimplemented from NodeRenderableInk.

Reimplemented in NodeMouldGroup, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 769 of file group.cpp.

00770 {
00771 //  return (AttrFillGeometry::s_bGroupTransparency &&                   // If pref allows group transparency
00772 //          (pAttr->IsATranspFill() ||                                  // And the attribute is a transparency type
00773 //           pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrTranspChange)) ||     // Return TRUE to apply the attr as an effect
00774 //           pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeTranspChange))
00775 //           )
00776 //          );
00777     CCRuntimeClass* pAttrType = pAttr->GetAttributeType();
00778 
00779     return (AttrFillGeometry::s_bGroupTransparency &&                   // If pref allows group transparency
00780             (pAttr->IsATranspFill() ||
00781             pAttrType == CC_RUNTIME_CLASS(AttrTranspFillGeometry) || //->IsKindOf(CC_RUNTIME_CLASS(AttrTranspChange)) ||
00782             pAttrType == CC_RUNTIME_CLASS(AttrStrokeTransp) || //pAttr->IsKindOf(CC_RUNTIME_CLASS(AttrStrokeTranspChange)) ||
00783             pAttrType == CC_RUNTIME_CLASS(AttrTranspFillMapping)
00784             )
00785            );
00786 }

ChangeCode NodeGroup::OnChildChange ObjChangeParam pParam  )  [virtual]
 

This function should be overridden in derived object classes. Composite objects can use this function to respond to one of their children undergoing a change. They should return CC_FAIL whenever they are unable to cope with the change.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
07/02/95
Parameters:
pParam = pointer to a object change parameter class [INPUTS]
Returns:
CC_OK if we have successfully processed the change. CC_FAIL if we cannot handle this particular change and must prevent the child from continuing
Groups will hide themselves if the op has left it in a state where it has no bounds, i.e. all it's node renderable bounded children are gone.

See also:
WarnParentOfChange(),AllowOp();

Reimplemented from NodeCompound.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1624 of file group.cpp.

01625 {
01626     ERROR2IF(pParam == NULL,CC_FAIL,"pParam == NULL");
01627 
01628     ObjChangeType cType = pParam->GetChangeType();
01629 
01630     if (cType == OBJCHANGE_FINISHED)
01631     {
01632         InvalidateBoundingRect();
01633         // The groups 
01634         DocRect Rect = GetBoundingRect();
01635 
01636         if (Rect.IsEmpty())
01637         {
01638             UndoableOperation* pOp = pParam->GetOpPointer();
01639             if (pOp != NULL)
01640             { 
01641                 Node* pParent = FindParent(); 
01642                 if (!pOp->DoHideNode(this,TRUE))
01643                 {
01644                     return CC_FAIL;
01645                 }
01646                 // This bit is a bit scary, but should work !
01647                 // After a deletion we factor out all attributes on the parent of this group
01648                 if (pParent && pParent->IsCompound())
01649                 {
01650                     if (!pOp->DoFactorOutCommonChildAttributes(((NodeRenderableInk*)pParent),TRUE))
01651                     {
01652                         return CC_FAIL;
01653                     }
01654                 }
01655             }
01656         }
01657     }
01658 
01659     return NodeCompound::OnChildChange(pParam);
01660 }

BOOL NodeGroup::OnClick DocCoord  PointerPos,
ClickType  Click,
ClickModifiers  ClickMods,
Spread pSpread
[virtual]
 

Determines if the user has started a drag on one of the groups blobs. If they have then it starts the groups resize operation.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/09/94
Parameters:
PointerPos - The Location of the mouse pointer at the time of the click [INPUTS] Click - The type of click received (single, double, drag etc) ClickMods - The modifiers to the click (eg shift, control etc )
Returns:
TRUE if the node claims the click as its own and FALSE if it is not interested in the click

Reimplemented from NodeRenderableInk.

Reimplemented in NodeClipViewController, NodeMouldGroup, NodeBlend, NodeMoulder, and NodeMould.

Definition at line 1493 of file group.cpp.

01495 {
01496 #if !defined(EXCLUDE_FROM_RALPH)
01497     // Find a view and if we failed to find a view, then just don't claim the click
01498     DocView *pDocView = DocView::GetSelected();
01499     if (pDocView==NULL)
01500         return FALSE;
01501 
01502     // we only handle the click if we can confirm that object blobs are being displayed.
01503     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
01504     if (pBlobMgr == NULL)
01505         return FALSE;
01506     if (!pBlobMgr->GetCurrentInterest().Object)
01507         return FALSE;
01508 
01509     // Find the DocRect of blob size around the point that was clicked on 
01510     DocRect MouseBlob;
01511     OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), PointerPos, BT_SELECTEDLARGEST, &MouseBlob);
01512 
01513     INT32 StartBlob = 0; 
01514 
01515     // If the user has clicked on a blob we will need to set the centre of rotation to the 
01516     // oposite corner
01517     DocCoord OpCorner;
01518      
01519     // Has the user clicked on one of the group's blobs ?
01520     if  (MouseBlob.ContainsCoord(BoundingRectangle.lo))      // Bottom left
01521     {
01522         StartBlob = 6; 
01523         OpCorner = BoundingRectangle.hi; 
01524     }
01525     else if (MouseBlob.ContainsCoord(BoundingRectangle.hi))      // Top right
01526     {
01527         StartBlob = 3; 
01528         OpCorner = BoundingRectangle.lo; 
01529 
01530     }
01531     else if (MouseBlob.ContainsCoord(DocCoord(BoundingRectangle.lo.x,BoundingRectangle.hi.y)))  // Top left
01532     {
01533         StartBlob = 1; 
01534         OpCorner = DocCoord(BoundingRectangle.hi.x,BoundingRectangle.lo.y);
01535     }
01536     else if (MouseBlob.ContainsCoord(DocCoord(BoundingRectangle.hi.x,BoundingRectangle.lo.y))) // Bottom right
01537     {
01538         StartBlob = 8; 
01539         OpCorner = DocCoord(BoundingRectangle.lo.x,BoundingRectangle.hi.y);
01540 
01541     }
01542     if (StartBlob != 0)
01543     {
01544         // User has clicked on a blob 
01545         if (Click==CLICKTYPE_DRAG)
01546         {   
01547             // Try to create the operation to scale the group
01548             OpScaleTrans* pOp = new OpScaleTrans(); 
01549             if (pOp == NULL)
01550             {
01551                 InformError(); 
01552                 return TRUE; // Claim the click though
01553             }
01554 
01555             // Create a range containing only this object
01556 //          RangeControl RngCtl = { TRUE, FALSE, FALSE }; 
01557             
01558             static TransformData TransData; 
01559 
01560             // Setup the transform info 
01561             TransData.CentreOfTrans = OpCorner;
01562             TransData.StartBlob = StartBlob;
01563             TransData.LockAspect = FALSE; 
01564             TransData.LeaveCopy = FALSE; 
01565             TransData.ScaleLines = TRUE; 
01566             TransData.TransFills = TRUE;
01567             TransData.pRange = 0; 
01568 
01569             TransformBoundingData BoundingData;
01570             BoundingData.x        = BoundingRectangle.lo.x;
01571             BoundingData.y        = BoundingRectangle.lo.y;
01572             BoundingData.Width    = BoundingRectangle.Width();
01573             BoundingData.Height   = BoundingRectangle.Height();
01574             BoundingData.XScale   = (FIXED16) 1;
01575             BoundingData.YScale   = (FIXED16) 1;
01576             BoundingData.Rotation = (ANGLE) 0;
01577             BoundingData.Shear    = (ANGLE) 0;
01578 
01579 
01580             // Start the drag 
01581             pOp->DragStarted(&TransData, 
01582                              NULL, // Don't report to any tool
01583                              &BoundingData, // Must give bounds data or call fails
01584                              PointerPos, 
01585                              pSpread,
01586                              ClickMods,
01587                              DocCoord(0,0),
01588                              this
01589                              ); 
01590 
01591 
01592         }       
01593         // we have used that click up
01594         return TRUE;
01595     }
01596 #endif
01597     // we did not use the click, so let someone else try
01598     return FALSE;
01599 }

void NodeGroup::PolyCopyNodeContents NodeRenderable pNodeCopy  )  [virtual]
 

Polymorphically copies the contents of this node to another.

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

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1390 of file group.cpp.

01391 {
01392     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
01393     ENSURE(IS_A(pNodeCopy, NodeGroup), "PolyCopyNodeContents given wrong dest node type");
01394 
01395     if (IS_A(pNodeCopy, NodeGroup))
01396         CopyNodeContents((NodeGroup*)pNodeCopy);
01397 }

void NodeGroup::PreExportRender RenderRegion pRegion  )  [virtual]
 

Perform any rendering required when exporting to a file, and this node is being 'passed by' during the tree searching. For example, a group node being exported to EPS would output a "start group" token, and then its ExportRender function would output a "end group" token. By default, it does nothing. Nodes wishing to do special export processing should override this function (and ExportRender).

Author:
Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/03/94
Parameters:
pRender - the render region we are exporting to. [INPUTS]
See also:
Node::ExportRender; Node::NeedsToExport

Reimplemented from Node.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeMoulder, and NodeMould.

Definition at line 228 of file group.cpp.

00229 {
00230 #ifdef DO_EXPORT
00231     if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
00232     {
00233         // Output "start group" token
00234         EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
00235         pDC->OutputToken(_T("u"));
00236         pDC->OutputNewLine();
00237     }
00238 PORTNOTE("cmx", "Removed use of CMXRenderRegion")
00239 #ifndef EXCLUDE_FROM_XARALX
00240     else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
00241     {
00242         // mark start of a group...
00243         CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
00244         DocRect BBox = GetBoundingRect();
00245         pDC->StartGroup(&BBox);
00246     }
00247 #endif
00248 #endif
00249 }

void NodeGroup::RenderAfterSubtree RenderRegion pRegion  )  [virtual]
 

For determining quickly if the node is a compound object Capture the group as a cached bitmap.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/06/2004
Parameters:
pRender - The region to render into [INPUTS]

Reimplemented from Node.

Definition at line 313 of file group.cpp.

00314 {
00315     // Deal with group transparency capture
00316     // Call Helper function to run all my cacheing functionality for me...
00317     // If we have Effect attrs applied then the user wants "tight group transparency"
00318     if (HasEffectAttrs())
00319         CaptureTight(pRegion);
00320     else
00321         CaptureCached(pRegion);
00322 }

void NodeGroup::RenderObjectBlobs RenderRegion pRegion  )  [virtual]
 

Will render the group iff we have it cached - for hit detection reasonsRenders the object blobs.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/6/94
Parameters:
pRender - The region to draw the blobs in [INPUTS]

Reimplemented from NodeRenderable.

Reimplemented in NodeBlend, NodeBrush, and NodeMould.

Definition at line 842 of file group.cpp.

00843 {
00844     NodeCompound::RenderObjectBlobs(pRegion);
00845 
00846 #if !defined(EXCLUDE_FROM_RALPH)
00847     // Find out about the groups bounding rect
00848     DocRect BoundingRect = GetBoundingRect();
00849 
00850     // Find out where to draw the blobs
00851     DocCoord Low  = BoundingRect.LowCorner();
00852     DocCoord High = BoundingRect.HighCorner();
00853 
00854     // Set the colours of the blobs
00855     pRegion->SetFillColour(COLOUR_UNSELECTEDBLOB);
00856     pRegion->SetLineColour(COLOUR_NONE);
00857 
00858     // Draw all the blobs
00859     pRegion->DrawBlob(Low, BT_UNSELECTED);  
00860     pRegion->DrawBlob(High, BT_UNSELECTED); 
00861     pRegion->DrawBlob(DocCoord(Low.x, High.y), BT_UNSELECTED); 
00862     pRegion->DrawBlob(DocCoord(High.x, Low.y), BT_UNSELECTED); 
00863 
00864 #endif
00865 }

SubtreeRenderState NodeGroup::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:
29/06/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 NodeRenderableBounded.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, and NodeBrush.

Definition at line 340 of file group.cpp.

00341 {
00342     if (pRender == NULL)                            // If no render region supplied, assume we need to be rendered
00343         return SUBTREE_ROOTANDCHILDREN;
00344 
00345     // Go find out about my bounding rectangle
00346     DocRect BoundingRect = GetBoundingRect();
00347     DocRect ClipRect = pRender->GetClipRect();
00348 
00349     if (bClip && !ClipRect.IsIntersectedWith(BoundingRect)) // If not within the clipping rect then
00350         return SUBTREE_NORENDER;                    // Don't render us or our children
00351 
00352     // Ask Helper function to set up cacheing for me...
00353     // If we have Effect attrs applied then the user wants "tight group transparency"
00354     if (HasEffectAttrs())
00355     {
00356         if (RenderTight(pRender))
00357             return SUBTREE_NORENDER;
00358     }
00359     else
00360     {
00361         if (RenderCached(pRender))  // If we can find a cached bitmap for this node and render it
00362         {
00363 //TRACEUSER("Phil", _T("Skipping cached group %x %s\n"), this, GetRuntimeClass()->m_lpszClassName);
00364             return SUBTREE_NORENDER;                    // Then tell the renderer to move on without doing any more...
00365         }
00366 //TRACEUSER("Phil", _T("Re-rendering cached group %x %s\n"), this, GetRuntimeClass()->m_lpszClassName);
00367     }
00368 
00369     return SUBTREE_ROOTANDCHILDREN;                 // Else we must render ourselves and our children
00370 }

BOOL NodeGroup::RenderTight RenderRegion pRender  )  [virtual]
 

Protected Helper function Allow this node to render itself using cached data if it has it and for that cached data to represent an arbitrary section of the document (usually a subtree but can be more).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/01/2005
Returns:
TRUE if the node managed to render a cached version of itself then pNextNode contains the pointer to the node to continue rendering from FALSE if the node did not render a cached version of itself and thus normal rendering is required
For this implementation we assume that our cached info will represent just this subtree.

Also start to capture the rendered info into a cached bitmap if possible

See also:
NodeRenderableBounded::CaptureCached

Definition at line 397 of file group.cpp.

00398 {
00399     // If the caller wants his bitmap to respond to Effect Attributes
00400     // Then we have to behave quite differently than a normal cache/capture sequence
00401     // We must grab the bitmap regardless of the cache-enabling flag
00402     // We must grab at a controlled resolution
00403     // We must grab the whole thing
00404     // We must grab at 32BPP RGBT
00405     //
00406     // If the rendering quality is outline - no point showing cached bitmaps...
00407     if (pRender->RRQuality.GetFillQuality() <= Quality::Solid)
00408         return FALSE;
00409 
00410     // If the rendering system is doing black and white only then we can't sensibly
00411     // produce a monochrome version of the cached bitmap...
00412     if (pRender->IsVeryMono() || pRender->IsHitDetect())
00413         return FALSE;
00414 
00415     // Tight groups need to be rendered in the complex bitmap stages of printing
00416     if (pRender->IsKindOf(CC_RUNTIME_CLASS(ScanningRenderRegion)))
00417     {
00418         ScanningRenderRegion* pScanner = (ScanningRenderRegion*)pRender;
00419         pScanner->ComplexShapeFoundWrapper();
00420 
00421         return TRUE;    // Return TRUE so that rendering will NOT continue into the group normally
00422     }
00423 
00424     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00425     if (pBitmapCache==NULL)
00426         return FALSE;
00427 
00428     // If this node is definitely not cached, skip the cache rendering stuff...
00429     DocRect cliprect = pRender->GetClipRect();
00430     DocRect bounds = GetBoundingRect();                                     // Assure new bounds are recalced if they were invalid
00431     BOOL bRendered = FALSE;
00432 
00433     CBitmapCacheKey inky(this, GetTightGroupPixelWidth(pRender));
00434 
00435     // No need to check BackmostChanged node here because we never capture
00436     // our background in a 24BPP bitmap we always capture at 32BPP using cfLOCKEDTRANSPARENT
00437 
00438     // Look for a cached bitmap at the appropriate pixel size...
00439     CCachedBitmap cbmp;
00440     BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
00441     if (bFound)
00442     {
00443         // If cached bitmap covers the current clipped object rect, we can use it...
00444         DocRect clippedboundrect = cliprect.Intersection(bounds);
00445         if (cbmp.GetCachedRect().ContainsRect(clippedboundrect))
00446         {
00447 //TRACEUSER("Phil", _T("Rendering cached bitmap for %x %s\n"), this, GetRuntimeClass()->GetClassName() );
00448             bRendered = pRender->RenderBits(cbmp.pbmpInfo, cbmp.pbmpBits, &cbmp.coord0, 3, TRUE, this);
00449         }
00450     }
00451 
00452     if (bRendered)
00453         return bRendered;
00454 
00455     // If we couldn't find or render a cached bitmap then try to cache a new one
00456 //  double ScaledPixelWidth = pRender->GetScaledPixelWidth();
00457 
00458     // Work out how much of the object we propose to capture
00459     DocRect viewrect = cliprect;
00460     DocRect CaptureRect = bounds;
00461 
00462     if (!pRender->IsPrinting())
00463     {
00464         View* pView = pRender->GetRenderView();
00465         Spread* pSpread = pRender->GetRenderSpread();
00466         if (pView && pSpread)
00467         {
00468             viewrect = pView->GetDocViewRect(pSpread);
00469             pSpread->DocCoordToSpreadCoord(&viewrect);
00470             if (!viewrect.IsValid() || !viewrect.ContainsRect(cliprect))
00471                 viewrect = cliprect;
00472         }
00473     }
00474 
00475     CaptureRect = CaptureRect.Intersection(viewrect);               // Proposed capture area is obj x viewport
00476 
00477     // If our capture rect is invalid (no intersection) then don't do any rendering
00478     if (!CaptureRect.IsValid())
00479         return(TRUE);
00480 
00481     if (!pRender->IsPrinting())
00482     {
00483         // If we're nearly going to capture the whole object
00484         // (Compare area of bounding rect with area of view rect so that bitmap sizes don't get out of control)
00485         XLONG areaBounds = (XLONG)bounds.Width()*(XLONG)bounds.Height();
00486         XLONG area2View = (XLONG)2*(XLONG)viewrect.Width()*(XLONG)viewrect.Height();
00487         if (areaBounds < area2View)
00488         {
00489             // Then grab the whole thing
00490             // (Bounding Rect is small enough for us to capture the whole object ignoring clipping rect)
00491             CaptureRect = bounds;
00492         }
00493     }
00494 
00495     // Inflate by one pixel all round to allow for anti-aliasing effects at the edges
00496     CaptureRect.Inflate((INT32)GetTightGroupPixelWidth(pRender));
00497 
00498     BOOL bFullCoverage = CaptureRect.ContainsRect(bounds);
00499 
00500     // Finally start the Capture @ 32BPP
00501     CaptureFlags caFlags = CaptureFlags(cfLOCKEDTRANSPARENT | cfUNCLIP | (bFullCoverage ? cfFULLCOVERAGE : cfNONE));
00502 //TRACEUSER("Phil", _T("Starting TightGroup Capture %x, %f\n"), this, GetTightGroupPixelsPerInch(pRender));
00503     pRender->StartCapture(this, CaptureRect, CAPTUREINFO(ctNESTABLE, caFlags), TRUE, FALSE, GetTightGroupPixelsPerInch(pRender));
00504 
00505     return bRendered;
00506 }

void NodeGroup::RenderTinyBlobs RenderRegion pRegion  )  [virtual]
 

Renders the tiny blobs for a group (A Single blob on the topmost child object in the group).

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/6/94
Parameters:
pRender - The region to draw the blobs in [INPUTS]

Reimplemented from NodeRenderable.

Reimplemented in NodeContourController, NodeClipViewController, NodeBrush, and NodeMould.

Definition at line 881 of file group.cpp.

00882 {
00883 #if !defined(EXCLUDE_FROM_RALPH)
00884     if (NodeRenderableBounded::bShowCacheBlobs)
00885     {
00886         // To help see what the cacheing system is doing
00887         // If this node has a cached bitmap associated with it
00888         // Render a special blob to show that...
00889         CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00890         if (pBitmapCache && MayBeCached && !HasEffectAttrs())
00891         {
00892             CBitmapCacheKey inky(this, pRegion->GetScaledPixelWidth());         //GetScaledPixelWidthDouble?
00893             CCachedBitmap cbmp;
00894             BOOL bFound = pBitmapCache->Lookup(inky, cbmp);
00895             if (bFound)
00896             {
00897                 // Find out about the groups bounding rect
00898                 DocRect BoundingRect = GetBoundingRect();
00899 
00900                 // Draw a blob
00901                 if (cbmp.IsTransparent())
00902                     pRegion->DrawBitmapBlob(DocCoord(BoundingRect.hi.x - pRegion->GetScaledPixelWidth(), BoundingRect.lo.y - pRegion->GetScaledPixelWidth()), _R(IDB_CACHE_MARK_32));
00903                 else
00904                     pRegion->DrawBitmapBlob(DocCoord(BoundingRect.hi.x - pRegion->GetScaledPixelWidth(), BoundingRect.lo.y - pRegion->GetScaledPixelWidth()), _R(IDB_CACHE_MARK_24));
00905             }
00906         }
00907     }
00908 
00909     // get the topmost object in this group and tell it to render its tiny blobs.
00910     Node* pNode = FindLastChild();
00911     while (pNode != NULL && !pNode->IsAnObject())
00912         pNode = pNode->FindPrevious();
00913 
00914     // empty groups are not allowed!
00915     if (pNode == NULL)
00916     {
00917         ERROR3("NodeGroup::RenderTinyBlobs; This group is empty! Shouldn't be!");
00918         return;
00919     }
00920     else
00921     {
00922         ((NodeRenderableInk*)pNode)->RenderTinyBlobs(pRegion);
00923     }
00924 
00925 #endif
00926 }

Node * NodeGroup::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:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/4/93
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 NodeRenderableInk.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1342 of file group.cpp.

01343 {
01344     NodeGroup* NodeCopy; 
01345     NodeCopy = new NodeGroup();
01346     ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); 
01347     CopyNodeContents(NodeCopy);
01348     return (NodeCopy);
01349 }   

void NodeGroup::Transform TransformBase Trans  )  [virtual]
 

Transforms the group object and all its children.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/6/94
Parameters:
Trans - A transformation object [INPUTS]

Reimplemented from NodeRenderableBounded.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 940 of file group.cpp.

00941 {
00942     View* pView = View::GetCurrent();
00943     if (GroupCanTransformCached(Trans) && pView)
00944 //  if (GroupCanTransformCached() && pView)
00945     {
00946         // Note! View::GetScaledPixelWidth returns an unrounded fractional value where
00947         // RenderRegion::GetScaledPixelWidth return a rounded integer!!!
00948         //
00949         // Note! It would be better not to call HasEffectAttrs() here because it can be slow in large groups
00950         if (HasEffectAttrs())
00951             TransformTight(Trans, GetTightGroupPixelsPerInch());
00952         else
00953             TransformCached(Trans, (MILLIPOINT)(pView->GetScaledPixelWidth().MakeDouble()+0.5));
00954     }
00955     else
00956     {
00957         // Our cached data can't be transformed so we must remove it because
00958         // it will now be out of date
00959         // We must do it directly because ReleaseCached does conditional
00960         // stuff based on IsDragged
00961 //TRACEUSER("Phil", _T("NodeGroup::Transform releasing cache\n"));
00962         CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
00963         if (pBitmapCache!=NULL)
00964         {
00965             CBitmapCacheKey inky(this, 42);
00966             pBitmapCache->RemoveAllOwnedBitmaps(inky);
00967             MayBeCached = FALSE;
00968             Trans.bHaveTransformedCached = FALSE;
00969             Trans.bTransformYourChildren = TRUE;
00970         }
00971     }
00972 
00973     // Optimisation:
00974     // If we have transformed our cached data 
00975     //  And we're dragging 
00976     //  And we were holding cached data (sanity check)
00977     //  (And /assuming/ that the cached data fully represents the child objects!!!)
00978     //
00979     // Then we can avoid transforming our children to save time
00980     //
00981     // This is safe because we know that the dragged objects will not remain permanently in the
00982     // document so it doesn't matter if they're not up to date...
00983     //
00984     BOOL bTransCache = Trans.bHaveTransformedCached;
00985     if (Trans.bTransformYourChildren)
00986     {
00987         // Transform all the children
00988         NodeRenderableInk::TransformChildren(Trans);
00989     }
00990     else
00991     {
00992         // We can get away with just transforming our effect attrs
00993         TransformEffectAttrs(Trans);
00994         Trans.bHaveTransformedChildren = FALSE;
00995     }
00996     Trans.bHaveTransformedCached = bTransCache;
00997 
00998     // If we have successfully transformed the cached data for this
00999     // contour then we can simply transform the bounds to suit...
01000     // (Some derived classes might not be able to compute bounds
01001     //  if their children have not been transformed.)
01002     // (Bounds have to be correct for RenderCached to allow the cached
01003     //  bitmap to be used during dragging.)
01004     //
01005     // We can only do this for translations at the moment
01006     //
01007     if (Trans.bHaveTransformedCached && Trans.IsTranslation())
01008     {
01009         Trans.Transform(&BoundingRectangle.lo, 1);
01010         Trans.Transform(&BoundingRectangle.hi, 1);
01011 /*      The following code doesn't work because it keeps on transforming
01012         the results of previous transformed bounding rects, iteratively getting
01013         bigger and bigger.
01014         It needs to be able to work on the original bounding rect all the time
01015         DocCoord temp[4];
01016         temp[0] = BoundingRectangle.lo;
01017         temp[1] = BoundingRectangle.hi;
01018         temp[2] = DocCoord(BoundingRectangle.lox, BoundingRectangle.hiy);
01019         temp[3] = DocCoord(BoundingRectangle.hix, BoundingRectangle.loy);
01020 
01021         Trans.Transform(temp, 4);
01022 
01023         BoundingRectangle.lo = temp[0];
01024         BoundingRectangle.hi = temp[0];
01025         BoundingRectangle.IncludePoint(temp[1]);
01026         BoundingRectangle.IncludePoint(temp[2]);
01027         BoundingRectangle.IncludePoint(temp[3]);
01028 */
01029     }
01030     else
01031     {
01032         // The groups bounding rect is no longer valid
01033 //      ERROR3IF(!IS_A(this, NodeGroup) && !Trans.bHaveTransformedChildren, "Compound children not transformed but compound bounding rect depends on them\n");
01034         InvalidateBoundingRect();
01035     }
01036 
01037     // --------------------------------------------------------------------
01038     // CGS:  We need to check for a blend on a path here ....
01039     if (IS_A (this, NodeBlend))
01040     {
01041         NodeBlend* ptrBlend = (NodeBlend*) this;
01042         NodeBlender* ptrBlender = (NodeBlender*) ptrBlend->FindFirstBlender ();
01043 
01044         if (ptrBlender)
01045         {
01046             ptrBlender->UpdateBlendStartAngles ((Trans2DMatrix&) Trans);
01047 
01048             BOOL done = FALSE;
01049             
01050             while (!done)
01051             {
01052                 ptrBlender = ptrBlend->FindNextBlender (ptrBlender);
01053                 
01054                 if (!ptrBlender)
01055                 {
01056                     done = TRUE;
01057                 }
01058                 else
01059                 {
01060                     ptrBlender->UpdateBlendStartAngles ((Trans2DMatrix&) Trans);
01061                 }
01062             }
01063         }
01064     }
01065 }

void NodeGroup::TransformTight TransformBase Trans,
double  dTestPixelWidth
[virtual]
 

Transform all the cached bitmaps associated with this node.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/10/2004
Parameters:
Trans - Transformation [INPUTS] dPixelWidth - PixelWidth to be tested specifically to control Trans.bHaveTransformedCached
Returns:
-
See also:
NodeRenderableInk::RenderCached, CaptureCached

Definition at line 1084 of file group.cpp.

01085 {
01086     CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
01087 
01088     CBitmapCacheKey inky(this, 42);
01089     CCacheKeyMap::iterator pos = pBitmapCache->GetStartPosition();
01090     CCachedBitmap abitmap = pBitmapCache->FindNextOwnedBitmap(pos, inky);
01091     MayBeCached = abitmap.IsValid();                        // Update MayBeCached here because we can
01092     BOOL bTransformedTested = FALSE;
01093     while (abitmap.IsValid())
01094     {
01095         abitmap.Transform(Trans);
01096         pBitmapCache->StoreBitmap(inky, abitmap);
01097 
01098         if (inky.GetPixelWidth() == dTestPixelWidth && abitmap.IsTransparent())
01099             bTransformedTested = TRUE;
01100 
01101         abitmap = pBitmapCache->FindNextOwnedBitmap(pos, inky);
01102     }
01103 
01104     // We can only continue to transform cached things if all our bitmaps are transparent (32BPP)
01105     // And if we actually had some cached data to transform
01106     if (!bTransformedTested)
01107     {
01108         Trans.bHaveTransformedCached = FALSE;
01109         Trans.bTransformYourChildren = TRUE;
01110     }
01111 }

BOOL NodeGroup::WillWriteBounds BaseCamelotFilter pFilter  )  [virtual]
 

Determines if the down/up pair need to be written.

Author:
Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/10/05
Parameters:
pFilter = ptr to filter to write to [INPUTS]
Returns:
TRUE if this node will write out a bounds record

Reimplemented from NodeRenderableInk.

Definition at line 1759 of file group.cpp.

01760 {
01761     return(HasEffectAttrs() || pFilter->GetBoundsWriteLevel() >= BWL_COMPOUND);
01762 }

BOOL NodeGroup::WriteBoundsRecord BaseCamelotFilter pFilter  )  [virtual]
 

Write out a record containing the bounds of this object.

Author:
Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/10/05
Parameters:
pFilter = ptr to filter to write to [INPUTS]
Returns:
TRUE if ok, FALSE otherwise

Reimplemented from NodeRenderableInk.

Definition at line 1719 of file group.cpp.

01720 {
01721     BOOL ok = TRUE;
01722     // Write out the record
01723     DocRect Rect = GetBoundingRect();
01724 
01725     if (HasEffectAttrs())
01726     {
01727         CamelotFileRecord Rec(pFilter, TAG_COMPOUNDRENDER, TAG_COMPOUNDRENDER_SIZE);
01728         ok = Rec.Init();
01729         if (ok) ok = Rec.WriteUINT32(0);            // Reserved
01730         if (ok) ok = Rec.WriteCoord(Rect.lo);
01731         if (ok) ok = Rec.WriteCoord(Rect.hi);
01732         if (ok) ok = pFilter->Write(&Rec);
01733     }
01734     else
01735     {
01736         CamelotFileRecord Rec(pFilter, TAG_OBJECTBOUNDS, TAG_OBJECTBOUNDS_SIZE);
01737         ok = Rec.Init();
01738         if (ok) ok = Rec.WriteCoord(Rect.lo);
01739         if (ok) ok = Rec.WriteCoord(Rect.hi);
01740         if (ok) ok = pFilter->Write(&Rec);
01741     }
01742 
01743     return(ok);
01744 }

BOOL NodeGroup::WritePreChildrenNative BaseCamelotFilter pFilter  )  [virtual]
 

Reimplemented from Node.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1697 of file group.cpp.

01698 {
01699 #ifdef DO_EXPORT
01700     return WritePreChildrenWeb(pFilter);
01701 #else
01702     return FALSE;
01703 #endif
01704 }

BOOL NodeGroup::WritePreChildrenWeb BaseCamelotFilter pFilter  )  [virtual]
 

Writes the group record to the filter.

> virtual BOOL NodeGroup::WritePreChildrenWeb(BaseCamelotFilter* pFilter)

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

Reimplemented from Node.

Reimplemented in NodeContourController, NodeClipViewController, NodeMouldGroup, NodeBlend, NodeBrush, NodeMoulder, and NodeMould.

Definition at line 1679 of file group.cpp.

01680 {
01681 #ifdef DO_EXPORT
01682     ERROR2IF(pFilter == NULL,FALSE,"NULL filter param");
01683 
01684     CXaraFileRecord Rec(TAG_GROUP,0);
01685 
01686     BOOL ok = pFilter->Write(&Rec);
01687 
01688     return ok;
01689 #else
01690     return FALSE;
01691 #endif
01692 }


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