00001 // $Id: page.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // The Page class 00100 00101 00102 #include "camtypes.h" 00103 #include "page.h" 00104 //#include "simon.h" 00105 //#include "mario.h" 00106 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "exceptio.h" // For BlowUpOnCrashMe() method 00108 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "snap.h" 00110 #include "nodedoc.h" 00111 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "ralphint.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "layer.h" 00115 00116 //static INT32 abs(INT32 n) { if (n<0) return (0-n); else return (n);} 00117 00118 DocColour Page::PageColour(COLOUR_WHITE); // Initial colour of a page (white) 00119 // Note - will NOT colour-separate 00120 00121 #ifdef RALPH 00122 #define NO_PAGE 1 00123 #endif 00124 00125 CC_IMPLEMENT_DYNAMIC(Page, NodeRenderablePaper) 00126 00127 /********************************************************************************************* 00128 00129 > Page::Page() 00130 00131 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00132 Created: 13/5/93 00133 Inputs: - 00134 Outputs: 00135 Returns: - 00136 00137 Purpose: This constructor creates a Page linked to no other nodes, with all status 00138 flags false, and NULL bounding and pasteboard rectangles. 00139 00140 Errors: 00141 00142 **********************************************************************************************/ 00143 00144 00145 Page::Page(): NodeRenderablePaper() 00146 { 00147 } 00148 00149 00150 /*********************************************************************************************** 00151 > Page::Page 00152 ( 00153 Node* ContextNode, 00154 AttachNodeDirection Direction, 00155 const DocRect& PasteRect, 00156 MILLIPOINT PageWidth, 00157 MILLIPOINT PageHeight, 00158 BOOL Locked=FALSE, 00159 BOOL Mangled=FALSE, 00160 BOOL Marked=FALSE, 00161 BOOL Selected=FALSE 00162 ) 00163 00164 00165 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00166 Created: 26/4/93 00167 00168 Inputs: ContextNode: Pointer to a node which this node is to be attached to. 00169 00170 Direction: 00171 00172 Specifies the direction in which this node is to be attached to the 00173 ContextNode. The values this variable can take are as follows: 00174 00175 PREV : Attach node as a previous sibling of the context node 00176 NEXT : Attach node as a next sibling of the context node 00177 FIRSTCHILD: Attach node as the first child of the context node 00178 LASTCHILD : Attach node as a last child of the context node 00179 00180 PasteRect : Page's pasteboard rectangle 00181 PageWidth : The width of the page 00182 PageHeight: The height of the page 00183 00184 The remaining inputs specify the status of the node: 00185 00186 Locked: Is node locked ? 00187 Mangled: Is node mangled ? 00188 Marked: Is node marked ? 00189 Selected: Is node selected ? 00190 00191 Outputs: - 00192 Returns: - 00193 Purpose: This method initialises the page node and links it to ContextNode in the 00194 direction specified by Direction. The sizes of the pasteboard rectangles of all 00195 paper nodes above this page are recalculated, and the document extents changed. 00196 00197 Errors: An assertion error will occur if ContextNode is NULL 00198 00199 ***********************************************************************************************/ 00200 00201 Page::Page 00202 ( 00203 Node* ContextNode, 00204 AttachNodeDirection Direction, 00205 const DocRect& NewPageRect, 00206 BOOL Locked, 00207 BOOL Mangled, 00208 BOOL Marked, 00209 BOOL Selected 00210 ):NodeRenderablePaper(ContextNode, Direction, Locked, Mangled, 00211 Marked, Selected) 00212 { 00213 PageRect = NewPageRect; 00214 } 00215 00216 /******************************************************************************************** 00217 00218 > virtual String Page::Describe(BOOL Plural, BOOL Verbose = TRUE) 00219 00220 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00221 Created: 21/6/93 00222 Inputs: Plural: Flag indicating if the string description should be plural or 00223 singular. 00224 Outputs: - 00225 Retuns: Description of the object 00226 Purpose: To return a description of the Node object in either the singular or the 00227 plural. This method is called by the DescribeRange method. 00228 00229 The description will always begin with a lower case letter. 00230 00231 Errors: A resource exception will be thrown if a problem occurs when loading the 00232 string resource. 00233 SeeAlso: - 00234 00235 ********************************************************************************************/ 00236 /* 00237 Technical Notes: 00238 00239 The String resource identifiers should be of the form: ID_<Class>_DescriptionS for the 00240 singular description and ID_<Class>_DescriptionP for the plural. 00241 */ 00242 00243 String Page::Describe(BOOL Plural, BOOL Verbose) 00244 { 00245 if (Plural) 00246 return(String(_R(IDS_PAGE_DESCRP))); 00247 else 00248 return(String(_R(IDS_PAGE_DESCRS))); 00249 }; 00250 00251 00252 /*********************************************************************************************** 00253 00254 > void Page::Render() 00255 00256 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00257 Created: 10/5/93 00258 Inputs: - 00259 Outputs: - 00260 Returns: - 00261 Purpose: Renders page items: White page rectangle, page divider, print margin, and 00262 grid. 00263 00264 Errors: - 00265 SeeAlso: - 00266 00267 ***********************************************************************************************/ 00268 00269 void Page::Render( RenderRegion* pRender ) 00270 { 00271 // If we should blow up, then blow up - don't worry, this is a very quick inline check 00272 OpException::BlowUpOnCrashMe(); 00273 00274 // Sanity check 00275 ERROR3IF(pRender == NULL,"Page::Render null render region!"); 00276 if (pRender == NULL) 00277 return; 00278 00279 // If we have the new page background layer present then we needn't bother redrawing the 00280 // page as we might get a flash of white as we redraw 00281 Node * pCurrent = FindParent(); 00282 if (pCurrent->GetRuntimeClass() == CC_RUNTIME_CLASS(Spread)) 00283 { 00284 // We have found the spread 00285 Spread * pSpread = (Spread *)pCurrent; 00286 // Is there a page background layer on the spread? 00287 Layer* pLayer = pSpread->FindFirstPageBackgroundLayer(); 00288 // Yes, the layer is present but is it visible and does the quality level 00289 // dictate that we should show it? 00290 if ( 00291 pLayer && pLayer->IsVisible() && 00292 (pRender->RRQuality.GetFillQuality() >= Quality::NoFill) 00293 ) 00294 return; 00295 } 00296 00297 // This conditional replaces the correct code (directly below in the IF clause) in favour 00298 // of a bodged version that renders the single pixel page outline using filled rectangles 00299 // (the code in the ELSE clause). This is required because although GDI and GDraw fills 00300 // can be made to match up, their outlines can't (at the time of writing). 00301 // 00302 // By the way, Gavin says, it's faster to plot four upright rects than to stroke a path 00303 // to become the outline of the page!!! 00304 // 00305 #if 0 00306 // Set up attributes for drawing page rectangle 00307 pRender->SetLineWidth(0); // Means single-pixel lines 00308 pRender->SetLineColour(DocColour(BLACK)); 00309 pRender->SetFillColour(PageColour); 00310 00311 // Draw a rectangle covering the page 00312 pRender->DrawRect(&PageRect); 00313 00314 #else 00315 // Draw a rectangle covering the page 00316 // Set up attributes for drawing page rectangle 00317 pRender->SetLineWidth(0); // Means single-pixel lines 00318 pRender->SetLineColour(COLOUR_TRANS); 00319 00320 // randomly change page colour to see which bit is redrawing 00321 #if 0 00322 static COLORREF pc = 0x00000000; 00323 switch (pc) 00324 { 00325 case 0x007FFFFF: pc = 0x00FF7FFF; break; 00326 case 0x00FF7FFF: pc = 0x00FFFF7F; break; 00327 case 0x00FFFF7F: pc = 0x007FFFFF; break; 00328 default: pc = 0x007FFFFF; 00329 } 00330 pRender->SetFillColour(DocColour((pc>>16)&0xFF,(pc>>8)&0xFF,pc&0xFF)); 00331 #else 00332 pRender->SetFillColour(PageColour); 00333 #endif 00334 pRender->DrawRect(&PageRect); 00335 00336 00337 #ifndef NO_PAGE 00338 // This is the default non-Ralph behaviour 00339 00340 pRender->SetFillColour(COLOUR_BLACK); 00341 pRender->DrawPixelRect(&PageRect); 00342 #else 00343 // Ralph Docs only render paper in some modes 00344 00345 //find the parent NodeDocument 00346 Node* pCurrentNode = FindParent(); 00347 while(pCurrentNode != NULL) 00348 { 00349 if (pCurrentNode->IsNodeDocument()) 00350 break; 00351 pCurrentNode = pCurrentNode->FindParent(); 00352 } 00353 BaseDocument * pDoc =NULL; 00354 // get a Document * 00355 if(pCurrentNode) 00356 pDoc = ((NodeDocument*)(pCurrentNode))->GetParentDoc(); 00357 // should we render paper ? 00358 if(((Document*)pDoc)->RalphDontShowPaper()==FALSE) 00359 { 00360 pRender->SetFillColour(COLOUR_BLACK); 00361 pRender->DrawPixelRect(&PageRect); 00362 } 00363 #endif // NO_PAGE 00364 00365 #endif // simple redraw or redraw lines and page as filled rects 00366 00367 //Draw print margin 00368 //if Document::PrintSpreads ***** 00369 //DocColour Red(0.87,0,0) 00370 // DocColour Transparent(TRANS); 00371 00372 //obtain the printer margin from the PrintView 00373 // pCurrentRenderRegion->DrawRect(&PrintMarginRect) 00374 00375 // The rendering of the grid will have to wait until the grid exists. 00376 } 00377 00378 /*********************************************************************************************** 00379 > Node* Page::SimpleCopy() // Private method 00380 00381 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00382 Created: 28/4/93 00383 00384 Inputs: - 00385 Outputs: 00386 Returns: A copy of the node, or NULL if memory runs out 00387 00388 Purpose: This method returns a shallow copy of the node with all Node pointers NULL. 00389 The function is virtual, and must be defined for all derived classes. 00390 00391 Errors: If memory runs out when trying to copy, then ERROR is called with an out of memory 00392 error and the function returns NULL. 00393 00394 00395 Scope: protected 00396 **********************************************************************************************/ 00397 00398 Node* Page::SimpleCopy() 00399 { 00400 Page* NodeCopy; 00401 NodeCopy = new Page(); 00402 ERRORIF(NodeCopy == NULL, _R(IDE_NOMORE_MEMORY), NULL); 00403 CopyNodeContents(NodeCopy); 00404 return (NodeCopy); 00405 } 00406 00407 /*********************************************************************************************** 00408 > void Page::CopyNodeContents(Page* NodeCopy) 00409 00410 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00411 Created: 28/4/93 00412 00413 Inputs: - 00414 Outputs: A copy of this node 00415 00416 Returns: - 00417 00418 Purpose: This method copies the node's contents to the node pointed to by NodeCopy. 00419 00420 Errors: An assertion failure will occur if NodeCopy is NULL 00421 00422 Scope: protected 00423 00424 ***********************************************************************************************/ 00425 00426 00427 void Page::CopyNodeContents(Page* NodeCopy) 00428 { 00429 ENSURE(NodeCopy != NULL,"Trying to copy a page's contents to a NULL node"); 00430 NodeRenderablePaper::CopyNodeContents(NodeCopy); 00431 NodeCopy->PageRect = PageRect; 00432 NodeCopy->PageColour = PageColour; 00433 } 00434 00435 00436 /*********************************************************************************************** 00437 > void Page::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00438 00439 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00440 Created: 18/12/2003 00441 Outputs: - 00442 Purpose: Polymorphically copies the contents of this node to another 00443 Errors: An assertion failure will occur if NodeCopy is NULL 00444 Scope: protected 00445 00446 ***********************************************************************************************/ 00447 00448 void Page::PolyCopyNodeContents(NodeRenderable* pNodeCopy) 00449 { 00450 ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node"); 00451 ENSURE(IS_A(pNodeCopy, Page), "PolyCopyNodeContents given wrong dest node type"); 00452 00453 if (IS_A(pNodeCopy, Page)) 00454 CopyNodeContents((Page*)pNodeCopy); 00455 } 00456 00457 00458 00459 /********************************************************************************************* 00460 00461 > const DocRect& Page::GetPageRect() 00462 00463 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00464 Created: 13/5/93 00465 Inputs: - 00466 Outputs: The pages rectangle 00467 Returns: - 00468 00469 Purpose: For obtaining the page rectangle 00470 00471 Errors: 00472 00473 **********************************************************************************************/ 00474 00475 00476 const DocRect& Page::GetPageRect(void) const 00477 { 00478 return (PageRect); 00479 } 00480 00481 /********************************************************************************************* 00482 00483 > BOOL Page::SetPageRect(DocRect) 00484 00485 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00486 Created: 14/12/93 00487 Inputs: The pages rectangle 00488 Outputs: - 00489 Returns: - 00490 00491 Purpose: For setting up a new page rectangle 00492 00493 Errors: 00494 00495 **********************************************************************************************/ 00496 00497 00498 BOOL Page::SetPageRect(DocRect NewPageRect) 00499 { 00500 PageRect = NewPageRect; 00501 00502 return TRUE; 00503 } 00504 00505 00506 00507 /********************************************************************************************** 00508 00509 > Page* Page::FindNextPage(void) 00510 00511 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00512 Created: 11/5/93 00513 Inputs: - 00514 Outputs: - 00515 Returns: The next sibling page of this node, or NULL if there are none. 00516 Purpose: To find the next sibling page 00517 Errors: - 00518 SeeAlso: - 00519 00520 ***********************************************************************************************/ 00521 00522 Page* Page::FindNextPage(void) 00523 { 00524 Node* CurrentNode = FindNext(); 00525 while (CurrentNode != NULL) 00526 { 00527 if(CurrentNode->IsKindOf(CC_RUNTIME_CLASS(Page))) 00528 return ((Page*) CurrentNode); 00529 CurrentNode = CurrentNode->FindNext(); 00530 } 00531 return (NULL); // No page found 00532 } 00533 00534 /*********************************************************************************************** 00535 00536 > Page* Page::FindRightPage(void) 00537 00538 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00539 Created: 11/6/93 00540 Inputs: - 00541 Outputs: - 00542 Returns: If this page has another page joined to its right hand edge, then a 00543 pointer to the right page is returned, else NULL is returned. 00544 00545 Purpose: To find the page joined to the right of this page. 00546 Errors: - 00547 SeeAlso: Page::BottomPage 00548 ***********************************************************************************************/ 00549 00550 Page* Page::FindRightPage(void) 00551 { 00552 Page* SiblingPage = FindNextPage(); 00553 00554 if (SiblingPage != NULL) 00555 { 00556 const DocRect& SiblingPageRect = SiblingPage->GetPageRect(); 00557 00558 //For two pages joined together horizontally the hi.x of the left-hand page must 00559 //be equal to the lo.x of the right hand page, also the two pages will have 00560 //identical y coordinates (i.e. they have the same height and are in the same place 00561 //vertically. 00562 00563 // This can be optimised ** 00564 if (((PageRect.HighCorner().x) == (SiblingPageRect.LowCorner().x)) && 00565 ((PageRect.LowCorner().y ) == (SiblingPageRect.LowCorner().y)) && 00566 ((PageRect.HighCorner().y) == (SiblingPageRect.HighCorner().y)) 00567 ) 00568 return (SiblingPage); 00569 else 00570 return (NULL); 00571 } 00572 return (NULL); 00573 } 00574 00575 /*********************************************************************************************** 00576 00577 > Page* Page::FindBottomPage(void) 00578 00579 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00580 Created: 11/6/93 00581 Inputs: - 00582 Outputs: - 00583 Returns: If this page has another page joined beneath it, then a pointer to the 00584 bottom page is returned, else NULL is returned. 00585 00586 Purpose: To find the page joined to the bottom of this page. 00587 Errors: - 00588 SeeAlso: Page::RightPage 00589 00590 ***********************************************************************************************/ 00591 00592 Page* Page::FindBottomPage(void) 00593 { 00594 Page* SiblingPage = FindNextPage(); 00595 while (SiblingPage != NULL) 00596 { 00597 DocRect SiblingPageRect = SiblingPage->GetPageRect(); 00598 // For two pages joined together vertically the hi.y of the lower page must be 00599 // equal to lo.y of the upper page, also the two pages will have identical x 00600 // coordinates (i.e. they have the same width and are in the same place horizontally). 00601 // This condition could be optimised 00602 if ( ((SiblingPageRect.HighCorner().y) == (PageRect.LowCorner().y)) && 00603 ((SiblingPageRect.HighCorner().x) == (PageRect.HighCorner().x)) && 00604 ((SiblingPageRect.LowCorner().x) == (PageRect.LowCorner().x)) 00605 ) 00606 return(SiblingPage); 00607 SiblingPage = SiblingPage->FindNextPage(); 00608 } 00609 return (NULL); // No page was found to be joined beneath this page 00610 } 00611 00612 /*********************************************************************************************** 00613 00614 > void Page::CopyIntoSpread(Page* ContextPage, LinkDirection ld) 00615 00616 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00617 Created: 14/5/93 00618 Inputs: ContextPage: Page to which the copied page is to be attached 00619 ld: The direction in which the copied page is to be attached to the 00620 ContextPage 00621 Outputs: - 00622 Returns: - 00623 Purpose: To make a copy of the current page and attach it to ContextPage 00624 in the direction specified by ld. 00625 00626 (********* This fn is not finished yet it will be quite complex) 00627 Errors: - 00628 SeeAlso: - 00629 00630 ***********************************************************************************************/ 00631 00632 void Page::CopyIntoSpread(Page* ContextPage, LinkDirection ld) 00633 { 00634 } 00635 00636 #ifdef _DEBUG 00637 00638 void Page::ShowDebugTreeDetails() const 00639 { 00640 TRACE( _T("Page ")); 00641 Node::ShowDebugTreeDetails(); 00642 } 00643 00644 #endif 00645 00646 /******************************************************************************************** 00647 00648 > void Page::SetPageColour(DocColour &NewColour) 00649 00650 00651 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00652 Created: 13/7/93 00653 Inputs: NewColour: The new page colour 00654 Outputs: - 00655 Returns: - 00656 Purpose: Sets the page colour to NewColour 00657 Errors: - 00658 SeeAlso: Page::GetPageColour 00659 00660 ********************************************************************************************/ 00661 00662 void Page::SetPageColour(DocColour &NewColour) 00663 { 00664 PageColour = NewColour; 00665 } 00666 00667 /******************************************************************************************** 00668 00669 > DocColour &Page::GetPageColour(void) const 00670 00671 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00672 Created: 13/7/93 00673 Inputs: - 00674 Outputs: - 00675 Returns: The colour of a camelot page 00676 Purpose: For finding the colour of a page 00677 Errors: - 00678 SeeAlso: - 00679 00680 ********************************************************************************************/ 00681 00682 DocColour &Page::GetPageColour(void) 00683 { 00684 return (PageColour); 00685 } 00686 00687 /******************************************************************************************** 00688 00689 > void* Page::GetDebugDetails(StringBase* Str) 00690 00691 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00692 Created: 21/9/93 00693 Inputs: - 00694 Outputs: Str: String giving debug info about the node 00695 Returns: - 00696 Purpose: For obtaining debug information about the Node 00697 Errors: - 00698 SeeAlso: - 00699 00700 ********************************************************************************************/ 00701 00702 00703 void Page::GetDebugDetails(StringBase* Str) 00704 { 00705 #ifdef _DEBUG 00706 NodeRenderablePaper::GetDebugDetails(Str); 00707 String_256 TempStr; 00708 if (!PageRect.IsValid()) 00709 { 00710 TempStr = TEXT("\r\nPage Rectangle = *INVALID*\r\n"); 00711 } 00712 else 00713 TempStr._MakeMsg(TEXT("\r\nPage Rectangle\r\n Low(#1%ld, #2%ld)\r\n High(#3%ld, #4%ld)\r\n"), 00714 PageRect.LowCorner().x, 00715 PageRect.LowCorner().y, 00716 PageRect.HighCorner().x, 00717 PageRect.HighCorner().y); 00718 (*Str)+=TempStr; 00719 #endif 00720 } 00721 00722 /******************************************************************************************** 00723 00724 > virtual UINT32 Page::GetNodeSize() const 00725 00726 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00727 Created: 6/10/93 00728 Inputs: - 00729 Outputs: - 00730 Returns: The size of the node in bytes 00731 Purpose: For finding the size of the node 00732 00733 SeeAlso: Node::GetSubtreeSize 00734 00735 ********************************************************************************************/ 00736 00737 UINT32 Page::GetNodeSize() const 00738 { 00739 return (sizeof(Page)); 00740 } 00741 00742 /******************************************************************************************** 00743 00744 > INT32 Page::SnapOrdinate(INT32 Lo, INT32 Hi,INT32 Src,INT32 SnapDist) 00745 00746 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00747 Created: 12/12/95 00748 Inputs: Lo = low ordinate 00749 Hi = high ordinate 00750 Src = Source ordinate 00751 SnapDist = snap distance threshold 00752 Outputs: 00753 Returns: The snapped version of Src. 00754 00755 Purpose: This function will return either Lo, Hi, or Src depending on the following: 00756 00757 if Src is closest to Lo, and the distance is <= SnapDist, Hi is returned 00758 if Src is closest to Hi, and the distance is <= SnapDist, Hi is returned 00759 00760 Otherwise Src is returned back. 00761 Errors: 00762 Scope: public 00763 00764 ********************************************************************************************/ 00765 00766 INT32 Page::SnapOrdinate(INT32 Lo, INT32 Hi,INT32 Src,INT32 SnapDist) 00767 { 00768 INT32 DistLo = abs(Lo-Src); 00769 INT32 DistHi = abs(Hi-Src); 00770 00771 if (DistLo < DistHi) 00772 { 00773 if (DistLo <= SnapDist) 00774 Src = Lo; 00775 } 00776 else 00777 { 00778 if (DistHi <= SnapDist) 00779 Src = Hi; 00780 } 00781 00782 return Src; 00783 } 00784 00785 /******************************************************************************************** 00786 00787 > virtual BOOL Page::Snap(DocCoord* pDocCoord) 00788 00789 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00790 Created: 12/12/95 00791 Inputs: pDocCoord = a coord in Spread coords 00792 Outputs: 00793 Returns: TRUE - the DocCoord has been snapped . 00794 FALSE - the DocCoord has not been processed. 00795 00796 Purpose: Snaps to given coord to the nearest point on the page boundary 00797 Errors: 00798 Scope: public 00799 00800 ********************************************************************************************/ 00801 00802 BOOL Page::Snap(DocCoord* pDocCoord) 00803 { 00804 ERROR3IF(pDocCoord == NULL,"pDocCoord == NULL"); 00805 if (pDocCoord == NULL) return FALSE; 00806 00807 MILLIPOINT SnapDist = CSnap::GetSnapDist(); 00808 00809 DocRect BigRect = PageRect; 00810 DocRect SmallRect = PageRect; 00811 00812 BigRect.Inflate(SnapDist); 00813 SmallRect.Inflate(-SnapDist); 00814 00815 if (BigRect.ContainsCoord(*pDocCoord) && !SmallRect.ContainsCoord(*pDocCoord)) 00816 { 00817 pDocCoord->x = SnapOrdinate(PageRect.lo.x,PageRect.hi.x,pDocCoord->x,SnapDist); 00818 pDocCoord->y = SnapOrdinate(PageRect.lo.y,PageRect.hi.y,pDocCoord->y,SnapDist); 00819 00820 return TRUE; 00821 } 00822 return FALSE; 00823 } 00824 00825 /*********************************************************************************************** 00826 00827 > BOOL Page::Snap(DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 00828 00829 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00830 Created: 12/12/95 00831 Inputs: pDocCoord - the rectangle to snap 00832 StartDrag - Start coord of drag 00833 EndDrag - End coord of drag 00834 Outputs: 00835 Returns: TRUE - the DocRect been snapped. 00836 FALSE - the DocRect has not been processed. 00837 00838 Purpose: Snaps the given rect to the page, preserving its width and height. 00839 00840 It will snap the side of the rect that corresponds to the direction the 00841 mouse is moving, e.g. if the mouse is moving left, the left hand side of the 00842 rect is snapped. 00843 00844 To force the bottom left hand corner of the rect to be snapped, 00845 supply PrevCoord=(0,0) and CurCoord(-1,-1). 00846 00847 ALWAYS RETURNS FALSE currently. 00848 00849 Scope: public 00850 00851 **********************************************************************************************/ 00852 00853 BOOL Page::Snap(DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 00854 { 00855 #if !defined(EXCLUDE_FROM_RALPH) 00856 ERROR3IF(pDocRect == NULL,"pDocRect == NULL"); 00857 if (pDocRect == NULL) return FALSE; 00858 00859 DocCoord OrigCoord; 00860 00861 if (PrevCoord.x < CurCoord.x) 00862 OrigCoord.x = pDocRect->hi.x; 00863 else 00864 OrigCoord.x = pDocRect->lo.x; 00865 00866 if (PrevCoord.y < CurCoord.y) 00867 OrigCoord.y = pDocRect->hi.y; 00868 else 00869 OrigCoord.y = pDocRect->lo.y; 00870 00871 DocCoord SnapCoord = OrigCoord; 00872 00873 if (Snap(&SnapCoord)) 00874 { 00875 INT32 DeltaX = SnapCoord.x - OrigCoord.x; 00876 INT32 DeltaY = SnapCoord.y - OrigCoord.y; 00877 00878 pDocRect->Translate(DeltaX,DeltaY); 00879 00880 return TRUE; 00881 } 00882 else 00883 #endif 00884 return FALSE; 00885 } 00886 00887 //--------------------------------------------------------------- 00888 //--------------------------------------------------------------- 00889 //--------------------------------------------------------------- 00890 00891 /******************************************************************************************** 00892 00893 > virtual BOOL Page::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00894 00895 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00896 Created: 5/7/96 00897 Inputs: pFilter = ptr to the filter 00898 Returns: TRUE if record is written, FALSE if not 00899 Purpose: Writes the Page record to the filter (if it's required) 00900 SeeAlso: Node::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00901 00902 ********************************************************************************************/ 00903 00904 BOOL Page::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00905 { 00906 // This is not required in the web format 00907 return TRUE; 00908 } 00909 00910 //-------------------------------------------------------------- 00911 // See Page::WritePreChildrenWeb(BaseCamelotFilter* pFilter) 00912 // 00913 BOOL Page::WritePreChildrenNative(BaseCamelotFilter* pFilter) 00914 { 00915 #if 0 //NEW_NATIVE_FILTER // New native filters, only available to those who need them at present 00916 ERROR2IF(pFilter == NULL,FALSE,"Page - NULL filter param"); 00917 00918 // Only write out in the native file format 00919 // Just write out the position of this page as other information such as 00920 // show bleed is spread related and written in the spread information record 00921 BOOL RecordWritten = TRUE; 00922 BOOL ok = TRUE; 00923 00924 CXaraFileRecord Rec(TAG_PAGE,TAG_PAGE_SIZE); 00925 00926 ok = Rec.Init(); 00927 00928 if (ok) ok = Rec.WriteCoord(PageRect.lo); // write out low corner details 00929 if (ok) ok = Rec.WriteCoord(PageRect.hi); // write out high corner details 00930 00931 // Finally, write the record out to file 00932 // In the process get the record number that this was written out as 00933 INT32 RecordNumber = 0L; 00934 if (ok) RecordNumber = pFilter->Write(&Rec); 00935 00936 // If we have had a problem at any of the stages then return that to the caller 00937 if (!ok || RecordNumber <= 0) 00938 RecordWritten = FALSE; 00939 00940 return RecordWritten; 00941 #else 00942 return TRUE; 00943 #endif //NEW_NATIVE_FILTER 00944 } 00945