00001 // $Id: scanrr.cpp 1282 2006-06-09 09:46:49Z 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 // The Scanning Render Region class 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 #include "scanrr.h" 00105 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "nodebmp.h" 00108 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "lineattr.h" 00110 #include "nodebldr.h" 00111 00112 // An implement to match the Declare in the .h file. 00113 // If you have many classes, it is recommended to place them all together, here at the start of the file 00114 CC_IMPLEMENT_DYNAMIC(ScanningRenderRegion, RenderRegion); 00115 CC_IMPLEMENT_DYNAMIC(NodeListItemWithComplexity, NodeListItem) 00116 00117 // Proper memory dumps 00118 #define new CAM_DEBUG_NEW 00119 00120 00121 00122 00123 /******************************************************************************************** 00124 00125 > ScanningRenderRegion::ScanningRenderRegion(BOOL Printing) 00126 00127 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00128 Created: 6/4/95 00129 Purpose: The Scanning Render Regions constructor. This sets all the member vars of 00130 the class to default values (usually 0 or NULL). 00131 00132 ********************************************************************************************/ 00133 00134 ScanningRenderRegion::ScanningRenderRegion(BOOL Printing) 00135 { 00136 // The complex nodes if there are any. Default to none 00137 pFirstComplex = NULL; 00138 pLastComplex = NULL; 00139 00140 // Counts of objects, default to none 00141 NumComplexShapes = 0; 00142 00143 // The bounds of the complex objects 00144 ComplexBounds.MakeEmpty(); 00145 00146 // Flag to say if we have finished rendering or not 00147 IsFinishedRendering = FALSE; 00148 00149 // Assume the host render region can do nothing till we get told otherwise 00150 HostCaps.CanDoNothing(); 00151 00152 // Start by assuming that the first node is simple for now 00153 IsFirstComplex = FALSE; 00154 InComplexRun = FALSE; 00155 RunLength = 0; 00156 00157 // The list info 00158 NodeRuns.DeleteAll(); 00159 pCurrentListItem = NULL; 00160 IsThisTheFirstNode = FALSE; 00161 00162 bIsComplex = FALSE; 00163 bIsSimple = FALSE; 00164 pLastClipAttr = NULL; 00165 00166 // Render flags 00167 RenderFlags.Printing = Printing; 00168 } 00169 00170 00171 00172 /******************************************************************************************** 00173 00174 > ScanningRenderRegion::~ScanningRenderRegion() 00175 00176 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00177 Created: 6/4/95 00178 Purpose: Destructor - It will do something if it needs to but at present this function 00179 is empty 00180 00181 ********************************************************************************************/ 00182 00183 ScanningRenderRegion::~ScanningRenderRegion() 00184 { 00185 // Make sure the list is cleared out. 00186 NodeRuns.DeleteAll(); 00187 } 00188 00189 00190 /******************************************************************************************** 00191 00192 > virtual BOOL ScanningRenderRegion::StartRender() 00193 00194 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00195 Created: 6/4/95 00196 Returns: TRUE if everything went OK, FALSE if there was a problem 00197 Purpose: Called to start the rendering process. Allows the render region to get 00198 ready to start rendering 00199 SeeAlso: ScanningRenderRegion::StopRender 00200 00201 ********************************************************************************************/ 00202 00203 BOOL ScanningRenderRegion::StartRender() 00204 { 00205 // Call base class first 00206 if (!RenderRegion::StartRender()) 00207 return FALSE; 00208 00209 // Say that we have not rendered any nodes yet 00210 IsThisTheFirstNode = TRUE; 00211 00212 // All worked 00213 return TRUE; 00214 } 00215 00216 00217 /******************************************************************************************** 00218 00219 > virtual BOOL ScanningRenderRegion::StopRender() 00220 00221 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00222 Created: 6/4/95 00223 Purpose: Called to stop rendering. Since Scanning render regions are not used to 00224 background render, this marks the end of all rendering. This function 00225 marks the render region as completed, so all the get functions that return 00226 info about the objects found in the region start to function. 00227 00228 ********************************************************************************************/ 00229 00230 BOOL ScanningRenderRegion::StopRender() 00231 { 00232 SetRenderState(NULL); 00233 // Update the RunLength of the last span 00234 NodeListItemWithComplexity* pLast = (NodeListItemWithComplexity*)NodeRuns.GetTail(); 00235 if (pLast) 00236 { 00237 // TRACEUSER( "Gerry", _T("Just finished a run of %ld %s shapes\n", RunLength, pLast->wasClassifiedSimple ? "simple" : "complex")); 00238 pLast->RunLength = RunLength; 00239 pLast->BoundsRect = SpanBounds; 00240 } 00241 IsFinishedRendering = TRUE; 00242 return TRUE; 00243 } 00244 00245 00246 00247 /******************************************************************************************** 00248 00249 > virtual void ScanningRenderRegion::DrawPathToOutputDevice(Path* pPathToRender) 00250 00251 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00252 Created: 6/4/95 00253 Inputs: pPathToRender - The path that we want to try and render 00254 Purpose: This function will examine the attributes etc to see if this represents a 00255 simple or compex shape and update the counters that this class keeps. 00256 There is no actual rendering, as this class does not actually render anything 00257 to a device. 00258 00259 ********************************************************************************************/ 00260 00261 void ScanningRenderRegion::DrawPathToOutputDevice(Path* pPathToRender, PathShape) 00262 { 00263 // see if this is a complex shape 00264 if (TestForComplexShape(&HostCaps)) 00265 ComplexShapeFound(); 00266 else 00267 SimpleShapeFound(); 00268 } 00269 00270 00271 /******************************************************************************************** 00272 00273 > virtual void ScanningRenderRegion::DrawRect(DocRect* pRectToRender) 00274 00275 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00276 Created: 6/4/95 00277 Inputs: pRectToRender - The Rectangle that we need to render 00278 Purpose: This function will examine the attributes etc to see if this represents a 00279 simple or compex shape and update the counters that this class keeps. 00280 There is no actual rendering, as this class does not actually render anything 00281 to a device. 00282 00283 ********************************************************************************************/ 00284 00285 void ScanningRenderRegion::DrawRect(DocRect* pRectToRender) 00286 { 00287 // see if this is a complex shape 00288 if (TestForComplexShape(&HostCaps)) 00289 ComplexShapeFound(); 00290 else 00291 SimpleShapeFound(); 00292 } 00293 00294 00295 /******************************************************************************************** 00296 00297 > virtual void ScanningRenderRegion::DrawLine(const DocCoord &StartPoint, 00298 const DocCoord &EndPoint) 00299 00300 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00301 Created: 6/4/95 00302 Inputs: StartPoint, EndPoint - the coords to draw a line between 00303 Purpose: This function will examine the attributes etc to see if this represents a 00304 simple or compex shape and update the counters that this class keeps. 00305 There is no actual rendering, as this class does not actually render anything 00306 to a device. 00307 00308 ********************************************************************************************/ 00309 00310 void ScanningRenderRegion::DrawLine(const DocCoord &StartPoint, const DocCoord &EndPoint) 00311 { 00312 // see if this is a complex shape 00313 if (TestForComplexShape(&HostCaps)) 00314 ComplexShapeFound(); 00315 else 00316 SimpleShapeFound(); 00317 } 00318 00319 00320 /******************************************************************************************** 00321 00322 > virtual void ScanningRenderRegion::DrawPixel(const DocCoord &Point) 00323 00324 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00325 Created: 6/4/95 00326 Inputs: Point - the coord to draw the pixel in 00327 Purpose: This function will examine the attributes etc to see if this represents a 00328 simple or compex shape and update the counters that this class keeps. 00329 There is no actual rendering, as this class does not actually render anything 00330 to a device. 00331 00332 ********************************************************************************************/ 00333 00334 void ScanningRenderRegion::DrawPixel(const DocCoord &Point) 00335 { 00336 // see if this is a complex shape 00337 if (TestForComplexShape(&HostCaps)) 00338 ComplexShapeFound(); 00339 else 00340 SimpleShapeFound(); 00341 } 00342 00343 00344 /******************************************************************************************** 00345 00346 > virtual void ScanningRenderRegion::DrawBitmap(const DocCoord &Point, KernelBitmap* pBitmap) 00347 00348 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00349 Created: 6/4/95 00350 Inputs: Point - The position to draw the bitmap at 00351 pBitmap - the bitmap that needs drawing 00352 Purpose: This function will examine the attributes etc to see if this represents a 00353 simple or compex shape and update the counters that this class keeps. 00354 There is no actual rendering, as this class does not actually render anything 00355 to a device. 00356 00357 ********************************************************************************************/ 00358 00359 void ScanningRenderRegion::DrawBitmap(const DocCoord &Point, KernelBitmap* pBitmap) 00360 { 00361 // see if this is a complex shape 00362 if (TestForComplexShape(&HostCaps)) 00363 ComplexShapeFound(); 00364 else 00365 SimpleShapeFound(); 00366 } 00367 00368 00369 /******************************************************************************************** 00370 00371 > virtual void ScanningRenderRegion::DrawBitmap(const DocCoord &Point, UINT32 BitmapID, 00372 UINT32 ToolID) 00373 00374 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00375 Created: 6/4/95 00376 Inputs: Point - the position to draw the bitmap at 00377 BitmapID - The ID of the bitmap to render 00378 ToolID - the ID of the tool that the bitmap belongs to 00379 Purpose: This function will examine the attributes etc to see if this represents a 00380 simple or compex shape and update the counters that this class keeps. 00381 There is no actual rendering, as this class does not actually render anything 00382 to a device. 00383 00384 ********************************************************************************************/ 00385 00386 void ScanningRenderRegion::DrawBitmap(const DocCoord &Point, UINT32 BitmapID, UINT32 ToolID) 00387 { 00388 // see if this is a complex shape 00389 if (TestForComplexShape(&HostCaps)) 00390 ComplexShapeFound(); 00391 else 00392 SimpleShapeFound(); 00393 } 00394 00395 00396 /******************************************************************************************** 00397 00398 > BOOL ScanningRenderRegion::DrawTransformedBitmap(NodeBitmap *pNodeBitmap) 00399 00400 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00401 Created: 24/7/95 00402 Inputs: pNodeBitmap - The bitmap to render 00403 Returns: TRUE if it worked, FLASE if not 00404 Purpose: Works out if it can draw a Transformed bitmap. 00405 00406 ********************************************************************************************/ 00407 00408 BOOL ScanningRenderRegion::DrawTransformedBitmap(NodeBitmap *pNodeBitmap) 00409 { 00410 BOOL IsShapeComplex = FALSE; 00411 00412 // see if this is a complex shape (e.g. transparency) 00413 if (TestForComplexShape(&HostCaps) || pNodeBitmap->NeedsTransparency()) 00414 { 00415 ComplexShapeFound(); 00416 return TRUE; 00417 } 00418 00419 // See what kind of bitmaps this render region can do 00420 if (HostCaps.ArbitraryBitmaps) 00421 { 00422 // We can do anything... 00423 if (!IsShapeComplex) 00424 SimpleShapeFound(); 00425 00426 return TRUE; 00427 } 00428 00429 if (HostCaps.SimpleBitmaps) 00430 { 00431 // Check that the bitmap area is rectangular, and is perpendicular to 00432 // the x and y axes. 00433 if (pNodeBitmap->HasSimpleOrientation(this)) 00434 { 00435 SimpleShapeFound(); 00436 return TRUE; 00437 } 00438 } 00439 00440 // If we get here, then we can't do the bitmap directly 00441 ComplexShapeFound(); 00442 00443 return TRUE; 00444 } 00445 00446 00447 /******************************************************************************************** 00448 00449 > virtual void ScanningRenderRegion::DrawDragRect(DocRect *RectToRender) 00450 00451 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00452 Created: 6/4/95 00453 Inputs: RectToRender - The Rectangle 00454 Purpose: None - I just had to overide this function as it is pure virtual. Does nothing 00455 00456 ********************************************************************************************/ 00457 00458 void ScanningRenderRegion::DrawDragRect(DocRect *RectToRender) 00459 { 00460 } 00461 00462 00463 /******************************************************************************************** 00464 00465 > virtual void ScanningRenderRegion::DrawBlob(DocCoord p, BlobType type) 00466 00467 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00468 Created: 6/4/95 00469 Inputs: p - A coord 00470 type - The type of blob 00471 Purpose: None - I just had to overide this function as it is pure virtual. Does nothing 00472 00473 ********************************************************************************************/ 00474 00475 void ScanningRenderRegion::DrawBlob(DocCoord p, BlobType type) 00476 { 00477 } 00478 00479 00480 /******************************************************************************************** 00481 00482 > virtual void ScanningRenderRegion::DrawCross(const DocCoord &Point, const UINT32 Size) 00483 00484 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00485 Created: 6/4/95 00486 Inputs: Point - a Coord 00487 Size - the size of the cross 00488 Purpose: None - I just had to overide this function as it is pure virtual. Does nothing 00489 00490 ********************************************************************************************/ 00491 00492 void ScanningRenderRegion::DrawCross(const DocCoord &Point, const UINT32 Size) 00493 { 00494 } 00495 00496 00497 /******************************************************************************************** 00498 00499 > virtual void ScanningRenderRegion::DrawBitmapBlob(const DocCoord &Point, 00500 KernelBitmap* BlobShape) 00501 00502 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00503 Created: 6/4/95 00504 Inputs: Point - A Coord 00505 BlobShape - the bitmap to use 00506 Purpose: None - I just had to overide this function as it is pure virtual. Does nothing 00507 00508 ********************************************************************************************/ 00509 00510 void ScanningRenderRegion::DrawBitmapBlob(const DocCoord &Point, KernelBitmap* BlobShape) 00511 { 00512 } 00513 00514 00515 /******************************************************************************************** 00516 00517 > virtual void ScanningRenderRegion::DrawBitmapBlob(const DocCoord &Point, char TCHAR* pszBitmap) 00518 00519 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00520 Created: 6/4/95 00521 Inputs: Point - A coord 00522 BitmapID - the ID of a bitmap 00523 ToolID - the Id of the tool the bitmap resource is in 00524 Purpose: None - I just had to overide this function as it is pure virtual. Does nothing 00525 00526 ********************************************************************************************/ 00527 00528 void ScanningRenderRegion::DrawBitmapBlob(const DocCoord &Point, ResourceID resID ) 00529 { 00530 } 00531 00532 00533 00534 /******************************************************************************************** 00535 00536 > virtual void ScanningRenderRegion::GetRenderRegionCaps(RRCaps* pCaps) 00537 00538 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00539 Created: 10/4/95 00540 Outputs: pCaps - The details about what types of thing this render region can render 00541 Purpose: This function allows render regions to admit to what they can and can not 00542 render. This allows other areas of the program to come in and help render 00543 regions out in some situations, if they are unable to render everything. 00544 eg. an OSRenderRegion can not render transparancy. 00545 00546 ********************************************************************************************/ 00547 00548 void ScanningRenderRegion::GetRenderRegionCaps(RRCaps* pCaps) 00549 { 00550 pCaps->CanDoAll(); 00551 } 00552 00553 00554 /******************************************************************************************** 00555 00556 > void ScanningRenderRegion::SetHostRRCaps(const RRCaps& Caps) 00557 00558 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00559 Created: 10/4/95 00560 Inputs: Caps - The Device Caps for the render region we are scanning on behalf of. 00561 Purpose: This function makes a note of what things the render region we are scanning 00562 on behalf of can render and what it can not. We use the info take a copy 00563 if pCaps and use it to make the decisions as to what is a complex object 00564 and what is not. 00565 00566 ********************************************************************************************/ 00567 00568 void ScanningRenderRegion::SetHostRRCaps(const RRCaps& Caps) 00569 { 00570 // make a copy of the RRCaps field 00571 // Host caps is used in TestForComplexShape(); 00572 HostCaps = Caps; 00573 } 00574 00575 00576 00577 00578 /******************************************************************************************** 00579 00580 > Node* ScanningRenderRegion::GetFirstComplexObject() 00581 00582 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00583 Created: 6/4/95 00584 Returns: A pointer to a Node 00585 Purpose: This function will return a pointer to the first complex (ie one that can 00586 not be rendered without GDraw - such as a transparant shape) node that the 00587 render region would need to render. This function will return NULL if there 00588 were no complex shapes found. 00589 If the Scanning render region has not yet finished rendering, then this 00590 function will always return NULL 00591 SeeAlso: ScanningRenderRegion::GetLastComplexObject; 00592 ScanningRenderRegion::IsFinished 00593 00594 ********************************************************************************************/ 00595 00596 Node* ScanningRenderRegion::GetFirstComplexObject() 00597 { 00598 // If we have not yet finished rendering then this function returns NULL 00599 if (!IsFinishedRendering) 00600 return NULL; 00601 00602 // Its finished so we these values are accurate 00603 return pFirstComplex; 00604 } 00605 00606 00607 /******************************************************************************************** 00608 00609 > Node* ScanningRenderRegion::GetLastComplexObject() 00610 00611 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00612 Created: 6/4/95 00613 Returns: A pointer to a Node 00614 Purpose: This function will return a pointer to the last complex (ie one that can 00615 not be rendered without GDraw - such as a transparant shape) node that the 00616 render region would need to render. This function will return NULL if there 00617 were no complex shapes found. 00618 If the Scanning render region has not yet finished rendering, then this 00619 function will always return NULL 00620 SeeAlso: ScanningRenderRegion::GetLastComplexObject; 00621 ScanningRenderRegion::IsFinished 00622 00623 ********************************************************************************************/ 00624 00625 Node* ScanningRenderRegion::GetLastComplexObject() 00626 { 00627 // If we have not yet finished rendering then this function returns NULL 00628 if (!IsFinishedRendering) 00629 return NULL; 00630 00631 // We have finished, so return the true value 00632 return pLastComplex; 00633 } 00634 00635 00636 00637 00638 /******************************************************************************************** 00639 00640 > INT32 ScanningRenderRegion::GetNumComplex() 00641 00642 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00643 Created: 6/4/95 00644 Returns: The number of complex nodes that need to be rendered 00645 Purpose: This function returns the number of complex shapes that have been found in 00646 the scanning render region. It only counts the complex shapes in the region. 00647 It will return 0 if there were no complex shapes in the region. 00648 If the Scanning render region has not yet finished rendering, then this 00649 function will always return 0 00650 00651 ********************************************************************************************/ 00652 00653 INT32 ScanningRenderRegion::GetNumComplex() 00654 { 00655 // If we have not yet finished rendering then this function returns 0 00656 if (!IsFinishedRendering) 00657 return 0; 00658 00659 return NumComplexShapes; 00660 } 00661 00662 00663 00664 00665 /******************************************************************************************** 00666 00667 > DocRect ScanningRenderRegion::GetComplexBounds() 00668 00669 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00670 Created: 18/4/95 00671 Returns: DocRect - the smallest rect that covers all the complex shapes 00672 in this render region 00673 Purpose: Used to find out the bounding rect of all the complex shapes in the completed 00674 render region. If it is called before the region has finished rendering, then 00675 it will return the empty rectangle. If there are no complex shapes in the 00676 region then it will also return the empty rectangle. 00677 00678 ********************************************************************************************/ 00679 00680 DocRect ScanningRenderRegion::GetComplexBounds() 00681 { 00682 // If we have not yet finished rendering then this function returns an empty rectangle 00683 if (!IsFinishedRendering) 00684 { 00685 DocRect EmptyOne(0,0,0,0); 00686 return EmptyOne; 00687 } 00688 00689 return ComplexBounds; 00690 } 00691 00692 00693 /******************************************************************************************** 00694 00695 > void ScanningRenderRegion::SetRenderState(Node* pNode) 00696 00697 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 00698 Created: 20/05/2004 00699 Inputs: pNode - The Node about to be rendered 00700 Purpose: Sets the next Node to be rendered 00701 00702 ********************************************************************************************/ 00703 00704 void ScanningRenderRegion::SetRenderState(Node* pNode) 00705 { 00706 // If we have been rendering a Node then stick it's details where needed 00707 // Node* pLastNode = GetRenderState(); 00708 // if (pLastNode) 00709 // { 00710 if (bIsComplex || (bIsSimple && GetCaptureDepth() > 1)) 00711 ComplexShapeFoundHelper(); // go ahead and record the node 00712 else if (bIsSimple) 00713 SimpleShapeFoundHelper(); // go ahead and record the node 00714 // } 00715 00716 RenderRegion::SetRenderState(pNode); 00717 bIsComplex = FALSE; 00718 bIsSimple = FALSE; 00719 } 00720 00721 00722 /******************************************************************************************** 00723 00724 > void ScanningRenderRegion::ComplexShapeFoundWrapper () 00725 00726 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00727 Created: 20/12/2000 00728 Purpose: This function is a public wrapper for ComplexShapeFound(). You should only 00729 call this function if you know what you are doing! 00730 00731 e.g. if you have geometry that does not regenerate certain parts of itself 00732 when inside blends (hence missing the complex classification), you should 00733 detect this situation and call this function directly. NodeBevel::Render() 00734 uses this method at present. 00735 00736 ********************************************************************************************/ 00737 00738 void ScanningRenderRegion::ComplexShapeFoundWrapper() 00739 { 00740 ComplexShapeFound(); 00741 } 00742 00743 00744 /******************************************************************************************** 00745 00746 > void ScanningRenderRegion::ComplexShapeFoundHelper() 00747 00748 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00749 Created: 12/10/2000 00750 Purpose: This function is called every time the rendering functions find that the 00751 node they are dealing with is complex. It updates all the info the scanning 00752 render region tracks about complex shapes, such as the first and last complex 00753 nodes and the bounding rectangle of all the complex shapes. 00754 00755 ********************************************************************************************/ 00756 void ScanningRenderRegion::ComplexShapeFoundHelper() 00757 { 00758 // TRACE( _T("ComplexShapeFound\n")); 00759 00760 Node* pThisNode = GetRenderState(); 00761 if (pThisNode == NULL) 00762 { 00763 TRACE( _T("NULL RenderState in ComplexShapeFoundHelper\n")); 00764 } 00765 00766 // Update the count of complex shapes 00767 NumComplexShapes++; 00768 00769 // update the first complex shape pointers as needed 00770 if (pFirstComplex==NULL) 00771 pFirstComplex = pThisNode; 00772 00773 // This is the last complex shape we know about so far... 00774 pLastComplex = pThisNode; 00775 00776 // Now deal with the runs of Nodes system, in case they want to use that. 00777 if (IsThisTheFirstNode) 00778 { 00779 // This node represents the first renderable node in the region 00780 // so make sure that we note the fact that the first node is complex 00781 IsFirstComplex = TRUE; 00782 IsThisTheFirstNode = FALSE; 00783 InComplexRun = TRUE; 00784 00785 NodeListItemWithComplexity* pItem = new NodeListItemWithComplexity(pThisNode, FALSE); 00786 if (pItem!=NULL) 00787 NodeRuns.AddTail(pItem); 00788 } 00789 00790 // Karim 12/12/2000 00791 // Clipping changes - basically, all objects in a run of complex shapes 00792 // must share the same clip-attr. 00793 if (pThisNode) 00794 { 00795 // if we were in the middle of a Simple Nodes Run, then record this node 00796 // as the first node in the Complex run and mark that we are now in a complex run 00797 if (!InComplexRun) 00798 { 00799 // TRACEUSER( "Gerry", _T("Just finished a run of %ld simple shapes - Add Next Complex shape\n"), RunLength); 00800 NodeListItemWithComplexity* pLast = (NodeListItemWithComplexity*)NodeRuns.GetTail(); 00801 if (pLast) 00802 pLast->RunLength = RunLength; 00803 00804 SpanBounds.MakeEmpty(); 00805 00806 // Add this node to the list 00807 RunLength = 0; 00808 NodeListItemWithComplexity* pItem = new NodeListItemWithComplexity(pThisNode, FALSE); 00809 if (pItem!=NULL) 00810 NodeRuns.AddTail(pItem); 00811 } 00812 00813 // Update the bounds to date of complex shapes 00814 if (pThisNode->IsBounded()) 00815 { 00816 DocRect NodeBounds = ((NodeRenderableBounded*)pThisNode)->GetBoundingRect(); 00817 ComplexBounds = NodeBounds.Union(ComplexBounds); 00818 SpanBounds = NodeBounds.Union(SpanBounds); 00819 // TRACE( _T("BoundsRect = (%d, %d) - (%d, %d)\n"), SpanBounds.lox, SpanBounds.loy, SpanBounds.hix, SpanBounds.hiy); 00820 } 00821 } 00822 00823 // Make sure we know we are rendering complex shapes now 00824 InComplexRun = TRUE; 00825 RunLength++; 00826 } 00827 00828 00829 /******************************************************************************************** 00830 00831 > void ScanningRenderRegion::SimpleShapeFoundHelper () 00832 00833 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00834 Created: 12/10/2000 00835 Purpose: This function should be called whenever a simple node is encountered. This 00836 allows the list of runs of simple / complex nodes to be maintained. 00837 00838 ********************************************************************************************/ 00839 void ScanningRenderRegion::SimpleShapeFoundHelper () 00840 { 00841 // TRACE( _T("SimpleShapeFound\n")); 00842 00843 Node* pThisNode = GetRenderState(); 00844 if (pThisNode == NULL) 00845 { 00846 TRACE( _T("NULL RenderState in SimpleShapeFoundHelper\n")); 00847 } 00848 00849 if (IsThisTheFirstNode) 00850 { 00851 // This node represents the first renderable node in the region 00852 // so make sure that we note the fact that the first node is simple 00853 IsThisTheFirstNode = FALSE; 00854 00855 NodeListItemWithComplexity* pItem = new NodeListItemWithComplexity(pThisNode, TRUE); 00856 if (pItem!=NULL) 00857 NodeRuns.AddTail(pItem); 00858 } 00859 00860 // If we are in the middle of a Complex run then change over to a simple run 00861 if (InComplexRun) 00862 { 00863 // Add this node to the list as the first node in a simple run 00864 // TRACEUSER( "Gerry", _T("Just finished a run of %ld complex shapes - Add Next Simple shape\n"), RunLength); 00865 00866 NodeListItemWithComplexity* pLast = (NodeListItemWithComplexity*)NodeRuns.GetTail(); 00867 if (pLast) 00868 { 00869 pLast->RunLength = RunLength; 00870 pLast->BoundsRect = SpanBounds; 00871 } 00872 00873 SpanBounds.MakeEmpty(); 00874 RunLength = 0; 00875 NodeListItemWithComplexity* pItem = NULL; 00876 if (pThisNode) 00877 { 00878 // If this is the first non-attribute sibling then make the new simple 00879 // run start with our parent and continue up the tree 00880 while (TRUE) 00881 { 00882 // Get the previous sibling 00883 Node* pTestNode = pThisNode->FindPrevious(); 00884 // If we don't have one or it is an attribute then get our parent 00885 // and try again otherwise use this node 00886 if (!pTestNode || pTestNode->IsAnAttribute()) 00887 pThisNode = pThisNode->FindParent(); 00888 else 00889 break; 00890 } 00891 00892 pItem = new NodeListItemWithComplexity(pThisNode, TRUE); 00893 } 00894 00895 if (pItem != NULL) 00896 NodeRuns.AddTail(pItem); 00897 } 00898 00899 // We are no longer in a complex run 00900 InComplexRun = FALSE; 00901 RunLength++; 00902 } 00903 00904 00905 00906 /******************************************************************************************** 00907 00908 > BOOL ScanningRenderRegion::IsFinished() 00909 00910 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00911 Created: 6/4/95 00912 Returns: TRUE if the scanning render region has finished scanning, FALSE if it still 00913 has more nodes to look at 00914 Purpose: Lets you find out if the render region has finished rendering yet. If it 00915 has not finished then all the information that this class has to offer about 00916 the number of complex shapes etc is not valid. All the info functions will 00917 return 0 or NULL until the rendering is finished to stop you looking at 00918 incomplete data. 00919 00920 ********************************************************************************************/ 00921 00922 BOOL ScanningRenderRegion::IsFinished() 00923 { 00924 return IsFinishedRendering; 00925 } 00926 00927 00928 00929 00930 00931 00932 /******************************************************************************************** 00933 00934 > BOOL ScanningRenderRegion::IsFirstNodeComplex() 00935 00936 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00937 Created: 24/7/95 00938 Returns: TRUE if the First node to be rendered is Complex, FALSE if not 00939 Purpose: 00940 00941 ********************************************************************************************/ 00942 00943 BOOL ScanningRenderRegion::IsFirstNodeComplex() 00944 { 00945 return IsFirstComplex; 00946 } 00947 00948 00949 00950 /******************************************************************************************** 00951 00952 > Node* ScanningRenderRegion::FindFirstFromList() 00953 00954 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00955 Created: 24/7/95 00956 Returns: The first node in the list or NULL. 00957 Purpose: The nodes in the list represent the first node in a run of simple / complex 00958 nodes. You can determine if the first node to be rendered is simple or 00959 complex by calling IsFirstNodeComplex(). eg. If IsFirstNodeComplex() returned 00960 FALSE, then all the nodes up to the node returned by FindFirstFromList() will 00961 be simple. All the nodes from this one to the node returned by FindNextFromList 00962 will be complex. This toggle carries on all the way through the tree until 00963 there are no more nodes. 00964 If this function returns NULL, you can assume that there are no runs of nodes 00965 in the tree and all the nodes are of the same start as the first one (ie the 00966 same as what IsFirstNodeComplex() says). 00967 00968 ********************************************************************************************/ 00969 00970 Node* ScanningRenderRegion::FindFirstFromList() 00971 { 00972 // Reset our list pointer 00973 pCurrentListItem = NULL; 00974 00975 // If we have not finished yet, then return NULL 00976 if (!IsFinishedRendering) 00977 { 00978 return NULL; 00979 } 00980 00981 // return the first item in the list 00982 pCurrentListItem = (NodeListItemWithComplexity*) NodeRuns.GetHead(); 00983 if (pCurrentListItem!=NULL) 00984 return pCurrentListItem->pNode; 00985 00986 // the list was empty 00987 return NULL; 00988 } 00989 00990 00991 00992 00993 /******************************************************************************************** 00994 00995 > Node* ScanningRenderRegion::FindNextFromList() 00996 00997 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00998 Created: 24/7/95 00999 Returns: The Next Node in the list of runs of nodes 01000 Purpose: Finds the first node in the next run of nodes. 01001 SeeAlso: ScanningRenderRegion::FirstFirstFromList 01002 01003 ********************************************************************************************/ 01004 01005 Node* ScanningRenderRegion::FindNextFromList() 01006 { 01007 // If we have not finished rendering, or we are not looking at a list already, return null 01008 if ((!IsFinishedRendering) || (pCurrentListItem==NULL)) 01009 { 01010 return NULL; 01011 } 01012 01013 // return the next item in the list 01014 pCurrentListItem = (NodeListItemWithComplexity*) NodeRuns.GetNext(pCurrentListItem); 01015 if (pCurrentListItem!=NULL) 01016 return pCurrentListItem->pNode; 01017 01018 // the list was empty 01019 return NULL; 01020 } 01021 01022 /******************************************************************************************** 01023 01024 > BOOL ScanningRenderRegion::IsThisNodeComplex() 01025 01026 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01027 Created: 06/01/05 01028 Returns: TRUE if the currentlist node is Complex, FALSE if not 01029 Purpose: 01030 01031 ********************************************************************************************/ 01032 01033 BOOL ScanningRenderRegion::IsThisNodeComplex() 01034 { 01035 if ((!IsFinishedRendering) || (pCurrentListItem==NULL)) 01036 { 01037 return FALSE; 01038 } 01039 01040 return(!(pCurrentListItem->wasClassifiedSimple)); 01041 } 01042 01043 01044 /******************************************************************************************** 01045 01046 > DocRect ScanningRenderRegion::GetSpanBounds() 01047 01048 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01049 Created: 06/01/05 01050 Returns: DocRect - the smallest rect that covers all the shapes in this span 01051 in this render region 01052 Purpose: Used to find out the bounding rect of all the shapes in the span. This 01053 rectanlge is only calculated for complex spans. If it is called before 01054 the region has finished rendering, then it will return the empty rectangle. 01055 If there are no complex shapes in the region then it will also return the 01056 empty rectangle. 01057 01058 ********************************************************************************************/ 01059 01060 DocRect ScanningRenderRegion::GetSpanBounds() 01061 { 01062 // If we have not yet finished rendering then this function returns an empty rectangle 01063 if (!IsFinishedRendering || !pCurrentListItem) 01064 { 01065 DocRect EmptyOne(0,0,0,0); 01066 return EmptyOne; 01067 } 01068 01069 return pCurrentListItem->BoundsRect; 01070 } 01071 01072 01073 01074 01075 /******************************************************************************************** 01076 01077 > virtual void ScanningRenderRegion::InitClipping() 01078 01079 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01080 Created: 6/4/95 01081 Purpose: Sets up the clipping - does nothing in this class 01082 01083 ********************************************************************************************/ 01084 01085 void ScanningRenderRegion::InitClipping() 01086 { 01087 } 01088 01089 01090 /******************************************************************************************** 01091 01092 > virtual void ScanningRenderRegion::InitAttributes() 01093 01094 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01095 Created: 6/4/95 01096 Purpose: Sets up the attributes. Does nothing in this class 01097 01098 ********************************************************************************************/ 01099 01100 void ScanningRenderRegion::InitAttributes() 01101 { 01102 } 01103 01104 01105 /******************************************************************************************** 01106 01107 > virtual void ScanningRenderRegion::SetLineAttributes() 01108 01109 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01110 Created: 6/4/95 01111 Purpose: Does nothing in this class 01112 01113 ********************************************************************************************/ 01114 01115 void ScanningRenderRegion::SetLineAttributes() 01116 { 01117 } 01118 01119 01120 /******************************************************************************************** 01121 01122 > virtual void ScanningRenderRegion::SetOSDrawingMode() 01123 01124 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01125 Created: 6/4/95 01126 Purpose: Does nothing in this class 01127 01128 ********************************************************************************************/ 01129 01130 void ScanningRenderRegion::SetOSDrawingMode() 01131 { 01132 } 01133 01134 01135 /******************************************************************************************** 01136 01137 > virtual void ScanningRenderRegion::SetQualityLevel() 01138 01139 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01140 Created: 6/4/95 01141 Purpose: Does nothing in this class 01142 01143 ********************************************************************************************/ 01144 01145 void ScanningRenderRegion::SetQualityLevel() 01146 { 01147 } 01148 01149 01150 /******************************************************************************************** 01151 01152 > virtual MILLIPOINT ScanningRenderRegion::CalcPixelWidth() 01153 01154 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01155 Created: 6/4/95 01156 Purpose: Does nothing in this class 01157 01158 ********************************************************************************************/ 01159 01160 MILLIPOINT ScanningRenderRegion::CalcPixelWidth() 01161 { 01162 return 0; 01163 } 01164 01165 01166 /******************************************************************************************** 01167 01168 > virtual MILLIPOINT ScanningRenderRegion::CalcScaledPixelWidth() 01169 01170 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 01171 Created: 6/4/95 01172 Purpose: Does nothing in this class 01173 01174 ********************************************************************************************/ 01175 01176 MILLIPOINT ScanningRenderRegion::CalcScaledPixelWidth() 01177 { 01178 01179 return 0; 01180 } 01181 01182 #ifdef _DEBUG 01183 void ScanningRenderRegion::DumpNodeRuns() 01184 { 01185 NodeListItemWithComplexity* pItem = (NodeListItemWithComplexity*) NodeRuns.GetHead(); 01186 while (pItem) 01187 { 01188 if (pItem->wasClassifiedSimple) 01189 { 01190 TRACE( _T("NormalSpan of %d nodes 0x%08x - %s\n"), pItem->RunLength, pItem->pNode, 01191 pItem->pNode->GetRuntimeClass()->GetClassName()); 01192 } 01193 else 01194 { 01195 TRACE( _T("ComplexSpan of %d nodes 0x%08x - %s\n"), pItem->RunLength, pItem->pNode, 01196 pItem->pNode->GetRuntimeClass()->GetClassName()); 01197 } 01198 TRACE( _T("BoundsRect = (%d, %d) - (%d, %d)\n"), pItem->BoundsRect.lo.x, pItem->BoundsRect.lo.y, 01199 pItem->BoundsRect.hi.x, pItem->BoundsRect.hi.y); 01200 pItem = (NodeListItemWithComplexity*) NodeRuns.GetNext(pItem); 01201 } 01202 } 01203 #endif 01204 01206 // Implementation of NodeListItemWithComplexity 01208 01209 /******************************************************************************************** 01210 01211 > NodeListItemWithComplexity::NodeListItemWithComplexity() 01212 01213 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01214 Created: 7/11/2000 01215 Inputs: - 01216 Outputs: - 01217 Returns: - 01218 Purpose: default constructor. Initialises pNode = NULL 01219 Errors: - 01220 SeeAlso: - 01221 01222 ********************************************************************************************/ 01223 01224 NodeListItemWithComplexity::NodeListItemWithComplexity() 01225 { 01226 pNode = NULL; 01227 wasClassifiedSimple = TRUE; 01228 RunLength = 0; 01229 } 01230 01231 /******************************************************************************************** 01232 01233 > NodeListItemWithComplexity::NodeListItemWithComplexity(Node* WhichNode, BOOL val) 01234 01235 Author: Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com> 01236 Created: 22/7/94 01237 Inputs: - 01238 Outputs: - 01239 Returns: - 01240 Purpose: Constructor for NodeListItem which sets the pNode variable to WhichNode 01241 Errors: - 01242 SeeAlso: - 01243 01244 ********************************************************************************************/ 01245 01246 NodeListItemWithComplexity::NodeListItemWithComplexity(Node* WhichNode, BOOL val) 01247 { 01248 pNode = WhichNode; 01249 wasClassifiedSimple = val; 01250 RunLength = 0; 01251 }