00001 // $Id: spread.cpp 1737 2006-09-04 15:17:04Z luke $ 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 00099 // Spread class implementation 00100 00101 00102 #include "camtypes.h" 00103 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 //#include "simon.h" 00105 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "rndrgn.h" 00107 #include "page.h" 00108 #include "exceptio.h" // For BlowUpOnCrashMe() method 00109 #include "chapter.h" 00110 //#include "mario.h" // amounst other things _R(IDE_NOMORE_MEMORY) 00111 #include "layer.h" 00112 //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "sglayer.h" 00115 #include "usercord.h" 00116 //#include "tim.h" 00117 00118 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 #include "cxftags.h" 00120 //#include "cxfdefs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00121 //#include "camfiltr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 #include "viewcomp.h" 00123 #include "unitcomp.h" 00124 00125 #include "nodedoc.h" 00126 #include "backgrnd.h" // OpBackground 00127 //#include "animparams.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00128 #include "progress.h" 00129 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00130 #include "optsmsgs.h" 00131 #include "oilbitmap.h" // CWxBitmap 00132 #include "grid.h" 00133 00134 //#include "prevwres.h" // _R(IDS_TAG_LAYER_FRAMEPROPS) 00135 //#include "frameops.h" // for OpGrabAllFrames 00136 00137 CC_IMPLEMENT_DYNAMIC(Spread, NodeRenderablePaper) 00138 00139 // Declare smart memory handling in Debug builds 00140 #define new CAM_DEBUG_NEW 00141 00142 00143 00144 #if NEW_PASTEBOARD 00145 // See the spread.h header for the definition of NEW_PASTEBOARD 00146 // Note that I've set it to fail to compile until you've been made aware of the problem! 00147 #error ("New pasteboard code is enabled. Import/Export is probably broken") 00148 #endif 00149 00150 00151 // Maximum pasteboard size - beyond this size we start to get problems at high zoom or something 00152 // SeeAlso: kernel\optspage.cpp 00153 const MILLIPOINT MaxPasteboardSize = 9 * 72000 * 12; // maximum = 108in = 9 ft = 275cm 00154 00155 00156 #ifdef RALPH 00157 #define NO_SPREAD 1 00158 #endif 00159 00160 /********************************************************************************************* 00161 00162 > Spread::Spread() 00163 00164 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00165 Created: 13/5/93 00166 Inputs: - 00167 Outputs: 00168 Returns: - 00169 00170 Purpose: This constructor creates a Spread linked to no other nodes, with all status 00171 flags false, and NULL bounding and pasteboard rectangles. 00172 00173 Errors: 00174 00175 **********************************************************************************************/ 00176 00177 00178 Spread::Spread(): NodeRenderablePaper() 00179 { 00180 UserOrigin = DocCoord(0, 0); 00181 SpreadOrigin = DocCoord(0, 0); 00182 BleedOffset = 36000; 00183 ShowDropShadow = TRUE; 00184 RalphDontShowPaper = FALSE; 00185 //AnimPropertiesParam = constructed 00186 //SpreadDimScale = constructed 00187 } 00188 00189 00190 /*********************************************************************************************** 00191 00192 > Spread::Spread 00193 ( 00194 Node* ContextNode, 00195 AttachNodeDirection Direction, 00196 MILLIPOINT BleedOffset = 0, 00197 BOOL Locked = FALSE, 00198 BOOL Mangled = FALSE, 00199 BOOL Marked = FALSE, 00200 BOOL Selected = FALSE, 00201 ) 00202 00203 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00204 Created: 26/4/93 00205 00206 Inputs: ContextNode: Pointer to a node which this node is to be attached to. 00207 00208 Direction: 00209 00210 Specifies the direction in which this node is to be attached to the 00211 ContextNode. The values this variable can take are as follows: 00212 00213 PREV : Attach node as a previous sibling of the context node 00214 NEXT : Attach node as a next sibling of the context node 00215 FIRSTCHILD: Attach node as the first child of the context node 00216 LASTCHILD : Attach node as a last child of the context node 00217 00218 BoundingRect: Bounding rectangle 00219 00220 The remaining inputs specify the status of the node: 00221 00222 Locked: Is node locked ? 00223 Mangled: Is node mangled ? 00224 Marked: Is node marked ? 00225 Selected: Is node selected ? 00226 00227 Outputs: - 00228 Returns: - 00229 Purpose: This method initialises the node and links it to ContextNode in the 00230 direction specified by Direction. All neccesary tree links are 00231 updated. 00232 00233 Errors: An assertion error will occur if ContextNode is NULL 00234 00235 00236 ***********************************************************************************************/ 00237 00238 Spread::Spread(Node* ContextNode, 00239 AttachNodeDirection Direction, 00240 const DocRect& PasteRect, 00241 MILLIPOINT Bleed, 00242 BOOL Locked, 00243 BOOL Mangled, 00244 BOOL Marked, 00245 BOOL Selected 00246 ): NodeRenderablePaper(ContextNode, Direction, Locked, Mangled, 00247 Marked, Selected) 00248 { 00249 BleedOffset = Bleed; 00250 00251 // Set the default spread coord origin 00252 SpreadOrigin = PasteRect.lo; 00253 00254 // Pasteboard is used to indicate the width of the document (for scroll bars etc) 00255 SetInitialPasteboardRect(PasteRect); 00256 00257 // Default to showing the drop shadow on the page 00258 ShowDropShadow = TRUE; 00259 00260 // we only render paper in some ralph document modes 00261 RalphDontShowPaper = FALSE; 00262 00263 UserOrigin = DocCoord(0,0); 00264 } 00265 00266 00267 00268 /******************************************************************************************** 00269 00270 > virtual String Spread::Describe(BOOL Plural, BOOL Verbose = TRUE) 00271 00272 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00273 Created: 21/6/93 00274 Inputs: Plural: Flag indicating if the string description should be plural or 00275 singular. 00276 Outputs: - 00277 Retuns: Description of the object 00278 Purpose: To return a description of the Node object in either the singular or the 00279 plural. This method is called by the DescribeRange method. 00280 00281 The description will always begin with a lower case letter. 00282 00283 Errors: A resource exception will be thrown if a problem occurs when loading the 00284 string resource. 00285 SeeAlso: - 00286 00287 ********************************************************************************************/ 00288 /* 00289 Technical Notes: 00290 00291 The String resource identifiers should be of the form: ID_<Class>_DescriptionS for the 00292 singular description and ID_<Class>_DescriptionP for the plural. 00293 */ 00294 00295 String Spread::Describe(BOOL Plural, BOOL Verbose) 00296 { 00297 if (Plural) 00298 return(String(_R(IDS_SPREAD_DESCRP))); 00299 else 00300 return(String(_R(IDS_SPREAD_DESCRS))); 00301 }; 00302 00303 00304 00305 00306 /******************************************************************************************** 00307 00308 > DocRect Spread::GetBoundingRect(BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE) 00309 00310 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00311 Created: 11/9/94 00312 Inputs: DontUseAttrs - If this is TRUE the node should not try to use the 00313 attributes associated with the node. It will also leave the flag 00314 IsBoundingRectValid FALSE. This var defaults to FALSE 00315 HitTest - TRUE if being called during HitTest 00316 Returns: The nodes bounding rectangle 00317 Purpose: returns the nodes bounding rectangle. If the rectangle is valid the 00318 rectangle is simply returned, but is IsBoundingRectValid is FALSE (cos 00319 someone called InvaldateBoundingRect() on this node, or one of its 00320 children) then the bounding rect is first calculated and the flag reset, 00321 before it is returned. The Spreads bounds rect is measured in Document 00322 Coords and this conversion is made in here. ie. All objects below the spread 00323 measure their coords etc relative to the spread, but the spread itself is 00324 measured relative to the document. 00325 00326 ********************************************************************************************/ 00327 00328 DocRect Spread::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest) 00329 { 00330 // if the bounding rect of this node is not valid then fill in something 00331 if (!IsBoundingRectValid || DontUseAttrs) 00332 { 00333 // just set it to be an empty rectangle 00334 DocRect BoundRect(0,0,0,0); 00335 00336 Node* pNode = FindFirstChild(); 00337 while (pNode!=NULL) 00338 { 00339 // Add in the bounding rect of this node with all the others 00340 if (pNode->IsBounded()) 00341 BoundRect = BoundRect.Union(((NodeRenderableBounded*)pNode)->GetBoundingRect(DontUseAttrs)); 00342 00343 // And find the next node 00344 pNode = pNode->FindNext(); 00345 } 00346 00347 // Convert the bounding rect obtained from spread coords to document coords 00348 SpreadCoordToDocCoord(&BoundRect); 00349 00350 if (DontUseAttrs) 00351 return BoundRect; 00352 00353 // Copy the unions into the nodes bounding rect param 00354 BoundingRectangle = BoundRect; 00355 00356 // mark the bounding rect as valid 00357 IsBoundingRectValid = TRUE; 00358 } 00359 00360 // and return the bounding rect 00361 return BoundingRectangle; 00362 } 00363 00364 00365 00366 00367 /******************************************************************************************** 00368 00369 > DocRect Spread::GetDrawingSize () const 00370 00371 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00372 Created: 25/09/96 00373 Returns: Size of the rectangle encompassing the drawing. 00374 Purpose: Works out the size of the rectangle encompassing the drawing. 00375 Code also used to work out the pixel size in the bitmap export options 00376 dialog box. 00377 Graeme (13/7/00) - Changed the code so that the background layer is ignored. 00378 00379 ********************************************************************************************/ 00380 00381 DocRect Spread::GetDrawingSize () const 00382 { 00383 // Start out with an empty clip rectangle. 00384 DocRect SpreadRect; 00385 SpreadRect.MakeEmpty (); 00386 00387 // Find the first layer in the spread. 00388 Layer* pLayer = FindFirstLayer (); 00389 00390 // Loop through the layers, and union the bounding boxes of all visible, non-background 00391 // layers. 00392 while ( pLayer != NULL ) 00393 { 00394 // Let's see if it is visible, and not a background layer. 00395 if ( pLayer->IsVisible() && !pLayer->IsBackground () ) 00396 { 00397 // This one is visible, so union its bounding box in. 00398 SpreadRect = SpreadRect.Union(pLayer->GetBoundingRect () ); 00399 } 00400 00401 // Find the next layer. 00402 pLayer = pLayer->FindNextLayer (); 00403 } 00404 00405 // Return the found rectangle to the caller. 00406 return SpreadRect; 00407 } 00408 00409 00410 /******************************************************************************************** 00411 00412 > BOOL Spread::IsSpread() const 00413 00414 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00415 Created: 15/02/95 00416 Returns: TRUE - this IS a spread node. 00417 Purpose: Tell the caller that this is a spread node. 00418 00419 ********************************************************************************************/ 00420 00421 BOOL Spread::IsSpread() const 00422 { 00423 // Yes, this is a spread! 00424 return TRUE; 00425 } 00426 00427 00428 00429 /*********************************************************************************************** 00430 00431 > void Spread::RenderPasteboard(void) const 00432 00433 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00434 Created: 14/5/93 00435 Inputs: - 00436 Outputs: - 00437 Returns: - 00438 Purpose: To render the pasteboard and off-paste area 00439 Errors: - 00440 Scope: Private 00441 SeeAlso: - 00442 00443 ***********************************************************************************************/ 00444 00445 void Spread::RenderPasteboard( RenderRegion* pRender ) 00446 { 00447 // Ensure we don't dither the filled areas 00448 pRender->SetSolidColours(TRUE); 00449 00450 // Ensure that the top coord of this pasteboard is exactly the same as the bottom of 00451 // the upper pasteboard. 00452 00453 #ifdef _DEBUG 00454 Spread* PrevSpread = FindPreviousSpread(); 00455 if (PrevSpread != NULL) 00456 ENSURE((PasteboardRect.HighCorner().y == 00457 PrevSpread->GetPasteboardRect(FALSE,pRender->GetRenderView()).LowCorner().y), 00458 "Spreads are not properly vertically aligned"); 00459 #endif 00460 00461 // Find out the Clip rect of the render region to help decide which rectangles to try to draw 00462 DocRect SpreadPasteboard = GetWidePasteboard(pRender->GetRenderView()); 00463 00464 DocCoordToSpreadCoord(&SpreadPasteboard); 00465 00466 Page* CurrentPage = FindFirstPageInSpread(); 00467 00468 // --- Divide the pasteboard up into filled rectangles and render them --- 00469 00470 DocRect CurrentPageRect = CurrentPage->GetPageRect(); 00471 00472 // Ensure that we have a transparent line colour throughout 00473 pRender->SetLineColour(COLOUR_TRANS); 00474 00475 // Set up a pasteboard colour 00476 DocColour COLOUR_PASTEBOARD(192L, 192L, 192L); 00477 #ifdef NO_SPREAD 00478 COLOUR_PASTEBOARD = DocColour(Page::PageColour); 00479 #endif 00480 // colour the pasteboard white to hide it if we're in ralph DRAWING_VIEW mode 00481 // ( this flag is set in Render() ) 00482 if (RalphDontShowPaper) 00483 COLOUR_PASTEBOARD = DocColour(255L, 255L, 255L); 00484 00485 COLOUR_PASTEBOARD.SetSeparable(FALSE); // Don't colour-separate the pasteboard 00486 00487 // We can now have a zero sized top pasteboard and due to pixelization of the 00488 // SpreadPasteboard DocRect this may give rise to errors if Top is just 00489 // constructed. So we must check it before hand. 00490 // Effectively doing the same as the ENSURE((Low.x <= High.x) && (Low.y <= High.y) 00491 // in the DocRect constructor. 00492 if (SpreadPasteboard.HighCorner().y > CurrentPageRect.HighCorner().y) 00493 { 00494 // Render the top pasteboard rectangle 00495 DocRect Top(DocCoord(SpreadPasteboard.LowCorner().x, 00496 CurrentPageRect.HighCorner().y), 00497 DocCoord(SpreadPasteboard.HighCorner().x, 00498 SpreadPasteboard.HighCorner().y)); 00499 00500 pRender->SetFillColour(COLOUR_PASTEBOARD); 00501 pRender->DrawRect(&Top); 00502 } 00503 00504 // For each row of pages in a spread, render a rectangle to the left of the left-most 00505 // page reaching the left of the pasteboard, and a rectangle to the right of the right-most 00506 // page reaching the right of the pasteboard. Also if any off-paste area needs to be rendered 00507 // then render a rectangle to the right of the right pasteboard rectangle. 00508 00509 do 00510 { 00511 // Render rectangle to the left of the left-most page but first check 00512 // that there is enough of a left section to worry about 00513 if (CurrentPageRect.LowCorner().x > SpreadPasteboard.LowCorner().x) 00514 { 00515 // Render rectangle to the left of the left-most page 00516 DocRect Left(DocCoord(SpreadPasteboard.LowCorner().x, 00517 CurrentPageRect.LowCorner().y), 00518 DocCoord(CurrentPageRect.LowCorner().x, 00519 CurrentPageRect.HighCorner().y)); 00520 00521 pRender->SetFillColour(COLOUR_PASTEBOARD); 00522 pRender->DrawRect(&Left); 00523 } 00524 00525 // Find the right-most page in the current row 00526 while (CurrentPage->FindRightPage()) 00527 CurrentPage = CurrentPage->FindNextPage(); 00528 00529 CurrentPageRect = CurrentPage->GetPageRect(); 00530 00531 // Render rectangle to the right of the right-most page but first check 00532 // that there is enough of a right section to worry about 00533 if (SpreadPasteboard.HighCorner().x > CurrentPageRect.HighCorner().x) 00534 { 00535 // Render a rectangle to the right of the right-most page 00536 DocRect Right(DocCoord(CurrentPageRect.HighCorner().x, 00537 CurrentPageRect.LowCorner().y), 00538 DocCoord(SpreadPasteboard.HighCorner().x, 00539 CurrentPageRect.HighCorner().y)); 00540 00541 pRender->SetFillColour(COLOUR_PASTEBOARD); // added 24/3/97 00542 pRender->DrawRect(&Right); 00543 } 00544 00545 CurrentPage = CurrentPage->FindNextPage(); // Move to the first page in the next row 00546 if (CurrentPage != NULL) 00547 { 00548 CurrentPageRect = CurrentPage->GetPageRect(); 00549 } 00550 } while (CurrentPage != NULL); // While there are more rows 00551 00552 // Check that there is enough of a bottom section to worry about 00553 if (CurrentPageRect.LowCorner().y > SpreadPasteboard.LowCorner().y) 00554 { 00555 // Render a rectangle below the lowest page 00556 DocRect Bottom(DocCoord(SpreadPasteboard.LowCorner().x, 00557 SpreadPasteboard.LowCorner().y), 00558 DocCoord(SpreadPasteboard.HighCorner().x, 00559 CurrentPageRect.LowCorner().y)); 00560 00561 pRender->SetFillColour(COLOUR_PASTEBOARD); 00562 pRender->DrawRect(&Bottom); 00563 } 00564 00565 // And revert to normal dithered plotting 00566 pRender->SetSolidColours(FALSE); 00567 } 00568 00569 00570 00571 /*********************************************************************************************** 00572 00573 > void Spread::RenderDropShadows(void) const 00574 00575 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00576 Created: 11/5/93 00577 Purpose: To render right-hand and bottom drop shadows 00578 Scope: private 00579 00580 ***********************************************************************************************/ 00581 00582 void Spread::RenderDropShadows(RenderRegion* pRender) 00583 { 00584 // If we have the new page background layer present then we needn't bother redrawing the 00585 // page as we might get a flash of white as we redraw 00586 // Therefore, we don't need to add a pixel on the right hand side page border 00587 BOOL PageBackgroundPresent = FALSE; 00588 // Is there a page background layer on the spread? 00589 Layer* pLayer = FindFirstPageBackgroundLayer(); 00590 // Yes, the layer is present but is it visible? 00591 if (pLayer && pLayer->IsVisible()) 00592 PageBackgroundPresent = TRUE; 00593 00594 // Ensure filled areas are not dithered 00595 pRender->SetSolidColours(TRUE); 00596 00597 // Setup attributes 00598 pRender->SetLineWidth(0); // means single pixel lines 00599 pRender->SetLineColour(COLOUR_TRANS); 00600 00601 DocColour COLOUR_SHADOW(COLOUR_MIDGREY); 00602 pRender->SetFillColour(COLOUR_SHADOW); 00603 00604 // Get the scaled pixel size for the view 00605 FIXED16 ScaledPixelWidth; 00606 FIXED16 ScaledPixelHeight; 00607 pRender->GetRenderView()->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight); 00608 00609 // Find out how many millipoints 4 pixels is 00610 MILLIPOINT DropWidth = 4 * (min(ScaledPixelWidth.MakeLong(), ScaledPixelHeight.MakeLong() )); 00611 00612 MILLIPOINT ExtraPixel = ScaledPixelWidth.MakeLong(); 00613 if (PageBackgroundPresent) 00614 ExtraPixel = 0; 00615 00616 // The page we are currently drawing drop shadows for 00617 Page* CurrentPage = FindFirstPageInSpread(); 00618 00619 //Render drop shadows for each page in turn 00620 while (CurrentPage != NULL) 00621 { 00622 // Will indicate if page has a left or right drop shadow 00623 BOOL PageHasADropShadow = FALSE; 00624 DocRect PageRect = CurrentPage->GetPageRect(); 00625 00626 // If the current page has no page to its right then we should render a right-hand 00627 // drop shadow 00628 if (!(CurrentPage->FindRightPage())) 00629 { 00630 // Take width of page outline into account by rendering drop shadow one pixel beyond 00631 // edge of page! This makes drop shadow same width as its height below the page. 00632 DocRect RightHandDropShadow(PageRect.HighCorner().x + ExtraPixel, 00633 PageRect.LowCorner().y - DropWidth, 00634 PageRect.HighCorner().x + DropWidth + ExtraPixel, 00635 PageRect.HighCorner().y - DropWidth 00636 ); 00637 00638 pRender->DrawRect(&RightHandDropShadow); 00639 00640 /* // Attempt to render fuzzy shadow edge using bitmap... 00641 { 00642 DocRect r = RightHandDropShadow; 00643 CWxBitmap* pBitmap = new CWxBitmap(); 00644 pBitmap->LoadBitmap(_R(IDB_SPREAD_RIGHTEDGE)); 00645 KernelBitmap* pkBitmap = new KernelBitmap(pBitmap, TRUE); 00646 00647 pRender->RenderBits(pkBitmap, (DocCoord*)&r, 2, TRUE, NULL); // Unclean! 00648 00649 if (pBitmap) 00650 { 00651 pBitmap->BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes; 00652 } 00653 if (pkBitmap) 00654 { 00655 delete pkBitmap; 00656 pkBitmap = NULL; 00657 } 00658 } 00659 */ 00660 PageHasADropShadow = TRUE; 00661 00662 } 00663 00664 // If the current page has no page vertically joined beneath it then render a 00665 // bottom drop shadow. 00666 if (!(CurrentPage->FindBottomPage())) 00667 { 00668 //Render bottom drop shadow 00669 DocRect BottomDropShadow(PageRect.LowCorner().x + DropWidth, 00670 PageRect.LowCorner().y - DropWidth, 00671 PageRect.HighCorner().x + DropWidth, 00672 PageRect.LowCorner().y 00673 ); 00674 00675 pRender->DrawRect(&BottomDropShadow); 00676 00677 /* // Attempt to render fuzzy shadow edge using bitmap... 00678 { 00679 DocRect r = BottomDropShadow; 00680 CWxBitmap* pBitmap = new CWxBitmap(); 00681 pBitmap->LoadBitmap(_R(IDB_SPREAD_BOTTOMEDGE)); 00682 KernelBitmap* pkBitmap = new KernelBitmap(pBitmap, TRUE); 00683 00684 pRender->RenderBits(pkBitmap, (DocCoord*)&r, 2, TRUE, NULL); // Unclean! 00685 00686 if (pBitmap) 00687 { 00688 pBitmap->BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes; 00689 } 00690 if (pkBitmap) 00691 { 00692 delete pkBitmap; 00693 pkBitmap = NULL; 00694 } 00695 } 00696 */ 00697 PageHasADropShadow = TRUE; 00698 } 00699 00700 // This bit is not very beautiful. If a page has a page to its right and a page beneath 00701 // it, and the page to its right does not have have a page beneath it, then there will 00702 // be a little cube of drop shadow left to draw at the bottom right hand corner of the 00703 // page. 00704 00705 if (!PageHasADropShadow) 00706 { 00707 // The page has a page to its right and a page beneath it 00708 ENSURE( CurrentPage->FindRightPage(), 00709 "Spread::RenderDropShadows: Cannot find right page"); 00710 if (CurrentPage->FindRightPage()->FindBottomPage() == NULL) 00711 { 00712 DocRect MissingCube(PageRect.HighCorner().x, 00713 PageRect.LowCorner().y - DropWidth, 00714 PageRect.HighCorner().x + DropWidth, 00715 PageRect.LowCorner().y); 00716 00717 pRender->DrawRect(&MissingCube); 00718 } 00719 } 00720 00721 // Move to next page 00722 CurrentPage = CurrentPage->FindNextPage(); 00723 } 00724 00725 // And return to normal dithered rendering 00726 pRender->SetSolidColours(FALSE); 00727 } 00728 00729 00730 /*********************************************************************************************** 00731 00732 > void Spread::RenderBleedArea( RenderRegion* pRender ) 00733 00734 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00735 Created: 15/5/93 00736 Purpose: Renders the Bleed Area rectangle if the BleedOffset is not 0 00737 Scope: private 00738 00739 ***********************************************************************************************/ 00740 00741 void Spread::RenderBleedArea( RenderRegion* pRender) 00742 { 00743 if (BleedOffset != 0) 00744 { 00745 // Draw a rectangle BleedOffset outside the common bounding rectangle of all pages 00746 // in the spread. 00747 00748 // Calculate the common bounding rectangle of all the spread's pages 00749 DocRect BleedRectangle; 00750 00751 Page* CurrentPage = FindFirstPageInSpread(); 00752 while(CurrentPage != NULL) 00753 { 00754 DocRect PageRect = CurrentPage->GetPageRect(); 00755 BleedRectangle = BleedRectangle.Union(PageRect); 00756 CurrentPage = CurrentPage->FindNextPage(); 00757 } 00758 BleedRectangle.Inflate(BleedOffset); 00759 00760 // Ensure plotting does not use dithered colours 00761 pRender->SetSolidColours(TRUE); 00762 00763 // Draw a rectangle covering the page 00764 // Set up attributes for drawing page rectangle 00765 pRender->SetLineWidth(0); // Means single-pixel lines 00766 pRender->SetLineColour(COLOUR_TRANS); 00767 00768 DocColour COLOUR_BLEEDAREA(COLOUR_RED); 00769 pRender->SetFillColour(COLOUR_BLEEDAREA); 00770 pRender->DrawPixelRect(&BleedRectangle); 00771 00772 // And return to normal dithered rendering 00773 pRender->SetSolidColours(FALSE); 00774 } 00775 } 00776 00777 00778 00779 /*********************************************************************************************** 00780 00781 > void Spread::Render( RenderRegion* pRender ) 00782 00783 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00784 Created: 10/5/93 00785 Inputs: pRender - The render region to draw into 00786 Purpose: Renders spread items: 00787 Pasteboard and off-paste area 00788 Main fold line 00789 Spread dividers 00790 Bleed Area 00791 Drop-shadows 00792 Spread outline 00793 Print margin 00794 00795 ***********************************************************************************************/ 00796 00797 void Spread::Render( RenderRegion* pRender ) 00798 { 00799 // If we should blow up, then blow up - don't worry, this is a very quick inline check 00800 OpException::BlowUpOnCrashMe(); 00801 00802 // ralph only renders paper/pasteboard in some view modes 00803 #ifdef RALPH 00804 //find the parent NodeDocument 00805 Node* pCurrentNode = FindParent(); 00806 while(pCurrentNode != NULL) 00807 { 00808 if (pCurrentNode->IsNodeDocument()) 00809 break; 00810 pCurrentNode = pCurrentNode->FindParent(); 00811 } 00812 BaseDocument * pDoc =NULL; 00813 // get a Document * 00814 if(pCurrentNode) 00815 pDoc = ((NodeDocument*)(pCurrentNode))->GetParentDoc(); 00816 // set RalphDontShowPaper - it will be tested in RenderPasteboard 00817 if(pDoc) 00818 RalphDontShowPaper =((Document*)pDoc)->RalphDontShowPaper(); 00819 #endif 00820 00821 // --- Render pasteboard --- 00822 RenderPasteboard(pRender); 00823 00824 if(!RalphDontShowPaper) 00825 { 00826 00827 // --- Render main fold line --- 00828 Chapter* pChapter = FindParentChapter(); 00829 ERROR3IF(pChapter == NULL,"Spread::Render: Could not find parent chapter"); 00830 00831 if (pChapter != NULL && pChapter->ShouldShowFoldLine()) 00832 { 00833 MILLIPOINT MainFoldLineXCoord = pChapter->GetFoldLineXCoord(); 00834 00835 DocRect PBRect = GetPasteboardRect(TRUE, pRender->GetRenderView()); 00836 00837 pRender->SetLineWidth(0); // Means single-pixel lines 00838 pRender->SetLineColour(COLOUR_TRANS); 00839 00840 DocColour COLOUR_FOLDLINE = DocColour(150L, 150L, 150L); 00841 COLOUR_FOLDLINE.SetSeparable(FALSE); // Don't colour-separate the fold line 00842 00843 pRender->SetFillColour(COLOUR_FOLDLINE); 00844 pRender->DrawPixelLine(DocCoord(MainFoldLineXCoord, PBRect.lo.y), 00845 DocCoord(MainFoldLineXCoord, PBRect.hi.y)); 00846 } 00847 00848 // --- Render spread dividers --- 00849 00850 // Set the colour for the spread divide (mid grey) 00851 /* DocColour COLOUR_SPREADDIVIDE = DocColour(64L, 32L, 32L); //DocColour(127L, 127L, 127L); 00852 COLOUR_SPREADDIVIDE.SetSeparable(FALSE); // Don't colour-separate the spread divider 00853 00854 pRender->SetLineColour(COLOUR_SPREADDIVIDE); 00855 00856 // Set the line width (Wider for the first spread in the chapter) 00857 if (FindPrevious()==NULL) 00858 { 00859 MILLIPOINT LineWidth = 4*PixelHeight; 00860 pRender->SetLineWidth(LineWidth); 00861 } 00862 else 00863 pRender->SetLineWidth(0); 00864 00865 // Draw line along the top of the pasteboard 00866 View *pView = pRender->GetRenderView(); 00867 MILLIPOINT Width = GetWidePasteboard(pView).Width(); 00868 MILLIPOINT Height = GetWidePasteboard(pView).Height(); 00869 pRender->DrawLine(DocCoord(-Width, Height), DocCoord(Width, Height)); 00870 */ 00871 00872 if (FindPreviousSpread()!=NULL) 00873 { 00874 DocColour COLOUR_SPREADDIVIDE = DocColour(64L, 32L, 32L); //DocColour(127L, 127L, 127L); 00875 COLOUR_SPREADDIVIDE.SetSeparable(FALSE); // Don't colour-separate the spread divider 00876 pRender->SetFillColour(COLOUR_SPREADDIVIDE); 00877 00878 View *pView = pRender->GetRenderView(); 00879 DocRect sd = GetWidePasteboard(pView); 00880 DocCoordToSpreadCoord(&sd); 00881 00882 FIXED16 ScaledPixelWidth; 00883 FIXED16 ScaledPixelHeight; 00884 pRender->GetRenderView()->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight); 00885 sd.lo.y = sd.hi.y - ScaledPixelWidth.MakeLong(); 00886 pRender->DrawRect(&sd); 00887 } 00888 00889 // --- Render drop shadows --- 00890 if (ShowDropShadow) 00891 RenderDropShadows( pRender ); 00892 00893 // --- Render bleed area, if not 0 size --- 00894 // Render after page shadow as otherwise page shadow may overdraw the bleed margin 00895 // and the bleed margin will disappear. 00896 RenderBleedArea(pRender); 00897 } 00898 } 00899 00900 00901 00902 /*********************************************************************************************** 00903 00904 > Node* Spread::SimpleCopy() 00905 00906 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00907 Created: 28/4/93 00908 00909 Inputs: - 00910 Outputs: 00911 Returns: A copy of the node, or NULL if memory runs out 00912 00913 Purpose: This method returns a shallow copy of the node with all Node pointers NULL. 00914 The function is virtual, and must be defined for all derived classes. 00915 00916 Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory 00917 error and the function returns NULL. 00918 00919 Scope: protected 00920 00921 **********************************************************************************************/ 00922 00923 Node* Spread::SimpleCopy() 00924 { 00925 Spread* NodeCopy; 00926 NodeCopy = new Spread(); 00927 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); 00928 CopyNodeContents(NodeCopy); 00929 return (NodeCopy); 00930 } 00931 00932 00933 00934 /*********************************************************************************************** 00935 00936 > void Spread::CopyNodeContents(Spread* NodeCopy) 00937 00938 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00939 Created: 28/4/93 00940 00941 Inputs: 00942 Outputs: A copy of this node 00943 Returns: - 00944 00945 Purpose: This method copies the node's contents to the node pointed to by NodeCopy. 00946 00947 Errors: An assertion failure will occur if NodeCopy is NULL 00948 00949 Scope: protected 00950 00951 ***********************************************************************************************/ 00952 00953 void Spread::CopyNodeContents(Spread* NodeCopy) 00954 { 00955 ERROR3IF(NodeCopy == NULL,"Trying to copy node contents to\n" 00956 "a node pointed to by a NULL pointer"); 00957 NodeRenderablePaper::CopyNodeContents(NodeCopy); 00958 00959 NodeCopy->BleedOffset = BleedOffset; 00960 NodeCopy->ShowDropShadow = ShowDropShadow; 00961 NodeCopy->SpreadOrigin = SpreadOrigin; 00962 NodeCopy->UserOrigin = UserOrigin; 00963 NodeCopy->m_AnimPropertiesParam = m_AnimPropertiesParam; 00964 NodeCopy->SpreadDimScale = SpreadDimScale; 00965 NodeCopy->RalphDontShowPaper = RalphDontShowPaper; 00966 } 00967 00968 00969 /*********************************************************************************************** 00970 > void Spread::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00971 00972 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00973 Created: 18/12/2003 00974 Outputs: - 00975 Purpose: Polymorphically copies the contents of this node to another 00976 Errors: An assertion failure will occur if NodeCopy is NULL 00977 Scope: protected 00978 00979 ***********************************************************************************************/ 00980 00981 void Spread::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00982 { 00983 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node"); 00984 ENSURE(IS_A(pNodeCopy, Spread), "PolyCopyNodeContents given wrong dest node type"); 00985 00986 if (IS_A(pNodeCopy, Spread)) 00987 CopyNodeContents((Spread*)pNodeCopy); 00988 } 00989 00990 00991 00992 /*********************************************************************************************** 00993 00994 > Page* Spread::FindFirstPageInSpread() const 00995 00996 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00997 Created: 11/5/93 00998 Inputs: - 00999 Outputs: - 01000 Returns: The first page in the spread, or NULL if the spread has no pages 01001 Purpose: To find the first page in a spread 01002 Errors: - 01003 SeeAlso: - 01004 01005 ***********************************************************************************************/ 01006 01007 Page* Spread::FindFirstPageInSpread() const 01008 { 01009 Node* CurrentNode = FindFirstChild(); 01010 while(CurrentNode != NULL) 01011 { 01012 if (CurrentNode->IsKindOf(CC_RUNTIME_CLASS(Page))) 01013 return ((Page*)CurrentNode); 01014 CurrentNode = CurrentNode->FindNext(); 01015 } 01016 return (NULL); // No pages were found 01017 } 01018 01019 01020 01021 /*********************************************************************************************** 01022 01023 > Spread* Spread::FindNextSpread(void) 01024 01025 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01026 Created: 11/5/93 01027 Inputs: - 01028 Outputs: - 01029 Returns: The next sibling spread of this node, or NULL if there are no more spreads. 01030 Purpose: To find the next sibling spread 01031 Errors: - 01032 SeeAlso: - 01033 01034 ***********************************************************************************************/ 01035 01036 Spread* Spread::FindNextSpread(void) 01037 { 01038 Node* CurrentNode = FindNext(); 01039 while (CurrentNode != 0) 01040 { 01041 if (CurrentNode->IsSpread()) return (Spread*) CurrentNode; 01042 CurrentNode = CurrentNode->FindNext(); 01043 } 01044 return 0; // No spread found 01045 } 01046 01047 01048 01049 /*********************************************************************************************** 01050 01051 > Spread* Spread::FindPreviousSpread(void) 01052 01053 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01054 Created: 11/5/93 01055 Inputs: - 01056 Outputs: - 01057 Returns: The previous sibling spread of this node, or NULL if there are none. 01058 Purpose: To find the current spreads previous sibling spread 01059 Errors: - 01060 SeeAlso: - 01061 01062 ***********************************************************************************************/ 01063 01064 Spread* Spread::FindPreviousSpread(void) 01065 { 01066 Node* CurrentNode = FindPrevious(); 01067 while (CurrentNode != 0) 01068 { 01069 if (CurrentNode->IsSpread()) return (Spread*) CurrentNode; 01070 CurrentNode = CurrentNode->FindPrevious(); 01071 } 01072 return 0; // No spread found 01073 } 01074 01075 01076 01077 /******************************************************************************************** 01078 01079 > Layer* Spread::FindActiveLayer(void) 01080 01081 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01082 Created: 6/1/94 01083 Inputs: - 01084 Outputs: - 01085 Returns: The active layer for the spread, or NULL if there is no active layer 01086 Note: a spread should always have one active layer, so in a DEBUG build an 01087 ENSURE failure will occur if no active layer exists. 01088 01089 Purpose: For finding the spreads active layer. 01090 Errors: An ENSURE failure will occur if the spread has no active layer, or if the spread 01091 has more than one active layer. 01092 SeeAlso: - 01093 01094 ********************************************************************************************/ 01095 01096 Layer* Spread::FindActiveLayer(void) 01097 { 01098 // Changed by MarkN 11/8/94 to use Spread::FindFirstLayer()and Layer::FindNextLayer() 01099 01100 Layer* pActiveLayer = NULL; 01101 Layer* pLayer = FindFirstLayer(); // Get first child 01102 BOOL MultipleActiveLayers = FALSE; 01103 while (pLayer != NULL) 01104 { 01105 if (pLayer->IsActive()) // we have found an active layer 01106 { 01107 // There should only ever be one active layer 01108 ERROR3IF(pActiveLayer != NULL, "Spread has more than one active layer"); 01109 if (pActiveLayer != NULL) 01110 MultipleActiveLayers = TRUE; 01111 pActiveLayer = pLayer; 01112 } 01113 01114 pLayer = pLayer->FindNextLayer(); // Find next layer 01115 } 01116 01117 // This line added by MarkN 22/3/95, to ensure that this function cannot fail 01118 // as long as there is at least one layer in this spread. 01119 // The MultipleActiveLayers added by Neville 12/6/96 so that multiple active layers 01120 // are fixed, if found. 01121 if (pActiveLayer == NULL || MultipleActiveLayers) 01122 LayerSGallery::EnsureActiveLayerIntegrity(this,&pActiveLayer); 01123 // Fail if the spread has no active layer 01124 return (pActiveLayer); 01125 } 01126 01127 01128 01129 /******************************************************************************************** 01130 01131 > Layer* Spread::FindFirstLayer() const 01132 01133 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01134 Created: 18/1/94 01135 Inputs: - 01136 Outputs: - 01137 Returns: The first layer on the spread, or NULL if the spread has no layers. 01138 01139 Purpose: To find the spread's first layer. 01140 01141 Errors: - 01142 SeeAlso: - 01143 01144 ********************************************************************************************/ 01145 01146 Layer* Spread::FindFirstLayer() const 01147 { 01148 Node* Current = FindFirstChild(); 01149 while (Current != NULL) 01150 { 01151 if (Current->GetRuntimeClass() == CC_RUNTIME_CLASS(Layer)) 01152 { 01153 return (Layer*)Current; 01154 } 01155 Current = Current->FindNext(); 01156 } 01157 01158 return (NULL); 01159 } 01160 01161 01162 /******************************************************************************************** 01163 01164 > Layer* Spread::FindLastLayer() const 01165 01166 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01167 Created: 9/8/94 01168 Inputs: - 01169 Outputs: - 01170 Returns: The last layer on the spread, or NULL if the spread has no layers. 01171 01172 Purpose: To find the spread's last layer. 01173 01174 Errors: - 01175 SeeAlso: - 01176 01177 ********************************************************************************************/ 01178 01179 Layer* Spread::FindLastLayer() const 01180 { 01181 Node* pNode = FindFirstChild(); 01182 Layer* pLastLayer = NULL; 01183 01184 while (pNode != NULL) 01185 { 01186 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(Layer)) 01187 pLastLayer = (Layer*)pNode; 01188 01189 pNode = pNode->FindNext(); 01190 } 01191 01192 return (pLastLayer); 01193 } 01194 01195 01196 01197 /******************************************************************************************** 01198 01199 > Layer* Spread::FindFirstGuideLayer() const 01200 01201 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01202 Created: 4/10/95 01203 Inputs: - 01204 Outputs: - 01205 Returns: The first guide layer on the spread, or NULL if the spread has no layers. 01206 01207 Purpose: To find the spread's first guide layer. 01208 01209 Errors: - 01210 SeeAlso: - 01211 01212 ********************************************************************************************/ 01213 01214 Layer* Spread::FindFirstGuideLayer() const 01215 { 01216 Layer* pLayer = FindFirstLayer(); 01217 while (pLayer != NULL) 01218 { 01219 if (pLayer->IsGuide()) 01220 return pLayer; 01221 01222 pLayer = pLayer->FindNextLayer(); 01223 } 01224 01225 return NULL; 01226 } 01227 01228 /******************************************************************************************** 01229 01230 > Layer* Spread::FindFirstPageBackgroundLayer() const 01231 01232 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01233 Created: 4/4/97 01234 Inputs: - 01235 Outputs: - 01236 Returns: The first page background layer on the spread, or NULL if the spread has no layers. 01237 Purpose: To find the spread's first page background layer. 01238 Errors: - 01239 SeeAlso: - 01240 01241 ********************************************************************************************/ 01242 01243 Layer* Spread::FindFirstPageBackgroundLayer() const 01244 { 01245 // Search through the children of this Spread, looking for Layer nodes. 01246 // Use the special flag of the page background layer as its identifier. 01247 Layer* pLayer = FindFirstLayer(); 01248 while (pLayer != NULL) 01249 { 01250 // See if this is a page background layer 01251 if (pLayer->IsPageBackground()) 01252 { 01253 // Cor blimey, we've found one, so return this layer to the caller 01254 return pLayer; 01255 } 01256 01257 pLayer = pLayer->FindNextLayer(); 01258 } 01259 01260 // Nothing found 01261 return NULL; 01262 } 01263 01264 /******************************************************************************************** 01265 01266 > Layer* Spread::FindFirstFrameLayer() const 01267 01268 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01269 Created: 23/4/97 01270 Inputs: - 01271 Outputs: - 01272 Returns: The first frame layer on the spread, or NULL if the spread has no layers. 01273 Purpose: To find the spread's first frame layer. 01274 Errors: - 01275 SeeAlso: - 01276 01277 ********************************************************************************************/ 01278 01279 Layer* Spread::FindFirstFrameLayer() const 01280 { 01281 // Search through the children of this Spread, looking for Layer nodes. 01282 // Use the special flag for frame layers as its identifier. 01283 Layer* pLayer = FindFirstLayer(); 01284 while (pLayer != NULL) 01285 { 01286 // See if this is a frame layer 01287 if (pLayer->IsFrame()) 01288 { 01289 // Cor blimey, we've found one, so return this layer to the caller 01290 return pLayer; 01291 } 01292 01293 pLayer = pLayer->FindNextLayer(); 01294 } 01295 01296 // Nothing found 01297 return NULL; 01298 } 01299 01300 /******************************************************************************************** 01301 01302 > Layer* Spread::FindLastFrameLayer() const 01303 01304 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01305 Created: 21/5/97 01306 Inputs: - 01307 Outputs: - 01308 Returns: The last frame layer on the spread, or NULL if the spread has no frame layers. 01309 Purpose: To find the spread's last framelayer. 01310 Errors: - 01311 SeeAlso: - 01312 01313 ********************************************************************************************/ 01314 01315 Layer* Spread::FindLastFrameLayer() const 01316 { 01317 // Search through the children of this Spread, looking for Layer nodes. 01318 // Use the special flag for frame layers as its identifier. 01319 Layer* pLayer = FindFirstLayer(); 01320 Layer* pLastLayer = NULL; 01321 while (pLayer != NULL) 01322 { 01323 // See if this is a frame layer 01324 if (pLayer->IsFrame()) 01325 { 01326 // Cor blimey, we've found one, so remember this as a potential last frame layer 01327 pLastLayer = pLayer; 01328 } 01329 01330 pLayer = pLayer->FindNextLayer(); 01331 } 01332 01333 // Return what we found as the last layer 01334 return pLastLayer; 01335 } 01336 01337 /******************************************************************************************** 01338 01339 > Page* Spread::FindLastPageInSpread() const 01340 01341 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01342 Created: 4/4/97 01343 Inputs: - 01344 Outputs: - 01345 Returns: The last page on the spread, or NULL if the spread has no pages. 01346 Purpose: To find the spread's last page. 01347 Layers and other renderable nodes should always be inserted after the last page. 01348 Otherwise, there is likely to be redraw problems. 01349 Errors: - 01350 SeeAlso: FindFirstPageInSpread; 01351 01352 ********************************************************************************************/ 01353 01354 Page* Spread::FindLastPageInSpread() const 01355 { 01356 // Get the first page and then continually get the next page until one is not found 01357 // Each time we get a real page we note this as a potential last page. 01358 Page *pLastPage = NULL; 01359 Page *pPage = FindFirstPageInSpread(); 01360 while (pPage != NULL) 01361 { 01362 pLastPage = pPage; // note this page as a potential last page 01363 pPage = pPage->FindNextPage(); 01364 } 01365 01366 // return what we think is the last page 01367 return pLastPage; 01368 } 01369 01370 /******************************************************************************************** 01371 01372 > DocRect Spread::GetWidePasteboard(View *pView) 01373 01374 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01375 Created: 22/11/94 01376 Inputs: pView - the view to pixelise to. 01377 Purpose: Return the pixelised boundary of the "wide pasteboard" 01378 01379 ********************************************************************************************/ 01380 01381 DocRect Spread::GetWidePasteboard(View *pView) 01382 { 01383 ERROR2IF(this==NULL,DocRect(0,0,0,0),"GetWidePasteboard called on NULL pointer"); 01384 01385 // A large size - roughly the width/height of 30 A4 pages. We use this to extend 01386 // the WPB to an effective "infinity" in certain directions. 01387 const MILLIPOINT LargeNumber = 30 * (10 * 72000); 01388 01389 DocRect WPB(PasteboardRect); 01390 01391 // Inflate the left/right sides out to effective "infinity" 01392 WPB.Inflate(LargeNumber, 0); 01393 01394 // If this is the very last spread in the chapter, expand its WPB down by "infinity" 01395 if (FindNextSpread() == NULL) 01396 WPB.lo.y -= LargeNumber; 01397 01398 // Pixelise and return the result 01399 WPB.lo.Pixelise(pView); 01400 WPB.hi.Pixelise(pView); 01401 01402 return(WPB); 01403 } 01404 01405 01406 01407 01408 #ifdef _DEBUG 01409 01410 void Spread::ShowDebugTreeDetails() const 01411 { 01412 TRACE( _T("Spread ")); 01413 Node::ShowDebugTreeDetails(); 01414 } 01415 01416 #endif 01417 01418 /******************************************************************************************** 01419 01420 > void* Spread::GetDebugDetails(StringBase* Str) 01421 01422 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01423 Created: 21/9/93 01424 Inputs: - 01425 Outputs: Str: String giving debug info about the node 01426 Returns: - 01427 Purpose: For obtaining debug information about the Node 01428 Errors: - 01429 SeeAlso: - 01430 01431 ********************************************************************************************/ 01432 01433 void Spread::GetDebugDetails(StringBase* Str) 01434 { 01435 NodeRenderablePaper::GetDebugDetails(Str); 01436 String_256 TempStr; 01437 01438 TempStr._MakeMsg(TEXT("\r\nBleed Offset = #1%ld"), BleedOffset); 01439 *Str += TempStr; 01440 01441 TempStr._MakeMsg(TEXT("\r\nSpreadCoord Origin = #1%ld, #2%ld"), 01442 SpreadOrigin.x, SpreadOrigin.y); 01443 *Str += TempStr; 01444 } 01445 01446 01447 01448 /******************************************************************************************** 01449 01450 > virtual UINT32 Spread::GetNodeSize() const 01451 01452 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 01453 Created: 6/10/93 01454 Inputs: - 01455 Outputs: - 01456 Returns: The size of the node in bytes 01457 Purpose: For finding the size of the node 01458 01459 SeeAlso: Node::GetSubtreeSize 01460 01461 ********************************************************************************************/ 01462 01463 UINT32 Spread::GetNodeSize() const 01464 { 01465 return (sizeof(Spread)); 01466 } 01467 01468 01469 01470 /******************************************************************************************** 01471 01472 > DocRect Spread::GetPageBounds() const 01473 01474 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01475 Created: 18/5/94 01476 Inputs: - 01477 Outputs: - 01478 Returns: A document rectangle which is the rectangle bounding all Pages in 01479 this Spread. This really is a document rectangle, not a spread 01480 rectangle hiding as a DocRect, ie. it is relative to the bottom-left 01481 of the document, not the spread. 01482 Purpose: Finds the bounding rectangle of this Spread, defined as the smallest 01483 rectangle enclosing all the Pages the Spread contains. 01484 Errors: - 01485 SeeAlso: Page::GetPageRect 01486 01487 ********************************************************************************************/ 01488 01489 DocRect Spread::GetPageBounds() const 01490 { 01491 // Start with an empty bounding rectangle. 01492 DocRect drBound; 01493 drBound.MakeEmpty(); 01494 01495 // Search through the children of this Spread, looking for Page nodes. 01496 Node* Current = FindFirstChild(); 01497 while (Current != NULL) 01498 { 01499 if (Current->GetRuntimeClass() == CC_RUNTIME_CLASS(Page)) 01500 { 01501 // Found a page node. Take the union of its bounding rectangle and 01502 // the accumulated bounds. 01503 drBound = drBound.Union(((Page*) Current)->GetPageRect()); 01504 } 01505 Current = Current->FindNext(); 01506 } 01507 01508 // Convert the value from spread coordinates to document coords 01509 SpreadCoordToDocCoord(&drBound); 01510 01511 // Return the accumulated bounds. 01512 return drBound; 01513 } 01514 01515 01516 01517 /******************************************************************************************** 01518 01519 > DocRect Spread::GetPageVisibleBounds() const 01520 01521 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01522 Created: 18/5/94 01523 Inputs: - 01524 Outputs: - 01525 Returns: A document rectangle which is the rectangle bounding all Pages in 01526 this Spread. This really is a document rectangle, not a spread 01527 rectangle hiding as a DocRect, ie. it is relative to the bottom-left 01528 of the document, not the spread. 01529 01530 Purpose: Finds the bounding rectangle of this Spread, defined as the smallest 01531 rectangle enclosing all the Pages the Spread contains. 01532 01533 The visible bounds exclude all non-visible layers 01534 01535 Errors: - 01536 SeeAlso: Page::GetPageRect 01537 01538 ********************************************************************************************/ 01539 01540 DocRect Spread::GetPageVisibleBounds() const 01541 { 01542 // Start with an empty bounding rectangle. 01543 DocRect drBound; 01544 drBound.MakeEmpty(); 01545 01546 // Search through the children of this Spread, looking for Layer nodes. 01547 Layer* pCurrent = ((Spread*)this)->FindFirstLayer(); 01548 while (pCurrent != NULL) 01549 { 01550 // Only add the bounding box of the layer in if it is visible and if it is not 01551 // either a guide layer or the page background layer. 01552 if (pCurrent->IncludeLayerInBoundingCalcs()) 01553 { 01554 // Found a visible layer node. Take the union of its bounding rectangle and 01555 // the accumulated bounds. 01556 drBound = drBound.Union(pCurrent->GetBoundingRect()); 01557 } 01558 01559 pCurrent = pCurrent->FindNextLayer(); 01560 } 01561 01562 // Convert the value from spread coordinates to document coords 01563 SpreadCoordToDocCoord(&drBound); 01564 01565 // Return the accumulated bounds. 01566 return drBound; 01567 } 01568 01569 01570 01571 /******************************************************************************************** 01572 01573 > DimScale* Spread::GetPtrDimScale() 01574 01575 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 01576 Created: 14/6/94 01577 Inputs: - 01578 Outputs: - 01579 Returns: A ptr to the dimension scale object for all objects in this Spread 01580 Purpose: For getting a ptr to the Spread's dimension scale object 01581 Errors: - 01582 SeeAlso: - 01583 01584 ********************************************************************************************/ 01585 01586 DimScale* Spread::GetPtrDimScale() 01587 { 01588 return (&SpreadDimScale); 01589 } 01590 01591 01592 01593 /******************************************************************************************** 01594 01595 > MILLIPOINT Spread::GetBleedOffset() const 01596 01597 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01598 Created: 14/12/94 01599 Inputs: - 01600 Outputs: - 01601 Returns: The current size in millipoints of this spreads bleed are. 01602 Purpose: For getting the Spread's bleed area size. 01603 Errors: - 01604 SeeAlso: SetBleedOffset(); 01605 01606 ********************************************************************************************/ 01607 01608 MILLIPOINT Spread::GetBleedOffset() const 01609 { 01610 return BleedOffset; 01611 } 01612 01613 01614 01615 /******************************************************************************************** 01616 01617 > BOOL Spread::SetBleedOffset(MILLIPOINT Bleed) 01618 01619 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01620 Created: 14/12/94 01621 Inputs: - 01622 Outputs: - 01623 Returns: The current size in millipoints of this spreads bleed are. 01624 Purpose: For setting a new value for the Spread's bleed area size. 01625 Errors: - 01626 SeeAlso: GetBleedOffset(); 01627 01628 ********************************************************************************************/ 01629 01630 BOOL Spread::SetBleedOffset(MILLIPOINT Bleed) 01631 { 01632 BleedOffset = Bleed; // set up new bleed value 01633 01634 return TRUE; 01635 } 01636 01637 01638 01639 /******************************************************************************************** 01640 01641 > BOOL Spread::GetShowDropShadow() const 01642 01643 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01644 Created: 14/12/94 01645 Inputs: - 01646 Outputs: - 01647 Returns: The current drop shadow display state as either True or False. 01648 Purpose: Finds out the current drop shadow display state. 01649 Errors: - 01650 SeeAlso: SetShowDropShadow(); 01651 01652 ********************************************************************************************/ 01653 01654 BOOL Spread::GetShowDropShadow() const 01655 { 01656 return ShowDropShadow; 01657 } 01658 01659 01660 01661 /******************************************************************************************** 01662 01663 > BOOL Spread::SetShowDropShadow(BOOL NewState) 01664 01665 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01666 Created: 14/12/94 01667 Inputs: New drop shadow display state. 01668 Outputs: - 01669 Returns: The old drop shadow display state as either True or False. 01670 Purpose: Allows the setting of a new drop shadow display state. 01671 Errors: - 01672 SeeAlso: GetShowDropShadow(); 01673 01674 ********************************************************************************************/ 01675 01676 BOOL Spread::SetShowDropShadow(BOOL NewState) 01677 { 01678 // WEBSTER-ranbirr-13/11/96 01679 #ifndef WEBSTER 01680 BOOL OldState = ShowDropShadow; // note current old state 01681 ShowDropShadow = NewState; // Set up the required new state 01682 return OldState; // return old state to the caller 01683 01684 #else //webster 01685 01686 BOOL OldState = FALSE; 01687 ShowDropShadow = FALSE ; 01688 return OldState; // return old state to the caller 01689 #endif //Webster 01690 01691 } 01692 01693 #if NEW_PASTEBOARD 01694 // New pasteboard code by Jason. This keeps the bottom left corner of the page where 01695 // it was, and rejigs the page size, other pages, bleed, and pasteboard to fit tidily 01696 // around the outside. This results in a much tidier spread than the old code, but 01697 // due to flaws in our V1 save file format, completely scrags save/load! 01698 // Hopefully for V2, we can fix the save/load code to allow us to use more sensible layouts 01699 01700 /******************************************************************************************** 01701 01702 > BOOL Spread::GetPageSize(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Margin, 01703 MILLIPOINT *Bleed, BOOL *Dps, BOOL *ShowDropShadow) 01704 01705 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01706 Created: 4/1/95 01707 Inputs: - 01708 Outputs: Width returned width of the page in millipoints 01709 Height returned height of the page in millipoints 01710 Margin returned size of the margin area in millipoints (0 = none) 01711 Bleed returned size of the bleed area in millipoints (0 = none) 01712 Dps returned whether another page (or pages) is present or not. 01713 ShowDropShadow returned new drop shadow display state. 01714 Returns: Whether we completed the scanning operation ok or not as True or False. 01715 Purpose: Allows the current page size specified for a spread to be determined. 01716 Assumes that all pages in one spread are the same size and hence returns 01717 this size. 01718 01719 Note: Any of the input params can be NULL (Markn 4/4/95) 01720 01721 Errors: Will error if pages are not consistent. 01722 SeeAlso: Spread::SetPageSize 01723 01724 ********************************************************************************************/ 01725 01726 BOOL Spread::GetPageSize(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Margin, 01727 MILLIPOINT *Bleed, BOOL *Dps, BOOL *ShowDropShadow) 01728 { 01729 ERROR2IF(this==NULL,FALSE,"Spread::GetPageSize called on NULL pointer"); 01730 01731 // Set up defaults in case of dodgy exit 01732 if (Width != NULL) *Width = 0; 01733 if (Height != NULL) *Height = 0; 01734 if (Margin != NULL) *Margin = 0; 01735 if (Bleed != NULL) *Bleed = 0; 01736 if (Dps != NULL) *Dps = FALSE; 01737 if (ShowDropShadow != NULL) *ShowDropShadow = TRUE; 01738 01739 Page *pPage = FindFirstPageInSpread(); 01740 ERROR2IF(pPage == NULL,FALSE,"Spread::GetPageSize(): Could not find first Page"); 01741 01742 // Measured in millipoints 01743 DocRect PageRect = pPage->GetPageRect(); 01744 01745 MILLIPOINT PageWidth = PageRect.Width(); 01746 MILLIPOINT PageHeight = PageRect.Height(); 01747 01748 // Set up the return height and width according to this first page 01749 if (Width != NULL) *Width = PageWidth; 01750 if (Height != NULL) *Height = PageHeight; 01751 01752 // Calculate the margin value 01753 if (Margin != NULL) 01754 { 01755 // The margin is the border between the edge of the page and the pasteboard 01756 // We assume that this is the same on all sides, which is the default whenever 01757 // the page size changes - If the user makes it lopsided, we'll use the maximum 01758 // value so that the page options dialogue shows a sensible new value. 01759 DocRect PasteRect = GetPasteboardRect(); 01760 DocCoordToSpreadCoord(&PasteRect); 01761 01762 INT32 MaxMargin = ABS(PageRect.lo.x - PasteRect.lo.x); 01763 01764 INT32 temp = ABS(PageRect.lo.y - PasteRect.lo.y); 01765 if (temp > MaxMargin) MaxMargin = temp; 01766 01767 temp = ABS(PageRect.hi.x - PasteRect.hi.x); 01768 if (temp > MaxMargin) MaxMargin = temp; 01769 01770 temp = ABS(PageRect.hi.y - PasteRect.hi.y); 01771 if (temp > MaxMargin) MaxMargin = temp; 01772 01773 *Margin = MaxMargin; 01774 } 01775 01776 // Find out if dps by finding the next page in the spread and see if measurements are 01777 // the same as at present. Will only work in the simple case. 01778 pPage = pPage->FindNextPage(); 01779 01780 if (pPage != NULL) 01781 { 01782 // Measured in millipoints 01783 DocRect Page2Rect = pPage->GetPageRect(); 01784 01785 MILLIPOINT Page2Width = PageRect.Width(); 01786 MILLIPOINT Page2Height = PageRect.Height(); 01787 01788 // lox,loy,hix,hiy 01789 if (Page2Rect.lo.x == PageRect.hi.x && Page2Rect.lo.y == PageRect.lo.y && 01790 Page2Width == PageWidth && Page2Height == PageHeight) 01791 { 01792 if (Dps != NULL) 01793 *Dps = TRUE; 01794 } 01795 else 01796 { 01797 // unrecognised page structure found 01798 ERROR2(FALSE,"bad page structure found in Spread::GetPageSize"); 01799 } 01800 } 01801 else 01802 { 01803 if (Dps != NULL) 01804 *Dps = FALSE; 01805 } 01806 01807 // Now get the current bleed size for the spread 01808 if (Bleed != NULL) 01809 *Bleed = GetBleedOffset(); 01810 01811 if (ShowDropShadow != NULL) 01812 *ShowDropShadow = GetShowDropShadow(); 01813 01814 return TRUE; 01815 } 01816 01817 01818 01819 /******************************************************************************************** 01820 01821 > BOOL Spread::SetPageSize(const MILLIPOINT Width, const MILLIPOINT Height, const MILLIPOINT Margin, 01822 const MILLIPOINT Bleed, const BOOL Dps, const BOOL ShowDropShadow) 01823 01824 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Hacked about a lot by Jason, 13/3/96) 01825 Created: 14/12/94 01826 Inputs: Width New width of pages in millipoints 01827 Height New height of pages in millipoints 01828 Margin New size of the margin area in millipoints (0 = none) 01829 Bleed New size of the bleed area in millipoints (0 = none) 01830 Dps (Double page spread) FALSE = 1 page; TRUE = 2 pages 01831 ShowDropShadow New drop shadow display state. 01832 Outputs: - 01833 01834 Returns: TRUE if we were successful 01835 01836 Purpose: Allows the setting of a new page size by height and width for all pages 01837 in this spread. Also allows changing of other spread attributes such as:- 01838 margin around pages in spread (gap between pasteboard edge and pages), 01839 bleed size 01840 single/double page spread 01841 whether a drop shadow is displayed for pages on this spread. 01842 01843 Notes: The pages will be resized such that the bottom left of the bottom-left-most 01844 page stays in the same spot. 01845 01846 Assumes there is only one default grid per spread 01847 01848 Errors: - 01849 SeeAlso: - 01850 01851 ********************************************************************************************/ 01852 01853 BOOL Spread::SetPageSize(const MILLIPOINT Width, const MILLIPOINT Height, const MILLIPOINT Margin, 01854 const MILLIPOINT Bleed, const BOOL Dps, const BOOL ShowDropShadow) 01855 { 01856 ERROR2IF(this == NULL,FALSE,"Spread::SetPageSize called on NULL pointer"); 01857 01858 // Include the bleed area into the margin we were given 01859 MILLIPOINT PageMargin = Margin + Bleed; 01860 01861 // --- Sort out the default grid (* Assumes there is only one default grid *) 01862 // Find the position of the grid relative to the pages so this can be maintained 01863 // (see the end of this function) 01864 NodeGrid* pGrid = FindFirstDefaultGridInSpread(); 01865 DocCoord PageRelGridOrigin; 01866 01867 if (pGrid != NULL) 01868 { 01869 DocCoord GridOrigin; 01870 01871 pGrid->GetOrigin(&GridOrigin.x, &GridOrigin.y); 01872 SpreadCoordToPagesCoord(&PageRelGridOrigin, GridOrigin); 01873 } 01874 01875 // --- Reposition/resize/add/remove pages as necessary 01876 if (!AdjustAllPages(Width, Height, Margin, Dps)) 01877 return FALSE; 01878 01879 01880 // --- Create and set a tidy new pasteboard rectangle 01881 { 01882 // Determine the new combined width of all the pages 01883 MILLIPOINT WidthOfPages = Width; // 1 page (single page spread) 01884 if (Dps) 01885 WidthOfPages = 2 * Width; // 2 pages (double page spread) 01886 01887 // First, make it the right size, centered about (0,0) 01888 MILLIPOINT x = (WidthOfPages + 2*PageMargin) / 2; 01889 MILLIPOINT y = (Height + 2*PageMargin) / 2; 01890 01891 DocRect NewPasteRect = DocRect(-x, -y, x, y); 01892 01893 // Translate it to the center of the new page spread, so it is centered on the pages 01894 // Note that the Rect is now in the correct place in _Document_ coords. 01895 DocRect PagesRect = GetPageBounds(); 01896 x = (PagesRect.lo.x / 2) + (PagesRect.hi.x / 2); // NOTE: Maths done carefully 01897 y = (PagesRect.lo.y / 2) + (PagesRect.hi.y / 2); // to avoid integer overflows! 01898 NewPasteRect.Translate(x, y); 01899 01900 // And expand it as necessary to include all the objects in the spread 01901 01902 /* Strangely, the BoundingRect seems to include the entire pasteboard area if the document is blank- 01903 This means we always make the pasteboard 1 inch bigger than requested! 01904 01905 01906 DocRect ObjectBounds = GetBoundingRect(); 01907 if (ObjectBounds.IsValid()) 01908 { 01909 // Inflate to get a 1inch margin around the objects, to ensure you can 01910 // see all their blobs and have a bit of a margin near the edge of the 01911 // scroll extent. 01912 ObjectBounds.Inflate(72000); 01913 NewPasteRect = NewPasteRect.Union(ObjectBounds); 01914 } 01915 */ 01916 // Convert it from spread coordinates into document coords, and set it 01917 ChangePasteboardRect(NewPasteRect); 01918 01919 // Finally, ensure all pasteboards butt up to each other tidily 01920 AdjustPasteboards(); 01921 } 01922 01923 // --- Set fold line position 01924 // Find the chapter in which we belong 01925 Chapter* pChapter = FindParentChapter(); 01926 ERROR3IF(pChapter == NULL,"Spread::SetPageSize: Could not find parent chapter"); 01927 if (pChapter != NULL) 01928 { 01929 // Set the main fold line x coordinate. Initialise to non-showing value 01930 MILLIPOINT FoldLineX = 0; 01931 BOOL ShowFoldLine = FALSE; 01932 01933 // Check if there is another spread present or not 01934 // If not and only a single page then do not show the fold line 01935 Spread* pNextSpread = FindNextSpread(); 01936 if (pNextSpread != NULL || Dps) 01937 { 01938 // We have more than one spread and/or a double page spread so 01939 // set the fold line to the join between the two pages or the right hand 01940 // side of the left page 01941 FoldLineX = PageMargin + Width; 01942 ShowFoldLine = TRUE; 01943 } 01944 01945 // Set the fold line position, and enable/disable display of it as appropriate 01946 pChapter->SetFoldLineXCoord(FoldLineX, ShowFoldLine); 01947 pChapter->InvalidateBoundingRect(); 01948 } 01949 01950 // --- Set the new bleed size for this spread 01951 if (!SetBleedOffset(Bleed)) 01952 return FALSE; 01953 01954 // --- Set the new dropshadow state 01955 SetShowDropShadow(ShowDropShadow); 01956 01957 // --- Adjust the default grid origin to a sensible place relative to the page 01958 if (pGrid != NULL) 01959 { 01960 DocCoord GridOrigin; 01961 PagesCoordToSpreadCoord(&GridOrigin, PageRelGridOrigin); 01962 pGrid->SetOrigin(GridOrigin.x, GridOrigin.y); 01963 } 01964 01965 return TRUE; 01966 } 01967 01968 01969 01970 /******************************************************************************************** 01971 01972 > BOOL Spread::AdjustAllPages(const MILLIPOINT Width, const MILLIPOINT Height, 01973 const MILLIPOINT Margin, const BOOL Dps) 01974 01975 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Hacked about a lot by Jason, 13/3/96) 01976 Created: 16/1/95 01977 01978 Inputs: Width New width of the page in millipoints 01979 Height New height of the page in millipoints 01980 Margin New size of the margin area in millipoints (0 = none) 01981 Dps Whether another page is required or not. 01982 01983 Outputs: - 01984 Returns: TRUE if we were successful 01985 01986 Purpose: Configures the pages in a spread. 01987 This simple function only allows: 01988 * All pages must be the same size 01989 * Spreads can only be Single or Double page spreads 01990 01991 This will: 01992 * Make all pages the given size 01993 * Move all pages so they butt up against each other 01994 * Ensure that the pasteboard includes the margin around the outside 01995 of the pages 01996 * Create/delete page(s) as necessary to make a single/double page spread 01997 01998 ********************************************************************************************/ 01999 02000 BOOL Spread::AdjustAllPages(const MILLIPOINT Width, const MILLIPOINT Height, 02001 const MILLIPOINT Margin, const BOOL Dps) 02002 { 02003 // Find the first page in the spread 02004 Page *pFirstPage = FindFirstPageInSpread(); 02005 ERROR2IF(pFirstPage == NULL, FALSE, "This spread has no pages?!"); 02006 02007 // Get the size and position of the first page 02008 DocRect OldPageRect = pFirstPage->GetPageRect(); 02009 02010 // And place the new page with its bottom left corner in the same spot 02011 DocRect PageRect(0, 0, Width, Height); 02012 PageRect.Translate(OldPageRect.lo.x, OldPageRect.lo.y); 02013 02014 if (!pFirstPage->SetPageRect(PageRect)) 02015 return FALSE; 02016 02017 // Find out if there is a 2nd page in the spread. This will be created/deleted/adjusted 02018 // as necessary to achieve the desired set of pages 02019 Page *pPage = pFirstPage->FindNextPage(); 02020 if (pPage != NULL) 02021 { 02022 // --- We have 2 (or more) pages... 02023 if (Dps) 02024 { 02025 // ... and we want 2 pages, so just translate the current page to butt up 02026 // to the first page, and also set it to the new size 02027 PageRect.Translate(Width, 0); 02028 if (!pPage->SetPageRect(PageRect)) 02029 return FALSE; 02030 02031 // And advance to the next page. This should be NULL, but if it's not, 02032 // we'll drop out and delete all surplus pages anyway 02033 pPage = pPage->FindNextPage(); 02034 ERROR3IF(pPage != NULL, "Surplus page(s) found in double page spread - I've deleted them"); 02035 } 02036 02037 // Finally, delete any surplus pages 02038 Page *pNext; 02039 while (pPage != NULL) 02040 { 02041 pNext = pPage->FindNextPage(); 02042 pPage->CascadeDelete(); 02043 // Of course, Cascade delete does not actually delete the page, so now do that 02044 delete pPage; 02045 pPage = pNext; 02046 } 02047 } 02048 else 02049 { 02050 // --- There is only one page 02051 // If we need 2 pages, then we'll have to create a new one 02052 if (Dps) 02053 { 02054 // Position the new one just to the right of the first page 02055 PageRect.Translate(Width, 0); 02056 02057 Page *Page2 = new Page(this, LASTCHILD, PageRect); 02058 if (Page2 == NULL) 02059 { 02060 // We ran out of memory 02061 InformError(_R(IDE_NOMORE_MEMORY)); 02062 return FALSE; 02063 } 02064 } 02065 } 02066 02067 return TRUE; 02068 } 02069 02070 #else 02071 02072 /******************************************************************************************** 02073 02074 > BOOL Spread::GetPageSize(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Margin, 02075 MILLIPOINT *Bleed, BOOL *Dps, BOOL *ShowDropShadow) 02076 02077 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02078 Created: 4/1/95 02079 Inputs: - 02080 Outputs: Width returned width of the page in millipoints 02081 Height returned height of the page in millipoints 02082 Margin returned size of the margin area in millipoints (0 = none) 02083 Bleed returned size of the bleed area in millipoints (0 = none) 02084 Dps returned whether another page (or pages) is present or not. 02085 ShowDropShadow returned new drop shadow display state. 02086 Returns: Whether we completed the scanning operation ok or not as True or False. 02087 Purpose: Allows the current page size specified for a spread to be determined. 02088 Assumes that all pages in one spread are the same size and hence returns 02089 this size. 02090 02091 Note: Any of the input params can be NULL (Markn 4/4/95) 02092 02093 Errors: Will error if pages are not consistent. 02094 SeeAlso: SetPageSize; 02095 02096 ********************************************************************************************/ 02097 BOOL Spread::GetPageSize(MILLIPOINT *Width, MILLIPOINT *Height, MILLIPOINT *Margin, 02098 MILLIPOINT *Bleed, BOOL *Dps, BOOL *ShowDropShadow) 02099 { 02100 ERROR2IF(this==NULL,FALSE,"Spread::GetPageSize called on NULL pointer"); 02101 02102 // Set up defaults in case of dodgy exit 02103 if (Width != NULL) *Width = 0; 02104 if (Height != NULL) *Height = 0; 02105 if (Margin != NULL) *Margin = 0; 02106 if (Bleed != NULL) *Bleed = 0; 02107 if (Dps != NULL) *Dps = FALSE; 02108 // WEBSTER-ranbirr-13/11/96 02109 #ifndef WEBSTER 02110 if (ShowDropShadow != NULL) *ShowDropShadow = TRUE; 02111 #endif //webster 02112 Page *pPage = FindFirstPageInSpread(); 02113 ERROR2IF(pPage == NULL,FALSE,"Spread::GetPageSize(): Could not find first Page"); 02114 02115 // Measured in millipoints 02116 DocRect PageRect = pPage->GetPageRect(); 02117 02118 MILLIPOINT PageWidth = PageRect.Width(); 02119 MILLIPOINT PageHeight = PageRect.Height(); 02120 02121 // Set up the return height and width according to this first page 02122 if (Width != NULL) *Width = PageWidth; 02123 if (Height != NULL) *Height = PageHeight; 02124 02125 // Get present low corner position, we will use this to calculate the gap around the pages 02126 DocCoord Low = PageRect.LowCorner(); 02127 // Assume: Margin = the position of the bottom left hand corner of the old page. 02128 // Use y as the initial defualt page is shifted across giving large x and correct y. 02129 if (Margin != NULL) *Margin = Low.y; 02130 02131 // Find out if dps by finding the next page in the spread and see if measurements are 02132 // the same as at present. Will only work in the simple case. 02133 pPage = pPage->FindNextPage(); 02134 02135 if (pPage != NULL) 02136 { 02137 // Measured in millipoints 02138 DocRect Page2Rect = pPage->GetPageRect(); 02139 02140 MILLIPOINT Page2Width = PageRect.Width(); 02141 MILLIPOINT Page2Height = PageRect.Height(); 02142 02143 // lox,loy,hix,hiy 02144 if( Page2Rect.lo.x == PageRect.hi.x && 02145 Page2Rect.lo.y == PageRect.lo.y && 02146 Page2Width == PageWidth && 02147 Page2Height == PageHeight) 02148 { 02149 if (Dps != NULL) *Dps = TRUE; 02150 } 02151 else 02152 { 02153 // unrecognised page structure found 02154 ERROR2(FALSE,"bad page structure found in Spread::GetPageSize"); 02155 } 02156 } 02157 else 02158 { 02159 if (Dps != NULL) *Dps = FALSE; 02160 } 02161 02162 // Now get the current bleed size for the spread 02163 if (Bleed != NULL) *Bleed = GetBleedOffset(); 02164 02165 if (ShowDropShadow != NULL) *ShowDropShadow = GetShowDropShadow(); 02166 02167 return TRUE; 02168 } 02169 02170 /******************************************************************************************** 02171 02172 > BOOL Spread::SetPageSize(const MILLIPOINT Width, const MILLIPOINT Height, const MILLIPOINT Margin, 02173 const MILLIPOINT Bleed, const BOOL Dps, const BOOL ShowDropShadow) 02174 02175 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02176 Created: 14/12/94 02177 Inputs: Width New width of the page in millipoints 02178 Height New height of the page in millipoints 02179 Margin New size of the margin area in millipoints (0 = none) 02180 Bleed New size of the bleed area in millipoints (0 = none) 02181 Dps Whether another page is required or not. 02182 ShowDropShadow New drop shadow display state. 02183 Outputs: - 02184 Returns: Whether we completed the operation ok or not as True or False. 02185 Purpose: Allows the setting of a new page size by height and width for all pages 02186 in this spread. Also allows changing of other spread attributes such as:- 02187 margin around pages in spread, 02188 bleed size 02189 single/double page spread 02190 whether a drop shadow is displayed for this spread. 02191 Errors: - 02192 SeeAlso: - 02193 02194 ********************************************************************************************/ 02195 02196 BOOL Spread::SetPageSize(const MILLIPOINT Width, const MILLIPOINT Height, const MILLIPOINT Margin, 02197 const MILLIPOINT Bleed, const BOOL Dps, const BOOL ShowDropShadow) 02198 { 02199 ERROR2IF(this==NULL,FALSE,"Spread::SetPageSize called on NULL pointer"); 02200 02201 // Resize all the pages in the spread to be of the new size specified. 02202 02203 // To set page size for all pages in this spread we will... 02204 // Find the layout of the pages in the spread (could be X or T shaped!) and calculate 02205 // the overall bounds plus the bounds of the objects on the page. 02206 // Expand pasteboard rect to give same offsets around new pages 02207 // (We won't allow pasteboard to shrink smaller than outermost objects) 02208 // Translate any spread after this one so there's no gap or overlap with this one 02209 // Set each page to the new page size 02210 // Translate pages so they butt up exactly to each other 02211 // (in their original layout of course) 02212 // (We won't try to translate any objects on this spread.) 02213 02214 BOOL ok = TRUE; 02215 02216 // Note the present pages rect 02217 DocRect OldPagesRect; 02218 GetPagesRect(&OldPagesRect); 02219 02220 // find the position of the grid relative to the pages so this can be maintained 02221 NodeGrid* pGrid=FindFirstDefaultGridInSpread(); 02222 ERROR2IF(pGrid==NULL,FALSE,"Spread::SetPageSize() no current default grid"); 02223 DocCoord GridOrigin; 02224 pGrid->GetOrigin(&GridOrigin.x,&GridOrigin.y); 02225 DocCoord PageRelGridOrigin; 02226 SpreadCoordToPagesCoord(&PageRelGridOrigin,GridOrigin); 02227 // Check if Margin < Bleed, if so then add the margin to the bleed 02228 MILLIPOINT PageMargin = 0; 02229 if (Margin < Bleed) 02230 PageMargin = Margin + Bleed; 02231 else 02232 PageMargin = Margin; 02233 02234 // Set up a new pasteboard rectangle to be of the correct size according to the new spec 02235 // for the page or pages for this spread. 02236 // First set up the width of the pages according to whether we require one or two pages. 02237 MILLIPOINT WidthOfPages = 0; 02238 if (Dps) 02239 WidthOfPages = PageMargin + 2 * Width; 02240 else 02241 WidthOfPages = Width; 02242 02243 // Set up the class variables for page height/width to echo the new values so any 02244 // pasteboard calculations use them. 02245 // REMOVED - No other code actually references these variables, so I've removed 'em! 02246 // PageWidth = Width; 02247 // PageHeight = Height; 02248 02249 // Get current pasteboard rectangle 02250 //DocRect OldPasteRect = GetPasteboardRect(FALSE); 02251 02252 // Resize this by the required amount i.e. difference between old and new 02253 DocRect PasteRect(MinDocCoord + 0x10000, 02254 (MaxDocCoord - 0x10000) - (PageMargin + Height + PageMargin), 02255 (MinDocCoord + 0x10000) + (PageMargin + WidthOfPages + PageMargin), 02256 MaxDocCoord - 0x10000); 02257 02258 // Align all the pasteboards for all spreads in this chapter 02259 ok = AlignPasteboards(PasteRect, PageMargin); 02260 if (!ok) 02261 return FALSE; 02262 02263 // Find the chapter which we belong to 02264 Chapter* pChapter = FindParentChapter(); 02265 ERROR3IF(pChapter == NULL,"Spread::SetPageSize: Could not find parent chapter"); 02266 if (pChapter != NULL) 02267 { 02268 // Set the main fold line x coordinate. Initialise to non-showing value 02269 MILLIPOINT FoldLineX = -1000; 02270 // Check if there is another spread present or not 02271 // If not and only a single page then do not show the fold line 02272 Spread* pNextSpread = FindNextSpread(); 02273 if (pNextSpread != NULL || Dps == TRUE) 02274 { 02275 // We have more than one spread and/or a double page spread so 02276 // set the fold line to the join between the two pages or the right hand 02277 // side of the left page 02278 FoldLineX = PageMargin + Width; 02279 } 02280 pChapter->SetFoldLineXCoord(FoldLineX); 02281 pChapter->InvalidateBoundingRect(); 02282 } 02283 02284 // Now change the position of all pages in the spread. 02285 // Calling routine has checked if the page size has changed or not and not called us 02286 // if nothing has changed. 02287 // Should have checked everything including going from dps to sps or sps to dps and 02288 // deleting/adding pages accordingly and setting the new bleed and shadow state. 02289 ok = SetSizeOfAllPages(Width, Height, PageMargin, Dps); 02290 if (!ok) 02291 return FALSE; 02292 02293 // Now set the current bleed size for this spread 02294 ok = ok && SetBleedOffset(Bleed); 02295 if (!ok) 02296 return FALSE; 02297 02298 SetShowDropShadow(ShowDropShadow); 02299 02300 // Adjust the default grid size to fit the new page layout 02301 DocRect Rect = GetPasteboardRect(FALSE); 02302 Rect.Translate(-Rect.lo.x, -Rect.lo.y); 02303 02304 pGrid->SetBoundingRect(Rect); 02305 pGrid->InvalidateBoundingRect(); 02306 PagesCoordToSpreadCoord(&GridOrigin,PageRelGridOrigin); 02307 pGrid->SetOrigin(GridOrigin.x,GridOrigin.y); 02308 02309 // Now, we must ensure that the special page background layer, if present 02310 // gets resized to fit around the new page structure 02311 Layer * pLayer = FindFirstPageBackgroundLayer(); 02312 if (pLayer) 02313 { 02314 // Call the static function in the background op to go and fix up 02315 // the covering rectangle 02316 // First, get that size of the rectangle required to fill the present 02317 // pages. 02318 DocRect NewPagesRect; 02319 GetPagesRect(&NewPagesRect); 02320 // Translate the old pages from the old origin to the new 02321 OldPagesRect.Translate(-OldPagesRect.lo.x, -OldPagesRect.lo.y); 02322 OldPagesRect.Translate(NewPagesRect.lo.x, NewPagesRect.lo.y); 02323 02324 PORTNOTE("other","Removed OpBackground usage") 02325 #ifndef EXCLUDE_FROM_XARALX 02326 OpBackground::FixBackgroundLayer(pLayer, NewPagesRect, OldPagesRect); 02327 #endif 02328 } 02329 02330 return TRUE; 02331 } 02332 02333 /******************************************************************************************** 02334 02335 > BOOL Spread::AlignPasteboards(const DocRect PasteRect, const INT32 Margin) 02336 02337 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02338 Created: 16/1/95 02339 Inputs: New size of the paste board rectangle for this spread. 02340 Outputs: - 02341 Returns: Whether we completed the operation ok or not as True or False. 02342 Purpose: Tries to align all the pasteboards of the spreads in this chapter to the new 02343 size of this spread. 02344 Checks to see if the objects on the spread are bigger than the newly specified 02345 pasteboard rectangle and if so will put a margin around the object rectangle 02346 and then combine this with the specified pasteboard height. This means we will 02347 not loose any objects off the spread. 02348 As it is changing the size and position of the spread, it will invalidate the 02349 spreads bounding rectangle so that hopefully all bounding boxes will be 02350 recalculated rather than using the old and more than likely wrong cached one. 02351 Assumes at present that it is only called on the first spread in the chapter. 02352 Errors: - 02353 SeeAlso: - 02354 02355 ********************************************************************************************/ 02356 02357 BOOL Spread::AlignPasteboards(const DocRect NewPasteRect, const MILLIPOINT Margin) 02358 { 02359 ERROR2IF(this==NULL,FALSE,"Spread::AlignPasteboards called on NULL pointer"); 02360 02361 // Work out the overall bounds of the pages and objects on the page in the spread 02362 // This will be in document coordinates 02363 DocRect ObjectsBounds = GetBoundingRect(FALSE); 02364 02365 // Take copy of entry pasteboard rectangle size 02366 DocRect PasteRect = NewPasteRect; 02367 02368 // Note:: The tops of the old paste board rectangle and the new are aligned rather 02369 // than the bottoms. Hence the 0,0s are different. This means that direct comparisons 02370 // between new size, old size and bounding rectangles are not possible. 02371 // First, get the current paste board rectangle for this spread. 02372 DocRect SpreadRect = GetPasteboardRect(); 02373 02374 // Work out the maximum height and width of pasteboard required to encompass all the 02375 // current objects on the page. Include a margin around the outside. 02376 MILLIPOINT HeightReqd = ObjectsBounds.hi.y - SpreadRect.lo.y + Margin; 02377 MILLIPOINT WidthReqd = ObjectsBounds.hi.x - SpreadRect.lo.x + Margin; 02378 // Above calculations will not include objects off the bottom and/or left hand side of 02379 // the page. We would need to shift the bottom left hand corner of the page plus all 02380 // objects if we were going to move these objects back onto the page. 02381 02382 // If bounding rectangle of objects on page is bigger than the size of this new pasteboard 02383 // rectangle then resize the pasteboard to include the objects bounding box. 02384 if (PasteRect.Width() < WidthReqd || 02385 PasteRect.Height() < HeightReqd ) 02386 { 02387 // Work out what the new required width and height of the pasteboard rectangle is 02388 // including a margin size border around the outside of the objects bounding rectangle 02389 // so that all the handles are accessable. 02390 MILLIPOINT SpreadHeight = 0; 02391 MILLIPOINT SpreadWidth = 0; 02392 if (HeightReqd < PasteRect.Height() ) 02393 SpreadHeight = PasteRect.Height(); 02394 else 02395 SpreadHeight = HeightReqd; 02396 02397 if (WidthReqd < PasteRect.Width() ) 02398 SpreadWidth = PasteRect.Width(); 02399 else 02400 SpreadWidth = WidthReqd; 02401 02402 // Contruct a new PasteRect to take this object bounding rectangle into account. 02403 PasteRect = DocRect(MinDocCoord + 0x10000, 02404 (MaxDocCoord - 0x10000) - (SpreadHeight), 02405 (MinDocCoord + 0x10000) + (SpreadWidth), 02406 MaxDocCoord - 0x10000); 02407 } 02408 02409 // Now we have the required size and position, go and set it 02410 ChangePasteboardRect(PasteRect); 02411 02412 // Make the wide pasteboard align to the new one 02413 // REMOVED - WPB now calculated on the fly rather than cached 02414 // WidePasteboard.lo.y = PasteRect.lo.y; 02415 // WidePasteboard.hi.y = PasteRect.hi.y; 02416 02417 // Make sure bounding rectangles are invalidated so that they are recalculated 02418 InvalidateBoundingRect(); 02419 02420 // Now ensure all following spreads are properly attached to this one 02421 // Assumes that we are altering the first spread in the document 02422 // Note this spread as a possible last spread in the document 02423 Spread* pLastSpread = this; 02424 Spread* pThisSpread = this; 02425 Spread* pNextSpread = FindNextSpread(); 02426 while (pNextSpread != NULL) 02427 { 02428 // Next spread present, so adjust the pasteboard on the first/previous spread to 02429 // be correct assuming that it is not the last one present. 02430 // REMOVED- AdjustPasteboardHeight used to set the wide pasteboard - this is no longer necessary 02431 // as the Wide Pasteboard is calculated on the fly rather than cached now. 02432 // pThisSpread->AdjustPasteboardHeight(FALSE); 02433 02434 DocRect FirstPasteRect = pThisSpread->GetPasteboardRect(FALSE); 02435 DocRect SecondPasteRect = pNextSpread->GetPasteboardRect(FALSE); 02436 // Construct a new Pasteboard rectangle of the correct size and initial position 02437 // and then move it down by the height of the first spread (Down = -ve). 02438 DocRect TempPasteRect(MinDocCoord + 0x10000, 02439 (MaxDocCoord - 0x10000) - SecondPasteRect.Height(), 02440 (MinDocCoord + 0x10000) + SecondPasteRect.Width(), 02441 MaxDocCoord - 0x10000); 02442 02443 TempPasteRect.Translate(0, -( FirstPasteRect.Height() )); 02444 // Now we have the required size and position, go and set it 02445 pNextSpread->ChangePasteboardRect(TempPasteRect); 02446 02447 // Make the wide pasteboard align to the new one 02448 // REMOVED - WPB now calculated on the fly rather than cached 02449 // pNextSpread->WidePasteboard.lo.y = TempPasteRect.lo.y; 02450 // pNextSpread->WidePasteboard.hi.y = TempPasteRect.hi.y; 02451 02452 #ifdef _DEBUG 02453 // On Debug versions check that the spreads are aligned correctly 02454 FirstPasteRect = pThisSpread->GetPasteboardRect(FALSE); 02455 SecondPasteRect = pNextSpread->GetPasteboardRect(FALSE); 02456 TRACEUSER( "Neville", _T("First spread low corner y = %d\n"),FirstPasteRect.LowCorner().y); 02457 TRACEUSER( "Neville", _T("Second spread high corner y = %d\n"),SecondPasteRect.HighCorner().y); 02458 ENSURE((SecondPasteRect.HighCorner().y == FirstPasteRect.LowCorner().y), 02459 "Spread::SetPageSize() Spreads are not properly vertically aligned"); 02460 #endif 02461 02462 // Make sure bounding rectangles are invalidated so that they are recalculated 02463 pNextSpread->InvalidateBoundingRect(); 02464 02465 // Note this next spread as a possible last spread and this spread 02466 pLastSpread = pNextSpread; 02467 pThisSpread = pNextSpread; 02468 02469 // Now, see whether there is a next spread or not. 02470 pNextSpread = pNextSpread->FindNextSpread(); 02471 } 02472 02473 // Last spread in document/chapter so adjust the bottom pasteboard to be correct 02474 // REMOVED - this method just adjusts the Wide pasteboard - no longer necessary as the WPB 02475 // is calculated on the fly rather than cached 02476 // if (pLastSpread != NULL) 02477 // pLastSpread->AdjustPasteboardHeight(TRUE); 02478 02479 return TRUE; 02480 } 02481 02482 /******************************************************************************************** 02483 02484 > BOOL Spread::SetSizeOfAllPages(const MILLIPOINT Width, const MILLIPOINT Height, 02485 const MILLIPOINT Margin, const BOOL Dps) 02486 02487 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02488 Created: 16/1/95 02489 Inputs: Width New width of the page in millipoints 02490 Height New height of the page in millipoints 02491 Margin New size of the margin area in millipoints (0 = none) 02492 Dps Whether another page is required or not. 02493 02494 Outputs: - 02495 Returns: Whether we completed the operation ok or not as True or False. 02496 Purpose: Sets the sizes of all pages in this spread to conform to the newly specified 02497 width and height. It will try and align all the pages. It will also try and 02498 create and or delete any pages which are necessary to conform to the specified 02499 single/double page spread flag. 02500 Assumes all the pages in a spread are the same size. 02501 Errors: - 02502 SeeAlso: - 02503 02504 ********************************************************************************************/ 02505 02506 BOOL Spread::SetSizeOfAllPages(const MILLIPOINT Width, const MILLIPOINT Height, 02507 const MILLIPOINT Margin, const BOOL Dps) 02508 { 02509 ERROR2IF(this==NULL,FALSE,"Spread::SetSizeOfAllPages called on NULL pointer"); 02510 02511 BOOL ok = TRUE; 02512 02513 // Find the first page in the spread 02514 Page *pPage = FindFirstPageInSpread(); 02515 ERROR2IF(pPage == NULL,FALSE,"Spread::SetSizeOfAllPages(): Could not find first Page"); 02516 02517 // Take note of where this first page is 02518 // Page* pFirstPage = pPage; 02519 02520 // Get the size and position of the first page 02521 DocRect OldPageRect = pPage->GetPageRect(); 02522 02523 // Get present low corner position, we will use this to calculate the gap around the pages 02524 DocCoord Low = OldPageRect.LowCorner(); 02525 02526 // Set up the new starting position of the page 02527 Low.x = Margin; 02528 Low.y = Margin; 02529 02530 // Construct a new position and size with the required params 02531 DocRect PageRect(Low, Width, Height); 02532 ok = pPage->SetPageRect(PageRect); 02533 if (!ok) 02534 return FALSE; 02535 02536 // Find out if there is a next page in the spread. If there is, then we need to 02537 // change that as well, if we are in dps mode, or delete it if dps is off 02538 Page* pCurrentPage = pPage; 02539 pPage = pPage->FindNextPage(); 02540 if (pPage != NULL) 02541 { 02542 if (Dps) 02543 { 02544 // Move the current page across by one page worths and set this as the new 02545 // size/position for the next page 02546 PageRect.Translate(Width, 0); 02547 ok = pPage->SetPageRect(PageRect); 02548 if (!ok) 02549 return FALSE; 02550 02551 // Now check to see if any more pages exist. If so then delete them. 02552 pPage = pPage->FindNextPage(); 02553 while (pPage != NULL) 02554 { 02555 ERROR3("Spread::SetSizeOfAllPages extra page found in double page spread"); 02556 } 02557 } 02558 else 02559 { 02560 // Delete any pages over the initial one. 02561 do 02562 { 02563 pPage->CascadeDelete(); 02564 // Of course, Cascade delete does not actually delete the page, so now do that 02565 delete pPage; 02566 // Check to see if any pages remain after the first required one 02567 pPage = pCurrentPage; 02568 pPage = pPage->FindNextPage(); 02569 } 02570 while (pPage != NULL); 02571 } 02572 } 02573 else 02574 { 02575 // If not double page spread then everything is correct 02576 // otherwise we will need to create a page of the correct size and position 02577 if (Dps) 02578 { 02579 // move first page across by one page worths 02580 PageRect.Translate(Width, 0); 02581 // Create a new last page based on this size/position 02582 Page* Page2 = new Page(this, LASTCHILD, PageRect); 02583 if (Page2 == NULL) 02584 { 02585 // We ran out of memory or something 02586 InformError(_R(IDE_NOMORE_MEMORY)); 02587 return FALSE; 02588 } 02589 } 02590 } 02591 02592 return TRUE; 02593 } 02594 #endif 02595 02596 /******************************************************************************************** 02597 02598 > Document* Spread::FindParentDocument() 02599 02600 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02601 Created: 12/6/97 02602 Returns: A pointer to the parent document of this spread. 02603 Purpose: Finds the parent document for this spread. Should always be one present. 02604 Defined as an explicit function so that caller just has to check for NULL 02605 returns, rather than also checking that the parent is a chapter. Also, makes 02606 it more encapsulated and friendly. 02607 02608 ********************************************************************************************/ 02609 02610 Document* Spread::FindParentDocument() 02611 { 02612 BaseDocument *pBaseDoc = FindOwnerDoc(); 02613 02614 // Make sure we have a real document 02615 if (!pBaseDoc || !pBaseDoc->IS_KIND_OF(Document)) 02616 { 02617 if (pBaseDoc == NULL) 02618 { 02619 ERROR3("Eh up, the spread has no parent document"); 02620 } 02621 else 02622 { 02623 ERROR3("Document is not a real Document - it's a BaseDocument!"); 02624 } 02625 02626 return NULL; 02627 } 02628 02629 Document *pDoc = (Document *) pBaseDoc; 02630 return pDoc; 02631 } 02632 02633 /******************************************************************************************** 02634 02635 > Chapter* Spread::FindParentChapter() 02636 02637 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02638 Created: 17/1/95 02639 Inputs: - 02640 Outputs: - 02641 Returns: A pointer to the parent chapter of this spread. Will be NULL if no parent 02642 chapter is found. This of course should never happen. 02643 Purpose: Finds the parent chapter for this spread. Should always be one present. 02644 Defined as an explicit function so that caller just has to check for NULL 02645 returns, rather than also checking that the parent is a chapter. Also, makes 02646 it more encapsulated and friendly. 02647 Errors: - 02648 SeeAlso: - 02649 02650 ********************************************************************************************/ 02651 02652 Chapter* Spread::FindParentChapter() 02653 { 02654 ERROR2IF(this==NULL,NULL,"Spread::FindParentChapter called on NULL pointer"); 02655 02656 Node* pCurrentNode = FindParent(); 02657 while(pCurrentNode != NULL) 02658 { 02659 if (pCurrentNode->IsKindOf(CC_RUNTIME_CLASS(Chapter))) 02660 return ((Chapter*)pCurrentNode); 02661 pCurrentNode = pCurrentNode->FindParent(); 02662 } 02663 return NULL; 02664 } 02665 02666 /******************************************************************************************** 02667 02668 > NodeGrid* Spread::FindFirstDefaultGridInSpread() 02669 02670 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02671 Created: 9/1/95 02672 Inputs: - 02673 Outputs: - 02674 Returns: A pointer to the grid node. Will be NULL if no default grid is found. 02675 Purpose: Finds the first default grid that has been defined in this spread. Should be 02676 the only one present. 02677 Errors: - 02678 SeeAlso: - 02679 02680 ********************************************************************************************/ 02681 02682 NodeGrid* Spread::FindFirstDefaultGridInSpread() 02683 { 02684 ERROR2IF(this==NULL,NULL,"Spread::FindFirstDefaultGridInSpread called on NULL pointer"); 02685 02686 Node* pCurrentNode = FindFirstChild(); 02687 while(pCurrentNode != NULL) 02688 { 02689 if (pCurrentNode->IsKindOf(CC_RUNTIME_CLASS(NodeGrid))) 02690 { 02691 // Found a grid type node. Check if its a default type. 02692 NodeGrid* pCurrentGrid = (NodeGrid*)pCurrentNode; 02693 if (pCurrentGrid->IsDefault()) 02694 return (pCurrentGrid); 02695 } 02696 02697 pCurrentNode = pCurrentNode->FindNext(); 02698 } 02699 return (NULL); // No default grids were found 02700 } 02701 02702 02703 /******************************************************************************************** 02704 02705 > BOOL Spread::CreateDefaultPageAndGrid(BOOL CreateGrid = TRUE) 02706 02707 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 02708 Created: 5/8/96 02709 Inputs: CreateGrid = TRUE if you want a grid & page 02710 FALSE if you only want a grid 02711 Outputs: - 02712 Returns: TRUE if ok, FALSE if it fails 02713 Purpose: This creates a default page and a default grid and places them as children of the spread. 02714 02715 It doesn't check to see the spread has already got a page(s) or grid(s), so only call 02716 this when creating a spread for the first time. 02717 02718 (I appoligise for the disgusting default parameter - it is due to circumstances beyond my control) 02719 Errors: - 02720 SeeAlso: - 02721 02722 ********************************************************************************************/ 02723 02724 MILLIPOINT PageWidth = ( 8 * 72000); 02725 MILLIPOINT PageHeight = (11 * 72000); 02726 02727 // Default page size/position. 02728 MILLIPOINT Gap = 72000L; 02729 02730 BOOL Spread::CreateDefaultPageAndGrid(BOOL CreateGrid) 02731 { 02732 // Work out where to put the page and create it 02733 DocRect PageRect(Gap, Gap, Gap+PageWidth, Gap+(1*PageHeight)); 02734 Page *pPage = new Page(this, FIRSTCHILD, PageRect); 02735 if (pPage == NULL) 02736 return(FALSE); 02737 02738 // Create a default blanket grid in the given spread 02739 if (CreateGrid) 02740 NodeGrid::MakeDefaultGrid(this); 02741 02742 return TRUE; 02743 } 02744 02745 /******************************************************************************************** 02746 > DocCoord Spread::GetUserOrigin() 02747 02748 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02749 Created: 6/9/95 02750 Returns: Offset from SpreadCoords to UserCoords 02751 ********************************************************************************************/ 02752 02753 DocCoord Spread::GetUserOrigin() 02754 { 02755 return UserOrigin; 02756 } 02757 02758 02759 /******************************************************************************************** 02760 > BOOL Spread::GetPagesRect(DocRect* pPagesRect) 02761 02762 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02763 Created: 17/1/95 02764 Outputs: pPagesRect 02765 Returns: FALSE if fails (PagesRect unchanged) 02766 Purpose: Get the union rect of all pages on the spread (in SpreadCoords) 02767 Errors: pPagesRect==NULL 02768 no pages in spread 02769 ********************************************************************************************/ 02770 02771 BOOL Spread::GetPagesRect(DocRect* pPagesRect) 02772 { 02773 ERROR2IF(pPagesRect==NULL,FALSE,"Spread::GetPagesRect() - pPagesRect==NULL"); 02774 02775 Page* pPage=FindFirstPageInSpread(); 02776 ERROR2IF(pPage==NULL,FALSE,"Spread::GetPagesRect() - no pages in spread!"); 02777 02778 *pPagesRect=pPage->GetPageRect(); 02779 pPage=pPage->FindNextPage(); 02780 while (pPage) 02781 { 02782 DocRect PageRect=pPage->GetPageRect(); 02783 *pPagesRect=pPagesRect->Union(PageRect); 02784 pPage=pPage->FindNextPage(); 02785 } 02786 02787 return TRUE; 02788 } 02789 02790 02791 /******************************************************************************************** 02792 > BOOL Spread::SpreadCoordToPagesCoord(DocCoord* pPagesCoord, DocCoord SpreadCoord) 02793 02794 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02795 Created: 17/1/95 02796 Inputs: SpreadCoord 02797 Outputs: pPagesCoord 02798 Returns: FALSE if fails (PagesCoord unchanged) 02799 Purpose: Convert SpreadCoord to PagesCoord (relative to union of pages in spread) 02800 ********************************************************************************************/ 02801 02802 BOOL Spread::SpreadCoordToPagesCoord(DocCoord* pPagesCoord, DocCoord SpreadCoord) 02803 { 02804 ERROR2IF(pPagesCoord==NULL,FALSE,"Spread::SpreadCoordToPagesCoord() - pPagesCoord==NULL"); 02805 02806 DocRect PagesRect; 02807 if (GetPagesRect(&PagesRect)==FALSE) 02808 return FALSE; 02809 02810 *pPagesCoord=SpreadCoord-PagesRect.lo; 02811 return TRUE; 02812 } 02813 02814 02815 /******************************************************************************************** 02816 > BOOL Spread::PagesCoordToSpreadCoord(DocCoord* pSpreadCoord, DocCoord PagesCoord) 02817 02818 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02819 Created: 17/1/95 02820 Inputs: PagesCoord 02821 Outputs: pSpreadCoord 02822 Returns: FALSE if fails (SpreadCoord unchanged) 02823 Purpose: Convert PagesCoord (relative to union of pages in spread) to SpreadCoord 02824 ********************************************************************************************/ 02825 02826 BOOL Spread::PagesCoordToSpreadCoord(DocCoord* pSpreadCoord, DocCoord PagesCoord) 02827 { 02828 ERROR2IF(pSpreadCoord==NULL,FALSE,"Spread::PagesCoordToSpreadCoord() - pSpreadCoord==NULL"); 02829 02830 DocRect PagesRect; 02831 if (GetPagesRect(&PagesRect)==FALSE) 02832 return FALSE; 02833 02834 *pSpreadCoord=PagesCoord+PagesRect.lo; 02835 return TRUE; 02836 } 02837 02838 02839 /******************************************************************************************** 02840 > BOOL Spread::TextToSpreadCoord(DocCoord* pSpreadCoord, StringBase* pxText, StringBase* pyText) 02841 02842 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02843 Created: 17/1/95 02844 Inputs: pxText - x UserCoord in text form 02845 pyText - y UserCoord in text form 02846 Outputs: pSpreadCoord 02847 Returns: FALSE if fails (SpreadCoord unchanged) 02848 Purpose: Convert Coord in text form (relative to union of pages in spread) into SpreadCoord 02849 ********************************************************************************************/ 02850 02851 BOOL Spread::TextToSpreadCoord(DocCoord* pSpreadCoord, StringBase* pxText, StringBase* pyText) 02852 { 02853 ERROR2IF(pSpreadCoord==NULL,FALSE,"Spread::TextToSpreadCoord() - pSpreadCoord==NULL"); 02854 ERROR2IF( pxText==NULL,FALSE,"Spread::TextToSpreadCoord() - pxText==NULL"); 02855 ERROR2IF( pyText==NULL,FALSE,"Spread::TextToSpreadCoord() - pyText==NULL"); 02856 02857 DimScale* pDimScale=DimScale::GetPtrDimScale(this); 02858 ERROR2IF(pDimScale==NULL,FALSE,"Spread::TextToSpreadCoord() - pDimScale==NULL"); 02859 02860 UserCoord UserPos(0,0); 02861 if (pDimScale->ConvertToMillipoints(*pxText, &(UserPos.x))==FALSE) 02862 return FALSE; 02863 if (pDimScale->ConvertToMillipoints(*pyText, &(UserPos.y))==FALSE) 02864 return FALSE; 02865 02866 *pSpreadCoord = UserPos.ToSpread(this); 02867 return TRUE; 02868 } 02869 02870 02871 /******************************************************************************************** 02872 > BOOL Spread::SpreadCoordToText(StringBase* pxText, StringBase* pyText, DocCoord SpreadCoord, 02873 BOOL xUnitSpecifier=TRUE, BOOL yUnitSpecifier=TRUE, INT32 dp=-1) 02874 02875 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02876 Created: 17/1/95 02877 Inputs: SpreadCoord 02878 xUnitSpecifier (default TRUE) - append unit specifier to x text 02879 yUnitSpecifier (default TRUE) - append unit specifier to y text 02880 dp (default 2) - decimal places (-1 = use system default) 02881 Outputs: pxText - x UserCoord in text form 02882 pyText - y UserCoord in text form 02883 Returns: FALSE if fails (xText,yText unchanged) 02884 Purpose: Convert SpreadCoord into Coord in text form (relative to union of pages in spread) 02885 Note: If only Y specifier required and units are prefix 02886 then the unit specifier is actually placed before the x value 02887 ********************************************************************************************/ 02888 02889 BOOL Spread::SpreadCoordToText(String_256* pxText, String_256* pyText, DocCoord SpreadCoord, 02890 BOOL xUnitSpecifier, BOOL yUnitSpecifier, INT32 dp) 02891 { 02892 ERROR2IF(pxText==NULL,FALSE,"Spread::SpreadCoordToText() - pxText==NULL"); 02893 ERROR2IF(pyText==NULL,FALSE,"Spread::SpreadCoordToText() - pyText==NULL"); 02894 ERROR2IF( dp<-1 ,FALSE,"Spread::SpreadCoordToText() - dp<-1"); 02895 02896 DimScale* pDimScale=DimScale::GetPtrDimScale(this); 02897 ERROR2IF(pDimScale==NULL,FALSE,"Spread::SpreadCoordToText() - pDimScale==NULL"); 02898 02899 // if only Y unit specified, and units are prefix, force X unit specifier only 02900 if (xUnitSpecifier==FALSE && yUnitSpecifier==TRUE) 02901 { 02902 // Get the current unit list from the document and the the current scale units 02903 DocUnitList* pDocUnitList=DocUnitList::GetCurrentDocUnitList(); 02904 ERROR2IF(pDocUnitList==NULL,FALSE,"Spread::SpreadCoordToText() - DocUnitList::GetCurrentDocUnitList() returned NULL"); 02905 Unit* pUnit=pDocUnitList->FindUnit(pDimScale->GetUnits()); 02906 ERROR2IF(pUnit==NULL,FALSE,"Spread::SpreadCoordToText() - pDocUnitList->FindUnit() returned NULL"); 02907 if (pUnit->IsPrefix()) 02908 { 02909 xUnitSpecifier=TRUE; 02910 yUnitSpecifier=FALSE; 02911 } 02912 } 02913 02914 UserCoord UserPos=SpreadCoord.ToUser(this); 02915 pDimScale->ConvertToUnits(UserPos.x, pxText, xUnitSpecifier, dp); 02916 pDimScale->ConvertToUnits(UserPos.y, pyText, yUnitSpecifier, dp); 02917 02918 return TRUE; 02919 } 02920 02921 02922 /******************************************************************************************** 02923 > BOOL Spread::GetDecimalPlacesForPixelResolution(View *pView, INT32* dp) 02924 02925 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02926 Created: 18/1/95 02927 Returns: FALSE if fails 02928 Outputs: dp - number of dp (-ve values limited to 0) 02929 Purpose: Find the number of dp to resolve a pixel in units and scale associated with spread 02930 (calulates the both x and y and returns max) 02931 ********************************************************************************************/ 02932 02933 BOOL Spread::GetDecimalPlacesForPixelResolution(View *pView, INT32* dp) 02934 { 02935 DimScale* pDimScale=DimScale::GetPtrDimScale(this); 02936 ERROR2IF(pDimScale==NULL,FALSE,"Spread::GetDecimalPlacesForPixelResolution() - pDimScale==NULL"); 02937 02938 INT32 xdp=2; 02939 INT32 ydp=2; 02940 double MPPerUnit=0.0; 02941 if( pDimScale->ConvertToDouble( String_8( _T("1") ), &MPPerUnit ) == FALSE ) 02942 return FALSE; 02943 02944 FIXED16 PixelWidth, 02945 PixelHeight; 02946 02947 pView->GetScaledPixelSize(&PixelWidth, &PixelHeight); 02948 02949 if (PixelWidth==0 || PixelHeight==0) 02950 return FALSE; 02951 02952 ERROR2IF(MPPerUnit<1,FALSE,"Spread::GetDecimalPlacesForPixelResolution() - Millipoints per Unit < 1!"); 02953 xdp=(INT32)log10(MPPerUnit/PixelWidth.MakeDouble() )+1; 02954 ydp=(INT32)log10(MPPerUnit/PixelHeight.MakeDouble())+1; 02955 02956 if (xdp<0) xdp=0; 02957 if (ydp<0) ydp=0; 02958 *dp = xdp>ydp ? xdp : ydp; 02959 return TRUE; 02960 } 02961 02962 02963 02964 /******************************************************************************************** 02965 02966 > DocCoord Spread::GetSpreadCoordOrigin(BOOL Pixelise, View *pView) const 02967 02968 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02969 Created: 7/3/96 02970 02971 Inputs: Pixelise - TRUE if you want the coordinate pixelised 02972 pView - NULL, or the View to use for pixelisation purposes. 02973 (These inputs are exactly the same as those in GetPasteboardRect) 02974 02975 Returns: The spread coordinate origin, in document coordinates 02976 02977 Purpose: To determine the spread coordinate origin 02978 This is used to convert between document and spread coordinates: 02979 DocCoord = SpreadCoord + Origin 02980 SpreadCoord = DocCoord - Origin 02981 02982 Notes: In the past, spread coords shared their origin with the bottom left corner 02983 of a spread's pasteboard. Obviously, if we tried to move this corner, we got 02984 into deep strife, so I've separated out the 2 points. By default the origin 02985 will happen to sit on the bottom left corner of the pasteboard, but this 02986 will change if the pasteboard is ever resized. Generally the SCO does not 02987 move (unless you have multiple spreads and a whole spread has to shift 02988 down to make room). 02989 02990 WARNING: Because the SCO is not associated with the pasteboard corner any 02991 more, it is easy to resize the pasteboard so that the SCO lies *outside* 02992 the pasteboard. This can cause ERROR3's to go off if you try to call 02993 FindEnclosingChapter on the SCO (because no chapter encloses it!). 02994 Note that FindEnclosingChapter is called by the (document form) of 02995 DocCoord::ToWork. I have changed the ERROR3 message to point at this warning. 02996 02997 SeeAlso: NodePaper::GetPasteBoardRect; Spread::SetSpreadCoordOrigin 02998 02999 ********************************************************************************************/ 03000 03001 DocCoord Spread::GetSpreadCoordOrigin(BOOL Pixelise, View *pView) const 03002 { 03003 #if NEW_PASTEBOARD 03004 // New functionality: Spread Origin is separate from pasteboard bottom left corner 03005 if (Pixelise) 03006 { 03007 DocCoord temp(SpreadOrigin); 03008 03009 if (pView != NULL) 03010 temp.Pixelise(pView); 03011 else 03012 temp.Pixelise(); 03013 03014 return(temp); 03015 } 03016 03017 return(SpreadOrigin); 03018 #else 03019 // To keep the old functionality, the spread origin currently always sits on the 03020 // pasteboard bottom left corner. 03021 if (Pixelise) 03022 { 03023 DocCoord temp(PasteboardRect.lo); 03024 03025 if (pView != NULL) 03026 temp.Pixelise(pView); 03027 else 03028 temp.Pixelise(); 03029 03030 return(temp); 03031 } 03032 03033 return(PasteboardRect.lo); 03034 #endif 03035 } 03036 03037 03038 03039 /******************************************************************************************** 03040 03041 > void Spread::SetSpreadCoordOrigin(DocCoord NewOrigin) 03042 03043 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03044 Created: 7/3/96 03045 03046 Inputs: NewOrigin - the new origin point for the spread coordinates within 03047 this spread 03048 03049 Purpose: To set the spread coordinate origin 03050 This is used to convert between document and spread coordinates: 03051 DocCoord = SpreadCoord + Origin 03052 SpreadCoord = DocCoord - Origin 03053 03054 Notes: Moving the spread coord origin effectively moves all nodes on the 03055 spread (pages, layers, objects, etc) in the opposite direction. It 03056 may therefore result in objects and even pages moving off the pasteboard. 03057 03058 Note also that you'll probably have to redraw some stuff! 03059 03060 Use carefully - Talk to Jason about it first! 03061 03062 SeeAlso: Spread::GetSpreadCoordOrigin 03063 03064 ********************************************************************************************/ 03065 03066 void Spread::SetSpreadCoordOrigin(DocCoord NewOrigin) 03067 { 03068 #if !NEW_PASTEBOARD 03069 ERROR3("You can't set the spread coord origin (unimplemented) - Talk to Jason/Phil"); 03070 #endif 03071 03072 SpreadOrigin = NewOrigin; 03073 } 03074 03075 03076 03077 /******************************************************************************************** 03078 03079 > void Spread::SpreadCoordToDocCoord(DocCoord *pSpreadCoord) const 03080 > void Spread::SpreadCoordToDocCoord(DocRect *pSpreadRect) const 03081 03082 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03083 Created: 11/3/96 03084 03085 Inputs: } pSpreadCoord/pSpreadRect - The coordinate/rectangle to be converted 03086 Outputs: } 03087 03088 Purpose: To convert between Document and Spread coordinate spaces 03089 03090 SeeAlso: Spread::GetSpreadCoordOrigin 03091 03092 ********************************************************************************************/ 03093 03094 void Spread::SpreadCoordToDocCoord(DocCoord *pSpreadCoord) const 03095 { 03096 ERROR3IF(pSpreadCoord == NULL, "Illegal NULL params"); 03097 03098 DocCoord Origin = GetSpreadCoordOrigin(); 03099 03100 pSpreadCoord->x += Origin.x; 03101 pSpreadCoord->y += Origin.y; 03102 } 03103 03104 03105 03106 void Spread::SpreadCoordToDocCoord(DocRect *pSpreadRect) const 03107 { 03108 ERROR3IF(pSpreadRect == NULL, "Illegal NULL params"); 03109 03110 SpreadCoordToDocCoord(&pSpreadRect->lo); 03111 SpreadCoordToDocCoord(&pSpreadRect->hi); 03112 } 03113 03114 03115 03116 /******************************************************************************************** 03117 03118 > void Spread::DocCoordToSpreadCoord(DocCoord *pDocCoord) const 03119 > void Spread::DocCoordToSpreadCoord(DocCoord *pDocRect) const 03120 03121 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03122 Created: 11/3/96 03123 03124 Inputs: } pDocCoord/pDocRect - The coordinate/rectangle to be converted 03125 Outputs: } 03126 03127 Purpose: To convert between Document and Spread coordinate spaces 03128 03129 SeeAlso: Spread::GetSpreadCoordOrigin 03130 03131 ********************************************************************************************/ 03132 03133 void Spread::DocCoordToSpreadCoord(DocCoord *pDocCoord) const 03134 { 03135 ERROR3IF(pDocCoord == NULL, "Illegal NULL params"); 03136 03137 DocCoord Origin = GetSpreadCoordOrigin(); 03138 03139 pDocCoord->x -= Origin.x; 03140 pDocCoord->y -= Origin.y; 03141 } 03142 03143 03144 03145 void Spread::DocCoordToSpreadCoord(DocRect *pDocRect) const 03146 { 03147 ERROR3IF(pDocRect == NULL, "Illegal NULL params"); 03148 03149 DocCoordToSpreadCoord(&pDocRect->lo); 03150 DocCoordToSpreadCoord(&pDocRect->hi); 03151 } 03152 03153 03154 03155 /******************************************************************************************** 03156 03157 > DocCoord Spread::GetMaxPasteboardSize(void) 03158 03159 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03160 Created: 19/2/96 03161 03162 Returns: The maximum pasteboard size (x,y) 03163 03164 Purpose: To determine the maximum size that the pasteboard will allow itself 03165 to be expanded to. 03166 03167 Notes: In document coordinates, the bottom left of the pasteboard is fixed. 03168 However, by moving all objects inside the pasteboard (all spread coords) 03169 we can effectively expand the pasteboard in any direction. Thus, if the 03170 pasteboard width/height is smaller than the returned maximum, you can 03171 still expand the pasteboard in any direction. Thus, the return value from 03172 this method gives the maximum size rather than the max position rectangle. 03173 03174 SeeAlso: Spread::ExpandPasteboardToInclude 03175 03176 ********************************************************************************************/ 03177 03178 DocCoord Spread::GetMaxPasteboardSize(void) 03179 { 03180 #if !NEW_PASTEBOARD 03181 ERROR3("Warning: GetMaxPasteboardSize is unsupported at present! See Jason/Phil"); 03182 #endif 03183 03184 DocCoord MPB(MaxPasteboardSize, MaxPasteboardSize); 03185 return(MPB); 03186 } 03187 03188 03189 03190 /******************************************************************************************** 03191 03192 > BOOL Spread::ExpandPasteboardToInclude(DocRect IncludeRect) 03193 03194 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03195 Created: 19/2/96 03196 03197 Inputs: IncludeRect - The rectangle (in SPREAD coordinates, i.e. standard renderable 03198 object bounds) which you wish to include into the spread's pasteboard range. 03199 03200 Returns: TRUE if the pasteboard was successfully expanded. 03201 FALSE if the pasteboard has reached its maximum size and cannot be expanded 03202 further (note: the pasteboard may still expand during this call, but the 03203 return code indicates that it has now reached maximum extent). The given 03204 rectangle lies outside the available maximum bounds. 03205 03206 Purpose: To expand the pasteboard area to include the given rectangle. Used when 03207 objects are moved outside the current pasteboard area to keep them in an 03208 area which the user can see. The pasteboard will never expand beyond 03209 a maximum size (see Spread::GetMaxPasteboardSize) 03210 03211 Notes: **** This has only been tested for single-spread documents **** 03212 03213 The pasteboard expands equally in all directions in order to keep all 03214 page "margins" equal. This is necessary so that window scroll positions 03215 are not messed when we re-load a file 03216 03217 SeeAlso: Spread::GetMaxPasteboardSize; NodeRenderablePaper::ChangePasteboardRect 03218 03219 ********************************************************************************************/ 03220 03221 BOOL Spread::ExpandPasteboardToInclude(DocRect IncludeRect) 03222 { 03223 #if NEW_PASTEBOARD 03224 #error ("This code has been commented out for safety. Please uncomment and try again"); 03225 03226 Progress Hourglass; // Ensure an hourglass is running while we're busy 03227 03228 // Convert the Spread coordinates "IncludeRect" into Document coordinates "IncludeDocRect" 03229 DocRect IncludeDocRect(IncludeRect); 03230 SpreadCoordToDocCoord(&IncludeDocRect); 03231 03232 // If the pasteboard is already big enough, return immediately (success) 03233 if (PasteboardRect.ContainsRect(IncludeDocRect)) 03234 return(TRUE); 03235 03236 // Remember where the view was looking before we moved things about 03237 DocView *pView = DocView::GetSelected(); 03238 DocRect ViewRect; 03239 if (pView != NULL) 03240 { 03241 ViewRect = pView->GetDocViewRect(this); 03242 DocCoordToSpreadCoord(&ViewRect); 03243 } 03244 03245 // Inflate the IncludeRect in order to add a margin outside it. 72000mpt => 1 inch 03246 IncludeDocRect.Inflate(72000); 03247 03248 // And include the rectangle into the new pasteboard rectangle 03249 DocRect NewBounds(PasteboardRect); 03250 NewBounds = NewBounds.Union(IncludeDocRect); 03251 03252 // And now find the amount by which the "margin" should change, and inflate the pasteboard 03253 // rect in all directions, to keep the margin equal around the pages. 03254 INT32 InflateBy = 0; 03255 { 03256 InflateBy = ABS(NewBounds.lo.x - PasteboardRect.lo.x); 03257 03258 INT32 temp = ABS(NewBounds.lo.y - PasteboardRect.lo.y); 03259 if (temp > InflateBy) InflateBy = temp; 03260 03261 temp = ABS(NewBounds.hi.x - PasteboardRect.hi.x); 03262 if (temp > InflateBy) InflateBy = temp; 03263 03264 temp = ABS(NewBounds.hi.y - PasteboardRect.hi.y); 03265 if (temp > InflateBy) InflateBy = temp; 03266 03267 03268 // Make sure we don't expand beyond the maximum size 03269 DocCoord MaxSize = GetMaxPasteboardSize(); 03270 if (PasteboardRect.Width() + 2*InflateBy > MaxSize.x) 03271 InflateBy = (MaxSize.x - PasteboardRect.Width()) / 2; 03272 03273 if (PasteboardRect.Height() + 2*InflateBy > MaxSize.y) 03274 InflateBy = (MaxSize.y - PasteboardRect.Height()) / 2; 03275 03276 // And inflate the original pasteboard 03277 NewBounds = PasteboardRect; 03278 NewBounds.Inflate(InflateBy, InflateBy); 03279 } 03280 03281 // Now we have the required size and position, go and set it 03282 ChangePasteboardRect(NewBounds); 03283 03284 // Make sure bounding rectangles are invalidated so that they are recalculated 03285 InvalidateBoundingRect(); 03286 03287 // Now run through all spreads, lining up their pasteboards so they don't overlap, 03288 // and making sure that their default grids fully cover the pasteboards. 03289 // Note that this also ensures that the document is redrawn 03290 AdjustPasteboards(); 03291 03292 Document *pParentDoc = (Document *) FindOwnerDoc(); 03293 if (pParentDoc != NULL) 03294 { 03295 // Pretend that page size has changed to cause related UI to change (rulers mainly) 03296 BROADCAST_TO_ALL(OptionsChangingMsg(pParentDoc, 03297 OptionsChangingMsg::NEWPAGESIZE)); 03298 } 03299 03300 // Try to keep the scroll offsets sensible 03301 if (pView != NULL && pView->GetDoc() == pParentDoc) 03302 { 03303 // First, scroll to the previously visible view rectangle - this will adjust for the 03304 // new size of the pasteboard (i.e. new size of the view window extent) to make the 03305 // view look like it has not moved at all. 03306 pView->ScrollToShow(&ViewRect); 03307 03308 // Now, make sure that the IncludeRect is visible on screen 03309 pView->ScrollToShow(&IncludeRect); 03310 } 03311 03312 return(TRUE); // return - successful 03313 03314 #else 03315 // Pasteboard can never expand. Sniffle, Sob! 03316 // We return TRUE if the pasteboard already includes the specified rectangle, and 03317 // FALSE if we would have to expand to include it. 03318 03319 // Convert the Spread coordinates "IncludeRect" into Document coordinates "IncludeDocRect" 03320 DocRect IncludeDocRect(IncludeRect); 03321 SpreadCoordToDocCoord(&IncludeDocRect); 03322 03323 // If the pasteboard is already big enough, return immediately (success) 03324 if (PasteboardRect.ContainsRect(IncludeDocRect)) 03325 return(TRUE); 03326 03327 return(FALSE); 03328 #endif 03329 } 03330 03331 03332 03333 /******************************************************************************************** 03334 03335 > void Spread::AdjustPasteboards(void) 03336 03337 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03338 Created: 13/3/96 03339 03340 Purpose: This runs through all spreads in this spread's parent chapter, doing 03341 the following: 03342 03343 1) Find the minimum and maximum x values of all spread pasteboards in 03344 the chapter, and set all pasteboards to have this same x extent 03345 so that they all line up tidily in a nice clean column. 03346 03347 2) Move the pasteboards (and contents) as necessary so that recently 03348 expanded pasteboards do not overlap neighbouring spreads, and 03349 they all butt up against each other nicely. 03350 (Note: The whole pasteboard is moved, including shifting the 03351 spread coord origin to keep it in the same relative position) 03352 03353 3) Ensure that all default grids fully cover their pasteboard. 03354 03355 Finally, it will cause a redraw of all views onto this document to 03356 ensure that they are correctly updated. 03357 03358 Notes: **** This has only been tested for single-spread Chapters **** 03359 (Although it has been written to hopefully handle multiple spreads) 03360 03361 SeeAlso: Spread::GetMaxPasteboardSize; NodeRenderablePaper::ChangePasteboardRect 03362 03363 ********************************************************************************************/ 03364 03365 void Spread::AdjustPasteboards(void) 03366 { 03367 //#if NEW_PASTEBOARD 03368 Chapter* ParentChapter = FindParentChapter(); 03369 ERROR3IF(ParentChapter == NULL, "No parent Chapter?!"); 03370 03371 // First, find the minimum and maximum pasteboard x extents for the entire document. 03372 // Helpfully, our parent Chapter's pasteboard rect is a union of all of ours! 03373 DocRect ChapterBounds = ParentChapter->GetPasteboardRect(); 03374 03375 // Now we loop through all spreads from this one onwards, doing 2 things 03376 // 1) Make sure that each following spread is shifted to the correct document coordinates 03377 // by ensuring its pasteboard is placed after this spread's one. 03378 // 2) Make sure that all default grids in all spreads fully cover the pasteboards. 03379 Spread* pThisSpread = ParentChapter->FindFirstSpread(); 03380 03381 // Force the x extent of the first pasteboard to match all others in this chapter 03382 DocRect TempPasteRect = pThisSpread->GetPasteboardRect(); 03383 TempPasteRect.lo.x = ChapterBounds.lo.x; 03384 TempPasteRect.hi.x = ChapterBounds.hi.x; 03385 03386 /*if (pThisSpread->FindNextSpread()) 03387 { 03388 DocCoord OriginOffset(pThisSpread->SpreadOrigin.x - pThisSpread->PasteboardRect.lo.x, 03389 pThisSpread->SpreadOrigin.y - pThisSpread->PasteboardRect.lo.y); 03390 03391 DocRect r; 03392 pThisSpread->GetPagesRect(&r); 03393 pThisSpread->SpreadCoordToDocCoord(&r); 03394 r.Inflate(18000); 03395 INT32 ydiff = r.lo.y - TempPasteRect.lo.y; 03396 TempPasteRect.lo.y = r.lo.y; 03397 03398 pThisSpread->SpreadOrigin.x = TempPasteRect.lo.x + OriginOffset.x; 03399 pThisSpread->SpreadOrigin.y = TempPasteRect.lo.y + OriginOffset.y - ydiff; 03400 } 03401 */ 03402 03403 pThisSpread->ChangePasteboardRect(TempPasteRect); 03404 pThisSpread->InvalidateBoundingRect(); 03405 03406 // For each spread... 03407 while (pThisSpread != NULL) 03408 { 03409 Progress::Update(); // Update any active hourglass 03410 03411 Spread* pNextSpread = pThisSpread->FindNextSpread(); 03412 03413 // --- If there is a spread following this one, fix its pasteboard rect position 03414 if (pNextSpread != NULL) 03415 { 03416 DocRect FirstPasteRect = pThisSpread->GetPasteboardRect(FALSE); 03417 /*if (pThisSpread->FindNextSpread()) 03418 { 03419 DocRect r; 03420 pThisSpread->GetPagesRect(&r); 03421 pThisSpread->SpreadCoordToDocCoord(&r); 03422 r.Inflate(18000); 03423 FirstPasteRect.lo.y = r.lo.y; 03424 } 03425 if (pThisSpread->FindPreviousSpread()) 03426 { 03427 DocRect r; 03428 pThisSpread->GetPagesRect(&r); 03429 pThisSpread->SpreadCoordToDocCoord(&r); 03430 r.Inflate(18000); 03431 FirstPasteRect.hi.y = r.hi.y; 03432 } 03433 */ 03434 DocRect SecondPasteRect = pNextSpread->GetPasteboardRect(FALSE); 03435 DocCoord OriginOffset(pNextSpread->SpreadOrigin.x - pNextSpread->PasteboardRect.lo.x, 03436 pNextSpread->SpreadOrigin.y - pNextSpread->PasteboardRect.lo.y); 03437 03438 /*if (pNextSpread->FindNextSpread()) 03439 { 03440 DocRect r; 03441 pNextSpread->GetPagesRect(&r); 03442 pNextSpread->SpreadCoordToDocCoord(&r); 03443 r.Inflate(18000); 03444 INT32 ydiff = r.lo.y - SecondPasteRect.lo.y; 03445 SecondPasteRect.lo.y = r.lo.y; 03446 OriginOffset.y -= ydiff; 03447 } 03448 if (pNextSpread->FindPreviousSpread()) 03449 { 03450 DocRect r; 03451 pNextSpread->GetPagesRect(&r); 03452 pNextSpread->SpreadCoordToDocCoord(&r); 03453 r.Inflate(18000); 03454 SecondPasteRect.hi.y = r.hi.y; 03455 } 03456 */ 03457 03458 // Construct a new Pasteboard rectangle of the correct size, and move it 03459 // to lie just below the previous spread's pasteboard area 03460 TempPasteRect = SecondPasteRect; 03461 03462 TempPasteRect.Translate(-TempPasteRect.lo.x, -TempPasteRect.lo.y); 03463 TempPasteRect.Translate(FirstPasteRect.lo.x, FirstPasteRect.lo.y - TempPasteRect.Height()); 03464 03465 // And force the x extent of this pasteboard to match all others in this chapter 03466 TempPasteRect.lo.x = ChapterBounds.lo.x; 03467 TempPasteRect.hi.x = ChapterBounds.hi.x; 03468 03469 // Move the spread coordinate origin so that it stays at the same relative offset 03470 // from the pasteboard bottom left corner, or else all objects inside the spread 03471 // will suddenly shift to a new place on (or off) the pasteboard! 03472 pNextSpread->SpreadOrigin.x = TempPasteRect.lo.x + OriginOffset.x; 03473 pNextSpread->SpreadOrigin.y = TempPasteRect.lo.y + OriginOffset.y; 03474 03475 // Set the new paste rect 03476 pNextSpread->ChangePasteboardRect(TempPasteRect); 03477 03478 // Make sure bounding rectangles are invalidated so that they are recalculated 03479 pNextSpread->InvalidateBoundingRect(); 03480 } 03481 03482 // --- Fix all the default grids to exactly cover their pasteboards 03483 Node *ptr = pThisSpread->FindFirstChild(); 03484 while (ptr != NULL) 03485 { 03486 if (ptr->IsKindOf(CC_RUNTIME_CLASS(NodeGrid))) 03487 { 03488 // Found a grid type node. Check if its a default type. 03489 NodeGrid* pCurrentGrid = (NodeGrid*)ptr; 03490 03491 if (pCurrentGrid->IsDefault()) 03492 { 03493 // Default grids need to fill the spread's pasteboard rect 03494 DocRect Bounds = pThisSpread->GetPasteboardRect(); 03495 DocCoordToSpreadCoord(&Bounds); 03496 03497 // And set the new bounding rect 03498 pCurrentGrid->SetBoundingRect(Bounds); 03499 } 03500 } 03501 03502 ptr = ptr->FindNext(); 03503 } 03504 03505 // --- And move on to the next spread to fix 03506 pThisSpread = pNextSpread; 03507 } 03508 03509 // And invalidate all displayed views on this document, in order to make sure they 03510 // correctly update on screen. 03511 Document *pDoc = (Document *)FindOwnerDoc(); 03512 if (pDoc != NULL) 03513 pDoc->ForceRedraw(); 03514 03515 //#else 03516 //ERROR3("Spread::AdjustPasteboards is unimplemented - see Jason/Phil"); 03517 //#endif 03518 } 03519 03520 03521 03522 /*********************************************************************************************** 03523 03524 > virtual void Spread::SetInitialPasteboardRect(const DocRect& PasteRect) 03525 03526 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03527 Created: 12/3/96 03528 03529 Inputs: PasteRect: Rectangle representing the outer limits of the pasteboard 03530 03531 Purpose: To set the initial pasteboard rectangle of this node, and then change the 03532 pasteboard rectangles of all its parents. 03533 03534 The method also changes the document extents in the NodeDocument node at 03535 the root of the tree. 03536 03537 Notes: Spread overrides this base class method in order to set its Spread Coordinate 03538 Origin suitably. It then calls the base class to do the normal things. 03539 03540 SeeAlso: NodeRenderablePaper::SetInitialPasteboardRect 03541 03542 ***********************************************************************************************/ 03543 03544 void Spread::SetInitialPasteboardRect(const DocRect& PasteRect) 03545 { 03546 // Call the base class to do its stuff 03547 NodeRenderablePaper::SetInitialPasteboardRect(PasteRect); 03548 03549 // Set the spread coordinate origin to be at the bottom left of the pasteboard by default 03550 SpreadOrigin = PasteboardRect.lo; 03551 } 03552 03553 03554 03555 /******************************************************************************************** 03556 03557 > virtual BOOL Spread::PostImport() 03558 03559 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03560 Created: 18/3/96 03561 03562 Inputs: - 03563 Outputs: - 03564 Returns: TRUE/FALSE for success/failure 03565 03566 Purpose: This function is called after a document is imported. Nodes should override 03567 this function to do any post-import processing. 03568 03569 The spread overrides this function in order to automatically resize its 03570 pasteboard to include all the newly imported nodes if possible. 03571 03572 Notes: Calls the base class PostImport after doing its own processing 03573 03574 SeeAlso: Node::PostImport 03575 03576 ********************************************************************************************/ 03577 03578 BOOL Spread::PostImport() 03579 { 03580 // Get the bounding rect. This comes back in document coords, so we convert to spread 03581 // coords and then call ExpandPasteboardToInclude to include our bounds in the PB area. 03582 if (NodeRenderablePaper::PostImport()) 03583 { 03584 DocRect Bounds = GetBoundingRect(); 03585 DocCoordToSpreadCoord(&Bounds); 03586 ExpandPasteboardToInclude(Bounds); 03587 03588 AdjustPasteboards(); 03589 03590 return(TRUE); 03591 } 03592 03593 return(FALSE); 03594 } 03595 03596 03597 //--------------------------------------------------------------- 03598 //--------------------------------------------------------------- 03599 //--------------------------------------------------------------- 03600 03601 /******************************************************************************************** 03602 03603 > virtual BOOL Spread::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 03604 03605 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03606 Created: 24/6/96 03607 Inputs: pFilter = ptr to the filter 03608 Returns: TRUE if record is written, FALSE if not 03609 Purpose: Web files do not write out spreads. 03610 03611 This code assumes that the document only has one spread 03612 03613 SeeAlso: Node::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 03614 03615 ********************************************************************************************/ 03616 03617 BOOL Spread::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 03618 { 03619 return FALSE; 03620 } 03621 03622 /******************************************************************************************** 03623 03624 > virtual BOOL Spread::WritePreChildrenNative(BaseCamelotFilter* pFilter) 03625 03626 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03627 Created: 24/6/96 03628 Inputs: pFilter = ptr to the filter 03629 Returns: TRUE if record is written, FALSE if not 03630 Purpose: Writes the spread record to the filter 03631 03632 Native files write out all spreads. 03633 03634 SeeAlso: Node::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 03635 03636 ********************************************************************************************/ 03637 03638 BOOL Spread::WritePreChildrenNative(BaseCamelotFilter* pFilter) 03639 { 03640 #ifdef DO_EXPORT 03641 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 03642 03643 BOOL RecordWritten = FALSE; 03644 03645 // Always write out the spread record in native files 03646 CXaraFileRecord Rec(TAG_SPREAD,TAG_SPREAD_SIZE); 03647 if (pFilter->Write(&Rec) != 0) 03648 RecordWritten = TRUE; 03649 else 03650 pFilter->GotError(_R(IDE_FILE_WRITE_ERROR)); 03651 03652 return RecordWritten; 03653 #else 03654 return FALSE; 03655 #endif 03656 } 03657 03658 /******************************************************************************************** 03659 03660 > BOOL Spread::WriteBeginChildRecordsNative(BaseCamelotFilter* pFilter) 03661 03662 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03663 Created: 1/8/96 03664 Inputs: pFilter = ptr to the filter to write to 03665 Outputs: - 03666 Returns: TRUE ok, FALSE otherwise 03667 Purpose: Begins the child record sequence for spread in the native format 03668 03669 The native format writes out all spreads and includes the spread details record 03670 as the spread's first child record 03671 03672 SeeAlso: WritePreChildrenNative() 03673 03674 ********************************************************************************************/ 03675 03676 BOOL Spread::WriteBeginChildRecordsNative(BaseCamelotFilter* pFilter) 03677 { 03678 #ifdef DO_EXPORT 03679 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 03680 03681 BOOL RecordWritten = FALSE; 03682 03683 // First thing to do is write out the Down record 03684 RecordWritten = (pFilter->WriteZeroSizedRecord(TAG_DOWN)); 03685 03686 // Write out the page sizes etc for this spread 03687 if (RecordWritten) RecordWritten = WriteSpreadInformation(pFilter); 03688 if (RecordWritten) RecordWritten = WriteSpreadScaling(pFilter); 03689 03690 // write out the Animtion Record. 03691 if (RecordWritten) RecordWritten = WriteSpreadAnimProperties(pFilter); 03692 03693 return RecordWritten; 03694 #else 03695 return TRUE; 03696 #endif //DO_EXPORT 03697 } 03698 03699 /******************************************************************************************** 03700 03701 > BOOL Spread::WriteEndChildRecordsNative(BaseCamelotFilter* pFilter) 03702 03703 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03704 Created: 1/8/96 03705 Inputs: pFilter = ptr to the filter to write to 03706 Outputs: - 03707 Returns: TRUE ok, FALSE otherwise 03708 Purpose: Ends the child record sequence for spreads in the native format 03709 03710 The native format writes out all spreads. This func just writes out the Up record 03711 03712 SeeAlso: WritePreChildrenNative() 03713 03714 ********************************************************************************************/ 03715 03716 BOOL Spread::WriteEndChildRecordsNative(BaseCamelotFilter* pFilter) 03717 { 03718 #ifdef DO_EXPORT 03719 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 03720 return pFilter->WriteZeroSizedRecord(TAG_UP); 03721 #else 03722 return FALSE; 03723 #endif 03724 } 03725 03726 /******************************************************************************************** 03727 03728 > BOOL Spread::WriteBeginChildRecordsWeb(BaseCamelotFilter* pFilter) 03729 03730 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03731 Created: 1/8/96 03732 Inputs: pFilter = ptr to the filter to write to 03733 Outputs: - 03734 Returns: TRUE ok, FALSE otherwise 03735 Purpose: Begins the child record sequence for spread in the web format 03736 03737 Web export doesn't write out spread records, so this overrides the default 03738 behaviour in Node by ensuring the Down record does not get written 03739 03740 SeeAlso: WritePreChildrenNative() 03741 03742 ********************************************************************************************/ 03743 03744 BOOL Spread::WriteBeginChildRecordsWeb(BaseCamelotFilter* pFilter) 03745 { 03746 return TRUE; 03747 } 03748 03749 /******************************************************************************************** 03750 03751 > BOOL Spread::WriteEndChildRecordsWeb(BaseCamelotFilter* pFilter) 03752 03753 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 03754 Created: 1/8/96 03755 Inputs: pFilter = ptr to the filter to write to 03756 Outputs: - 03757 Returns: TRUE ok, FALSE otherwise 03758 Purpose: Ends the child record sequence for spread in the web format 03759 03760 Web export doesn't write out spread records, so this overrides the default 03761 behaviour in Node by ensuring the Up record does not get written 03762 03763 SeeAlso: WritePreChildrenNative() 03764 03765 ********************************************************************************************/ 03766 03767 BOOL Spread::WriteEndChildRecordsWeb(BaseCamelotFilter* pFilter) 03768 { 03769 return TRUE; 03770 } 03771 03772 /******************************************************************************************** 03773 03774 > BOOL Spread::WriteSpreadAnimationProperties(BaseCamelotFilter* pFilter) 03775 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03776 Created: 8/5/97 03777 Input: pFilter = ptr to the filter to export to. 03778 Outputs: - 03779 Returns: TRUE if ok, FALSE otherwise. 03780 Purpose: Exports the Animation Properties details for this Spread to the filter. 03781 Notes: Karim 07/12/2000 - modified to save out transparent GIF information. 03782 03783 *********************************************************************************************/ 03784 03785 BOOL Spread::WriteSpreadAnimProperties(BaseCamelotFilter* pFilter) 03786 { 03787 #ifdef DO_EXPORT 03788 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 03789 03790 BOOL RecordWritten = FALSE; 03791 03792 BOOL ok = TRUE; 03793 03794 // Add a description of the TAG_SPREAD_ANIMPROPS record, for older importers that don't understand this record 03795 pFilter->AddTagDescription(TAG_SPREAD_ANIMPROPS, _R(IDS_TAG_SPREAD_ANIMPROPS)); 03796 03797 // Start a record to save our data in 03798 CXaraFileRecord Rec(TAG_SPREAD_ANIMPROPS, TAG_SPREAD_ANIMPROPS_SIZE); 03799 03800 // Get our information... 03801 DWORD Loop = m_AnimPropertiesParam.GetAnimLoop(); 03802 DWORD GlobalDelay = m_AnimPropertiesParam.GetGlobalAnimDelay(); 03803 DWORD Dither = m_AnimPropertiesParam.GetDither(); 03804 DWORD WebPalette = m_AnimPropertiesParam.GetPalette(); 03805 DWORD ColoursPalette = m_AnimPropertiesParam.GetPaletteCols(); 03806 DWORD NumColsInPalette = m_AnimPropertiesParam.GetNumColsInPalette(); 03807 03808 // We have a flags word so get the bits that affect it 03809 BOOL SystemCols = m_AnimPropertiesParam.GetUseSystemCols(); 03810 BOOL BgTransparent = m_AnimPropertiesParam.GetIsBackGroundTransp(); 03811 03812 // And now fill in the bits in the flags word. 03813 // To be compatible with CX2, we set the flag if BgTransparent is FALSE, 03814 // as CX2 automatically did bg transparent GIFs all the time. 03815 BYTE FlagsWord = (SystemCols ? 1 : 0); 03816 FlagsWord |= (BgTransparent ? 0 : 2); 03817 03818 ok = Rec.Init(); 03819 03820 if (ok) 03821 ok = Rec.WriteUINT32(Loop); 03822 if (ok) 03823 ok = Rec.WriteUINT32(GlobalDelay); 03824 if (ok) 03825 ok = Rec.WriteUINT32(Dither); 03826 if (ok) 03827 ok = Rec.WriteUINT32(WebPalette); 03828 if (ok) 03829 ok = Rec.WriteUINT32(ColoursPalette); 03830 if (ok) 03831 ok = Rec.WriteUINT32(NumColsInPalette); 03832 if (ok) 03833 ok = Rec.WriteUINT32(FlagsWord); 03834 03835 // Write out the record. 03836 if (pFilter->Write(&Rec) != 0) 03837 RecordWritten = TRUE; 03838 else 03839 pFilter->GotError(_R(IDE_FILE_WRITE_ERROR)); 03840 03841 return RecordWritten; 03842 #else 03843 return FALSE; 03844 #endif 03845 } 03846 03847 /****************************************************************************************************** 03848 03849 > void Spread::SetAnimationLoop(const DWORD &Loop) 03850 03851 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03852 Created: 8/5/97 03853 Input: Loop :- Global loop value. 03854 Outputs: - 03855 Returns: - 03856 Purpose: Sets the loop value within the class data member m_AnimPropertiesParam. 03857 This value has been recieved from the Animation properties tab. 03858 03859 *******************************************************************************************************/ 03860 void Spread::SetAnimationLoop(const DWORD &Loop) 03861 { 03862 m_AnimPropertiesParam.SetAnimLoop(Loop); 03863 } 03864 03865 03866 /****************************************************************************************************** 03867 03868 > void Spread::SetAnimationDelay(const DWORD GlobalDelay) 03869 03870 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03871 Created: 8/5/97 03872 Input: Global Delay :- Global Delay value. 03873 Outputs: - 03874 Returns: - 03875 Purpose: Sets the the delay value within the class data member m_AnimPropertiesParam. 03876 This value has been recieved from the Animation properties tab. 03877 03878 *******************************************************************************************************/ 03879 void Spread::SetAnimationDelay(const DWORD GlobalDelay) 03880 { 03881 m_AnimPropertiesParam.SetGlobalanimDelay(GlobalDelay); 03882 } 03883 03884 /****************************************************************************************************** 03885 03886 > void SetAnimationColours(const DITHER& Dither, const WEB_PALETTE& WebPalette, 03887 const PALETTE_COLOURS& ColoursPalette, const DWORD& NumColsInPalette, 03888 const BOOL& IsBackgroundTransparent); 03889 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03890 Created: 8/5/97 03891 Input: Dither, WebPalette, ColoursPalette, NumColsInPalette, 03892 IsBackgroundTransparent:- Animation colour preferences. 03893 Outputs: - 03894 Returns: - 03895 Purpose: Sets the values for the animation colours within the class data member m_AnimPropertiesParam. 03896 These values have been recieved from the Animation properties tab. 03897 Notes: Karim 07/12/2000 - added IsBackgroundTransparent parameter. 03898 03899 *******************************************************************************************************/ 03900 void Spread::SetAnimationColours(const DITHER& Dither, const WEB_PALETTE& WebPalette, 03901 const PALETTE_COLOURS& ColoursPalette, const DWORD& NumColsInPalette, 03902 const BOOL& IsBackgroundTransparent) 03903 { 03904 // test if we need to junk any cached bitmaps 03905 if (Dither != m_AnimPropertiesParam.GetDither() || 03906 WebPalette != m_AnimPropertiesParam.GetPalette() || 03907 ColoursPalette != m_AnimPropertiesParam.GetPaletteCols() || 03908 NumColsInPalette != m_AnimPropertiesParam.GetNumColsInPalette() || 03909 IsBackgroundTransparent != m_AnimPropertiesParam.GetIsBackGroundTransp()) 03910 { 03911 // force a refresh (regrab) of all frames as 03912 // the palette has changed etc.. 03913 PORTNOTETRACE("OpGrabAllFrames","Spread::SetAnimationColours - Not setting OpGrabAllFrames force refresh flag"); 03914 #ifndef EXCLUDE_FROM_XARALX 03915 OpGrabAllFrames::ms_ForceRefreshOfAllFrames = TRUE; 03916 #endif 03917 } 03918 03919 m_AnimPropertiesParam.SetDither(Dither); 03920 m_AnimPropertiesParam.SetPalette(WebPalette); 03921 m_AnimPropertiesParam.SetPaletteCols(ColoursPalette); 03922 m_AnimPropertiesParam.SetNumColsInPalette(NumColsInPalette); 03923 m_AnimPropertiesParam.SetIsBackGroundTransp(IsBackgroundTransparent); 03924 } 03925 03926 /****************************************************************************************************** 03927 03928 > void GetAnimationColours(DITHER * pDither, WEB_PALETTE * pWebPalette, 03929 PALETTE_COLOURS * pColoursPalette, DWORD * pNumColsInPalette, 03930 BOOL * pIsBackgroundTransparent); 03931 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03932 Created: 31/7/97 03933 Outputs: Dither, WebPalette, ColoursPalette, NumColsInPalette, 03934 IsBackgroundTransparent:- Animation colour preferences. 03935 Returns: - 03936 Purpose: Gets the values for the animation colours within the class data member m_AnimPropertiesParam. 03937 Notes: Karim 07/12/2000 - added IsBackgroundTransparent parameter. 03938 03939 *******************************************************************************************************/ 03940 03941 void Spread::GetAnimationColours(DITHER * pDither, WEB_PALETTE * pWebPalette, 03942 PALETTE_COLOURS * pColoursPalette, DWORD * pNumColsInPalette, 03943 BOOL * pIsBackgroundTransparent) 03944 { 03945 if (pDither != NULL) 03946 *pDither = m_AnimPropertiesParam.GetDither(); 03947 if (pWebPalette != NULL) 03948 *pWebPalette = m_AnimPropertiesParam.GetPalette(); 03949 if (pColoursPalette != NULL) 03950 *pColoursPalette = m_AnimPropertiesParam.GetPaletteCols(); 03951 if (pNumColsInPalette != NULL) 03952 *pNumColsInPalette = m_AnimPropertiesParam.GetNumColsInPalette(); 03953 if (pIsBackgroundTransparent != NULL) 03954 *pIsBackgroundTransparent = m_AnimPropertiesParam.GetIsBackGroundTransp(); 03955 } 03956 03957 /******************************************************************************************** 03958 03959 > BOOL Spread::WriteSpreadInformation(BaseCamelotFilter* pFilter) 03960 03961 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03962 Created: 6/8/96 03963 Input: pFilter = ptr to the filter to export to 03964 Outputs: - 03965 Returns: TRUE if ok, FALSE otherwise 03966 Purpose: Exports the page details, margins, bleed size and other spread related 03967 information for this spread to the filter. 03968 We output an information record rather than the individual pages as:- 03969 - all the pages in the spread are defined to be the same size 03970 - this is the same way that the old format used (not a good argument I know!) 03971 - all the code to do it this way is present and proved 03972 - it is a logical packing of all spread related information into one record 03973 SeeAlso: Spread::WritePreChildrenNative; Spread::WritePreChildrenWeb; 03974 03975 ********************************************************************************************/ 03976 03977 BOOL Spread::WriteSpreadInformation(BaseCamelotFilter* pFilter) 03978 { 03979 #ifdef DO_EXPORT 03980 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 03981 03982 // BOOL RecordWritten = FALSE; 03983 03984 // Now save out the information record 03985 MILLIPOINT Width = 0; 03986 MILLIPOINT Height = 0; 03987 MILLIPOINT Margin = 0; 03988 MILLIPOINT Bleed = 0; 03989 BOOL Dps = TRUE; 03990 BOOL ShowDropShadow = TRUE; 03991 03992 BOOL ok = TRUE; 03993 03994 // and go and get all the page info 03995 if (ok) ok = GetPageSize(&Width, &Height, &Margin, &Bleed, &Dps, &ShowDropShadow); 03996 03997 // If it worked, we had better try and output some info 03998 if (ok) 03999 { 04000 CXaraFileRecord Rec(TAG_SPREADINFORMATION, TAG_SPREADINFORMATION_SIZE); 04001 04002 ok = Rec.Init(); 04003 04004 // Width, Height of page 04005 if (ok) ok = Rec.WriteINT32(Width); 04006 if (ok) ok = Rec.WriteINT32(Height); 04007 // <Margin : MILLIPOINT> The margin to add around all four sides of the pages in the spread to make up the pasteboard. 04008 if (ok) ok = Rec.WriteINT32(Margin); 04009 // <Bleed : MILLIPOINT> Bleed margin to add around all pages in this spread. (0 means none) 04010 if (ok) ok = Rec.WriteINT32(Bleed); 04011 // <SpreadFlags : BYTE> Flags for the current spread. 04012 // SpreadFlags ::= DoublePageSpread | ShowDropShadow 04013 // ShowDropShadow flag to say whether we apply a page shadow behind the page 04014 // DoublePageSpread flag to say whether one or two pages are present 04015 BYTE FlagsWord = (ShowDropShadow ? 2 : 0) | (Dps ? 1 : 0); 04016 if (ok) ok = Rec.WriteBYTE(FlagsWord); 04017 04018 // Finally, write the record out to file 04019 if (ok) ok = (pFilter->Write(&Rec) != 0); 04020 } 04021 04022 return ok; 04023 #else 04024 return FALSE; 04025 #endif 04026 } 04027 04028 04029 /******************************************************************************************** 04030 04031 > BOOL Spread::WriteSpreadScaling(BaseCamelotFilter* pFilter) 04032 04033 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04034 Created: 6/8/96 04035 Input: pFilter = ptr to the filter to export to 04036 Outputs: - 04037 Returns: TRUE if ok, FALSE otherwise 04038 Purpose: Exports the scaling information for this spread to the filter 04039 SeeAlso: Spread::WritePreChildrenNative; Spread::WritePreChildrenWeb; 04040 04041 ********************************************************************************************/ 04042 04043 BOOL Spread::WriteSpreadScaling(BaseCamelotFilter* pFilter) 04044 { 04045 #ifdef DO_EXPORT 04046 ERROR2IF(pFilter == NULL,FALSE,"NULL filter param"); 04047 04048 BOOL ok = FALSE; 04049 04050 DimScale* pDimScale = GetPtrDimScale(); 04051 if (pDimScale != NULL) 04052 { 04053 // Find out if it is active 04054 BOOL Active = pDimScale->IsActive(); 04055 04056 // Find out about the scale factor strings 04057 String_32 DrawingScale = pDimScale->GetDrawingScaleStr(); 04058 String_32 RealScale = pDimScale->GetRealScaleStr(); 04059 04060 // If we just save the strings directly, we will named references to the units being used. 04061 // This is bad as if somebody saves out '10cm' and then loads this onto a Japanese version, 04062 // they will not get what they expected. If we strip the scaling factor and units from the strings 04063 // and save this instead, the units as a units reference, then everything will be happy. The units 04064 // will get loaded in and converted into the correct locale format. (Apart from user units of course). 04065 UnitType Default = pDimScale->GetUnits(); 04066 04067 double DrawingScaleValue = 1.0; 04068 UnitType DrawingUnits = NOTYPE; 04069 ok = Convert::StringToComponents(DrawingScale, &DrawingScaleValue, &DrawingUnits); 04070 04071 if (DrawingUnits == NOTYPE) 04072 DrawingUnits = Default; 04073 04074 double RealScaleValue = 1.0; 04075 UnitType RealUnits = NOTYPE; 04076 ok = Convert::StringToComponents(RealScale, &RealScaleValue, &RealUnits); 04077 04078 if (RealUnits == NOTYPE) 04079 RealUnits = Default; 04080 04081 // Convert the unittype into a reference 04082 UnitListComponent * pUnitsComponent = pFilter->GetUnitDocComponent(); 04083 ERROR2IF(pUnitsComponent == NULL,FALSE,"WriteGridAndRulerSettings No units doc component present"); 04084 04085 INT32 DrawingUnitsRef = pUnitsComponent->GetWriteUnitReference(DrawingUnits, pFilter); 04086 INT32 RealUnitsRef = pUnitsComponent->GetWriteUnitReference(RealUnits, pFilter); 04087 04088 INT32 Tag = TAG_SPREADSCALING_INACTIVE; 04089 INT32 Size = TAG_SPREADSCALING_INACTIVE_SIZE; 04090 if (Active) 04091 { 04092 Tag = TAG_SPREADSCALING_ACTIVE; 04093 Size = TAG_SPREADSCALING_ACTIVE_SIZE; 04094 } 04095 04096 CXaraFileRecord Rec(Tag, Size); 04097 04098 ok = Rec.Init(); 04099 04100 if (ok) ok = Rec.WriteDOUBLE(DrawingScaleValue); 04101 if (ok) ok = Rec.WriteINT32(DrawingUnitsRef); 04102 if (ok) ok = Rec.WriteDOUBLE(RealScaleValue); 04103 if (ok) ok = Rec.WriteINT32(RealUnitsRef); 04104 04105 // Finally, write the record out to file 04106 // In the process get the record number that this was written out as 04107 INT32 RecordNumber = 0L; 04108 if (ok) RecordNumber = pFilter->Write(&Rec); 04109 04110 // If we have had a problem at any of the stages then return that to the caller 04111 if (!ok || RecordNumber <= 0) 04112 ok = FALSE; 04113 } 04114 04115 return ok; 04116 #else 04117 return TRUE; 04118 #endif //DO_EXPORT 04119 } 04120 04121 /******************************************************************************************** 04122 04123 > BOOL Sperad::SetAnimPropertiesParam(AnimPropertiesParam* pParam) 04124 04125 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 04126 Created: 07/05/97 04127 Inputs: pParam - Sets the Animation Properties details for this spread. 04128 Returns: TRUE if ok, FALSE otherwise. 04129 04130 ********************************************************************************************/ 04131 void Spread::SetSpreadAnimPropertiesParam(const AnimPropertiesParam& Param) 04132 { 04133 m_AnimPropertiesParam = Param; 04134 } 04135 04136 /******************************************************************************************** 04137 04138 > void Sperad::GetAnimPropertiesParam() 04139 04140 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 04141 Created: 07/05/97 04142 Purpose: Returns the the Animation Properties details for this spread. 04143 04144 ********************************************************************************************/ 04145 AnimPropertiesParam& Spread::GetSpreadAnimPropertiesParam() 04146 { 04147 return m_AnimPropertiesParam; 04148 } 04149 04150 /******************************************************************************************************************** 04151 > BOOL Spread::SetSpreadAnimPropertiesParam(const DWORD &Loop, const DWORD &GlobalDelay, const DITHER &Dither, 04152 const WEB_PALETTE &WebPalette, const PALETTE_COLOURS &ColoursPalette, 04153 const DWORD &NumColsInPalette, const BOOL& UseSystemColours, 04154 const BOOL& IsBackgroundTransparent) 04155 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 04156 Created: 07/05/97 04157 Purpose: Sets the Animation Properties details for this spread. 04158 Notes: Karim 07/12/00 - added IsBackgroundTransparent parameter. 04159 04160 *********************************************************************************************************************/ 04161 04162 BOOL Spread::SetSpreadAnimPropertiesParam(const DWORD &Loop, const DWORD &GlobalDelay, const DITHER &Dither, 04163 const WEB_PALETTE &WebPalette, const PALETTE_COLOURS &ColoursPalette, 04164 const DWORD &NumColsInPalette, const BOOL& UseSystemColours, 04165 const BOOL& IsBackgroundTransparent) 04166 { 04167 ERROR2IF(this==NULL,FALSE,"Spread::SetSpreadAnimProperties cslled on NULL pointer"); 04168 04169 m_AnimPropertiesParam.SetAnimLoop(Loop); 04170 m_AnimPropertiesParam.SetGlobalanimDelay(GlobalDelay); 04171 m_AnimPropertiesParam.SetDither(Dither); 04172 m_AnimPropertiesParam.SetPalette(WebPalette); 04173 m_AnimPropertiesParam.SetPaletteCols(ColoursPalette); 04174 m_AnimPropertiesParam.SetNumColsInPalette(NumColsInPalette); 04175 m_AnimPropertiesParam.SetUseSystemCols(UseSystemColours); 04176 m_AnimPropertiesParam.SetIsBackGroundTransp(IsBackgroundTransparent); 04177 04178 return TRUE; 04179 } 04180 04181 /******************************************************************************************************************** 04182 BOOL Spread::GetSpreadAnimPropertiesParam(DWORD *Loop, DWORD *GlobalDelay, DITHER *Dither, 04183 WEB_PALETTE *WebPalette, PALETTE_COLOURS* ColoursPalette, 04184 DWORD* NumColsInPalette, BOOL* UseSystemColours, 04185 BOOL* IsBgTransparent) 04186 04187 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 04188 Created: 01/04/97 04189 Purpose: Allows access to the Animation Properties details for this spread. 04190 Notes: Karim 07/12/00 - added IsBgTransparent parameter. 04191 04192 *********************************************************************************************************************/ 04193 BOOL Spread::GetSpreadAnimPropertiesParam(DWORD *Loop, DWORD *GlobalDelay, DITHER *Dither, 04194 WEB_PALETTE *WebPalette, PALETTE_COLOURS* ColoursPalette, 04195 DWORD* NumColsInPalette, BOOL* UseSystemColours, 04196 BOOL* IsBgTransparent) 04197 { 04198 ERROR2IF(this==NULL,FALSE,"Spread::GetSpreadAnimProperties cslled on NULL pointer"); 04199 04200 *Loop = m_AnimPropertiesParam.GetAnimLoop(); 04201 *GlobalDelay = m_AnimPropertiesParam.GetGlobalAnimDelay(); 04202 *Dither = m_AnimPropertiesParam.GetDither(); 04203 *WebPalette = m_AnimPropertiesParam.GetPalette(); 04204 *ColoursPalette = m_AnimPropertiesParam.GetPaletteCols(); 04205 *NumColsInPalette = m_AnimPropertiesParam.GetNumColsInPalette(); 04206 *UseSystemColours = m_AnimPropertiesParam.GetUseSystemCols(); 04207 if (IsBgTransparent != NULL) 04208 *IsBgTransparent= m_AnimPropertiesParam.GetIsBackGroundTransp(); 04209 04210 return TRUE; 04211 } 04212 04213 /******************************************************************************************** 04214 04215 > void Spread::SetAnimationBoundingRect(const DocRect& BoundingRect) 04216 04217 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04218 Created: 10/06/97 04219 Inputs: BoundingRect - the new bounding rect for this spread. 04220 Purpose: Sets the new stored bounding rect for this spread. 04221 04222 ********************************************************************************************/ 04223 04224 void Spread::SetAnimationBoundingRect(const DocRect& BoundingRect) 04225 { 04226 m_AnimPropertiesParam.SetBoundingRect(BoundingRect); 04227 } 04228 04229 /******************************************************************************************** 04230 04231 > DocRect Spread::GetAnimationBoundingRect() 04232 04233 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04234 Created: 10/06/97 04235 Returns: the stored bounding rect for the animation 04236 Purpose: Returns the stored animation bounding rect for this spread. 04237 04238 ********************************************************************************************/ 04239 04240 DocRect Spread::GetAnimationBoundingRect() 04241 { 04242 return m_AnimPropertiesParam.GetBoundingRect(); 04243 } 04244 04245 04246 /******************************************************************************************** 04247 04248 > void Spread::SetAnimationQuality(const Quality& NewQuality) 04249 04250 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04251 Created: 21/7/97 04252 Inputs: NewQuality - the new capture quality for this spread. 04253 Purpose: Sets the new stored quality that the animation for this spread was captured at. 04254 04255 ********************************************************************************************/ 04256 04257 void Spread::SetAnimationQuality(const Quality& NewQuality) 04258 { 04259 m_AnimPropertiesParam.SetAnimationQuality(NewQuality); 04260 } 04261 04262 04263 /******************************************************************************************** 04264 04265 > Quality Spread::GetAnimationQuality() 04266 04267 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 04268 Created: 21/7/97 04269 Returns: the stored quality for the animation 04270 Purpose: Returns the stored quality that the animation for this spread was captured at. 04271 04272 ********************************************************************************************/ 04273 04274 Quality Spread::GetAnimationQuality() 04275 { 04276 return m_AnimPropertiesParam.GetAnimationQuality(); 04277 } 04278 04279 04280 /******************************************************************************************** 04281 04282 > SubtreeRenderState Spread::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip) 04283 04284 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 04285 Created: 12/07/2004 04286 Returns: indicator as to whether rendering can proceed in this subtree 04287 Purpose: - 04288 04289 ********************************************************************************************/ 04290 04291 SubtreeRenderState Spread::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip) 04292 { 04293 return SUBTREE_ROOTANDCHILDREN; 04294 } 04295 04296 04297 /******************************************************************************************** 04298 04299 > BOOL Spread::NeedsToExport(RenderRegion *pRender, BOOL VisibleLayersOnly = FALSE, 04300 BOOL CheckSelected = FALSE) 04301 04302 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 04303 Created: 01/12/2004 04304 Inputs: pRender - A pointer to the current export region (null if none) 04305 VisibleLayersOnly - TRUE => remove nodes which are on invisible layers 04306 - FALSE => export everything 04307 CheckSelected - TRUE => we check if object selected and only export selected bjects 04308 - FALSE => we don't bother checking for selection or not 04309 Returns: FALSE => we never want to export NodeRenderablePaper objects. 04310 Purpose: Indicate that we don't want to export this class of nodes. 04311 SeeAlso: NodeRenderablePaper::NeedsToRender 04312 04313 ********************************************************************************************/ 04314 04315 BOOL Spread::NeedsToExport(RenderRegion *pRender, BOOL VisibleLayersOnly, BOOL CheckSelected) 04316 { 04317 return TRUE; 04318 } 04319 04320