00001 // $Id: prnmks.cpp 1320 2006-06-14 14:39:32Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // 00099 // Author : Mike 00100 // Created : 23/07/96 00101 // Purpose : The PrintMarks Manager and all its helper classes. 00102 // This manager handles the caching and rendering of print marks 00103 // within a document. PrintMarks are generally only used for typesetting 00104 00105 /* 00106 */ 00107 00108 #include "camtypes.h" 00109 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "prnmks.h" 00112 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "fileutil.h" 00114 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 #include "nativeop.h" 00118 #include "layer.h" 00119 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 #include "page.h" 00121 //#include "nodeattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 #include "colormgr.h" 00123 #include "prnmkcom.h" 00124 #include "qualattr.h" 00125 //#include "matrix.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00126 #include "dbugtree.h" 00127 //#include "paths.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00128 #include "cctime.h" 00129 #include "nodetxts.h" 00130 #include "nodetxtl.h" 00131 #include "colplate.h" 00132 #include "printctl.h" 00133 #include "fontman.h" 00134 #include "psrndrgn.h" 00135 #include "psdc.h" 00136 //#include "printstr.h" 00137 #include <stdlib.h> 00138 00139 CC_IMPLEMENT_MEMDUMP(LoadPrintMarks, LoadDirect); 00140 CC_IMPLEMENT_MEMDUMP(PrintMarksMan, CC_CLASS_MEMDUMP); 00141 CC_IMPLEMENT_MEMDUMP(PrintMarksCache, CC_CLASS_MEMDUMP); 00142 CC_IMPLEMENT_MEMDUMP(PrintMark, CC_CLASS_MEMDUMP); 00143 CC_IMPLEMENT_DYNCREATE(MarkPosition, ListItem); 00144 CC_IMPLEMENT_DYNCREATE(PrintMarkItem, ListItem); 00145 CC_IMPLEMENT_MEMDUMP(MarkFormatRegion, CC_CLASS_MEMDUMP); 00146 CC_IMPLEMENT_DYNCREATE(PageRect, ListItem); 00147 CC_IMPLEMENT_DYNAMIC(PageRectList, List); 00148 00149 DECLARE_SOURCE("$Revision: 1320 $"); 00150 00151 #define new CAM_DEBUG_NEW 00152 00153 00154 /***************************************************************************************** 00155 00156 > MarkFormat::MarkFormat() 00157 00158 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00159 Created: 23/07/96 00160 Purpose: Construct a Mark format object 00161 00162 *****************************************************************************************/ 00163 00164 MarkFormat::MarkFormat() 00165 { 00166 Top = Middle = Bottom = FALSE; 00167 Left = Centre = Right = FALSE; 00168 } 00169 00170 BOOL MarkFormat::IsValid() const 00171 { 00172 return (Top || Middle || Bottom || Left || Centre || Right); 00173 } 00174 00175 void MarkFormat::MakeValid() 00176 { 00177 Centre = Middle = TRUE; 00178 Top = Bottom = Left = Right = FALSE; 00179 } 00180 00181 INT32 operator==(const MarkFormat& x, const MarkFormat& y) 00182 { 00183 return ( (x.Centre == y.Centre) && 00184 (x.Middle == y.Middle) && 00185 (x.Left == y.Left) && 00186 (x.Right == y.Right) && 00187 (x.Top == y.Top) && 00188 (x.Bottom == y.Bottom) 00189 ); 00190 } 00191 00192 00193 00194 /***************************************************************************************** 00195 00196 > BYTE MarkFormat::GetAsFlagByte(void) 00197 00198 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00199 Created: 6/9/96 00200 00201 Returns: A Byte with bits set for each of the mark formats available 00202 00203 Purpose: Fill in a mark format object from a "flags byte" 00204 Used for native file load/save 00205 00206 SeeAlso: MarkFormat::SetFromFlagByte 00207 00208 *****************************************************************************************/ 00209 00210 BYTE MarkFormat::GetAsFlagByte(void) 00211 { 00212 BYTE Flags = 0; 00213 00214 if (Left) Flags |= 0x01; 00215 if (Centre) Flags |= 0x02; 00216 if (Right) Flags |= 0x04; 00217 if (Top) Flags |= 0x08; 00218 if (Middle) Flags |= 0x10; 00219 if (Bottom) Flags |= 0x20; 00220 00221 return(Flags); 00222 } 00223 00224 00225 00226 /***************************************************************************************** 00227 00228 > void MarkFormat::SetFromFlagByte(BYTE Flags) 00229 00230 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00231 Created: 6/9/96 00232 00233 Inputs: Flags - A Byte with bits set for each of the mark formats available 00234 00235 Purpose: Fill in a mark format object from a "flags byte" 00236 Used for native file load/save 00237 00238 SeeAlso: MarkFormat::GetAsFlagByte 00239 00240 *****************************************************************************************/ 00241 00242 void MarkFormat::SetFromFlagByte(BYTE Flags) 00243 { 00244 Left = (Flags & 0x01) ? TRUE : FALSE; 00245 Centre = (Flags & 0x02) ? TRUE : FALSE; 00246 Right = (Flags & 0x04) ? TRUE : FALSE; 00247 Top = (Flags & 0x08) ? TRUE : FALSE; 00248 Middle = (Flags & 0x10) ? TRUE : FALSE; 00249 Bottom = (Flags & 0x20) ? TRUE : FALSE; 00250 } 00251 00252 00253 00254 00255 00256 /***************************************************************************************** 00257 00258 > MarkPosition::MarkPosition() 00259 00260 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00261 Created: 23/07/96 00262 Purpose: Construct a mark position object 00263 00264 *****************************************************************************************/ 00265 00266 MarkPosition::MarkPosition() 00267 { 00268 Initialise(); 00269 } 00270 00271 00272 /***************************************************************************************** 00273 00274 > void MarkPosition::Initialise() 00275 00276 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00277 Created: 23/07/96 00278 Purpose: Initialise all the local variables in this mark position 00279 00280 *****************************************************************************************/ 00281 00282 void MarkPosition::Initialise() 00283 { 00284 Region = MarkRegion_TopLeft; 00285 } 00286 00287 00288 /***************************************************************************************** 00289 00290 > BOOL MarkPosition::IsEqualTo(const MarkPosition* pOther) const 00291 00292 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00293 Created: 23/07/96 00294 Inputs: pOther = a pointer to a mark position to match 00295 Returns: TRUE if pOther is identical to this mark 00296 FALSE if not 00297 Purpose: Check whether another mark position is identical to this one 00298 00299 *****************************************************************************************/ 00300 00301 BOOL MarkPosition::IsEqualTo(const MarkPosition* pOther) const 00302 { 00303 ERROR2IF(pOther==NULL, FALSE, "NULL pointer passed to MarkPosition::IsEqualTo"); 00304 return ( (Region == pOther->Region) && 00305 (Format == pOther->Format) 00306 ); 00307 } 00308 00309 00310 /***************************************************************************************** 00311 00312 > PrintMark::PrintMark 00313 00314 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00315 Created: 23/07/96 00316 Purpose: Construct a new print mark 00317 00318 *****************************************************************************************/ 00319 00320 PrintMark::PrintMark() 00321 { 00322 MarkIsCustom = FALSE; 00323 IDByte = 0; 00324 Type = MarkType_Unknown; 00325 Orientation = MO_None; 00326 OnAsDefault = FALSE; 00327 } 00328 00329 00330 /***************************************************************************************** 00331 00332 > virtual PrintMark::~PrintMark() 00333 00334 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00335 Created: 23/07/96 00336 Purpose: virtual destructor, destroys all instances of the 'MarkPositions' list 00337 00338 *****************************************************************************************/ 00339 00340 PrintMark::~PrintMark() 00341 { 00342 MarkPosition* pMarkPos; 00343 while ((pMarkPos=(MarkPosition*)MarkPositions.RemoveTail())) 00344 delete pMarkPos; 00345 } 00346 00347 00348 00349 /***************************************************************************************** 00350 00351 > void PrintMark::SetMarkMenuText(const String_256* pMenuText) 00352 00353 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00354 Created: 23/07/96 00355 Inputs: pMenuText = a pointer to a string containing the textual description of 00356 the print mark, (may be used in menus). 00357 Purpose: Set this print mars menu text 00358 00359 *****************************************************************************************/ 00360 00361 void PrintMark::SetMarkMenuText(const String_256* pMenuText) 00362 { 00363 ERROR3IF(pMenuText==NULL,"ERROR ERROR, NULL pointer passed to SetMarkMenuText"); 00364 if (pMenuText!=NULL) 00365 MenuText = (*pMenuText); 00366 } 00367 00368 00369 /***************************************************************************************** 00370 00371 > String_256 PrintMark::GetMarkMenuText() const 00372 00373 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00374 Created: 23/07/96 00375 Inputs: - 00376 Returns: This print marks textual description 00377 Purpose: Return the menu text string saved in this print mark 00378 00379 *****************************************************************************************/ 00380 00381 String_256 PrintMark::GetMarkMenuText() const 00382 { 00383 return MenuText; 00384 } 00385 00386 00387 /***************************************************************************************** 00388 00389 > void PrintMark::AddNewPosition(MarkPosition* pNewMarkPos) 00390 00391 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00392 Created: 23/07/96 00393 Inputs: pNewMarkPos, a pointer to a new mark position 00394 Returns: This print marks textual description 00395 Purpose: Return the menu text string saved in this print mark 00396 00397 *****************************************************************************************/ 00398 00399 void PrintMark::AddNewPosition(MarkPosition* pNewMarkPos) 00400 { 00401 ERROR3IF(pNewMarkPos==NULL,"NULL MarkPosition pointer passed to AddNewPosition"); 00402 if (pNewMarkPos) 00403 { 00404 if (!FindMarkPosition(pNewMarkPos)) 00405 MarkPositions.AddTail(pNewMarkPos); 00406 } 00407 } 00408 00409 /***************************************************************************************** 00410 00411 > BOOL PrintMark::FindMarkPosition(const MarkPosition* pSearchMark, MarkPosition** pFoundMark=NULL) const 00412 00413 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00414 Created: 23/07/96 00415 Inputs: pSearchMark = a pointer to a print mark to search for 00416 pFoundMark, a pointer to a pointer to be set on exit. This defaults to null 00417 when we're only interested in whether the mark exists or not. 00418 00419 Outputs: pFoundMark set to a pointer to the print mark in the cache if we find it 00420 pFoundMark set to NULL if no match found 00421 00422 Returns: TRUE if there is a mark in the cache identical to this search mark 00423 FALSE if there isn't 00424 Purpose: Check the cache to see if there's a mark already in it which matches 00425 pSearchMark. You can get the pointer to this cached mark by using pFoundMark 00426 00427 *****************************************************************************************/ 00428 00429 BOOL PrintMark::FindMarkPosition(const MarkPosition* pSearchMark, MarkPosition** pFoundMark) const 00430 { 00431 ERROR3IF(pSearchMark==NULL,"PrintMark::FindMarkPosition passed a NULL search mark pointer"); 00432 if (pSearchMark) 00433 { 00434 MarkPosition* pMarkPos = GetFirstPosition(); 00435 while (pMarkPos) 00436 { 00437 // Check to see if this exists 00438 if (pSearchMark->IsEqualTo(pMarkPos)) 00439 { 00440 if (pFoundMark!=NULL) 00441 (*pFoundMark=pMarkPos); 00442 return TRUE; 00443 } 00444 pMarkPos = GetNextPosition(pMarkPos); 00445 } 00446 } 00447 if (pFoundMark!=NULL) 00448 (*pFoundMark=NULL); 00449 return FALSE; 00450 } 00451 00452 /***************************************************************************************** 00453 00454 > BOOL PrintMark::IsSimilarTo(const PrintMark* pOther) const 00455 00456 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00457 Created: 23/07/96 00458 Inputs: pOther, a pointer to another print mark 00459 Returns: TRUE if this print mark is similar to pOther. 00460 FALSE if not 00461 Purpose: Checks whether this print mark is similar to pOther. The current checks 00462 for similarity are... 00463 (1) the mark is of the same type 00464 (2) the mark has the same menu text 00465 00466 *****************************************************************************************/ 00467 00468 BOOL PrintMark::IsSimilarTo(const PrintMark* pOther) const 00469 { 00470 ERROR2IF(pOther==NULL, FALSE, "NULL PrintMark pointer passed to IsSimilar()"); 00471 00472 if (Type == pOther->GetType()) 00473 { 00474 if (MenuText == pOther->GetMarkMenuText()) 00475 return TRUE; 00476 } 00477 return FALSE; 00478 } 00479 00480 00481 00482 /***************************************************************************************** 00483 00484 > PrintMarkItem::PrintMarkItem 00485 00486 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00487 Created: 23/07/96 00488 Purpose: Construct a new print mark item 00489 00490 *****************************************************************************************/ 00491 00492 PrintMarkItem::PrintMarkItem() 00493 { 00494 pMarkGlyph = NULL; 00495 Handle = 0; 00496 Saveable = TRUE; 00497 Renderable = TRUE; 00498 } 00499 00500 00501 /***************************************************************************************** 00502 00503 > PrintMarkItem::~PrintMarkItem 00504 00505 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00506 Created: 23/07/96 00507 Purpose: destruct a print mark item 00508 00509 *****************************************************************************************/ 00510 00511 PrintMarkItem::~PrintMarkItem() 00512 { 00513 RemoveMark(); 00514 } 00515 00516 00517 00518 00519 /***************************************************************************************** 00520 00521 BOOL PrintMarkItem::SetMarkGlyph(NodeGroup* pNewMark, BOOL MakeCopy=FALSE) 00522 00523 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00524 Created: 23/07/96 00525 Inputs: pNewMark = A pointer to a group node containing the mark. 00526 The node should still be in the tree. 00527 MakeCopy = TRUE, the mark will be left where it is and an 00528 attribute complete copy will be made. 00529 FALSE, the mark will be extracted from the document as is. 00530 Purpose: Cache a print mark in this print mark item. The mark pointer should be 00531 a group held in the document tree. As we attempt to make attributes 00532 complete on this group, it has to be in the tree. MakeCopy which defaults 00533 to FALSE will, when TRUE, copy the entire group and used the copy, hence 00534 it will leave the document unaffected. When FALSE the group will be 00535 extracted from the tree. This is only acceptable in a few circumstances 00536 when undo is not being generated. 00537 00538 *****************************************************************************************/ 00539 00540 BOOL PrintMarkItem::SetMarkGlyph(NodeGroup* pNewMark, BOOL MakeCopy) 00541 { 00542 ERROR2IF(pNewMark==NULL,FALSE, "NULL mark pointer passed to SetMark"); 00543 00544 if (MakeCopy) 00545 { 00546 NodeGroup* pNewGroup = new NodeGroup; 00547 if (pNewGroup==NULL) 00548 return FALSE; 00549 00550 NodeGroup* pNewGroup1 = new NodeGroup; 00551 if (pNewGroup1==NULL) 00552 { 00553 delete pNewGroup; 00554 return FALSE; 00555 } 00556 00557 // attach this new group to the tree 00558 pNewGroup->AttachNode(pNewMark,NEXT); 00559 pNewGroup1->AttachNode(pNewGroup,FIRSTCHILD); 00560 00561 // copy the children across to this new group 00562 if (!pNewMark->CopyChildrenTo(pNewGroup1)) 00563 { 00564 // CascadeDelete unlinks the node from the tree so don't panic. 00565 pNewGroup->CascadeDelete(); 00566 delete pNewGroup; 00567 return FALSE; 00568 } 00569 00570 // make sure we have all the attributes we're gonna need 00571 if (!pNewGroup->MakeAttributeComplete(NULL,TRUE,NULL,TRUE)) 00572 { 00573 pNewGroup->CascadeDelete(); 00574 delete pNewGroup; 00575 return FALSE; 00576 } 00577 00578 // dump the tree out 00579 //TRACEUSER( "Mike", _T("Dumping subtree contents\n\n")); 00580 //DebugTreeDlg::DumpSubTree(pNewGroup); 00581 00582 // rip the node out of the tree and stick it in our cache. 00583 pNewGroup->UnlinkNodeFromTree(); 00584 00585 // Make sure we get rid of any previously cached mark 00586 if (pMarkGlyph!=NULL) 00587 RemoveMark(); 00588 00589 pMarkGlyph = pNewGroup; 00590 } 00591 else 00592 { 00593 if (!pNewMark->MakeAttributeComplete(NULL,TRUE,NULL,TRUE)) 00594 return FALSE; 00595 00596 pNewMark->UnlinkNodeFromTree(); 00597 00598 // Make sure we get rid of any previously cached mark 00599 if (pMarkGlyph!=NULL) 00600 RemoveMark(); 00601 00602 pMarkGlyph = pNewMark; 00603 } 00604 00605 return TRUE; 00606 } 00607 00608 00609 /***************************************************************************************** 00610 00611 > void PrintMarkItem::RemoveMark() 00612 00613 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00614 Created: 23/07/96 00615 Purpose: Remove the cached mark from our list structure. This is generally 00616 called when the mark item is destroyed. 00617 00618 *****************************************************************************************/ 00619 00620 void PrintMarkItem::RemoveMark() 00621 { 00622 // check to see if we have a sub tree here 00623 if (pMarkGlyph!=NULL) 00624 { 00625 Node* pNode = pMarkGlyph->FindFirstChild(); 00626 if (pNode!=NULL) 00627 pMarkGlyph->DeleteChildren(pNode); 00628 } 00629 delete pMarkGlyph; 00630 pMarkGlyph = NULL; 00631 } 00632 00633 00634 INT32 PrintMarkItem::GetWidth() const 00635 { 00636 if (pMarkGlyph!=NULL) 00637 { 00638 DocRect bounds = pMarkGlyph->GetBoundingRect(); 00639 return bounds.Width(); 00640 } 00641 return 0; 00642 } 00643 00644 INT32 PrintMarkItem::GetHeight() const 00645 { 00646 if (pMarkGlyph!=NULL) 00647 { 00648 DocRect bounds = pMarkGlyph->GetBoundingRect(); 00649 return bounds.Height(); 00650 } 00651 return 0; 00652 } 00653 00654 DocCoord PrintMarkItem::GetOrigin() const 00655 { 00656 if (pMarkGlyph!=NULL) 00657 { 00658 DocRect bounds = pMarkGlyph->GetBoundingRect(); 00659 return bounds.lo; 00660 } 00661 return DocCoord(0,0); 00662 } 00663 00664 00665 MarkOrient PrintMarkItem::GetOrient() const 00666 { 00667 return Mark.GetOrientation(); 00668 } 00669 00670 00671 BOOL PrintMarkItem::DefaultsToOn() const 00672 { 00673 return Mark.DefaultsToOn(); 00674 } 00675 00676 00677 BOOL PrintMarkItem::NeedsSaving() const 00678 { 00679 return Saveable; 00680 } 00681 00682 00683 void PrintMarkItem::SetSaveable(BOOL savestate) 00684 { 00685 Saveable = savestate; 00686 } 00687 00688 BOOL PrintMarkItem::NeedsToRender() const 00689 { 00690 return Renderable; 00691 } 00692 00693 void PrintMarkItem::SetRenderable(BOOL renderstate) 00694 { 00695 Renderable = renderstate; 00696 } 00697 00698 00699 00700 /***************************************************************************************** 00701 00702 > PrintMarksCache::PrintMarksCache() 00703 00704 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00705 Created: 23/07/96 00706 Purpose: Construct the PrintMarksCache object. This used to be part of the print 00707 marks manager but I've now split it into its own class to prevent 00708 confusion with the handling of cache marks and document marks. Various 00709 functions do similar things so it could become confusing without a 00710 scope resolution operator PMMCache::FindMark as opposed to Doc::FindMark 00711 00712 *****************************************************************************************/ 00713 00714 PrintMarksCache::PrintMarksCache() 00715 { 00716 NextHandle=0; 00717 TextInfoHandle=0; 00718 CropMarkHandle=0; 00719 } 00720 00721 00722 /***************************************************************************************** 00723 00724 > PrintMarksCache::~PrintMarksCache() 00725 00726 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00727 Created: 23/07/96 00728 Purpose: Destroys the cached marks completely 00729 00730 *****************************************************************************************/ 00731 00732 PrintMarksCache::~PrintMarksCache() 00733 { 00734 Invalidate(); 00735 } 00736 00737 00738 /***************************************************************************************** 00739 00740 > PrintMarksCache::~PrintMarksCache() 00741 00742 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00743 Created: 23/07/96 00744 Purpose: Invalidate the cache list. If we do this, all the mark references 00745 in existing document will reference nothing. As we create new marks 00746 new handles will be built, so it might be necessary to delete references 00747 made in all doc components. 00748 Use with care. 00749 00750 *****************************************************************************************/ 00751 00752 void PrintMarksCache::Invalidate() 00753 { 00754 // destroy all marks in the cache. 00755 PrintMarkItem* pItem; 00756 while ((pItem=(PrintMarkItem*)PrintMarkCache.RemoveTail())) // assignment 00757 delete pItem; 00758 // Make sure the crop and text info handles don't reference anything 00759 CropMarkHandle=0; 00760 TextInfoHandle=0; 00761 } 00762 00763 00764 /***************************************************************************************** 00765 00766 > UINT32 PrintMarksCache::GetUniqueHandle() 00767 00768 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00769 Created: 23/07/96 00770 Inputs: - 00771 Returns: A handle used to reference a unique print mark 00772 Purpose: Generate a unique print mark handle. All handles will be >=1 and hence 00773 an illegal handle is given the value 0. 00774 00775 *****************************************************************************************/ 00776 00777 UINT32 PrintMarksCache::GetUniqueHandle() 00778 { 00779 NextHandle++; 00780 return (NextHandle); 00781 } 00782 00783 00784 00785 /***************************************************************************************** 00786 00787 > PrintMarkItem* PrintMarksCache::GetFirstMark() const 00788 00789 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00790 Created: 23/07/96 00791 Inputs: - 00792 Returns: A pointer to the first cached mark 00793 Purpose: Return a pointer to the first cached mark 00794 00795 *****************************************************************************************/ 00796 00797 PrintMarkItem* PrintMarksCache::GetFirstMark() const 00798 { 00799 return ((PrintMarkItem*)PrintMarkCache.GetHead()); 00800 } 00801 00802 00803 /***************************************************************************************** 00804 00805 > PrintMarkItem* PrintMarksCache::GetNextMark(PrintMarkItem* pCurrMark) const 00806 00807 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00808 Created: 23/07/96 00809 Inputs: A pointer to a print mark item 00810 Returns: A pointer to the next print mark item after this 00811 Purpose: Returns the next print mark item beyond pCurrMark 00812 00813 *****************************************************************************************/ 00814 00815 PrintMarkItem* PrintMarksCache::GetNextMark(PrintMarkItem* pCurrMark) const 00816 { 00817 return ((PrintMarkItem*)PrintMarkCache.GetNext(pCurrMark)); 00818 } 00819 00820 00821 /***************************************************************************************** 00822 00823 > BOOL PrintMarksCache::DoesMarkExist(PrintMark* pCheckMark) const 00824 00825 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00826 Created: 23/07/96 00827 Inputs: A pointer to a print mark 00828 Returns: TRUE if this mark already exists in the cache 00829 FALSE if not 00830 Purpose: Try to find a print mark in the cache 00831 00832 *****************************************************************************************/ 00833 00834 BOOL PrintMarksCache::DoesMarkExist(PrintMark* pCheckMark) const 00835 { 00836 PrintMarkItem* pItem = GetFirstMark(); 00837 while (pItem) 00838 { 00839 PrintMark* pCurrMark = pItem->GetPrintMark(); 00840 if (pCheckMark->IsSimilarTo(pCurrMark)) 00841 return TRUE; 00842 pItem = GetNextMark(pItem); 00843 } 00844 return FALSE; 00845 } 00846 00847 00848 /***************************************************************************************** 00849 00850 > PrintMarkItem* PrintMarksCache::FindMark(UINT32 SearchHandle) 00851 00852 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00853 Created: 23/07/96 00854 Inputs: SearchHandle = the handle of the mark to search for 00855 Returns: A pointer to the print mark described by this handle (NULL if none) 00856 Purpose: Try to find a print mark in the cache, using its handle 00857 00858 *****************************************************************************************/ 00859 00860 PrintMarkItem* PrintMarksCache::FindMark(UINT32 SearchHandle) 00861 { 00862 PrintMarkItem* pItem = GetFirstMark(); 00863 while (pItem) 00864 { 00865 if (pItem->GetHandle() == SearchHandle) 00866 return pItem; 00867 pItem = GetNextMark(pItem); 00868 } 00869 return NULL; 00870 } 00871 00872 00873 00874 00875 /***************************************************************************************** 00876 00877 > BOOL PrintMarksCache::DecodeCachedLayers(Document* pDocument) 00878 00879 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00880 Created: 23/07/96 00881 Inputs: pDocument = a pointer to a document 00882 Returns: TRUE if the document has been processed 00883 00884 Purpose: Given a document, we scan each layer in the document. For each layer 00885 we check the loaded layer name. If the layer name contains a % at the 00886 begining (meaning its a format string) and the format is PRINTMARK, we 00887 take the first group in the layer (+ all its contents) and assign a 00888 new print mark item to this group. This group object will (if successfully) 00889 loaded, become a new print mark. 00890 00891 *****************************************************************************************/ 00892 00893 BOOL PrintMarksCache::DecodeCachedLayers(Document* pDocument) 00894 { 00895 ERROR2IF(pDocument==NULL,FALSE,"NULL Layer passed to DecodeCachedLayer"); 00896 00897 Spread* pSpread = pDocument->FindFirstSpread(); 00898 Layer* pLayer; 00899 while (pSpread!=NULL) 00900 { 00901 pLayer = pSpread->FindFirstLayer(); 00902 while (pLayer!=NULL) 00903 { 00904 DecodeCachedLayer(pLayer); 00905 pLayer = pLayer->FindNextLayer(); // Find next layer 00906 } 00907 pSpread = pSpread->FindNextSpread(); 00908 } 00909 return TRUE; 00910 } 00911 00912 00913 /***************************************************************************************** 00914 00915 > BOOL PrintMarksMan::DecodeCachedLayer(Layer* pLayer) 00916 00917 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00918 Created: 23/07/96 00919 Inputs: pLayer = a pointer to a layer 00920 Returns: TRUE if the layer has been processed 00921 Purpose: Given a layer, if the layer contains a print mark, strip the print mark 00922 out and try to add it to the PrintMarksMan cache. 00923 00924 *****************************************************************************************/ 00925 00926 BOOL PrintMarksCache::DecodeCachedLayer(Layer* pLayer) 00927 { 00928 ERROR2IF(pLayer==NULL,FALSE,"NULL Layer passed to DecodeCachedLayer"); 00929 00930 // Read in the layer name 00931 String_256 Name; 00932 String_16 Token; 00933 00934 Name = pLayer->GetLayerID(); 00935 Name.Left(&Token, 10); 00936 00937 BOOL IsValid = FALSE; 00938 BOOL IsCustomMark = FALSE; 00939 if (Token == String_16(_T("%PRINTMARK"))) // This text must not be internationalised 00940 IsValid = TRUE; 00941 00942 if (!IsValid && Token == String_16(_T("%CUSTOMMAR"))) // This text must not be internationalised 00943 { 00944 IsValid = TRUE; 00945 IsCustomMark = TRUE; 00946 } 00947 00948 if (!IsValid) 00949 return FALSE; 00950 00951 // find the first renderable group in this layer. 00952 NodeGroup* pGroup = (NodeGroup*)pLayer->FindFirstChild(CC_RUNTIME_CLASS(NodeGroup)); 00953 if (pGroup==NULL) 00954 return FALSE; 00955 00956 // Create a new mark structure to put the decoded data into 00957 PrintMarkItem* pNewMark = new PrintMarkItem; 00958 if (!pNewMark) 00959 return FALSE; 00960 00961 PrintMark* pMark = pNewMark->GetPrintMark(); 00962 pMark->SetCustomOrDefault(IsCustomMark); // Remember if it's a custom or default mark 00963 if (!DecodeMarkFormat(&Name, pMark)) 00964 { 00965 delete pNewMark; 00966 return FALSE; 00967 } 00968 00969 // Right we have a new print mark descriptor, 00970 // we simply merge the mark into the 00971 // cache. It would be faster, before copying the subtree, to check whether we 00972 // dont already have this mark cached in the print mark manager. 00973 00974 if (DoesMarkExist(pMark)) 00975 { 00976 delete pNewMark; 00977 return TRUE; 00978 } 00979 00980 // Add a handle to this mark 00981 pNewMark->SetHandle(GetUniqueHandle()); 00982 00983 // ok the mark does not exist, so now look for that first group 00984 if (!pNewMark->SetMarkGlyph(pGroup, TRUE)) 00985 { 00986 delete pNewMark; 00987 return FALSE; 00988 } 00989 00990 // Hey hey, we've finally done it! cool! 00991 PrintMarkCache.AddTail(pNewMark); 00992 00993 return TRUE; 00994 } 00995 00996 00997 /***************************************************************************************** 00998 00999 > UINT32 PrintMarksCache::AddNewMark(PrintMarkItem* pNewMark, NodeGroup* pGroup) 01000 01001 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01002 Created: 23/07/96 01003 Inputs: pNewMark = a pointer to the new mark to add 01004 pGroup = a pointer to the glyph to use. 01005 Returns: The handle of the newly added mark 01006 Purpose: A simple way of adding a prebuilt mark to the list. The mark must be in 01007 a renderable format, in that it should be a group with all needed attrs 01008 as children, followed by a child group containing all the ink objects 01009 01010 *****************************************************************************************/ 01011 01012 UINT32 PrintMarksCache::AddNewMark(PrintMarkItem* pNewMark, NodeGroup* pGroup) 01013 { 01014 // Add a handle to this mark 01015 UINT32 hndle = GetUniqueHandle(); 01016 pNewMark->SetHandle(hndle); 01017 pNewMark->pMarkGlyph = pGroup; 01018 // Hey hey, we've finally done it! cool! 01019 PrintMarkCache.AddTail(pNewMark); 01020 return hndle; 01021 } 01022 01023 01024 /***************************************************************************************** 01025 01026 > void PrintMarksCache::UpdateMarkGlyph(PrintMarkItem *pMarkItem, NodeGroup *pGroup) 01027 01028 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01029 Created: 23/07/96 01030 Inputs: pMarkItem = a pointer to an existing cached mark 01031 pGroup = a pointer to a new glyph to use. 01032 Returns: - 01033 Purpose: Change the mark glyph to this new mark. 01034 01035 *****************************************************************************************/ 01036 01037 void PrintMarksCache::UpdateMarkGlyph(PrintMarkItem *pMarkItem, NodeGroup *pGroup) 01038 { 01039 if (pMarkItem!=NULL) 01040 { 01041 // Make sure there's nothing in there at the mo. 01042 pMarkItem->RemoveMark(); 01043 // now set the new mark glyph 01044 pMarkItem->pMarkGlyph = pGroup; 01045 } 01046 } 01047 01048 01049 01050 /***************************************************************************************** 01051 01052 > BOOL PrintMarksCache::DecodeMarkFormat(const String_256 *pFormatString, PrintMark* pMark) 01053 01054 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01055 Created: 23/07/96 01056 Inputs: pFormatString 01057 Outputs: pMark 01058 Returns: TRUE if the format string was valid. 01059 Purpose: Decode the string pointed to by pFormatString, placing each format 01060 identifier into the output mark. 01061 01062 Special tag Mark name ID On/off Type Position(s) 01063 %PRINTMARK = "Registration mark", 3, 1, _R(ID_STAR), 3MCS + 7MC + 11MCS + 15MC 01064 %CUSTOMMARK = "User registration mark", 0, 1, _R(ID_STAR), 3MCS + 7MC + 11MCS + 15MC 01065 01066 *****************************************************************************************/ 01067 01068 BOOL PrintMarksCache::DecodeMarkFormat(const String_256 *pFormatString, PrintMark* pMark) 01069 { 01070 ERROR2IF(pFormatString == NULL, FALSE, "NULL pointer passed to DecodeMarkFormat"); 01071 ERROR2IF(pMark == NULL, FALSE, "NULL mark pointer passed to DecodeMarkFormat"); 01072 01073 String_256 Name(*pFormatString); 01074 String_256 MenuText; 01075 String_256 MenuID; 01076 MarkFormat NewFormat; 01077 MarkRegion NewRegion; 01078 MarkOrient NewOrient; 01079 01080 const TCHAR COMMA = TEXT(','); // This text must not be internationalised 01081 // const TCHAR EQUALS = TEXT('='); 01082 const TCHAR QUOTES = TEXT('"'); 01083 const TCHAR PLUS = TEXT('+'); 01084 const TCHAR SPACE = TEXT(' '); 01085 01086 INT32 pos, pos1; 01087 01088 // Everything is hunky dory at the moment! ER NOT! 01089 BOOL AllIsWell = FALSE; 01090 01091 // Turn on the exceptions function in the string reading class 01092 StringBase::EnableExceptionHandler(); 01093 01094 //try 01095 { 01096 // toast everything up to the first quote 01097 pos = Name.FindNextChar(QUOTES); 01098 Name.Remove(0,pos+1); 01099 01100 // now find the last quote of the first string 01101 pos = Name.FindNextChar(QUOTES); 01102 Name.Left(&MenuText,pos); 01103 Name.Remove(0,pos+1); 01104 01105 // skip over the first comma onto the ID field 01106 pos = Name.SkipComma(); 01107 Name.Remove(0,pos); 01108 pos = 0; 01109 INT32 ID = Name.ConvertToInteger(pos); 01110 Name.Remove(0,pos); 01111 if (ID < 0 || ID > 255) 01112 ID = 0; 01113 pMark->SetIDByte((BYTE)ID); 01114 01115 // skip over the next comma onto the enable/disable state 01116 pos = Name.SkipComma(); 01117 Name.Remove(0,pos); 01118 BOOL Enabled = (Name[0] == TEXT('1')); 01119 01120 // skip comma to next field 01121 pos = Name.SkipComma(); 01122 pos1 = Name.FindNextChar(COMMA, pos+1); 01123 Name.Mid(&MenuID, pos, (pos1-pos)); 01124 Name.Remove(0,pos1+1); 01125 01126 // turn the menu id into a type of mark if we recognise it 01127 MarkType actid = (MarkType)DecodeToMarkType(&MenuID); 01128 01129 // skip the orientation field 01130 pos=Name.FindNextChar(); 01131 NewOrient=MO_None; 01132 if (Name[pos] == TEXT('H')) 01133 NewOrient=MO_Horizontal; 01134 else if (Name[pos] == TEXT('V')) 01135 NewOrient=MO_Vertical; 01136 01137 // remove the orientation bit 01138 pos = Name.SkipComma(); 01139 01140 // Add what we have so far 01141 pMark->SetMarkMenuText(&MenuText); 01142 pMark->SetOrientation(NewOrient); 01143 pMark->SetType(actid); 01144 pMark->SetDefaultState(Enabled); 01145 01146 // The remainder of this string is a format list 01147 // BOOL format=FALSE; 01148 // BOOL eos=FALSE; 01149 01150 // Turn our exception handler off but don't pop it. 01151 StringBase::DisableExceptionHandler(FALSE); 01152 01153 INT32 region; 01154 01155 while (pos>0) 01156 { 01157 // Try to create a new mark to add 01158 MarkPosition* pNewMark = new MarkPosition; 01159 01160 if (pNewMark!=NULL) 01161 { 01162 region = Name.ConvertToInteger(pos); 01163 01164 if (region<1 || region>MAXPAGEREGIONS) 01165 { 01166 // Ok, the region number is out of range so lets 01167 // skip to the next one (if there is one!) 01168 // we need to find the next + 01169 delete pNewMark; 01170 pos = Name.FindNextChar(PLUS, pos); 01171 } 01172 else 01173 { 01174 // store this type of region 01175 NewRegion = (MarkRegion)(region-1); 01176 pNewMark->SetRegion(NewRegion); 01177 01178 // if we haven't run off the end of the string 01179 while ( Name.IsLegal(pos) && (Name[pos]!=PLUS) ) 01180 { 01181 TCHAR c = Name[pos]; 01182 01183 switch (c) 01184 { 01185 case TEXT('T'): NewFormat.Top=TRUE; break; 01186 case TEXT('M'): NewFormat.Middle=TRUE; break; 01187 case TEXT('B'): NewFormat.Bottom=TRUE; break; 01188 case TEXT('L'): NewFormat.Left=TRUE; break; 01189 case TEXT('C'): NewFormat.Centre=TRUE; break; 01190 case TEXT('R'): NewFormat.Right=TRUE; break; 01191 default: 01192 // unknown token, just ignore it! 01193 if (c != SPACE) 01194 TRACEUSER( "Mike", _T("Unknown format character during PrintMarksMan::DecodeMarkFormat")); 01195 break; 01196 } 01197 01198 pos = Name.FindNextChar(pos+1); 01199 } 01200 01201 // make sure the format is ok 01202 if (!NewFormat.IsValid()) 01203 NewFormat.MakeValid(); 01204 01205 // and set it in the structure. 01206 pNewMark->SetFormat(NewFormat); 01207 01208 // Add the new mark position to the list. 01209 pMark->AddNewPosition(pNewMark); 01210 01211 AllIsWell=TRUE; 01212 01213 if (Name.IsLegal(pos)) 01214 pos = Name.FindNextChar(pos+1); 01215 } 01216 } 01217 else 01218 { 01219 pos = -1; 01220 } 01221 } 01222 } 01223 PORTNOTE("other", "Disabled random use of MFC CUserException in Kernel code") 01224 #ifndef EXCLUDE_FROM_XARALX 01225 catch (CUserException) 01226 { 01227 // An exception has been thrown which means 01228 // we failed to parse this string, so simply report failure 01229 AllIsWell = FALSE; 01230 } 01231 #endif 01232 01233 // Switch off the exception state finally, (and of course pop it)! 01234 StringBase::DisableExceptionHandler(); 01235 01236 return AllIsWell; 01237 } 01238 01239 01240 01241 /***************************************************************************************** 01242 01243 > UINT32 PrintMarksCache::DecodeToMarkType(String_256* Name) const 01244 01245 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01246 Created: 23/07/96 01247 Inputs: Name = a pointer to a string describing the mark type 01248 Returns: A unsigned integer describing the mark type (see MarkType for instances) 01249 Purpose: Have a look at the string passed in and check to see it matches any of 01250 the known mark type names. If so return the proper mark type enum, otherwise 01251 'Unkown' is returned. 01252 01253 *****************************************************************************************/ 01254 01255 UINT32 PrintMarksCache::DecodeToMarkType(const String_256* Name) const 01256 { 01257 ERROR2IF(Name == NULL, MarkType_Unknown, "NULL pointer passed to DecodeToMarkType"); 01258 01259 if ((*Name)==String_16(_T("ID_NONE"))) return