00001 // $Id: blobs.cpp 1601 2006-07-29 16:26:32Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // Provides a class to help manage the various types of blobs available in Camelot 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 #include "blobs.h" 00105 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 #include "osrndrgn.h" 00111 //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 00115 // Declare the source version number 00116 DECLARE_SOURCE("$Revision: 1601 $"); 00117 00118 //Give my name in memory dumps 00119 CC_IMPLEMENT_MEMDUMP(BlobManager, MessageHandler) 00120 00121 // This will get Camelot to display the filename and linenumber of any memory allocations 00122 // that are not released at program exit 00123 // Declare smart memory handling in Debug builds 00124 #define new CAM_DEBUG_NEW 00125 00126 //static BOOL CurrentCaretState = FALSE; 00127 00128 00129 /******************************************************************************************** 00130 00131 > BlobStyle::BlobStyle() 00132 00133 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00134 Created: 23/6/94 00135 Purpose: Default constructor for the blob style which sets all the types of blob to 00136 FALSE. 00137 00138 ********************************************************************************************/ 00139 00140 BlobStyle::BlobStyle() 00141 { 00142 // Set all the blobs to false 00143 Object = Artistic = Fill = Tiny = Pen = ToolObject = Effect = FALSE; 00144 } 00145 00146 00147 00148 /******************************************************************************************** 00149 00150 > BlobStyle::BlobStyle( BOOL BObject, BOOL BArtistic, BOOL BFill, 00151 BOOL BTiny, BOOL BPen, BOOL BToolObject, BOOL BEffect ) 00152 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00153 Created: 23/6/94 00154 Inputs: BObject - TRUE if you want Object blobs in the Blob Style 00155 BArtistic - TRUE if you want Artistic blobs in the Blob Style 00156 BFill - TRUE if you want Fill blobs in the Blob Style 00157 BTiny - TRUE if you want Tiny blobs in the Blob Style 00158 BPen - TRUE if Pen blobs are wanted 00159 BToolObject - TRUE if tool-specific object blobs are wanted. 00160 BEffect - TRUE if effect attributes blobs are wanted 00161 All these params default to FALSE. 00162 Purpose: Constructor for the blob style flags that lets you specify which of the blob 00163 types you want to use. 00164 00165 ********************************************************************************************/ 00166 00167 BlobStyle::BlobStyle( BOOL BObject, BOOL BArtistic, BOOL BFill, 00168 BOOL BTiny, BOOL BPen, BOOL BToolObject, BOOL BEffect ) 00169 { 00170 // Set the blobs that are required 00171 Object = BObject; 00172 Artistic = BArtistic; 00173 Fill = BFill; 00174 Tiny = BTiny; 00175 Pen = BPen; 00176 ToolObject = BToolObject; 00177 Effect = BEffect; 00178 } 00179 00180 00181 00182 00183 00184 /******************************************************************************************** 00185 00186 > BlobManager::BlobManager() 00187 00188 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00189 Created: 23/6/94 00190 Purpose: Default constructor for the blob manager, marks all the blobs as off 00191 00192 ********************************************************************************************/ 00193 00194 BlobManager::BlobManager() : MessageHandler(CC_RUNTIME_CLASS(MessageHandler), TRUE) 00195 { 00196 // There are no blobs visible when we start 00197 IsFillBlob = FALSE; 00198 IsObjectBlob = FALSE; 00199 IsArtisticBlob = FALSE; 00200 IsTinyBlob = FALSE; 00201 IsPenBlob = FALSE; 00202 IsToolObjectBlob = FALSE; 00203 IsEffectBlob = FALSE; 00204 00205 // Blob rendering is switched on by default 00206 DrawBlobsAtAll = TRUE; 00207 00208 RemovingBlobs = FALSE; 00209 00210 bToolBlobsAreOff = FALSE; 00211 } 00212 00213 /******************************************************************************************** 00214 00215 > void BlobManager::ToolInterest(BlobStyle Blobs) 00216 00217 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00218 Created: 16/6/94 00219 Inputs: - 00220 Outputs: - 00221 Returns: - 00222 Purpose: 00223 Errors: - 00224 SeeAlso: BlobStyle 00225 00226 ********************************************************************************************/ 00227 00228 void BlobManager::ToolInterest(BlobStyle Blobs) 00229 { 00230 BlobStyle BlobsToRemove; 00231 00232 // Find all the blobs that are NOT selected 00233 BlobsToRemove.Object = !Blobs.Object; 00234 BlobsToRemove.Artistic = !Blobs.Artistic; 00235 BlobsToRemove.Fill = !Blobs.Fill; 00236 BlobsToRemove.Tiny = !Blobs.Tiny; 00237 BlobsToRemove.Pen = !Blobs.Pen; 00238 BlobsToRemove.ToolObject= !Blobs.ToolObject; 00239 BlobsToRemove.Effect = !Blobs.Effect; 00240 00241 // and remove them 00242 RemoveInterest(BlobsToRemove); 00243 00244 // Add the selected blobs 00245 AddInterest(Blobs); 00246 00247 /* 00248 // Do we need to render Object Blobs 00249 BOOL DrawObject = FALSE; 00250 if ((Blobs.Object && !IsObjectBlob) || (!Blobs.Object && IsObjectBlob)) 00251 DrawObject = TRUE; 00252 00253 // Do we need to render Artistic Blobs 00254 BOOL DrawArtistic = FALSE; 00255 if ((Blobs.Artistic && !IsArtisticBlob) || (!Blobs.Artistic && IsArtisticBlob)) 00256 DrawArtistic = TRUE; 00257 00258 // Do we need to render Fill Blobs 00259 BOOL DrawFill = FALSE; 00260 if ((Blobs.Fill && !IsFillBlob) || (!Blobs.Fill && IsFillBlob)) 00261 DrawFill = TRUE; 00262 00263 // Do we need to render Tiny Blobs 00264 BOOL DrawTiny = FALSE; 00265 if ((Blobs.Tiny && !IsTinyBlob) || (!Blobs.Tiny && IsTinyBlob)) 00266 DrawTiny = TRUE; 00267 00268 // Do we need to render Tiny Blobs 00269 BOOL DrawPen = FALSE; 00270 if ((Blobs.Pen && !IsPenBlob) || (!Blobs.Pen && IsPenBlob)) 00271 DrawPen = TRUE; 00272 00273 00274 // Find out about the selection 00275 SelRange* Selected = GetApplication()->FindSelection(); 00276 Node* pNode = Selected->FindFirst(); 00277 00278 // was there a selection to render? 00279 if (pNode!=NULL && DrawBlobsAtAll) 00280 { 00281 // Find the parent spread 00282 Spread* pSpread = pNode->FindParentSpread(); 00283 00284 // Render what we need to 00285 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR); 00286 while (pRegion) 00287 { 00288 // Find the first selected object in the tree; 00289 Node* pNode = Selected->FindFirst(); 00290 while(pNode) 00291 { 00292 // Render only those blobs that are changing state (ie those appearing or disappearing) 00293 RenderSpecificBlobs((NodeRenderable*)pNode, pRegion, DrawObject, DrawArtistic, 00294 DrawFill, DrawTiny, DrawPen); 00295 00296 // Find the next selected node to render 00297 pNode = Selected->FindNext(pNode); 00298 } 00299 00300 // Go find the next region 00301 pRegion = DocView::GetNextOnTop(NULL); 00302 } 00303 } 00304 00305 // Now we have to set the flags to the appropraite value 00306 IsFillBlob = Blobs.Fill; 00307 IsArtisticBlob = Blobs.Artistic; 00308 IsObjectBlob = Blobs.Object; 00309 IsTinyBlob = Blobs.Tiny; 00310 IsPenBlob = Blobs.Pen; 00311 00312 // Bodge to stop fill meshes EOR each other out. 00313 AttrFillGeometry::LastRenderedMesh = NULL; 00314 */ 00315 } 00316 00317 00318 /******************************************************************************************** 00319 00320 > void BlobManager::AddInterest(BlobStyle Blobs) 00321 00322 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00323 Created: 16/6/94 00324 Inputs: Blobs - The blobs that you which to add to the ones currently displayed 00325 Purpose: If the blobs specified are not already displayed, then they are rendered 00326 onto the screen. The Flags that the blob manager maintains about which 00327 blobs are on screen and which are not are also updated 00328 SeeAlso: BlobManager::RemoveInterest; BlobStyle 00329 00330 ********************************************************************************************/ 00331 00332 void BlobManager::AddInterest(BlobStyle Blobs) 00333 { 00334 RemovingBlobs = FALSE; 00335 00336 // First we have to work out which bits of the we have to add. 00337 // Do we need Object blobs to be rendered 00338 BOOL DrawObject = FALSE; 00339 if (!IsObjectBlob && Blobs.Object) 00340 { 00341 DrawObject = TRUE; 00342 IsObjectBlob = TRUE; 00343 } 00344 00345 // Do we need Artistic blobs to be rendered 00346 BOOL DrawArtistic = FALSE; 00347 if (!IsArtisticBlob && Blobs.Artistic) 00348 { 00349 DrawArtistic = TRUE; 00350 IsArtisticBlob = TRUE; 00351 } 00352 00353 // Do we need Fill blobs to be rendered 00354 BOOL DrawFill = FALSE; 00355 if (!IsFillBlob && Blobs.Fill) 00356 { 00357 DrawFill = TRUE; 00358 IsFillBlob = TRUE; 00359 } 00360 00361 // Do we need Effect blobs to be rendered 00362 BOOL DrawEffect = FALSE; 00363 if (!IsEffectBlob && Blobs.Effect) 00364 { 00365 DrawEffect = TRUE; 00366 IsEffectBlob = TRUE; 00367 } 00368 00369 // Do we need Tiny blobs to be rendered 00370 BOOL DrawTiny = FALSE; 00371 if (!IsTinyBlob && Blobs.Tiny) 00372 { 00373 DrawTiny = TRUE; 00374 IsTinyBlob = TRUE; 00375 } 00376 00377 // Do we need Pen blobs to be rendered 00378 BOOL DrawPen = FALSE; 00379 if (!IsPenBlob && Blobs.Pen) 00380 { 00381 DrawPen = TRUE; 00382 IsPenBlob = TRUE; 00383 } 00384 00385 // Do we need ToolObject blobs to be rendered 00386 BOOL DrawToolObject = FALSE; 00387 if (!IsToolObjectBlob && Blobs.ToolObject) 00388 { 00389 DrawToolObject = TRUE; 00390 IsToolObjectBlob = TRUE; 00391 } 00392 00393 if (!NeedToRenderSelectionBlobs(NULL)) 00394 return; 00395 00396 RenderSpecificBlobsOnSelection( NULL, DrawObject, DrawArtistic, 00397 DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); 00398 00399 // Now EOR off in all the render regions that are still rendering, 00400 // so that the Blob rendering when the region is finished, 00401 // will put them on 00402 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00403 00404 if (!pRegionList->IsEmpty()) 00405 { 00406 // Find out which spread the selection is on 00407 SelRange* Selected = GetApplication()->FindSelection(); 00408 Node* pNode = Selected->FindFirst(); 00409 00410 if (pNode) // Is there a Selection ? 00411 { 00412 Spread* pSpread = pNode->FindParentSpread(); 00413 00414 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 00415 00416 while (pRegion) 00417 { 00418 // Check the RenderRegion is for the same spread. 00419 if (pRegion->GetRenderSpread() == pSpread && 00420 pRegion->GetRenderView()==DocView::GetSelected() && 00421 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 00422 { 00423 // Render the blobs 'clipped' to this Render Region. 00424 DocRect ClipRect = pRegion->GetRegionRect(); 00425 RenderSpecificBlobsOnSelection( &ClipRect, 00426 DrawObject, DrawArtistic, DrawFill, 00427 DrawTiny, DrawPen, DrawToolObject, DrawEffect ); 00428 } 00429 00430 // Get the Next render region 00431 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 00432 } 00433 } 00434 } 00435 } 00436 00437 00438 00439 00440 /******************************************************************************************** 00441 00442 > void BlobManager::RemoveInterest(BlobStyle Blobs) 00443 00444 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00445 Created: 16/6/94 00446 Inputs: Blobs - The blobs that you which to remove from the ones currently displayed 00447 Purpose: If the blobs specified are already displayed, then they are rendered 00448 onto the screen to get rid of them (EORing!). The Flags that the blob manager 00449 maintains about which blobs are on screen and which are not are also updated 00450 SeeAlso: BlobManager::AddInterest; BlobStyle 00451 00452 ********************************************************************************************/ 00453 00454 void BlobManager::RemoveInterest(BlobStyle Blobs) 00455 { 00456 RemovingBlobs = TRUE; 00457 00458 // First we have to work out which bits of the we have to add. 00459 // Do we need Object blobs to be rendered 00460 BOOL DrawObject = FALSE; 00461 if (IsObjectBlob && Blobs.Object) 00462 { 00463 DrawObject = TRUE; 00464 IsObjectBlob = FALSE; 00465 } 00466 00467 // Do we need Artistic blobs to be rendered 00468 BOOL DrawArtistic = FALSE; 00469 if (IsArtisticBlob && Blobs.Artistic) 00470 { 00471 DrawArtistic = TRUE; 00472 IsArtisticBlob = FALSE; 00473 } 00474 00475 // Do we need Fill blobs to be rendered 00476 BOOL DrawFill = FALSE; 00477 if (IsFillBlob && Blobs.Fill) 00478 { 00479 DrawFill = TRUE; 00480 IsFillBlob = FALSE; 00481 } 00482 00483 // Do we need Fill blobs to be rendered 00484 BOOL DrawEffect = FALSE; 00485 if (IsEffectBlob && Blobs.Effect) 00486 { 00487 DrawEffect = TRUE; 00488 IsEffectBlob = FALSE; 00489 } 00490 00491 // Do we need Tiny blobs to be rendered 00492 BOOL DrawTiny = FALSE; 00493 if (IsTinyBlob && Blobs.Tiny) 00494 { 00495 DrawTiny = TRUE; 00496 IsTinyBlob = FALSE; 00497 } 00498 00499 // Do we need Pen blobs to be rendered 00500 BOOL DrawPen = FALSE; 00501 if (IsPenBlob && Blobs.Pen) 00502 { 00503 DrawPen = TRUE; 00504 IsPenBlob = FALSE; 00505 } 00506 00507 // Do we need ToolObject blobs to be rendered 00508 BOOL DrawToolObject = FALSE; 00509 if (IsToolObjectBlob && Blobs.ToolObject) 00510 { 00511 DrawToolObject = TRUE; 00512 IsToolObjectBlob = FALSE; 00513 } 00514 00515 if (!NeedToRenderSelectionBlobs(NULL)) 00516 return; 00517 00518 // EOR on in all the render regions that are still rendering, 00519 // so that the Blob rendering when the region is finished, 00520 // will take them off 00521 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00522 00523 if (!pRegionList->IsEmpty()) 00524 { 00525 // Find out which spread the selection is on 00526 SelRange* Selected = GetApplication()->FindSelection(); 00527 Node* pNode = Selected->FindFirst(); 00528 00529 if (pNode) // Is there a Selection ? 00530 { 00531 Spread* pSpread = pNode->FindParentSpread(); 00532 00533 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 00534 00535 while (pRegion) 00536 { 00537 // Check the RenderRegion is for the same spread. 00538 if (pRegion->GetRenderSpread() == pSpread && 00539 pRegion->GetRenderView()==DocView::GetSelected() && 00540 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 00541 { 00542 // Render the blobs 'clipped' to this Render Region. 00543 DocRect ClipRect = pRegion->GetRegionRect(); 00544 RenderSpecificBlobsOnSelection( &ClipRect, 00545 DrawObject, DrawArtistic, DrawFill, 00546 DrawTiny, DrawPen, DrawToolObject, DrawEffect ); 00547 } 00548 00549 // Get the Next render region 00550 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 00551 } 00552 } 00553 } 00554 00555 RenderSpecificBlobsOnSelection( NULL, DrawObject, DrawArtistic, 00556 DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); 00557 } 00558 00559 /******************************************************************************************** 00560 00561 > BlobStyle BlobManager::GetCurrentInterest(BOOL bIgnoreOffState = FALSE) 00562 00563 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00564 Created: 15/8/94 00565 Inputs: bIgnoreOffState - Flag for use by GetBlobBoundingRect functions so that 00566 they can return correct bounds even when blob rendering is turned off 00567 Returns: A 'BlobStyle' refecting the current blob interest 00568 Purpose: Allows people other than the blobmanager to know what blob are currently 00569 displayed. 00570 SeeAlso: BlobManager::AddInterest; BlobStyle 00571 00572 ********************************************************************************************/ 00573 00574 BlobStyle BlobManager::GetCurrentInterest(BOOL bIgnoreOffState) 00575 { 00576 // Make a default blob style with all interest off. 00577 BlobStyle CurrentBlobs; 00578 00579 if (DrawBlobsAtAll || bIgnoreOffState) 00580 { 00581 // Update it with the current Interest 00582 CurrentBlobs.Fill = IsFillBlob; 00583 CurrentBlobs.Effect = IsEffectBlob; 00584 CurrentBlobs.Object = IsObjectBlob; 00585 CurrentBlobs.Artistic = IsArtisticBlob; 00586 CurrentBlobs.Tiny = IsTinyBlob; 00587 CurrentBlobs.Pen = IsPenBlob; 00588 CurrentBlobs.ToolObject = IsToolObjectBlob; 00589 } 00590 00591 return CurrentBlobs; 00592 } 00593 00594 /******************************************************************************************** 00595 00596 > void BlobManager::BlobRenderingOff(BOOL Redraw) 00597 00598 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00599 Created: 11/7/94 00600 Inputs: Redraw - TRUE if you want the blob to be rendered before blob rendering is 00601 turned off. 00602 Purpose: After calling this function, any attempts to render blobs from anywhere in 00603 Camelot will result in nothing appearing on screen. This is a dangerous 00604 function to call if you are not sure what is going on. 00605 Normally you should use this function if you are about to do something 00606 that will involve the selection state becoming inconsistent with the 00607 blobs on screen and you specifically do not want lots of blob rendering 00608 going on until you have finished. 00609 Here is an example way of using it 00610 MonoOn 00611 // Get rid of the blobs from the screen 00612 BlobMgr->BlobRenderingOff(TRUE); 00613 00614 // Party on the selection and change lots of things 00615 ... 00616 00617 // Invalidate the region of the blobs 00618 ... 00619 00620 // Switch the blob manager back on again 00621 // but leave the rendering of the blobs to the normal OnDraw loop 00622 BlobMgr->BlobRenderingOn(FALSE) 00623 MonoOff 00624 SeeAlso: BlobManager::BlobRenderingOn() 00625 00626 ********************************************************************************************/ 00627 00628 void BlobManager::BlobRenderingOff(BOOL Redraw) 00629 { 00630 RemovingBlobs = TRUE; 00631 00632 if (Redraw && NeedToRenderSelectionBlobs(NULL)) 00633 { 00634 // EOR on in all the render regions that are still rendering, 00635 // so that the Blob rendering when the region is finished, 00636 // will take them off 00637 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00638 00639 if (!pRegionList->IsEmpty()) 00640 { 00641 // Find out which spread the selection is on 00642 SelRange* Selected = GetApplication()->FindSelection(); 00643 Node* pNode = Selected->FindFirst(); 00644 00645 if (pNode) // Is there a Selection ? 00646 { 00647 Spread* pSpread = pNode->FindParentSpread(); 00648 00649 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 00650 00651 while (pRegion) 00652 { 00653 // Check the RenderRegion is for the same spread. 00654 if (pRegion->GetRenderSpread() == pSpread && 00655 pRegion->GetRenderView()==DocView::GetSelected() && 00656 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 00657 { 00658 // Render the blobs 'clipped' to this Render Region. 00659 DocRect ClipRect = pRegion->GetRegionRect(); 00660 RenderRequiredBlobsOnSelection(&ClipRect); 00661 } 00662 00663 // Get the Next render region 00664 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 00665 } 00666 } 00667 } 00668 00669 RenderRequiredBlobsOnSelection(NULL); 00670 } 00671 00672 // Mark blob rendering to be off 00673 DrawBlobsAtAll = FALSE; 00674 00675 // Bodge to stop fill meshes EOR each other out. 00676 AttrFillGeometry::LastRenderedMesh = NULL; 00677 } 00678 00679 00680 /******************************************************************************************** 00681 00682 > void BlobManager::BlobRenderingOn(BOOL Redraw) 00683 00684 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00685 Created: 11/7/94 00686 Inputs: Redraw - TRUE if you want the blobs to be rendered before blob rendering is 00687 turned on. 00688 Purpose: If blob rendering has been turned off ( by calling BlobRenderinOff() ) 00689 then this function will re-enable it so that rendering can carry on 00690 like normal. Ideally this should be called not very long after calling 00691 BlobRenderingOff(). 00692 SeeAlso: BlobManager::BlobRenderingOn() 00693 00694 ********************************************************************************************/ 00695 00696 void BlobManager::BlobRenderingOn(BOOL Redraw) 00697 { 00698 RemovingBlobs = FALSE; 00699 00700 if (Redraw && NeedToRenderSelectionBlobs(NULL)) 00701 { 00702 RenderRequiredBlobsOnSelection(NULL); 00703 00704 // Now EOR off in all the render regions that are still rendering, 00705 // so that the Blob rendering when the region is finished, 00706 // will put them on 00707 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00708 00709 if (!pRegionList->IsEmpty()) 00710 { 00711 // Find out which spread the selection is on 00712 SelRange* Selected = GetApplication()->FindSelection(); 00713 Node* pNode = Selected->FindFirst(); 00714 00715 if (pNode) // Is there a Selection ? 00716 { 00717 Spread* pSpread = pNode->FindParentSpread(); 00718 00719 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 00720 00721 while (pRegion) 00722 { 00723 // Check the RenderRegion is for the same spread. 00724 if (pRegion->GetRenderSpread() == pSpread && 00725 pRegion->GetRenderView()==DocView::GetSelected() && 00726 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 00727 { 00728 // Render the blobs 'clipped' to this Render Region. 00729 DocRect ClipRect = pRegion->GetRegionRect(); 00730 RenderRequiredBlobsOnSelection(&ClipRect); 00731 } 00732 00733 // Get the Next render region 00734 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 00735 } 00736 } 00737 } 00738 } 00739 00740 // Mark blob rendering to be on 00741 DrawBlobsAtAll = TRUE; 00742 00743 // Bodge to stop fill meshes EOR each other out. 00744 AttrFillGeometry::LastRenderedMesh = NULL; 00745 } 00746 00747 00748 00749 00750 /******************************************************************************************** 00751 00752 > INT32 BlobManager::GetBlobSize() 00753 00754 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00755 Created: 27/6/94 00756 Returns: INT32 - The size (in DocCoords) of a blob. 00757 Purpose: This function allows you to find out how wide a blob should be. 00758 00759 ********************************************************************************************/ 00760 00761 INT32 BlobManager::GetBlobSize() 00762 { 00763 // To do this, we need to find out how big a blobs rect is 00764 DocRect Rect; 00765 GetBlobRect(DocCoord(0,0), &Rect); 00766 00767 // return the width of the resulting rect 00768 return Rect.Width(); 00769 } 00770 00771 00772 00773 /******************************************************************************************** 00774 00775 > void BlobManager::GetBlobRect(DocCoord& Centre, DocRect* Rect) 00776 00777 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00778 Created: 27/6/94 00779 Inputs: Centre - The coordinate to centre the blob on 00780 MFill = Whether we should force this routine to use multi-stage fill routine 00781 Outputs: Rect - The rect in DocCoords of the blobs 00782 Purpose: Finds the rectangle of a blob that surrounds a given coord. This is to 00783 replace the rather long winded method that had to be employed before. If 00784 there is no selected document it will leave the rect unchanged. 00785 00786 Karim 22/05/2000 - modified this method to take a BlobType param. Note that 00787 you *cannot* make use of this new param until the MFill param is removed and 00788 all current instances of GetBlobRect() updated. The new param is currently 00789 only checked against my ClipView blob type. 00790 00791 ********************************************************************************************/ 00792 00793 void BlobManager::GetBlobRect( const DocCoord &Centre, DocRect *Rect, BOOL MFill /*= FALSE*/, 00794 BlobType eBlobType) 00795 { 00796 // We will be needing a view to do this 00797 DocView* pDocView = DocView::GetSelected(); 00798 00799 // Find out how big a rect is these days, if we have a view 00800 if (pDocView!=NULL) 00801 { 00802 switch (eBlobType) 00803 { 00804 case BT_CLIPVIEW: 00805 OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_CLIPVIEW, Rect); 00806 break; 00807 00808 default: 00809 if (!MFill) 00810 { 00811 OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_SELECTEDLARGEST, Rect); 00812 } 00813 else 00814 { 00815 OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), Centre, BT_MSTAGESELECTEDLARGEST, Rect); 00816 } 00817 break; 00818 } 00819 } 00820 } 00821 00822 00823 /******************************************************************************************** 00824 00825 > void BlobManager::Render(DocRect Rect, Spread *pSpread) 00826 00827 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00828 Created: 16/6/94 00829 Purpose: This function will render all the blobs that are currently being displayed 00830 for the given clipping rectangle. 00831 00832 ********************************************************************************************/ 00833 00834 void BlobManager::Render(DocRect* Rect, Spread *pSpread) 00835 { 00836 // If we are not drawing blobs today, then return straight away 00837 if (!DrawBlobsAtAll) 00838 return; 00839 00840 // Now render the sections that need to be rendered to get the corrent blobs on screen 00841 RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); 00842 while (pRegion) 00843 { 00844 // Find out the clipping rect of this region 00845 DocRect TestRect = pRegion->GetClipRect(); 00846 00847 // Find the first selected object in the tree; 00848 SelRange* Selected = GetApplication()->FindSelection(); 00849 00850 // Karim 29/06/2000 00851 // PromoteToParent should never be set TRUE on the selection range, outside 00852 // of code in which its modifications are required. 00853 // I have included a TRACE statement here, as a 'quiet' note to programmers, 00854 // should this occur. 00855 RangeControl rc = Selected->GetRangeControlFlags(); 00856 if (rc.PromoteToParent) 00857 { 00858 TRACE( _T("BlobManager::Render; PromoteToParent is TRUE! Read inline comment for details.\n")); 00859 rc.PromoteToParent = FALSE; 00860 Selected->Range::SetRangeControl(rc); 00861 } 00862 00863 Node* pNode = Selected->FindFirst(); 00864 while(pNode) 00865 { 00866 // Render only the required blobs 00867 if (pNode->IsBounded()) 00868 { 00869 // This node is bounded, so see if we really need to render it 00870 if (TestRect.IsIntersectedWith(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect())) 00871 RenderRequiredBlobs((NodeRenderable*)pNode, pRegion); 00872 } 00873 else 00874 { 00875 // Always render it if it is not bounded (probably an Attribute) 00876 RenderRequiredBlobs((NodeRenderable*)pNode, pRegion); 00877 } 00878 00879 // Find the next selected node to render 00880 pNode = Selected->FindNext(pNode); 00881 } 00882 00883 // Go find the next region 00884 pRegion = DocView::GetNextOnTop(Rect); 00885 } 00886 00887 // Bodge to stop fill meshes EOR each other out. 00888 AttrFillGeometry::LastRenderedMesh = NULL; 00889 } 00890 00891 /******************************************************************************************** 00892 00893 > void BlobManager::RenderOn(DocRect Rect, Spread *pSpread) 00894 00895 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00896 Created: 13/6/95 00897 Purpose: This function will render on all the blobs that are currently being displayed 00898 for the given clipping rectangle. 00899 00900 ********************************************************************************************/ 00901 00902 void BlobManager::RenderOn(DocRect* Rect, Spread *pSpread) 00903 { 00904 RemovingBlobs = FALSE; 00905 00906 // If we are not drawing blobs today, then return straight away 00907 if (!DrawBlobsAtAll) 00908 return; 00909 00910 // Are we in the middle of a Background redraw ? 00911 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00912 if (pRegionList->IsEmpty()) 00913 { 00914 // Nope, so do stuff as normal 00915 00916 // Draw the blobs on 00917 Render(Rect, pSpread); 00918 00919 // Stop fill meshes EORing each other out. 00920 AttrFillGeometry::LastRenderedMesh = NULL; 00921 return; 00922 } 00923 00924 // We must be background rendering ... 00925 // So lets try a bit of an optimisation 00926 00927 // If the Blob we are about to render, is completely contained 00928 // within a pending Render Region, then we don't need to 00929 // render anything 00930 00931 if (!NeedToRenderSelectionBlobs(Rect)) 00932 return; 00933 00934 // Oh well, lets render some blobs then 00935 00936 // Draw the blobs on 00937 Render(Rect, pSpread); 00938 00939 // Stop fill meshes EORing each other out. 00940 AttrFillGeometry::LastRenderedMesh = NULL; 00941 00942 // Now EOR off in all the render regions that are still rendering, 00943 // so that the Blob rendering when the region is finished, 00944 // will put them on 00945 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 00946 00947 while (pRegion) 00948 { 00949 // Check the RenderRegion is for the same spread. 00950 if (pRegion->GetRenderSpread() == pSpread && 00951 pRegion->GetRenderView()==DocView::GetSelected() && 00952 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 00953 { 00954 // Render the blobs 'clipped' to this Render Region. 00955 DocRect ClipRect = pRegion->GetRegionRect(); 00956 Render(&ClipRect, pSpread); 00957 } 00958 00959 // Get the Next render region 00960 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 00961 } 00962 00963 // Stop fill meshes EORing each other out. 00964 AttrFillGeometry::LastRenderedMesh = NULL; 00965 } 00966 00967 /******************************************************************************************** 00968 00969 > void BlobManager::RenderOff(DocRect Rect, Spread *pSpread) 00970 00971 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00972 Created: 13/6/95 00973 Purpose: This function will render off all the blobs that are currently being displayed 00974 for the given clipping rectangle. 00975 00976 ********************************************************************************************/ 00977 00978 void BlobManager::RenderOff(DocRect* Rect, Spread *pSpread) 00979 { 00980 RemovingBlobs = TRUE; 00981 00982 // If we are not drawing blobs today, then return straight away 00983 if (!DrawBlobsAtAll) 00984 return; 00985 00986 // Are we in the middle of a Background redraw ? 00987 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 00988 if (pRegionList->IsEmpty()) 00989 { 00990 // Nope, so do stuff as normal 00991 00992 // Draw the blobs on 00993 Render(Rect, pSpread); 00994 00995 // Stop fill meshes EORing each other out. 00996 AttrFillGeometry::LastRenderedMesh = NULL; 00997 return; 00998 } 00999 01000 // We must be background rendering ... 01001 // So lets try a bit of an optimisation 01002 01003 // If the Blob we are about to render, is completely contained 01004 // within a pending Render Region, then we don't need to 01005 // render anything 01006 01007 if (!NeedToRenderSelectionBlobs(Rect)) 01008 return; 01009 01010 // Oh well, lets render some blobs then 01011 01012 // EOR on in all the render regions that are still rendering, 01013 // so that the Blob rendering when the region is finished, 01014 // will take them off 01015 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01016 01017 while (pRegion) 01018 { 01019 // Check the RenderRegion is for the same spread. 01020 if (pRegion->GetRenderSpread() == pSpread && 01021 pRegion->GetRenderView()==DocView::GetSelected() && 01022 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01023 { 01024 // Render the blobs 'clipped' to this Render Region. 01025 DocRect ClipRect = pRegion->GetRegionRect(); 01026 Render(&ClipRect, pSpread); 01027 } 01028 01029 // Get the Next render region 01030 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01031 } 01032 01033 // Stop fill meshes EORing each other out. 01034 AttrFillGeometry::LastRenderedMesh = NULL; 01035 01036 // Draw the blobs off 01037 Render(Rect, pSpread); 01038 01039 // Stop fill meshes EORing each other out. 01040 AttrFillGeometry::LastRenderedMesh = NULL; 01041 } 01042 01043 /******************************************************************************************** 01044 01045 > void BlobManager::RenderMyBlobs(NodeRenderable* pNode) 01046 01047 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01048 Created: 17/6/94 01049 Inputs: pNode - The node to render the blobs of 01050 Purpose: Renders the blobs for the given node. Only the required blobs are rendered 01051 and since the blobs are EOR rendered, this function can be used to put 01052 the blobs onto the screen or take them off the screen 01053 01054 ********************************************************************************************/ 01055 01056 void BlobManager::RenderMyBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01057 { 01058 // If we are not drawing blobs today, then return straight away 01059 if (!DrawBlobsAtAll) 01060 return; 01061 01062 // Now render the sections that need to be rendered to get the corrent blobs on screen 01063 RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); 01064 while (pRegion) 01065 { 01066 // Find out the clipping rect of this region 01067 DocRect TestRect = pRegion->GetClipRect(); 01068 01069 // Render only the blobs that need to be drawn 01070 if (pNode->IsBounded()) 01071 { 01072 // This node is bounded, so see if we really need to render it 01073 if (TestRect.IsIntersectedWith(((NodeRenderableBounded*)pNode)->GetBlobBoundingRect())) 01074 RenderRequiredBlobs(pNode, pRegion); 01075 } 01076 else 01077 { 01078 // Always render it if it is not bounded (probably an Attribute) 01079 RenderRequiredBlobs(pNode, pRegion); 01080 } 01081 01082 // Go find the next region 01083 pRegion = DocView::GetNextOnTop(Rect); 01084 } 01085 } 01086 01087 /******************************************************************************************** 01088 01089 > void BlobManager::RenderMyBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01090 01091 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01092 Created: 13/6/95 01093 Purpose: This function will render on all the blobs that are currently being displayed 01094 for the given clipping rectangle. 01095 01096 ********************************************************************************************/ 01097 01098 void BlobManager::RenderMyBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01099 { 01100 RemovingBlobs = FALSE; 01101 01102 // If we are not drawing blobs today, then return straight away 01103 if (!DrawBlobsAtAll) 01104 return; 01105 01106 // Are we in the middle of a Background redraw ? 01107 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01108 if (pRegionList->IsEmpty()) 01109 { 01110 // Nope, so do stuff as normal 01111 01112 // Draw the blobs on 01113 RenderMyBlobs(Rect, pSpread, pNode); 01114 return; 01115 } 01116 01117 // We must be background rendering ... 01118 01119 // So lets try a bit of an optimisation 01120 if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) 01121 return; 01122 01123 // Oh well, lets render some blobs then 01124 01125 // Draw the blobs on 01126 RenderMyBlobs(Rect, pSpread, pNode); 01127 01128 // Stop fill meshes EORing each other out. 01129 FillGeometryAttribute* pLastMesh = AttrFillGeometry::LastRenderedMesh; 01130 AttrFillGeometry::LastRenderedMesh = NULL; 01131 01132 // Now EOR off in all the render regions that are still rendering, 01133 // so that the Blob rendering when the region is finished, 01134 // will put them on 01135 01136 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01137 01138 while (pRegion) 01139 { 01140 // Check the RenderRegion is for the same spread. 01141 if (pRegion->GetRenderSpread() == pSpread && 01142 pRegion->GetRenderView()==DocView::GetSelected() && 01143 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01144 { 01145 // Render the blobs 'clipped' to this Render Region. 01146 DocRect ClipRect = pRegion->GetRegionRect(); 01147 RenderMyBlobs(&ClipRect, pSpread, pNode); 01148 } 01149 01150 // Get the Next render region 01151 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01152 } 01153 01154 // Stop fill meshes EORing each other out. 01155 AttrFillGeometry::LastRenderedMesh = pLastMesh; 01156 } 01157 01158 /******************************************************************************************** 01159 01160 > void BlobManager::RenderMyBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01161 01162 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01163 Created: 13/6/95 01164 Purpose: This function will render off all the blobs that are currently being displayed 01165 for the given clipping rectangle. 01166 01167 ********************************************************************************************/ 01168 01169 void BlobManager::RenderMyBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01170 { 01171 RemovingBlobs = TRUE; 01172 01173 // If we are not drawing blobs today, then return straight away 01174 if (!DrawBlobsAtAll) 01175 return; 01176 01177 // Are we in the middle of a Background redraw ? 01178 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01179 if (pRegionList->IsEmpty()) 01180 { 01181 // Nope, so do stuff as normal 01182 01183 // Draw the blobs off 01184 RenderMyBlobs(Rect, pSpread, pNode); 01185 return; 01186 } 01187 01188 // We must be background rendering ... 01189 01190 // So lets try a bit of an optimisation 01191 if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) 01192 return; 01193 01194 // Oh well, lets render some blobs then 01195 01196 // EOR on in all the render regions that are still rendering, 01197 // so that the Blob rendering when the region is finished, 01198 // will take them off 01199 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01200 01201 while (pRegion) 01202 { 01203 // Check the RenderRegion is for the same spread. 01204 if (pRegion->GetRenderSpread() == pSpread && 01205 pRegion->GetRenderView()==DocView::GetSelected() && 01206 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01207 { 01208 // Render the blobs 'clipped' to this Render Region. 01209 DocRect ClipRect = pRegion->GetRegionRect(); 01210 RenderMyBlobs(&ClipRect, pSpread, pNode); 01211 } 01212 01213 // Get the Next render region 01214 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01215 } 01216 01217 // Stop fill meshes EORing each other out. 01218 FillGeometryAttribute* pLastMesh = AttrFillGeometry::LastRenderedMesh; 01219 AttrFillGeometry::LastRenderedMesh = NULL; 01220 01221 // Draw the blobs off 01222 RenderMyBlobs(Rect, pSpread, pNode); 01223 01224 // Stop fill meshes EORing each other out. 01225 AttrFillGeometry::LastRenderedMesh = pLastMesh; 01226 } 01227 01228 /******************************************************************************************** 01229 01230 > void BlobManager::RenderObjectBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01231 01232 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01233 Created: 13/6/95 01234 Purpose: This function will render on all the blobs that are currently being displayed 01235 for the given clipping rectangle. 01236 01237 ********************************************************************************************/ 01238 01239 void BlobManager::RenderObjectBlobsOn(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01240 { 01241 RemovingBlobs = FALSE; 01242 01243 // Are we in the middle of a Background redraw ? 01244 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01245 if (pRegionList->IsEmpty()) 01246 { 01247 // Nope, so do stuff as normal 01248 01249 // Draw the blobs on 01250 RenderObjectBlobs(Rect, pSpread, pNode); 01251 return; 01252 } 01253 01254 // We must be background rendering ... 01255 01256 // So lets try a bit of an optimisation 01257 if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) 01258 return; 01259 01260 // Oh well, lets render some blobs then 01261 01262 // Draw the blobs on 01263 RenderObjectBlobs(Rect, pSpread, pNode); 01264 01265 // EOR off in all the render regions that are still rendering, 01266 // so that the Blob rendering when the region is finished, 01267 // will put them on 01268 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01269 01270 while (pRegion) 01271 { 01272 // Check the RenderRegion is for the same spread. 01273 if (pRegion->GetRenderSpread() == pSpread && 01274 pRegion->GetRenderView()==DocView::GetSelected() && 01275 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01276 { 01277 // Render the blobs 'clipped' to this Render Region. 01278 DocRect ClipRect = pRegion->GetRegionRect(); 01279 01280 // Render what we need to 01281 RenderObjectBlobs(&ClipRect, pSpread, pNode); 01282 } 01283 01284 // Get the Next render region 01285 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01286 } 01287 } 01288 01289 /******************************************************************************************** 01290 01291 > void BlobManager::RenderObjectBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01292 01293 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01294 Created: 13/6/95 01295 Purpose: This function will render off all the blobs that are currently being displayed 01296 for the given clipping rectangle. 01297 01298 ********************************************************************************************/ 01299 01300 void BlobManager::RenderObjectBlobsOff(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01301 { 01302 RemovingBlobs = TRUE; 01303 01304 // Are we in the middle of a Background redraw ? 01305 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01306 if (pRegionList->IsEmpty()) 01307 { 01308 // Nope, so do stuff as normal 01309 01310 // Draw the blobs off 01311 RenderObjectBlobs(Rect, pSpread, pNode); 01312 return; 01313 } 01314 01315 // We must be background rendering ... 01316 01317 // So lets try a bit of an optimisation 01318 if (!NeedToRenderNodeBlobs(Rect, pSpread, pNode)) 01319 return; 01320 01321 // Oh well, lets render some blobs then 01322 01323 // EOR on in all the render regions that are still rendering, 01324 // so that the Blob rendering when the region is finished, 01325 // will take them off 01326 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01327 01328 while (pRegion) 01329 { 01330 // Check the RenderRegion is for the same spread. 01331 if (pRegion->GetRenderSpread() == pSpread && 01332 pRegion->GetRenderView()==DocView::GetSelected() && 01333 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01334 { 01335 // Render the blobs 'clipped' to this Render Region. 01336 DocRect ClipRect = pRegion->GetRegionRect(); 01337 01338 // Render what we need to 01339 RenderObjectBlobs(&ClipRect, pSpread, pNode); 01340 } 01341 01342 // Get the Next render region 01343 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01344 } 01345 01346 // Draw the blobs off 01347 RenderObjectBlobs(Rect, pSpread, pNode); 01348 } 01349 01350 /******************************************************************************************** 01351 01352 > void BlobManager::RenderObjectBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01353 01354 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01355 Created: 13/6/95 01356 Purpose: This function will render all the blobs that are currently being displayed 01357 for the given clipping rectangle. 01358 01359 ********************************************************************************************/ 01360 01361 void BlobManager::RenderObjectBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01362 { 01363 RenderRegion* pOnTopRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); 01364 while (pOnTopRegion) 01365 { 01366 pNode->RenderObjectBlobs(pOnTopRegion); 01367 01368 // Go find the next region 01369 pOnTopRegion = DocView::GetNextOnTop(Rect); 01370 } 01371 } 01372 01373 /******************************************************************************************** 01374 01375 > void BlobManager::RenderRequiredBlobs(NodeRenderable* pNode, RenderRegion* pRegion) 01376 01377 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01378 Created: 22/6/94 01379 Inputs: pNode - The Node whos blobs need rendering 01380 pRegion - The render region to draw into 01381 Purpose: Renders the required blobs for the given node into the given render region. 01382 The required blobs are specified by the tool when it is activated. 01383 01384 ********************************************************************************************/ 01385 01386 void BlobManager::RenderRequiredBlobs(NodeRenderable* pNode, RenderRegion* pRegion) 01387 { 01388 // We know that the node is a renderable ink as it is selected 01389 ENSURE( pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), "Selected object was not Renderable!"); 01390 01391 // Render the Object Blobs of this node 01392 if (IsObjectBlob) 01393 pNode->RenderObjectBlobs(pRegion); 01394 01395 // Render the Artistic blobs of this node 01396 if (IsArtisticBlob) 01397 pNode->RenderArtisticBlobs(pRegion); 01398 01399 // Render the Fill blobs of this node 01400 if (IsFillBlob) 01401 pNode->RenderAppliedFillBlobs(pRegion); 01402 01403 // Render the Fill blobs of this node 01404 if (IsEffectBlob) 01405 pNode->RenderEffectBlobs(pRegion); 01406 01407 // Render the tiny blobs of this node 01408 if (IsTinyBlob) 01409 pNode->RenderTinyBlobs(pRegion); 01410 01411 // Render the pen blobs of this node 01412 if (IsPenBlob) 01413 pNode->RenderPenBlobs(pRegion); 01414 01415 // Render the ToolObject blobs of this node 01416 if (IsToolObjectBlob) 01417 pNode->RenderToolObjectBlobs(pRegion); 01418 } 01419 01420 /******************************************************************************************** 01421 01422 > void BlobManager::RenderRequiredBlobsOnSelection(DocRect* Rect) 01423 01424 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01425 Created: 14/6/95 01426 Inputs: pNode - The Node whos blobs need rendering 01427 pRegion - The render region to draw into 01428 Purpose: Renders the required blobs for the given node into the given render region. 01429 The required blobs are specified by the tool when it is activated. 01430 01431 ********************************************************************************************/ 01432 01433 void BlobManager::RenderRequiredBlobsOnSelection(DocRect* Rect) 01434 { 01435 // Find out which spread the selection is on 01436 SelRange* Selected = GetApplication()->FindSelection(); 01437 Node* pNode = Selected->FindFirst(); 01438 01439 // go and render the blobs if there are any selected nodes 01440 if (pNode!=NULL && DrawBlobsAtAll) 01441 { 01442 Spread* pSpread = pNode->FindParentSpread(); 01443 01444 // Render what we need to 01445 RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); 01446 while (pRegion) 01447 { 01448 // Find the first selected object in the tree; 01449 Node* pNode = Selected->FindFirst(); 01450 while(pNode) 01451 { 01452 // Render only those blobs that are changing state (ie those appearing or disappearing) 01453 RenderRequiredBlobs((NodeRenderable*) pNode, pRegion); 01454 01455 // Find the next selected node to render 01456 pNode = Selected->FindNext(pNode); 01457 } 01458 01459 // Go find the next region 01460 pRegion = DocView::GetNextOnTop(Rect); 01461 } 01462 } 01463 01464 // Bodge to stop fill meshes EOR each other out. 01465 AttrFillGeometry::LastRenderedMesh = NULL; 01466 } 01467 01468 /******************************************************************************************** 01469 01470 > void BlobManager::RenderSpecificBlobs(NodeRenderable* pNode, RenderRegion* pRegion, 01471 BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, 01472 BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) 01473 01474 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01475 Created: 22/6/94 01476 Inputs: pNode - The node to draw the blobs for 01477 pRegion - The region to render them into 01478 DrawObject - Do we want to draw the Object Blobs 01479 DrawArtistic - Do we want to draw the Artistic Blobs 01480 DrawFill - Do we want to draw the Fill Blobs 01481 DrawTiny - Do we want to draw the Tiny Blobs 01482 DrawPen - Do we want to draw the Pen Blobs 01483 DrawToolObject - Do we want to draw the ToolObject Blobs 01484 Purpose: Renders only the blobs specified. This is called from the Add and Remove 01485 Interest Functions to add new types of blob to the display or take types of 01486 blob that are no longer needed off the display. 01487 01488 ********************************************************************************************/ 01489 01490 void BlobManager::RenderSpecificBlobs(NodeRenderable* pNode, RenderRegion* pRegion, 01491 BOOL DrawObject, BOOL DrawArtistic, BOOL DrawFill, BOOL DrawTiny, 01492 BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) 01493 { 01494 // We know that the node is a renderable ink as it is selected 01495 ENSURE( pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), "Selected object was not Renderable!"); 01496 01497 // Render the Object Blobs of this node 01498 if (DrawObject) 01499 pNode->RenderObjectBlobs(pRegion); 01500 01501 // Render the Artistic blobs of this node 01502 if (DrawArtistic) 01503 pNode->RenderArtisticBlobs(pRegion); 01504 01505 // Render the Fill blobs of this node 01506 if (DrawFill) 01507 pNode->RenderAppliedFillBlobs(pRegion); 01508 01509 // Render the tiny blobs of this node 01510 if (DrawTiny) 01511 pNode->RenderTinyBlobs(pRegion); 01512 01513 // Render the Pen blobs of this node 01514 if (DrawPen) 01515 pNode->RenderPenBlobs(pRegion); 01516 01517 // Render the ToolObject blobs of this node 01518 if (DrawToolObject) 01519 pNode->RenderToolObjectBlobs(pRegion); 01520 01521 // Render the Effect blobs of this node 01522 if (DrawEffect) 01523 pNode->RenderEffectBlobs(pRegion); 01524 } 01525 01526 /******************************************************************************************** 01527 01528 > void BlobManager::RenderSpecificBlobsOnSelection(BOOL DrawObject, BOOL DrawArtistic, 01529 BOOL DrawFill, BOOL DrawTiny, 01530 BOOL DrawPen, BOOL DrawToolObject, BOOL DrawEffect) 01531 01532 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01533 Created: 13/6/95 01534 Inputs: pNode - The node to draw the blobs for 01535 pRegion - The region to render them into 01536 DrawObject - Do we want to draw the Object Blobs 01537 DrawArtistic - Do we want to draw the Artistic Blobs 01538 DrawFill - Do we want to draw the Fill Blobs 01539 DrawTiny - Do we want to draw the Tiny Blobs 01540 DrawPen - Do we want to draw the Pen Blobs 01541 DrawToolObject - Do we want to draw the ToolObject Blobs 01542 Purpose: Renders only the blobs specified. This is called from the Add and Remove 01543 Interest Functions to add new types of blob to the display or take types of 01544 blob that are no longer needed off the display. 01545 01546 ********************************************************************************************/ 01547 01548 void BlobManager::RenderSpecificBlobsOnSelection( DocRect* Rect, BOOL DrawObject, 01549 BOOL DrawArtistic, BOOL DrawFill, 01550 BOOL DrawTiny, BOOL DrawPen, 01551 BOOL DrawToolObject, BOOL DrawEffect ) 01552 { 01553 // Find out which spread the selection is on 01554 SelRange* Selected = GetApplication()->FindSelection(); 01555 Node* pNode = Selected->FindFirst(); 01556 01557 // go and render the blobs if there are any selected nodes 01558 if (pNode!=NULL && DrawBlobsAtAll) 01559 { 01560 Spread* pSpread = pNode->FindParentSpread(); 01561 01562 // Render what we need to 01563 RenderRegion* pRegion = DocView::RenderOnTop(Rect, pSpread, ClippedEOR); 01564 while (pRegion) 01565 { 01566 // Find the first selected object in the tree; 01567 Node* pNode = Selected->FindFirst(); 01568 while(pNode) 01569 { 01570 // Render only those blobs that are changing state (ie those appearing or disappearing) 01571 RenderSpecificBlobs((NodeRenderable*)pNode, pRegion, DrawObject, DrawArtistic, 01572 DrawFill, DrawTiny, DrawPen, DrawToolObject, DrawEffect); 01573 01574 // Find the next selected node to render 01575 pNode = Selected->FindNext(pNode); 01576 } 01577 01578 // Go find the next region 01579 pRegion = DocView::GetNextOnTop(Rect); 01580 } 01581 } 01582 01583 // Bodge to stop fill meshes EOR each other out. 01584 AttrFillGeometry::LastRenderedMesh = NULL; 01585 } 01586 01587 /******************************************************************************************** 01588 01589 > MsgResult BlobManager::Message(Msg* Message) 01590 01591 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01592 Created: 29/6/94 01593 Inputs: Message - the message to examine 01594 Returns: - 01595 Purpose: Handles the View Changing message, and makes sure that the blobs are 01596 removed from the old view and drawn onto the new view 01597 01598 ********************************************************************************************/ 01599 01600 MsgResult BlobManager::Message(Msg* Message) 01601 { 01602 if (MESSAGE_IS_A(Message, DocViewMsg)) 01603 { 01604 // Get a version of the message in the right type 01605 DocViewMsg* pDocViewMsg = (DocViewMsg*) Message; 01606 01607 switch (pDocViewMsg->State) 01608 { 01609 // respond to messages that arrive just before and just after the view has changed. 01610 case DocViewMsg::SELABOUTTOCHANGE: 01611 case DocViewMsg::SELCHANGED: 01612 { 01613 // rub blobs off old view or draw them in on the new one 01614 if (DocView::GetSelected()!=NULL) 01615 { 01616 // go find the selection 01617 SelRange* Selected = GetApplication()->FindSelection(); 01618 01619 // Have to be sure that the selection is correct for the view 01620 Selected->Update(); 01621 Node* pNode = Selected->FindFirst(); 01622 01623 // If there is something selected 01624 if (pNode!=NULL) 01625 { 01626 // Find its spread 01627 Spread* pSpread = pNode->FindParentSpread(); 01628 if (pSpread!=NULL) 01629 { 01630 // and render the blobs 01631 Render(NULL, pSpread); 01632 } 01633 } 01634 } 01635 break; 01636 } 01637 01638 01639 default: 01640 break; 01641 } 01642 } 01643 01644 return OK; 01645 } 01646 01647 /******************************************************************************************** 01648 01649 > void BlobManager::RenderToolBlobsOn(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) 01650 01651 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01652 Created: 13/6/95 01653 Purpose: This function will render on the specified tools blobs. 01654 01655 ********************************************************************************************/ 01656 01657 void BlobManager::RenderToolBlobsOn(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) 01658 { 01659 // If we are not drawing blobs today, then return straight away 01660 if (!DrawBlobsAtAll) 01661 return; 01662 01663 // Put the tool blobs on 01664 pTool->RenderToolBlobs(pSpread, pClipRect); 01665 01666 // Now EOR off in all the render regions that are still rendering, 01667 // so that the Blob rendering when the region is finished, 01668 // will put them on 01669 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01670 01671 if (!pRegionList->IsEmpty()) 01672 { 01673 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01674 01675 while (pRegion) 01676 { 01677 // Check the RenderRegion is for the same spread. 01678 if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected()) 01679 { 01680 // Render the blobs 'clipped' to this Render Region. 01681 DocRect ClipRect = pRegion->GetRegionRect(); 01682 pTool->RenderToolBlobs(pSpread, &ClipRect); 01683 } 01684 01685 // Get the Next render region 01686 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01687 } 01688 } 01689 bToolBlobsAreOff = FALSE; 01690 } 01691 01692 /******************************************************************************************** 01693 01694 > void BlobManager::RenderToolBlobsOff(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) 01695 01696 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01697 Created: 13/6/95 01698 Purpose: This function will render off the specified tools blobs. 01699 01700 ********************************************************************************************/ 01701 01702 void BlobManager::RenderToolBlobsOff(Tool_v1* pTool, Spread* pSpread, DocRect* pClipRect) 01703 { 01704 // If we are not drawing blobs today, then return straight away 01705 if (!DrawBlobsAtAll) 01706 return; 01707 01708 // if (bToolBlobsAreOff) 01709 // return; 01710 01711 // EOR on in all the render regions that are still rendering, 01712 // so that the Blob rendering when the region is finished, 01713 // will take them off 01714 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01715 01716 if (!pRegionList->IsEmpty()) 01717 { 01718 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01719 01720 while (pRegion) 01721 { 01722 // Check the RenderRegion is for the same spread. 01723 if (pRegion->GetRenderSpread() == pSpread && pRegion->GetRenderView()==DocView::GetSelected()) 01724 { 01725 // Render the blobs 'clipped' to this Render Region. 01726 DocRect ClipRect = pRegion->GetRegionRect(); 01727 pTool->RenderToolBlobs(pSpread, &ClipRect); 01728 } 01729 01730 // Get the Next render region 01731 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01732 } 01733 } 01734 01735 // Take the tool blobs off 01736 pTool->RenderToolBlobs(pSpread, pClipRect); 01737 bToolBlobsAreOff = TRUE; 01738 } 01739 01740 /******************************************************************************************** 01741 01742 > BOOL BlobManager::NeedToRenderSelectionBlobs(DocRect* Rect) 01743 01744 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01745 Created: 15/6/95 01746 Purpose: Check to make sure we need to render some blobs. 01747 01748 ********************************************************************************************/ 01749 01750 BOOL BlobManager::NeedToRenderSelectionBlobs(DocRect* Rect) 01751 { 01752 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01753 if (pRegionList->IsEmpty()) 01754 return TRUE; 01755 01756 // Find the first selected object in the tree; 01757 SelRange* Selected = GetApplication()->FindSelection(); 01758 01759 if (Selected->Count() == 0) 01760 return FALSE; // Nothing to render 01761 01762 Node* pNode = Selected->FindFirst(); 01763 Spread* pSpread = pNode->FindParentSpread(); 01764 01765 // Find out the blob rect of the selection 01766 DocRect SelRect = Selected->GetBlobBoundingRect(); 01767 01768 // If a clip rect was given, and it doesn't completely contain the sel bounds, 01769 // then we'll have to use that 01770 if (Rect && !Rect->ContainsRect(SelRect)) 01771 SelRect = *Rect; 01772 01773 if (!SelRect.IsEmpty()) 01774 { 01775 // So lets check the pending regions 01776 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01777 01778 while (pRegion) 01779 { 01780 // Check the RenderRegion is for the same spread. 01781 if (pRegion->GetRenderSpread() == pSpread && 01782 pRegion->GetRenderView()==DocView::GetSelected() && 01783 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01784 { 01785 // Get the 'clip' rect of this Render Region. 01786 DocRect ClipRect = pRegion->GetRegionRect(); 01787 01788 // If any of the RenderRegions completely contain the rect 01789 // then there is no point in rendering anything 01790 01791 if (ClipRect.ContainsRect(SelRect)) 01792 return FALSE; // We don't need to render any blobs 01793 } 01794 01795 // Get the Next render region 01796 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01797 } 01798 } 01799 return TRUE; 01800 } 01801 01802 /******************************************************************************************** 01803 01804 > BOOL BlobManager::NeedToRenderNodeBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01805 01806 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01807 Created: 15/6/95 01808 Purpose: Check to make sure we need to render some blobs. 01809 01810 ********************************************************************************************/ 01811 01812 BOOL BlobManager::NeedToRenderNodeBlobs(DocRect* Rect, Spread *pSpread, NodeRenderable* pNode) 01813 { 01814 RenderRegionList* pRegionList = GetApplication()->GetRegionList(); 01815 if (pRegionList->IsEmpty()) 01816 return TRUE; 01817 01818 if (Rect != NULL || pNode->IsBounded()) 01819 { 01820 // If the Blob we are about to render, is completely contained 01821 // within a pending Render Region, then we don't need to 01822 // render anything 01823 01824 // Find out the blob rect of this node, if we can 01825 DocRect NodeRect = DocRect(0,0,0,0); 01826 01827 if (pNode->IsBounded()) 01828 { 01829 // Use the node's blob bounds 01830 NodeRect = ((NodeRenderableBounded*)pNode)->GetBlobBoundingRect(); 01831 } 01832 01833 // If a clip rect was given, and it doesn't completely contain the node rect, 01834 // then we'll have to use that 01835 if (Rect && !Rect->ContainsRect(NodeRect)) 01836 NodeRect = *Rect; 01837 01838 if (!NodeRect.IsEmpty()) 01839 { 01840 // So lets check the pending regions 01841 RenderRegion* pRegion = (RenderRegion*)pRegionList->GetHead(); 01842 01843 while (pRegion) 01844 { 01845 // Check the RenderRegion is for the same spread. 01846 if (pRegion->GetRenderSpread() == pSpread && 01847 pRegion->GetRenderView()==DocView::GetSelected() && 01848 (pRegion->IsInkRenderStarted || pRegion->NeedsOSPaper)) 01849 { 01850 // Get the 'clip' rect of this Render Region. 01851 DocRect ClipRect = pRegion->GetRegionRect(); 01852 01853 // If any of the RenderRegions completely contain the rect 01854 // then there is no point in rendering anything 01855 01856 if (ClipRect.ContainsRect(NodeRect)) 01857 return FALSE; // We don't need to render this node's blobs 01858 } 01859 01860 // Get the Next render region 01861 pRegion = (RenderRegion*)pRegionList->GetNext(pRegion); 01862 } 01863 } 01864 } 01865 return TRUE; 01866 }