// $Id: blobs.cpp 1601 2006-07-29 16:26:32Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // Provides a class to help manage the various types of blobs available in Camelot /* */ #include "camtypes.h" #include "blobs.h" //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "osrndrgn.h" //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] // Declare the source version number DECLARE_SOURCE("$Revision: 1601 $"); //Give my name in memory dumps CC_IMPLEMENT_MEMDUMP(BlobManager, MessageHandler) // This will get Camelot to display the filename and linenumber of any memory allocations // that are not released at program exit // Declare smart memory handling in Debug builds #define new CAM_DEBUG_NEW //static BOOL CurrentCaretState = FALSE; /******************************************************************************************** > BlobStyle::BlobStyle() Author: Rik_Heywood (Xara Group Ltd) Created: 23/6/94 Purpose: Default constructor for the blob style which sets all the types of blob to FALSE. ********************************************************************************************/ BlobStyle::BlobStyle() { // Set all the blobs to false Object = Artistic = Fill = Tiny = Pen = ToolObject = Effect = FALSE; } /******************************************************************************************** > BlobStyle::BlobStyle( BOOL BObject, BOOL BArtistic, BOOL BFill, BOOL BTiny, BOOL BPen, BOOL BToolObject, BOOL BEffect ) Author: Rik_Heywood (Xara Group Ltd) Created: 23/6/94 Inputs: BObject - TRUE if you want Object blobs in the Blob Style BArtistic - TRUE if you want Artistic blobs in the Blob Style BFill - TRUE if you want Fill blobs in the Blob Style BTiny - TRUE if you want Tiny blobs in the Blob Style BPen - TRUE if Pen blobs are wanted BToolObject - TRUE if tool-specific object blobs are wanted. BEffect - TRUE if effect attributes blobs are wanted All these params default to FALSE. Purpose: Constructor for the blob style flags that lets you specify which of the blob types you want to use. ********************************************************************************************/ BlobStyle::BlobStyle( BOOL BObject, BOOL BArtistic, BOOL BFill, BOOL BTiny, BOOL BPen, BOOL BToolObject, BOOL BEffect ) { // Set the blobs that are required Object = BObject; Artistic = BArtistic; Fill = BFill; Tiny = BTiny; Pen = BPen; ToolObject = BToolObject; Effect = BEffect; } /******************************************************************************************** > BlobManager::BlobManager() Author: Rik_Heywood (Xara Group Ltd) Created: 23/6/94 Purpose: Default constructor for the blob manager, marks all the blobs as off ********************************************************************************************/ BlobManager::BlobManager() : MessageHandler(CC_RUNTIME_CLASS(MessageHandler), TRUE) { // There are no blobs visible when we start IsFillBlob = FALSE; IsObjectBlob = FALSE; IsArtisticBlob = FALSE; IsTinyBlob = FALSE; IsPenBlob = FALSE; IsToolObjectBlob = FALSE; IsEffectBlob = FALSE; // Blob rendering is switched on by default DrawBlobsAtAll = TRUE; RemovingBlobs = FALSE; bToolBlobsAreOff = FALSE; } /******************************************************************************************** > void BlobManager::ToolInterest(BlobStyle Blobs) Author: Rik_Heywood (Xara Group Ltd) Created: 16/6/94 Inputs: - Outputs: - Returns: - Purpose: Errors: - SeeAlso: BlobStyle ********************************************************************************************/ void BlobManager::ToolInterest(BlobStyle Blobs) { BlobStyle BlobsToRemove; // Find all the blobs that are NOT selected BlobsToRemove.Object = !Blobs.Object; BlobsToRemove.Artistic = !Blobs.Artistic; BlobsToRemove.Fill = !Blobs.Fill; BlobsToRemove.Tiny = !Blobs.Tiny; BlobsToRemove.Pen = !Blobs.Pen; BlobsToRemove.ToolObject= !Blobs.ToolObject; BlobsToRemove.Effect = !Blobs.Effect; // and remove them RemoveInterest(BlobsToRemove); // Add the selected blobs AddInterest(Blobs); /* // Do we need to render Object Blobs BOOL DrawObject = FALSE; if ((Blobs.Object && !IsObjectBlob) || (!Blobs.Object && IsObjectBlob)) DrawObject = TRUE; // Do we need to render Artistic Blobs BOOL DrawArtistic = FALSE; if ((Blobs.Artistic && !IsArtisticBlob) || (!Blobs.Artistic && IsArtisticBlob)) DrawArtistic = TRUE; // Do we need to render Fill Blobs BOOL DrawFill = FALSE; if ((Blobs.Fill && !IsFillBlob) || (!Blobs.Fill && IsFillBlob)) DrawFill = TRUE; // Do we need to render Tiny Blobs BOOL DrawTiny = FALSE; if ((Blobs.Tiny && !IsTinyBlob) || (!Blobs.Tiny && IsTinyBlob)) DrawTiny = TRUE; // Do we need to render Tiny Blobs BOOL DrawPen = FALSE; if ((Blobs.Pen && !IsPenBlob) || (!Blobs.Pen && IsPenBlob)) DrawPen = TRUE; // Find out about the selection SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); // was there a selection to render? if (pNode!=NULL && DrawBlobsAtAll) { // Find the parent spread Spread* pSpread = pNode->FindParentSpread(); // Render what we need to RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR); while (pRegion) { // Find the first selected object in the tree; Node* pNode = Selected->FindFirst(); while(pNode) { // Render only those blobs that are changing state (ie those appearing or disappearing) RenderSpecificBlobs((NodeRenderable*)pNode, pRegion, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen); // Find the next selected node to render pNode = Selected->FindNext(pNode); } // Go find the next region pRegion = DocView::GetNextOnTop(NULL); } } // Now we have to set the flags to the appropraite value IsFillBlob = Blobs.Fill; IsArtisticBlob = Blobs.Artistic; IsObjectBlob = Blobs.Object; IsTinyBlob = Blobs.Tiny; IsPenBlob = Blobs.Pen; // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; */ } /******************************************************************************************** > void BlobManager::AddInterest(BlobStyle Blobs) Author: Rik_Heywood (Xara Group Ltd) Created: 16/6/94 Inputs: Blobs - The blobs that you which to add to the ones currently displayed Purpose: If the blobs specified are not already displayed, then they are rendered onto the screen. The Flags that the blob manager maintains about which blobs are on screen and which are not are also updated SeeAlso: BlobManager::RemoveInterest; BlobStyle ********************************************************************************************/ void BlobManager::AddInterest(BlobStyle Blobs) { RemovingBlobs = FALSE; // First we have to work out which bits of the we have to add. // Do we need Object blobs to be rendered BOOL DrawObject = FALSE; if (!IsObjectBlob && Blobs.Object) { DrawObject = TRUE; IsObjectBlob = TRUE; } // Do we need Artistic blobs to be rendered BOOL DrawArtistic = FALSE; if (!IsArtisticBlob && Blobs.Artistic) { DrawArtistic = TRUE; IsArtisticBlob = TRUE; } // Do we need Fill blobs to be rendered BOOL DrawFill = FALSE; if (!IsFillBlob && Blobs.Fill) { DrawFill = TRUE; IsFillBlob = TRUE; } // Do we need Effect blobs to be rendered BOOL DrawEffect = FALSE; if (!IsEffectBlob && Blobs.Effect) { DrawEffect = TRUE; IsEffectBlob = TRUE; } // Do we need Tiny blobs to be rendered BOOL DrawTiny = FALSE; if (!IsTinyBlob && Blobs.Tiny) { DrawTiny = TRUE; IsTinyBlob = TRUE; } // Do we need Pen blobs to be rendered BOOL DrawPen = FALSE; if (!IsPenBlob && Blobs.Pen) { DrawPen = TRUE; IsPenBlob = TRUE; } // Do we need ToolObject blobs to be rendered BOOL DrawToolObject = FALSE; if (!IsToolObjectBlob && Blobs.ToolObject) { DrawToolObject = TRUE; IsToolObjectBlob = TRUE; } if (!NeedToRenderSelectionBlobs(NULL)) return; RenderSpecificBlobsOnSelection( NULL, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); // Now EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); if (pNode) // Is there a Selection ? { Spread* pSpread = pNode->FindParentSpread(); RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderSpecificBlobsOnSelection( &ClipRect, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect ); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } } } /******************************************************************************************** > void BlobManager::RemoveInterest(BlobStyle Blobs) Author: Rik_Heywood (Xara Group Ltd) Created: 16/6/94 Inputs: Blobs - The blobs that you which to remove from the ones currently displayed Purpose: If the blobs specified are already displayed, then they are rendered onto the screen to get rid of them (EORing!). The Flags that the blob manager maintains about which blobs are on screen and which are not are also updated SeeAlso: BlobManager::AddInterest; BlobStyle ********************************************************************************************/ void BlobManager::RemoveInterest(BlobStyle Blobs) { RemovingBlobs = TRUE; // First we have to work out which bits of the we have to add. // Do we need Object blobs to be rendered BOOL DrawObject = FALSE; if (IsObjectBlob && Blobs.Object) { DrawObject = TRUE; IsObjectBlob = FALSE; } // Do we need Artistic blobs to be rendered BOOL DrawArtistic = FALSE; if (IsArtisticBlob && Blobs.Artistic) { DrawArtistic = TRUE; IsArtisticBlob = FALSE; } // Do we need Fill blobs to be rendered BOOL DrawFill = FALSE; if (IsFillBlob && Blobs.Fill) { DrawFill = TRUE; IsFillBlob = FALSE; } // Do we need Fill blobs to be rendered BOOL DrawEffect = FALSE; if (IsEffectBlob && Blobs.Effect) { DrawEffect = TRUE; IsEffectBlob = FALSE; } // Do we need Tiny blobs to be rendered BOOL DrawTiny = FALSE; if (IsTinyBlob && Blobs.Tiny) { DrawTiny = TRUE; IsTinyBlob = FALSE; } // Do we need Pen blobs to be rendered BOOL DrawPen = FALSE; if (IsPenBlob && Blobs.Pen) { DrawPen = TRUE; IsPenBlob = FALSE; } // Do we need ToolObject blobs to be rendered BOOL DrawToolObject = FALSE; if (IsToolObjectBlob && Blobs.ToolObject) { DrawToolObject = TRUE; IsToolObjectBlob = FALSE; } if (!NeedToRenderSelectionBlobs(NULL)) return; // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); if (pNode) // Is there a Selection ? { Spread* pSpread = pNode->FindParentSpread(); RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderSpecificBlobsOnSelection( &ClipRect, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect ); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } } RenderSpecificBlobsOnSelection( NULL, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); } /******************************************************************************************** > BlobStyle BlobManager::GetCurrentInterest(BOOL bIgnoreOffState = FALSE) Author: Will_Cowling (Xara Group Ltd) Created: 15/8/94 Inputs: bIgnoreOffState - Flag for use by GetBlobBoundingRect functions so that they can return correct bounds even when blob rendering is turned off Returns: A 'BlobStyle' refecting the current blob interest Purpose: Allows people other than the blobmanager to know what blob are currently displayed. SeeAlso: BlobManager::AddInterest; BlobStyle ********************************************************************************************/ BlobStyle BlobManager::GetCurrentInterest(BOOL bIgnoreOffState) { // Make a default blob style with all interest off. BlobStyle CurrentBlobs; if (DrawBlobsAtAll || bIgnoreOffState) { // Update it with the current Interest CurrentBlobs.Fill = IsFillBlob; CurrentBlobs.Effect = IsEffectBlob; CurrentBlobs.Object = IsObjectBlob; CurrentBlobs.Artistic = IsArtisticBlob; CurrentBlobs.Tiny = IsTinyBlob; CurrentBlobs.Pen = IsPenBlob; CurrentBlobs.ToolObject = IsToolObjectBlob; } return CurrentBlobs; } /******************************************************************************************** > void BlobManager::BlobRenderingOff(BOOL Redraw) Author: Rik_Heywood (Xara Group Ltd) Created: 11/7/94 Inputs: Redraw - TRUE if you want the blob to be rendered before blob rendering is turned off. Purpose: After calling this function, any attempts to render blobs from anywhere in Camelot will result in nothing appearing on screen. This is a dangerous function to call if you are not sure what is going on. Normally you should use this function if you are about to do something that will involve the selection state becoming inconsistent with the blobs on screen and you specifically do not want lots of blob rendering going on until you have finished. Here is an example way of using it MonoOn // Get rid of the blobs from the screen BlobMgr->BlobRenderingOff(TRUE); // Party on the selection and change lots of things ... // Invalidate the region of the blobs ... // Switch the blob manager back on again // but leave the rendering of the blobs to the normal OnDraw loop BlobMgr->BlobRenderingOn(FALSE) MonoOff SeeAlso: BlobManager::BlobRenderingOn() ********************************************************************************************/ void BlobManager::BlobRenderingOff(BOOL Redraw) { RemovingBlobs = TRUE; if (Redraw && NeedToRenderSelectionBlobs(NULL)) { // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); if (pNode) // Is there a Selection ? { Spread* pSpread = pNode->FindParentSpread(); RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderRequiredBlobsOnSelection(&ClipRect); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } } RenderRequiredBlobsOnSelection(NULL); } // Mark blob rendering to be off DrawBlobsAtAll = FALSE; // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > void BlobManager::BlobRenderingOn(BOOL Redraw) Author: Rik_Heywood (Xara Group Ltd) Created: 11/7/94 Inputs: Redraw - TRUE if you want the blobs to be rendered before blob rendering is turned on. Purpose: If blob rendering has been turned off ( by calling BlobRenderinOff() ) then this function will re-enable it so that rendering can carry on like normal. Ideally this should be called not very long after calling BlobRenderingOff(). SeeAlso: BlobManager::BlobRenderingOn() ********************************************************************************************/ void BlobManager::BlobRenderingOn(BOOL Redraw) { RemovingBlobs = FALSE; if (Redraw && NeedToRenderSelectionBlobs(NULL)) { RenderRequiredBlobsOnSelection(NULL); // Now EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); if (pNode) // Is there a Selection ? { Spread* pSpread = pNode->FindParentSpread(); RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderRequiredBlobsOnSelection(&ClipRect); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } } } // Mark blob rendering to be on DrawBlobsAtAll = TRUE; // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > INT32 BlobManager::GetBlobSize() Author: Rik_Heywood (Xara Group Ltd) Created: 27/6/94 Returns: INT32 - The size (in DocCoords) of a blob. Purpose: This function allows you to find out how wide a blob should be. ********************************************************************************************/ INT32 BlobManager::GetBlobSize() { // To do this, we need to find out how big a blobs rect is DocRect Rect; GetBlobRect(DocCoord(0,0), &Rect); // return the width of the resulting rect return Rect.Width(); } /******************************************************************************************** > void BlobManager::GetBlobRect(DocCoord& Centre, DocRect* Rect) Author: Rik_Heywood (Xara Group Ltd) Created: 27/6/94 Inputs: Centre - The coordinate to centre the blob on MFill = Whether we should force this routine to use multi-stage fill routine Outputs: Rect - The rect in DocCoords of the blobs Purpose: Finds the rectangle of a blob that surrounds a given coord. This is to replace the rather long winded method that had to be employed before. If there is no selected document it will leave the rect unchanged. Karim 22/05/2000 - modified this method to take a BlobType param. Note that you *cannot* make use of this new param until the MFill param is removed and all current instances of GetBlobRect() updated. The new param is currently only checked against my ClipView blob type. ********************************************************************************************/ void BlobManager::GetBlobRect( const DocCoord &Centre, DocRect *Rect, BOOL MFill /*= FALSE*/, BlobType eBlobType) { // We will be needing a view to do this DocView* pDocView = DocView::GetSelected(); // Find out how big a rect is these days, if we have a view if (pDocView!=NULL) { switch (eBlobType) { case BT_CLIPVIEW: OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_CLIPVIEW, Rect); break; default: if (!MFill) { OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_SELECTEDLARGEST, Rect); } else { OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_MSTAGESELECTEDLARGEST, Rect); } break; } } } /******************************************************************************************** > void BlobManager::Render(DocRect Rect, Spread *pSpread) Author: Rik_Heywood (Xara Group Ltd) Created: 16/6/94 Purpose: This function will render all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::Render(DocRect* Rect, Spread *pSpread) { // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Now render the sections that need to be rendered to get the corrent blobs on screen RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); while (pRegion) { // Find out the clipping rect of this region DocRect TestRect = pRegion->GetClipRect(); // Find the first selected object in the tree; SelRange* Selected = GetApplication()->FindSelection(); // Karim 29/06/2000 // PromoteToParent should never be set TRUE on the selection range, outside // of code in which its modifications are required. // I have included a TRACE statement here, as a 'quiet' note to programmers, // should this occur. RangeControl rc = Selected->GetRangeControlFlags(); if (rc.PromoteToParent) { TRACE( _T("BlobManager::Render; PromoteToParent is TRUE! Read inline comment for details.\n")); rc.PromoteToParent = FALSE; Selected->Range::SetRangeControl(rc); } Node* pNode = Selected->FindFirst(); while(pNode) { // Render only the required blobs if (pNode->IsBounded()) { // This node is bounded, so see if we really need to render it if (TestRect.IsIntersectedWith(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect())) RenderRequiredBlobs((NodeRenderable*)pNode, pRegion); } else { // Always render it if it is not bounded (probably an Attribute) RenderRequiredBlobs((NodeRenderable*)pNode, pRegion); } // Find the next selected node to render pNode = Selected->FindNext(pNode); } // Go find the next region pRegion = DocView::GetNextOnTop(Rect); } // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > void BlobManager::RenderOn(DocRect Rect, Spread *pSpread) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render on all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderOn(DocRect* Rect, Spread *pSpread) { RemovingBlobs = FALSE; // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs on Render(Rect, pSpread); // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; return; } // We must be background rendering ... // So lets try a bit of an optimisation // If the Blob we are about to render, is completely contained // within a pending Render Region, then we don't need to // render anything if (!NeedToRenderSelectionBlobs(Rect)) return; // Oh well, lets render some blobs then // Draw the blobs on Render(Rect, pSpread); // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; // Now EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); Render(&ClipRect, pSpread); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > void BlobManager::RenderOff(DocRect Rect, Spread *pSpread) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render off all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderOff(DocRect* Rect, Spread *pSpread) { RemovingBlobs = TRUE; // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs on Render(Rect, pSpread); // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; return; } // We must be background rendering ... // So lets try a bit of an optimisation // If the Blob we are about to render, is completely contained // within a pending Render Region, then we don't need to // render anything if (!NeedToRenderSelectionBlobs(Rect)) return; // Oh well, lets render some blobs then // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); Render(&ClipRect, pSpread); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; // Draw the blobs off Render(Rect, pSpread); // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > void BlobManager::RenderMyBlobs(NodeRenderable* pNode) Author: Rik_Heywood (Xara Group Ltd) Created: 17/6/94 Inputs: pNode - The node to render the blobs of Purpose: Renders the blobs for the given node. Only the required blobs are rendered and since the blobs are EOR rendered, this function can be used to put the blobs onto the screen or take them off the screen ********************************************************************************************/ void BlobManager::RenderMyBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Now render the sections that need to be rendered to get the corrent blobs on screen RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); while (pRegion) { // Find out the clipping rect of this region DocRect TestRect = pRegion->GetClipRect(); // Render only the blobs that need to be drawn if (pNode->IsBounded()) { // This node is bounded, so see if we really need to render it if (TestRect.IsIntersectedWith(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect())) RenderRequiredBlobs(pNode, pRegion); } else { // Always render it if it is not bounded (probably an Attribute) RenderRequiredBlobs(pNode, pRegion); } // Go find the next region pRegion = DocView::GetNextOnTop(Rect); } } /******************************************************************************************** > void BlobManager::RenderMyBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render on all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderMyBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RemovingBlobs = FALSE; // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs on RenderMyBlobs(Rect, pSpread, pNode); return; } // We must be background rendering ... // So lets try a bit of an optimisation if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) return; // Oh well, lets render some blobs then // Draw the blobs on RenderMyBlobs(Rect, pSpread, pNode); // Stop fill meshes EORing each other out. FillGeometryAttribute* pLastMesh = AttrFillGeometry::LastRenderedMesh; AttrFillGeometry::LastRenderedMesh = NULL; // Now EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderMyBlobs(&ClipRect, pSpread, pNode); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = pLastMesh; } /******************************************************************************************** > void BlobManager::RenderMyBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render off all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderMyBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RemovingBlobs = TRUE; // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs off RenderMyBlobs(Rect, pSpread, pNode); return; } // We must be background rendering ... // So lets try a bit of an optimisation if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) return; // Oh well, lets render some blobs then // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); RenderMyBlobs(&ClipRect, pSpread, pNode); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } // Stop fill meshes EORing each other out. FillGeometryAttribute* pLastMesh = AttrFillGeometry::LastRenderedMesh; AttrFillGeometry::LastRenderedMesh = NULL; // Draw the blobs off RenderMyBlobs(Rect, pSpread, pNode); // Stop fill meshes EORing each other out. AttrFillGeometry::LastRenderedMesh = pLastMesh; } /******************************************************************************************** > void BlobManager::RenderObjectBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render on all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderObjectBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RemovingBlobs = FALSE; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs on RenderObjectBlobs(Rect, pSpread, pNode); return; } // We must be background rendering ... // So lets try a bit of an optimisation if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) return; // Oh well, lets render some blobs then // Draw the blobs on RenderObjectBlobs(Rect, pSpread, pNode); // EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); // Render what we need to RenderObjectBlobs(&ClipRect, pSpread, pNode); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } /******************************************************************************************** > void BlobManager::RenderObjectBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render off all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderObjectBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RemovingBlobs = TRUE; // Are we in the middle of a Background redraw ? RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) { // Nope, so do stuff as normal // Draw the blobs off RenderObjectBlobs(Rect, pSpread, pNode); return; } // We must be background rendering ... // So lets try a bit of an optimisation if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) return; // Oh well, lets render some blobs then // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); // Render what we need to RenderObjectBlobs(&ClipRect, pSpread, pNode); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } // Draw the blobs off RenderObjectBlobs(Rect, pSpread, pNode); } /******************************************************************************************** > void BlobManager::RenderObjectBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render all the blobs that are currently being displayed for the given clipping rectangle. ********************************************************************************************/ void BlobManager::RenderObjectBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RenderRegion* pOnTopRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); while (pOnTopRegion) { pNode->RenderObjectBlobs(pOnTopRegion); // Go find the next region pOnTopRegion = DocView::GetNextOnTop(Rect); } } /******************************************************************************************** > void BlobManager::RenderRequiredBlobs(NodeRenderable* pNode, RenderRegion* pRegion) Author: Rik_Heywood (Xara Group Ltd) Created: 22/6/94 Inputs: pNode - The Node whos blobs need rendering pRegion - The render region to draw into Purpose: Renders the required blobs for the given node into the given render region. The required blobs are specified by the tool when it is activated. ********************************************************************************************/ void BlobManager::RenderRequiredBlobs(NodeRenderable* pNode, RenderRegion* pRegion) { // We know that the node is a renderable ink as it is selected ENSURE( pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), "Selected object was not Renderable!"); // Render the Object Blobs of this node if (IsObjectBlob) pNode->RenderObjectBlobs(pRegion); // Render the Artistic blobs of this node if (IsArtisticBlob) pNode->RenderArtisticBlobs(pRegion); // Render the Fill blobs of this node if (IsFillBlob) pNode->RenderAppliedFillBlobs(pRegion); // Render the Fill blobs of this node if (IsEffectBlob) pNode->RenderEffectBlobs(pRegion); // Render the tiny blobs of this node if (IsTinyBlob) pNode->RenderTinyBlobs(pRegion); // Render the pen blobs of this node if (IsPenBlob) pNode->RenderPenBlobs(pRegion); // Render the ToolObject blobs of this node if (IsToolObjectBlob) pNode->RenderToolObjectBlobs(pRegion); } /******************************************************************************************** > void BlobManager::RenderRequiredBlobsOnSelection(DocRect* Rect) Author: Will_Cowling (Xara Group Ltd) Created: 14/6/95 Inputs: pNode - The Node whos blobs need rendering pRegion - The render region to draw into Purpose: Renders the required blobs for the given node into the given render region. The required blobs are specified by the tool when it is activated. ********************************************************************************************/ void BlobManager::RenderRequiredBlobsOnSelection(DocRect* Rect) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); // go and render the blobs if there are any selected nodes if (pNode!=NULL && DrawBlobsAtAll) { Spread* pSpread = pNode->FindParentSpread(); // Render what we need to RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); while (pRegion) { // Find the first selected object in the tree; Node* pNode = Selected->FindFirst(); while(pNode) { // Render only those blobs that are changing state (ie those appearing or disappearing) RenderRequiredBlobs((NodeRenderable*) pNode, pRegion); // Find the next selected node to render pNode = Selected->FindNext(pNode); } // Go find the next region pRegion = DocView::GetNextOnTop(Rect); } } // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > void BlobManager::RenderSpecificBlobs(NodeRenderable* pNode, RenderRegion* pRegion, BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) Author: Rik_Heywood (Xara Group Ltd) Created: 22/6/94 Inputs: pNode - The node to draw the blobs for pRegion - The region to render them into DrawObject - Do we want to draw the Object Blobs DrawArtistic - Do we want to draw the Artistic Blobs DrawFill - Do we want to draw the Fill Blobs DrawTiny - Do we want to draw the Tiny Blobs DrawPen - Do we want to draw the Pen Blobs DrawToolObject - Do we want to draw the ToolObject Blobs Purpose: Renders only the blobs specified. This is called from the Add and Remove Interest Functions to add new types of blob to the display or take types of blob that are no longer needed off the display. ********************************************************************************************/ void BlobManager::RenderSpecificBlobs(NodeRenderable* pNode, RenderRegion* pRegion, BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) { // We know that the node is a renderable ink as it is selected ENSURE( pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), "Selected object was not Renderable!"); // Render the Object Blobs of this node if (DrawObject) pNode->RenderObjectBlobs(pRegion); // Render the Artistic blobs of this node if (DrawArtistic) pNode->RenderArtisticBlobs(pRegion); // Render the Fill blobs of this node if (DrawFill) pNode->RenderAppliedFillBlobs(pRegion); // Render the tiny blobs of this node if (DrawTiny) pNode->RenderTinyBlobs(pRegion); // Render the Pen blobs of this node if (DrawPen) pNode->RenderPenBlobs(pRegion); // Render the ToolObject blobs of this node if (DrawToolObject) pNode->RenderToolObjectBlobs(pRegion); // Render the Effect blobs of this node if (DrawEffect) pNode->RenderEffectBlobs(pRegion); } /******************************************************************************************** > void BlobManager::RenderSpecificBlobsOnSelection(BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Inputs: pNode - The node to draw the blobs for pRegion - The region to render them into DrawObject - Do we want to draw the Object Blobs DrawArtistic - Do we want to draw the Artistic Blobs DrawFill - Do we want to draw the Fill Blobs DrawTiny - Do we want to draw the Tiny Blobs DrawPen - Do we want to draw the Pen Blobs DrawToolObject - Do we want to draw the ToolObject Blobs Purpose: Renders only the blobs specified. This is called from the Add and Remove Interest Functions to add new types of blob to the display or take types of blob that are no longer needed off the display. ********************************************************************************************/ void BlobManager::RenderSpecificBlobsOnSelection( DocRect* Rect, BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect ) { // Find out which spread the selection is on SelRange* Selected = GetApplication()->FindSelection(); Node* pNode = Selected->FindFirst(); // go and render the blobs if there are any selected nodes if (pNode!=NULL && DrawBlobsAtAll) { Spread* pSpread = pNode->FindParentSpread(); // Render what we need to RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); while (pRegion) { // Find the first selected object in the tree; Node* pNode = Selected->FindFirst(); while(pNode) { // Render only those blobs that are changing state (ie those appearing or disappearing) RenderSpecificBlobs((NodeRenderable*)pNode, pRegion, DrawObject, DrawArtistic, DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); // Find the next selected node to render pNode = Selected->FindNext(pNode); } // Go find the next region pRegion = DocView::GetNextOnTop(Rect); } } // Bodge to stop fill meshes EOR each other out. AttrFillGeometry::LastRenderedMesh = NULL; } /******************************************************************************************** > MsgResult BlobManager::Message(Msg* Message) Author: Rik_Heywood (Xara Group Ltd) Created: 29/6/94 Inputs: Message - the message to examine Returns: - Purpose: Handles the View Changing message, and makes sure that the blobs are removed from the old view and drawn onto the new view ********************************************************************************************/ MsgResult BlobManager::Message(Msg* Message) { if (MESSAGE_IS_A(Message, DocViewMsg)) { // Get a version of the message in the right type DocViewMsg* pDocViewMsg = (DocViewMsg*) Message; switch (pDocViewMsg->State) { // respond to messages that arrive just before and just after the view has changed. case DocViewMsg::SELABOUTTOCHANGE: case DocViewMsg::SELCHANGED: { // rub blobs off old view or draw them in on the new one if (DocView::GetSelected()!=NULL) { // go find the selection SelRange* Selected = GetApplication()->FindSelection(); // Have to be sure that the selection is correct for the view Selected->Update(); Node* pNode = Selected->FindFirst(); // If there is something selected if (pNode!=NULL) { // Find its spread Spread* pSpread = pNode->FindParentSpread(); if (pSpread!=NULL) { // and render the blobs Render(NULL, pSpread); } } } break; } default: break; } } return OK; } /******************************************************************************************** > void BlobManager::RenderToolBlobsOn(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render on the specified tools blobs. ********************************************************************************************/ void BlobManager::RenderToolBlobsOn(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) { // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // Put the tool blobs on pTool->RenderToolBlobs(pSpread, pClipRect); // Now EOR off in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will put them on RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected()) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); pTool->RenderToolBlobs(pSpread, &ClipRect); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } bToolBlobsAreOff = FALSE; } /******************************************************************************************** > void BlobManager::RenderToolBlobsOff(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) Author: Will_Cowling (Xara Group Ltd) Created: 13/6/95 Purpose: This function will render off the specified tools blobs. ********************************************************************************************/ void BlobManager::RenderToolBlobsOff(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) { // If we are not drawing blobs today, then return straight away if (!DrawBlobsAtAll) return; // if (bToolBlobsAreOff) // return; // EOR on in all the render regions that are still rendering, // so that the Blob rendering when the region is finished, // will take them off RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (!pRegionList->IsEmpty()) { RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected()) { // Render the blobs 'clipped' to this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); pTool->RenderToolBlobs(pSpread, &ClipRect); } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } // Take the tool blobs off pTool->RenderToolBlobs(pSpread, pClipRect); bToolBlobsAreOff = TRUE; } /******************************************************************************************** > BOOL BlobManager::NeedToRenderSelectionBlobs(DocRect* Rect) Author: Will_Cowling (Xara Group Ltd) Created: 15/6/95 Purpose: Check to make sure we need to render some blobs. ********************************************************************************************/ BOOL BlobManager::NeedToRenderSelectionBlobs(DocRect* Rect) { RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) return TRUE; // Find the first selected object in the tree; SelRange* Selected = GetApplication()->FindSelection(); if (Selected->Count() == 0) return FALSE; // Nothing to render Node* pNode = Selected->FindFirst(); Spread* pSpread = pNode->FindParentSpread(); // Find out the blob rect of the selection DocRect SelRect = Selected->GetBlobBoundingRect(); // If a clip rect was given, and it doesn't completely contain the sel bounds, // then we'll have to use that if (Rect && !Rect->ContainsRect(SelRect)) SelRect = *Rect; if (!SelRect.IsEmpty()) { // So lets check the pending regions RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Get the 'clip' rect of this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); // If any of the RenderRegions completely contain the rect // then there is no point in rendering anything if (ClipRect.ContainsRect(SelRect)) return FALSE; // We don't need to render any blobs } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } return TRUE; } /******************************************************************************************** > BOOL BlobManager::NeedToRenderNodeBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) Author: Will_Cowling (Xara Group Ltd) Created: 15/6/95 Purpose: Check to make sure we need to render some blobs. ********************************************************************************************/ BOOL BlobManager::NeedToRenderNodeBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) { RenderRegionList* pRegionList = GetApplication()->GetRegionList(); if (pRegionList->IsEmpty()) return TRUE; if (Rect != NULL || pNode->IsBounded()) { // If the Blob we are about to render, is completely contained // within a pending Render Region, then we don't need to // render anything // Find out the blob rect of this node, if we can DocRect NodeRect = DocRect(0,0,0,0); if (pNode->IsBounded()) { // Use the node's blob bounds NodeRect = ((NodeRenderableBounded*)pNode)->GetBlobBoundingRect(); } // If a clip rect was given, and it doesn't completely contain the node rect, // then we'll have to use that if (Rect && !Rect->ContainsRect(NodeRect)) NodeRect = *Rect; if (!NodeRect.IsEmpty()) { // So lets check the pending regions RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); while (pRegion) { // Check the RenderRegion is for the same spread. if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected() && (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) { // Get the 'clip' rect of this Render Region. DocRect ClipRect = pRegion->GetRegionRect(); // If any of the RenderRegions completely contain the rect // then there is no point in rendering anything if (ClipRect.ContainsRect(NodeRect)) return FALSE; // We don't need to render this node's blobs } // Get the Next render region pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); } } } return TRUE; }