00001 // $Id: impcol.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 // Encapsulates a set of colours imported from a file. 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 00106 #include "impcol.h" 00107 00108 #include "colcomp.h" // colour document component 00109 //#include "resource.h" 00110 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "colormgr.h" 00112 #include "progress.h" 00113 //#include "ben.h" 00114 //#include "filtrres.h" // _R(IDS_NATIVE_SORTCOLOURS) 00115 00116 DECLARE_SOURCE("$Revision: 1282 $"); 00117 00118 00119 NewColourInfo::NewColourInfo() 00120 { 00121 // Initially a normal colour 00122 Type = COLOURTYPE_NORMAL; 00123 00124 // If linked, defaults to no inheritance. 00125 for (INT32 i = 0; i < 4; i++) 00126 Inherits[i] = FALSE; 00127 00128 // If tinted, then no change in colour 00129 TintValue = 100.0; 00130 00131 // By default tints are normal tints, not shades. 00132 TintIsShade = FALSE; 00133 00134 // New bits for native/web file filter 00135 // By default we are not defining a web or native style colour 00136 WebNativeColour = FALSE; 00137 // By default this colour has not been imported yet so flag this in our variables 00138 pParentCol = NULL; 00139 RecordNumber = 0L; 00140 EntryNumber = 0L; 00141 } 00142 00143 /******************************************************************************************** 00144 00145 > class ContextItem : public ListItem 00146 00147 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00148 Created: 01/12/94 00149 Purpose: Provides information on a context level - see ColourImportContext for 00150 more detail. 00151 SeeAlso: ColourImportContext 00152 00153 ********************************************************************************************/ 00154 00155 class ContextItem : public ListItem 00156 { 00157 CC_DECLARE_MEMDUMP(ContextItem) 00158 00159 public: 00160 ContextItem(IndexedColour *pContext) : pCol(pContext) {} 00161 00162 public: 00163 IndexedColour *pCol; 00164 00165 private: 00166 // Prevent default constructor from being used. 00167 ContextItem(); 00168 }; 00169 00170 00171 00172 00173 CC_IMPLEMENT_MEMDUMP(NewColour, ListItem) 00174 CC_IMPLEMENT_MEMDUMP(NewColourList, List) 00175 CC_IMPLEMENT_MEMDUMP(ImportedColours, CCObject) 00176 CC_IMPLEMENT_MEMDUMP(ColourImportContext, List) 00177 CC_IMPLEMENT_MEMDUMP(ContextItem, ListItem) 00178 00179 00180 // Declare smart memory handling in Debug builds 00181 #define new CAM_DEBUG_NEW 00182 00183 00184 ColourImportContext::ColourImportContext() 00185 { 00186 } 00187 00188 ColourImportContext::~ColourImportContext() 00189 { 00190 // Just lose all the items in our list. 00191 DeleteAll(); 00192 } 00193 00194 BOOL ColourImportContext::Init() 00195 { 00196 // Add an initial context item 00197 ContextItem *pItem = new ContextItem(NULL); 00198 if (pItem == NULL) 00199 return FALSE; 00200 00201 // Add to the list 00202 AddTail(pItem); 00203 00204 // All ok 00205 return TRUE; 00206 } 00207 00208 00209 void ColourImportContext::SetContext(IndexedColour *pCol) 00210 { 00211 // Get the current context item (always the last) 00212 ContextItem *pItem = (ContextItem *) GetTail(); 00213 00214 // Update its colour pointer 00215 pItem->pCol = pCol; 00216 } 00217 00218 00219 IndexedColour *ColourImportContext::GetContext() 00220 { 00221 // Get the current context item (always the last) 00222 ContextItem *pItem = (ContextItem *) GetTail(); 00223 00224 // Return its colour pointer 00225 return pItem->pCol; 00226 } 00227 00228 BOOL ColourImportContext::SaveContext() 00229 { 00230 // Get a pointer to the current context node 00231 ContextItem *pCurrentItem = (ContextItem *) GetTail(); 00232 00233 // Add a new context node to the end of the list, and give it the same 00234 // context as the current context node. 00235 ContextItem *pItem = new ContextItem(pCurrentItem->pCol); 00236 if (pItem == NULL) 00237 return FALSE; 00238 00239 // Add to the list 00240 AddTail(pItem); 00241 00242 // All ok 00243 return TRUE; 00244 } 00245 00246 BOOL ColourImportContext::RestoreContext() 00247 { 00248 // Make sure we can do this - must always have at least one node 00249 if (GetCount() <= 1) 00250 { 00251 ERROR3("Bad call to ColourImportContext::RestoreContext()"); 00252 return FALSE; 00253 } 00254 00255 // Remove and delete the last context item 00256 delete RemoveTail(); 00257 00258 // All ok 00259 return TRUE; 00260 } 00261 00262 BOOL ColourImportContext::RestoreContextTo(UINT32 NewLevel) 00263 { 00264 // How many should we delete? 00265 INT32 NumToDelete = (INT32) (GetCount() - NewLevel) - 1; 00266 00267 // Make sure this is a legal request. 00268 if (NumToDelete < 0) 00269 // No - return failure 00270 return FALSE; 00271 00272 // Ok - delete this many items 00273 while (NumToDelete > 0) 00274 { 00275 if (!RestoreContext()) 00276 { 00277 ERROR3("Bad call to ColourImportContext::RestoreContextTo()"); 00278 return FALSE; 00279 } 00280 00281 NumToDelete--; 00282 } 00283 00284 // All ok 00285 return TRUE; 00286 } 00287 00288 00289 00290 /******************************************************************************************** 00291 00292 > NewColour::NewColour(IndexedColour *pNewCol, BOOL AlreadyExists) 00293 00294 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00295 Created: 30/11/94 00296 Inputs: pNewCol - the colour to put in the list. 00297 AlreadyExists - TRUE if pNewCol points to a colour that already exists in 00298 the destination document; 00299 FALSE if pNewCol poinst to a brand new colour. 00300 Purpose: Create a new colour list item from the given indexed colour. 00301 SeeAlso: NewColourList; NewColourList::AddColour 00302 00303 ********************************************************************************************/ 00304 00305 NewColour::NewColour(IndexedColour *pNewCol, BOOL AlreadyExists) 00306 { 00307 // Initialise to sensible values. 00308 pCol = pNewCol; 00309 AlreadyExistsInDoc = AlreadyExists; 00310 Duplicate = FALSE; 00311 pNextDuplicate = NULL; 00312 00313 // Get CMYK version of this colour for comparisons - this looks a bit nasty, but 00314 // actually I think it's the cleanest way of doing this. 00315 DocColour TempCol; 00316 TempCol.MakeRefToIndexedColour(pNewCol); 00317 TempCol.GetCMYKValue(&ColDefn); 00318 00319 // New web/native filter bits 00320 RecordNumber = 0L; 00321 EntryNumber = 0L; 00322 } 00323 00324 00325 /******************************************************************************************** 00326 00327 > BOOL NewColour::AddDuplicateColour(IndexedColour **pNewCol, 00328 BOOL AlreadyExists) 00329 00330 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00331 Created: 30/11/94 00332 Inputs: pNewCol - (pointer to a) pointer to the IndexedColour object to link to pMaster 00333 because they both have the same colour name. 00334 00335 AlreadyExists - TRUE => pNewCol matches a colour that is already in the 00336 destination document. 00337 FALSE => pNewCol does not match any colours in the 00338 destination document. 00339 00340 Outputs: pNewCol pointer is updated to point at the colour to use for the colour 00341 passed in (see below). 00342 00343 Returns: TRUE if the duplicate could be added; 00344 FALSE if out of memory => ERROR1 00345 00346 Purpose: Add another definition of a colour to an existing colour definition. 00347 i.e. We have a new colour but we have already found a definition of this 00348 colour name while importing, so we have duplicate colour names, so the 00349 IndexedColour object pointed to by pNewCol should be linked to the 00350 existing item (with which it shares a colour name). 00351 00352 Notes: AddDuplicateColour handles 2 types of duplicates: 00353 00354 1) Duplicated name, but different colour definitions. In this case, the 00355 dupes are remembered and added to the document (the colour list will ensure 00356 they have unique names when finally added) 00357 00358 2) Exact duplicate (now possible with parents of shade colours which might 00359 be defined twice in a CamEPS document). These are deleted out of hand, 00360 and the pNewCol pointer is updated to point at the original/first definition 00361 of the identical colour. 00362 00363 Errors: Out of memory => ERROR1 00364 SeeAlso: NewColour; ImportedColours::AddColour 00365 00366 ********************************************************************************************/ 00367 00368 BOOL NewColour::AddDuplicateColour(IndexedColour **pNewCol, BOOL AlreadyExists) 00369 { 00370 ERROR3IF(pNewCol == NULL || *pNewCol == NULL, "Illegal NULL param"); 00371 00372 // --- First, check if this colour is a real duplicate or just a duplicate in name 00373 // If it is a duplicate name, then we keep a copy around, but if it is a complete 00374 // duplicate, then we want to vape it and NOT put it in the dupes list - Jason 00375 00376 // NOTE: We *ONLY* do this if the colour is not already part of the existing document 00377 // (i.e. was merged with an existing exact match colour in the doc), i.e. if !AlreadyExists 00378 00379 if (!AlreadyExists) 00380 { 00381 NewColour *Ptr = this; 00382 while (Ptr != NULL) 00383 { 00384 if (!(*pNewCol)->IsDifferent(*(Ptr->pCol))) 00385 { 00386 delete (*pNewCol); // delete the identical twin 00387 *pNewCol = Ptr->pCol; // and return the pointer pointing at the original definition 00388 return(TRUE); 00389 } 00390 00391 Ptr = Ptr->pNextDuplicate; 00392 } 00393 } 00394 00395 // --- And now back to our regularly scheduled programme... 00396 00397 00398 00399 // First, try to make a new item 00400 NewColour *pNewItem = new NewColour(*pNewCol, AlreadyExists); 00401 if (pNewItem == NULL) 00402 return FALSE; 00403 00404 // Mark this object as being a duplicate 00405 Duplicate = TRUE; 00406 00407 // Ok, link to this object (at end of the one-way list)... 00408 NewColour *pLast = this; 00409 while (pLast->pNextDuplicate != NULL) 00410 pLast = pLast->pNextDuplicate; 00411 00412 // Found end of list - link it in and mark it as being a duplicate 00413 pLast->pNextDuplicate = pNewItem; 00414 pNewItem->Duplicate = TRUE; 00415 00416 // Worked ok 00417 return TRUE; 00418 } 00419 00420 00421 /******************************************************************************************** 00422 00423 > NewColour *NewColourList::AddColour(IndexedColour *pCol) 00424 00425 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00426 Created: 30/11/94 00427 Inputs: pCol - the new colour to add to the document. 00428 AlreadyExists - TRUE if pNewCol points to a colour that already exists in 00429 the destination document; 00430 FALSE if pNewCol poinst to a brand new colour. 00431 Returns: Pointer to the newly added colour, or 00432 NULL if out of memory => ERROR1 00433 Purpose: Add a new colour to the list of colours. 00434 Errors: Out of memory => ERROR1 00435 SeeAlso: NewColour 00436 00437 ********************************************************************************************/ 00438 00439 NewColour *NewColourList::AddColour(IndexedColour *pCol, BOOL AlreadyExists) 00440 { 00441 NewColour *pNewCol = new NewColour(pCol, AlreadyExists); 00442 00443 // Check for out of memory 00444 if (pNewCol == NULL) 00445 return NULL; 00446 00447 // Add to the list and return success 00448 AddTail(pNewCol); 00449 return pNewCol; 00450 } 00451 00452 00453 /******************************************************************************************** 00454 00455 > DWORD NewColourList::GetCount() 00456 00457 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00458 Created: 01/12/94 00459 Returns: Number of colours in this list. 00460 Purpose: Find out how many colours are held in this list - this includes any 00461 duplicates. 00462 00463 ********************************************************************************************/ 00464 00465 DWORD NewColourList::GetCount() const 00466 { 00467 DWORD Count = 0; 00468 NewColour *pItem = (NewColour *) GetHead(); 00469 00470 while (pItem != NULL) 00471 { 00472 // Count this item 00473 Count++; 00474 00475 // Count any duplicates 00476 NewColour *pDup = pItem->pNextDuplicate; 00477 00478 while (pDup != NULL) 00479 { 00480 // Count this duplicate 00481 Count++; 00482 00483 // Try next duplicate 00484 pDup = pDup->pNextDuplicate; 00485 } 00486 00487 // Try next item 00488 pItem = (NewColour *) GetNext(pItem); 00489 } 00490 00491 return Count; 00492 } 00493 00494 00495 00496 /******************************************************************************************** 00497 00498 > ImportedColours::ImportedColours(ColourListComponent *TheColourComponent, 00499 BOOL Strict) 00500 00501 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00502 Created: 30/11/94 00503 Inputs: TheColourComponent - the relevant colour component for this import. 00504 Strict - TRUE => when servicing calls to GetColour(), check the CMYK 00505 colour definition for a match in case a colour is being 00506 used which wasn't declared in the colour table (this is 00507 what we do for ArtWorks EPS). 00508 FALSE => don't bother checking CMYK - just use the name to look 00509 up the colour - we use this for Camelot EPS because we 00510 know we don't save out brain damaged EPS like ArtWorks 00511 does. 00512 Purpose: Create a table of imported colours (initially empty). 00513 SeeAlso: ImportedColours::Init 00514 00515 ********************************************************************************************/ 00516 00517 ImportedColours::ImportedColours(ColourListComponent *TheColourComponent, BOOL Strict) 00518 { 00519 // Remember this document component 00520 pColourComponent = TheColourComponent; 00521 00522 // Do we check CMYK values when matching colours? 00523 StrictColourMatching = Strict; 00524 00525 // No hash table yet 00526 pColourMap = NULL; 00527 } 00528 00529 /******************************************************************************************** 00530 00531 > ImportedColours::~ImportedColours() 00532 00533 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00534 Created: 30/11/94 00535 Inputs: - 00536 Outputs: - 00537 Returns: - 00538 Purpose: Destroy a table of imported colours. This should only be done after calling 00539 AddColoursToDocument() or DestroyColours() - an ERROR3 will occur if this 00540 is not done. 00541 Errors: Colours should be explicitly added to the document or deleted from this 00542 table before this function is called => ERROR3 00543 SeeAlso: ImportedColours::AddColoursToDocument; ImportedColours::DestroyColours 00544 00545 ********************************************************************************************/ 00546 00547 ImportedColours::~ImportedColours() 00548 { 00549 // MORE STUFF HERE... 00550 00551 // Trash the hash table 00552 delete pColourMap; 00553 pColourMap = NULL; 00554 } 00555 00556 /******************************************************************************************** 00557 00558 > BOOL ImportedColours::Init() 00559 00560 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00561 Created: 30/11/94 00562 Inputs: - 00563 Outputs: - 00564 Returns: - 00565 Purpose: Initialise the table of imported colours 00566 Errors: - 00567 SeeAlso: - 00568 00569 ********************************************************************************************/ 00570 00571 BOOL ImportedColours::Init() 00572 { 00573 // Get a hash table for the colour names... 00574 try 00575 { 00576 pColourMap = new CMapStringToNewColour; 00577 } 00578 catch( CMemoryException ) 00579 { 00580 ERROR(_R(IDS_OUT_OF_MEMORY), FALSE); 00581 } 00582 00583 // Check our document's colour list component... 00584 if (pColourComponent == NULL) 00585 { 00586 // Whoops - something's up 00587 delete pColourMap; 00588 pColourMap = NULL; 00589 ERROR2(FALSE, "NULL colour list component!"); 00590 } 00591 00592 // Ininitalise the colour linking context. 00593 if (!Context.Init()) 00594 return FALSE; 00595 00596 // All ok 00597 return TRUE; 00598 } 00599 00600 /******************************************************************************************** 00601 00602 > BOOL ImportedColours::AddColour(const String_64 *pColName, 00603 ColourCMYK *pCMYK, 00604 NewColourInfo *pColourInfo = NULL) 00605 00606 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00607 Created: 30/11/94 00608 Inputs: pColName - the name of the colour to add 00609 pCMYK - the definition of the colour to add 00610 pColourInfo - if NULL, then it is a normal colour; 00611 if non-NULL then colour is special in some way, i.e. a tint 00612 or a linked colour or a spot colour. 00613 Returns: TRUE if the colour could be added; 00614 FALSE if not 00615 Purpose: Add the specified colour to the colour table. If the colour name clashes 00616 with any already added or already in the destination document, this does not 00617 matter as the name specified in pColName is what should be used to access 00618 this colour again. 00619 If pColourInfo specifies a linked or tinted colour, then this colour 00620 is also linked to the colour currently specified by the colour link 00621 context (see SaveContext and RestoreContextTo). 00622 Errors: - 00623 SeeAlso: ImportedColours; ImportedColours::GetColour; 00624 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00625 00626 ********************************************************************************************/ 00627 00628 BOOL ImportedColours::AddColour(const String_64 *pColName, ColourCMYK *pCMYK, 00629 NewColourInfo *pColourInfo) 00630 { 00631 IndexedColour *pNewCol = new INDEXEDCOLOUR_CMYK(pCMYK); 00632 return AddColour(pColName, &pNewCol, pColourInfo); 00633 } 00634 00635 /******************************************************************************************** 00636 00637 > BOOL ImportedColours::AddColour(const String_64 *pColName, 00638 ColourRGBT *pRGB, 00639 NewColourInfo *pColourInfo = NULL) 00640 00641 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00642 Created: 30/11/94 00643 Inputs: pColName - the name of the colour to add 00644 pRGB - the definition of the colour to add 00645 pColourInfo - if NULL, then it is a normal colour; 00646 if non-NULL then colour is special in some way, i.e. a tint 00647 or a linked colour or a spot colour. 00648 Returns: TRUE if the colour could be added; 00649 FALSE if not 00650 Purpose: Add the specified colour to the colour table. If the colour name clashes 00651 with any already added or already in the destination document, this does not 00652 matter as the name specified in pColName is what should be used to access 00653 this colour again. 00654 If pColourInfo specifies a linked or tinted colour, then this colour 00655 is also linked to the colour currently specified by the colour link 00656 context (see SaveContext and RestoreContextTo). 00657 Errors: - 00658 SeeAlso: ImportedColours; ImportedColours::GetColour; 00659 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00660 00661 ********************************************************************************************/ 00662 00663 BOOL ImportedColours::AddColour(const String_64 *pColName, ColourRGBT *pRGB, 00664 NewColourInfo *pColourInfo) 00665 { 00666 IndexedColour *pNewCol = new INDEXEDCOLOUR_RGBT(pRGB); 00667 return AddColour(pColName, &pNewCol, pColourInfo); 00668 } 00669 00670 /******************************************************************************************** 00671 00672 > BOOL ImportedColours::AddColour(const String_64 *pColName, 00673 ColourHSVT *pHSV, 00674 NewColourInfo *pColourInfo = NULL) 00675 00676 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00677 Created: 30/11/94 00678 Inputs: pColName - the name of the colour to add 00679 pHSV - the definition of the colour to add 00680 pColourInfo - if NULL, then it is a normal colour; 00681 if non-NULL then colour is special in some way, i.e. a tint 00682 or a linked colour or a spot colour. 00683 Returns: TRUE if the colour could be added; 00684 FALSE if not 00685 Purpose: Add the specified colour to the colour table. If the colour name clashes 00686 with any already added or already in the destination document, this does not 00687 matter as the name specified in pColName is what should be used to access 00688 this colour again. 00689 If pColourInfo specifies a linked or tinted colour, then this colour 00690 is also linked to the colour currently specified by the colour link 00691 context (see SaveContext and RestoreContextTo). 00692 Errors: - 00693 SeeAlso: ImportedColours; ImportedColours::GetColour; 00694 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00695 00696 ********************************************************************************************/ 00697 00698 BOOL ImportedColours::AddColour(const String_64 *pColName, ColourHSVT *pHSV, 00699 NewColourInfo *pColourInfo) 00700 { 00701 IndexedColour *pNewCol = new INDEXEDCOLOUR_HSVT(pHSV); 00702 return AddColour(pColName, &pNewCol, pColourInfo); 00703 } 00704 00705 /******************************************************************************************** 00706 00707 > BOOL ImportedColours::AddColour(const String_64 *pColName, 00708 ColourGreyT *pGrey, 00709 NewColourInfo *pColourInfo = NULL) 00710 00711 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00712 Created: 30/11/94 00713 Inputs: pColName - the name of the colour to add 00714 pGrey - the definition of the colour to add 00715 pColourInfo - if NULL, then it is a normal colour; 00716 if non-NULL then colour is special in some way, i.e. a tint 00717 or a linked colour or a spot colour. 00718 Returns: TRUE if the colour could be added; 00719 FALSE if not 00720 Purpose: Add the specified colour to the colour table. If the colour name clashes 00721 with any already added or already in the destination document, this does not 00722 matter as the name specified in pColName is what should be used to access 00723 this colour again. 00724 If pColourInfo specifies a linked or tinted colour, then this colour 00725 is also linked to the colour currently specified by the colour link 00726 context (see SaveContext and RestoreContextTo). 00727 Errors: - 00728 SeeAlso: ImportedColours; ImportedColours::GetColour; 00729 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00730 00731 ********************************************************************************************/ 00732 00733 BOOL ImportedColours::AddColour(const String_64 *pColName, ColourGreyT *pGrey, 00734 NewColourInfo *pColourInfo) 00735 { 00736 IndexedColour *pNewCol = new INDEXEDCOLOUR_GREYT(pGrey); 00737 return AddColour(pColName, &pNewCol, pColourInfo); 00738 } 00739 00740 /******************************************************************************************** 00741 00742 > BOOL ImportedColours::AddColour(const String_64 *pColName, 00743 ImportedNewColour *pCol, 00744 NewColourInfo *pColourInfo = NULL) 00745 00746 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 00747 Created: 18 03 95 00748 Inputs: pColName - the name of the colour to add 00749 pGrey - the definition of the colour to add 00750 pColourInfo - if NULL, then it is a normal colour; 00751 if non-NULL then colour is special in some way, i.e. a tint 00752 or a linked colour or a spot colour. 00753 Returns: TRUE if the colour could be added; 00754 FALSE if not 00755 Purpose: Add the specified colour to the colour table. If the colour name clashes 00756 with any already added or already in the destination document, this does not 00757 matter as the name specified in pColName is what should be used to access 00758 this colour again. 00759 If pColourInfo specifies a linked or tinted colour, then this colour 00760 is also linked to the colour currently specified by the colour link 00761 context (see SaveContext and RestoreContextTo). 00762 This version adds a colour of from any colour model (supported by other 00763 AddColour functions) 00764 Errors: - 00765 SeeAlso: ImportedColours; ImportedColours::GetColour; 00766 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00767 00768 ********************************************************************************************/ 00769 00770 BOOL ImportedColours::AddColour(const String_64 *pColName, ImportedNewColour *pCol, 00771 NewColourInfo *pColourInfo) 00772 { 00773 switch(pCol->Model) 00774 { 00775 case COLOURMODEL_RGBT: 00776 return AddColour(pColName, (ColourRGBT *)&pCol->Colour, pColourInfo); 00777 break; 00778 00779 case COLOURMODEL_CMYK: 00780 return AddColour(pColName, (ColourCMYK *)&pCol->Colour, pColourInfo); 00781 break; 00782 00783 case COLOURMODEL_HSVT: 00784 return AddColour(pColName, (ColourHSVT *)&pCol->Colour, pColourInfo); 00785 break; 00786 00787 case COLOURMODEL_GREYT: 00788 return AddColour(pColName, (ColourGreyT *)&pCol->Colour, pColourInfo); 00789 break; 00790 00791 default: 00792 break; 00793 } 00794 00795 ERROR3("Colour model presented to ImportedColours::AddColour is not a recognised model"); 00796 00797 return FALSE; 00798 } 00799 00800 /******************************************************************************************** 00801 00802 > BOOL ImportedColours::AddTintOrShade(const String_64 *pColName, NewColourInfo *pLinkInfo) 00803 00804 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00805 Created: 29/5/96 00806 Inputs: pColName - the name of the colour to add 00807 pLinkInfo - the colour information data 00808 Returns: TRUE if the colour could be added; 00809 FALSE if not 00810 Purpose: Add the specified tint or shade to the colour table. 00811 Assumes the vital tint information has already been filled in. 00812 Errors: - 00813 SeeAlso: ColourListComponent::ReadTint; ColourListComponent::ReadShade; 00814 ColourListComponent::ImportColourDefinition; 00815 00816 ********************************************************************************************/ 00817 00818 BOOL ImportedColours::AddTintOrShade(const String_64 *pColName, NewColourInfo *pColourInfo) 00819 { 00820 // Get a new colour to add 00821 IndexedColour *pNewCol = new IndexedColour; 00822 00823 // Assumes tint and shade information already set up, this includes:- 00824 // pColourInfo->Type = COLOURTYPE_TINT; 00825 // pColourInfo->TintValue = 0.0; (FIXED24); 00826 // If shade then 00827 // pColourInfo->ShadeValue = 0.0; (FIXED24); 00828 00829 return AddColour(pColName, &pNewCol, pColourInfo); 00830 } 00831 00832 /******************************************************************************************** 00833 00834 > BOOL ImportedColours::AddTint(const String_64 *pColName, UINT32 Tint) 00835 00836 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00837 Created: 30/11/94 00838 Inputs: pColName - the name of the colour to add 00839 Tint - the tint value (between 0 and 100) 00840 Returns: TRUE if the colour could be added; 00841 FALSE if not 00842 Purpose: Add the specified colour to the colour table. If the colour name clashes 00843 with any already added or already in the destination document, this does not 00844 matter as the name specified in pColName is what should be used to access 00845 this colour again. 00846 This colour is a tint of the colour currently specified by the colour link 00847 context (see SaveContext and RestoreContextTo). 00848 Errors: - 00849 SeeAlso: ImportedColours; ImportedColours::GetColour; 00850 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00851 00852 ********************************************************************************************/ 00853 00854 BOOL ImportedColours::AddTint(const String_64 *pColName, UINT32 Tint) 00855 { 00856 // Get a new colour to add 00857 IndexedColour *pNewCol = new IndexedColour; 00858 00859 // Set up the tint information 00860 NewColourInfo ColourInfo; 00861 ColourInfo.Type = COLOURTYPE_TINT; 00862 00863 // Convert 0 <-> 100 to 0.0 <-> 1.0 and pass in as FIXED24. 00864 ColourInfo.TintValue = FIXED24(((double) Tint) / 100.0); 00865 00866 return AddColour(pColName, &pNewCol, &ColourInfo); 00867 } 00868 00869 00870 00871 /******************************************************************************************** 00872 00873 > BOOL ImportedColours::AddShade(const String_64 *pColName, INT32 ShadeX, INT32 ShadeY) 00874 00875 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (copied from code by Tim) 00876 Created: 7/9/95 (30/11/94) 00877 Inputs: pColName - the name of the colour to add 00878 ShadeX - the shade X value (between -100 and 100) 00879 ShadeY - the shade Y value (between -100 and 100) 00880 00881 Returns: TRUE if the colour could be added; 00882 FALSE if not 00883 Purpose: Add the specified colour to the colour table. If the colour name clashes 00884 with any already added or already in the destination document, this does not 00885 matter as the name specified in pColName is what should be used to access 00886 this colour again. 00887 This colour is a shade of the colour currently specified by the colour link 00888 context (see SaveContext and RestoreContextTo). 00889 Errors: - 00890 SeeAlso: ImportedColours; ImportedColours::GetColour; 00891 ImportedColours::SaveContext; ImportedColours::RestoreContextTo 00892 00893 ********************************************************************************************/ 00894 00895 BOOL ImportedColours::AddShade(const String_64 *pColName, INT32 ShadeX, INT32 ShadeY) 00896 { 00897 // Get a new colour to add 00898 IndexedColour *pNewCol = new IndexedColour; 00899 00900 // Set up the tint information 00901 NewColourInfo ColourInfo; 00902 ColourInfo.Type = COLOURTYPE_TINT; 00903 00904 // And flag the fact that this "tint" is really a shade! 00905 ColourInfo.TintIsShade = TRUE; 00906 00907 // Convert -100 <-> 100 to -1.0 <-> 1.0 and pass in as FIXED24. 00908 ColourInfo.TintValue = FIXED24(((double) ShadeX) / 100.0); 00909 ColourInfo.ShadeValue = FIXED24(((double) ShadeY) / 100.0); 00910 00911 return AddColour(pColName, &pNewCol, &ColourInfo); 00912 } 00913 00914 00915 00916 /******************************************************************************************** 00917 00918 > BOOL ImportedColours::AddColour(const String_64 *pColName, IndexedColour **pNewCol, 00919 NewColourInfo *pColourInfo) 00920 00921 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00922 Created: 30/11/94 00923 00924 Modified: Jason (8/9/95) - Now handles exact duplicates as well as duplicate names 00925 (This is needed for new shade-colour saving system which does nasty 00926 things in order to retain backward compatability with old loaders) 00927 00928 Inputs: pColName - the name of the colour 00929 pNewCol - ptr to ptr to the new indexed colour to use (if NULL then just 00930 returns FALSE immediately) (see also Outputs) 00931 pColourInfo - if NULL, then it is a normal colour; 00932 if non-NULL then colour is special in some way, i.e. a tint 00933 or a linked colour or a spot colour. 00934 00935 Outputs: If *pNewCol points to an IndexedColour which already has an *identical* 00936 twin colour (i.e. exactly the same colour appears twice in the doc) then 00937 *pNewCol will be modified to point at the first incarnation of the colour, 00938 and the IndexedColour you passed in will be deleted. 00939 DO NOT use the previous IndexedColour pointer - only use the pointer as 00940 passed back from this method. 00941 00942 Returns: TRUE if the colour was added ok; 00943 FALSE otherwise 00944 Purpose: Generic routine for adding a colour to the table of imported colours. 00945 All the other AddColour() routines map onto this. 00946 00947 Errors: Out of memory => ERROR1 00948 pNewCol is NULL => returns FALSE (no error set) 00949 SeeAlso: ImportedColours 00950 Scope: Protected 00951 00952 ********************************************************************************************/ 00953 00954 BOOL ImportedColours::AddColour(const String_64 *pColName, IndexedColour **pNewIndexedCol, 00955 NewColourInfo *pColourInfo) 00956 { 00957 // Do we have a valid colour? 00958 if (pNewIndexedCol == NULL || *pNewIndexedCol == NULL) 00959 // No! 00960 return FALSE; 00961 00962 // First, set the colour name to the one supplied. If it is unnamed, then we want 00963 // to set its unique-ID string to the value from the file. At the end of the import, 00964 // we will use SetUnnamed to force it to re-generate a unique name so that it is 00965 // (a) merged properly during import, and (b) doesn't clash with another colour 00966 // already in the same document once it is added. 00967 //String_64 Name = *pColName; 00968 //(*pNewIndexedCol)->SetName(*pColName, (ColName[0] != '_')); 00969 TCHAR ch = (*pColName)[0]; 00970 (*pNewIndexedCol)->SetName(*pColName, (ch != '_')); 00971 00972 00973 if (pColourInfo != NULL) 00974 { 00975 // Link the colour if required 00976 if ((pColourInfo->Type == COLOURTYPE_LINKED) || 00977 (pColourInfo->Type == COLOURTYPE_TINT)) 00978 { 00979 IndexedColour *pParent = NULL; 00980 if (pColourInfo->WebNativeColour) 00981 { 00982 pParent = pColourInfo->pParentCol; 00983 } 00984 else 00985 { 00986 // Importing a non-native or web file colour and so use the context of the colour 00987 // to define its parent. 00988 // Get the current colour context 00989 pParent = Context.GetContext(); 00990 ERROR2IF(pParent == NULL, FALSE, "NULL parent when creating linked colour!"); 00991 } 00992 00993 // Link to it - either as a linked colour or a tint 00994 if (pColourInfo->Type == COLOURTYPE_LINKED) 00995 { 00996 // Linked colour 00997 (*pNewIndexedCol)->SetLinkedParent(pParent, COLOURTYPE_LINKED); 00998 00999 // Set inheritance flags... 01000 for (INT32 i = 0; i < 4; i++) 01001 (*pNewIndexedCol)->SetInheritsComponent(i + 1, pColourInfo->Inherits[i]); 01002 } 01003 else 01004 { 01005 // Tinted colour 01006 (*pNewIndexedCol)->SetLinkedParent(pParent, COLOURTYPE_TINT); 01007 01008 // Set tint/shade value as appropriate. This makes the 'tint' colour a 01009 // tint or shade. (Shades are special cases of tints for historical reasons) 01010 if (pColourInfo->TintIsShade) 01011 (*pNewIndexedCol)->SetShadeValues(pColourInfo->TintValue, pColourInfo->ShadeValue); 01012 else 01013 (*pNewIndexedCol)->SetTintValue(pColourInfo->TintValue); 01014 } 01015 } 01016 else if (pColourInfo->Type == COLOURTYPE_SPOT) 01017 { 01018 // Mark this as a spot colour (in case the caller hasn't already) 01019 (*pNewIndexedCol)->SetLinkedParent(NULL, COLOURTYPE_SPOT); 01020 } 01021 } 01022 01023 // Is there a colour the same as this in the destination document already? 01024 IndexedColour *pIdenticalCol; 01025 pColourComponent->FindIdenticalColour(*pNewIndexedCol, &pIdenticalCol); 01026 01027 BOOL AlreadyExists = (pIdenticalCol != NULL); 01028 01029 /* 01030 Phil, 01/03/2004 01031 If we remove colours from the document before we have added our list of imported colours 01032 anything could come along and add colours back in the meantime. 01033 (e.g. GradFillAttribute::GradFillAttribute) 01034 So leave colours in the list and only move them later on... 01035 */ 01036 if (AlreadyExists) 01037 { 01038 // Graeme (5/4/00) - This code now changes the colour list so that an 01039 // existing colour is repositioned where the original definition was. 01040 01041 // Delete the new one because it duplicates one already in the document. 01042 delete *pNewIndexedCol; 01043 01044 // Make pNewIndexedCol point to the existing colour 01045 *pNewIndexedCol = pIdenticalCol; 01046 01047 // Set AlreadyExists to be FALSE so that the colour is included. 01048 AlreadyExists = FALSE; 01049 } 01050 01051 NewColour *pNewColour = NULL; 01052 01053 // If we are in web/native filter mode then we MUST always add a new colour item as this 01054 // is where we save the record number which will be reused later. So we must stop the 01055 // name look up and adding duplicates as this adds the new colour to the a list inside 01056 // the duplicated name that is in the ColourMap. 01057 BOOL WebNative = (pColourInfo && pColourInfo->WebNativeColour); 01058 01059 // First, check to see if we already have a definition of this colour *NAME* 01060 if( !WebNative && pColourMap->Lookup( *pColName, pNewColour ) ) 01061 { 01062 // Yes - mark the current definition as a duplicate and add this new one to it. 01063 if (!pNewColour->AddDuplicateColour(pNewIndexedCol, AlreadyExists)) 01064 // Error encountered. 01065 return FALSE; 01066 } 01067 else 01068 { 01069 // No - but is it already in the destination document? 01070 // 01071 // (i.e. is there a colour in the document with the same 01072 // name, colour model and definition?) 01073 // 01074 // If yes - add a new colour that references the already existing colour, and 01075 // mark it as being such; 01076 // 01077 // If no - it's a new colour, so add it to the list. 01078 01079 pNewColour = Colours.AddColour(*pNewIndexedCol, AlreadyExists); 01080 01081 if (pNewColour == NULL) 01082 // out of memory 01083 return FALSE; 01084 01085 // Either way, add it to the colour name map 01086 try 01087 { 01088 (*pColourMap)[ *pColName ] = pNewColour; 01089 } 01090 catch( CMemoryException ) 01091 { 01092 // Could not do it - report error to caller. 01093 ERROR(_R(IDS_OUT_OF_MEMORY), FALSE); 01094 } 01095 01096 // If we are in web/native filter mode then save the record number that we 01097 // have been passed in in the NewColourInfo 01098 // At the same time save out the entry number for where we want this colour in the list 01099 // of colours 01100 if (pColourInfo && pColourInfo->WebNativeColour) 01101 { 01102 pNewColour->RecordNumber = pColourInfo->RecordNumber; 01103 pNewColour->EntryNumber = pColourInfo->EntryNumber; 01104 } 01105 } 01106 01107 // We added the colour ok so set it as the current context colour 01108 // Note that AddDuplicateColour may have changed our pointer to point at a different 01109 // (identical) colour, but it will always point at the correct colour for us to use here. 01110 Context.SetContext(*pNewIndexedCol); 01111 01112 // All ok 01113 return TRUE; 01114 } 01115 01116 01117 /******************************************************************************************** 01118 01119 > void ImportedColours::SaveContext() 01120 01121 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01122 Created: 30/11/94 01123 Inputs: - 01124 Outputs: - 01125 Returns: - 01126 Purpose: None 01127 Errors: - 01128 SeeAlso: - 01129 01130 ********************************************************************************************/ 01131 01132 void ImportedColours::SaveContext() 01133 { 01134 Context.SaveContext(); 01135 } 01136 01137 /******************************************************************************************** 01138 01139 > void ImportedColours::RestoreContextTo(UINT32 Level) 01140 01141 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01142 Created: 30/11/94 01143 Inputs: - 01144 Outputs: - 01145 Returns: - 01146 Purpose: None 01147 Errors: - 01148 SeeAlso: - 01149 01150 ********************************************************************************************/ 01151 01152 void ImportedColours::RestoreContextTo(UINT32 Level) 01153 { 01154 if (Context.RestoreContextTo(Level) == FALSE) 01155 { 01156 ERROR3("Unbalanced colour import context"); 01157 } 01158 } 01159 01160 /******************************************************************************************** 01161 01162 > IndexedColour *ImportedColours::GetColour(const char *ColName) 01163 01164 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01165 Created: 30/11/94 01166 Inputs: ColName - the colour name to look for. 01167 Returns: Pointer to the indexed colour if successful; 01168 NULL if not found. 01169 Purpose: Find a named colour in the import list. This look up is obviously done 01170 purely on the colour name, and as such is a slightly risky thing to do, 01171 especially when importing such flaky file formats as EPS - use the 01172 version of GetColour that takes a PColourCMYK value to provide more 01173 reliable colour lookup. 01174 SeeAlso: ImportedColours 01175 01176 ********************************************************************************************/ 01177 01178 IndexedColour *ImportedColours::GetColour( PCTSTR ColName ) 01179 { 01180 // Do we have a definition of this colour name? 01181 NewColour *pNewColour=NULL; 01182 if( pColourMap->Lookup( ColName, pNewColour ) ) 01183 { 01184 // Yes - return the first entry 01185 return pNewColour->pCol; 01186 } 01187 else 01188 { 01189 // No - return failure. 01190 return NULL; 01191 } 01192 } 01193 01194 // This macro takes signed or unsigned values, and returns TRUE if they are equal, or 01195 // different by one. 01196 #define WITHIN_ONE(a,b) (Abs((INT32) (a) - (INT32) (b)) <= 1) 01197 01198 /******************************************************************************************** 01199 01200 > IndexedColour *ImportedColours::GetColour(const char *ColName, const PColourCMYK *Defn) 01201 01202 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01203 Created: 30/11/94 01204 Inputs: ColName - the colour name to look for. 01205 Defn - pointer to the CMYK values specified in the imported file. 01206 Returns: Pointer to the indexed colour if successful; 01207 NULL if not found. 01208 Purpose: Searches for a named colour. If the colour name has had duplicate 01209 definitions during this import, then the colour definition is compared 01210 against the values pointed to by Defn (converting to CMYK first if needed). 01211 Errors: - 01212 SeeAlso: ImportedColours 01213 01214 ********************************************************************************************/ 01215 01216 IndexedColour *ImportedColours::GetColour( PCTSTR ColName, const PColourCMYK *Defn ) 01217 { 01218 // Do we have a definition of this colour name? 01219 NewColour *pNewColour=NULL; 01220 if( pColourMap->Lookup( ColName, pNewColour ) ) 01221 { 01222 // Should we check colour values before returning this colour? 01223 if (StrictColourMatching || (pNewColour->pNextDuplicate != NULL)) 01224 { 01225 // Yes - find a colour from this entry that matches the colour definition too... 01226 while (pNewColour != NULL) 01227 { 01228 // Is this a match? 01229 // NB. We allow them to be out by one to cope with rounding problems. 01230 // This is ok, because it will only happen in ArtWorks EPS files, 01231 // and then only on colours that are 1 out in the colour definition, 01232 // so I don't think anyone's going to notice! -- Tim 01233 if (WITHIN_ONE(pNewColour->ColDefn.Cyan, Defn->Cyan) && 01234 WITHIN_ONE(pNewColour->ColDefn.Magenta, Defn->Magenta) && 01235 WITHIN_ONE(pNewColour->ColDefn.Yellow, Defn->Yellow) && 01236 WITHIN_ONE(pNewColour->ColDefn.Key, Defn->Key)) 01237 { 01238 // Yes - quit loop 01239 break; 01240 } 01241 01242 // Otherwise try next colour 01243 pNewColour = pNewColour->pNextDuplicate; 01244 } 01245 01246 // Did we find one? 01247 if (pNewColour != NULL) 01248 { 01249 // Yes - return it to the caller. 01250 return pNewColour->pCol; 01251 } 01252 else 01253 { 01254 // No - return failure 01255 return NULL; 01256 } 01257 } 01258 else 01259 { 01260 // No checking needed -just return this colour 01261 return pNewColour->pCol; 01262 } 01263 } 01264 else 01265 { 01266 // No - return failure. 01267 return NULL; 01268 } 01269 } 01270 01271 // Just to be safe... 01272 #undef WITHIN_ONE 01273 01274 01275 /******************************************************************************************** 01276 01277 > BOOL ImportedColours::AddColoursToDocument() 01278 01279 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01280 Created: 30/11/94 01281 Inputs: - 01282 Outputs: - 01283 Returns: - 01284 Purpose: None 01285 Errors: - 01286 SeeAlso: - 01287 01288 ********************************************************************************************/ 01289 01290 BOOL ImportedColours::AddColoursToDocument() 01291 { 01292 // Make an array for the new colours 01293 INT32 NumNewColours = Colours.GetCount(); 01294 INT32 TableSize = sizeof(IndexedColour *) * (NumNewColours + 1); 01295 IndexedColour **pNewArray = (IndexedColour **) CCMalloc(TableSize); 01296 if (pNewArray == NULL) 01297 { 01298 // Out of memory. 01299 return FALSE; 01300 } 01301 01302 // set up a slow job 01303 String_64 ImportMessage(_R(IDT_ADDCOLOURSTODOC)); 01304 BeginSlowJob( NumNewColours, TRUE, &ImportMessage ); 01305 INT32 Done = 0; 01306 01307 // Copy the colour pointers into this array 01308 INT32 i = 0; 01309 NewColour *pColour = (NewColour *) Colours.GetHead(); 01310 List *pUnnamedColours = pColourComponent->GetColourList()->GetUnnamedColours(); 01311 01312 while (pColour != NULL) 01313 { 01314 // Remove this colour from the list, and add it (and all duplicates of it) to the 01315 // palette and the array, but only if it is not already in the document,and it 01316 // is not an unnamed colour (i.e. its name starts with an underscore). 01317 Colours.RemoveItem(pColour); 01318 01319 while (pColour != NULL) 01320 { 01321 // Is it an unnamed colour? 01322 if (!pColour->pCol->IsNamed()) // Is it an unnamed colour? 01323 { 01324 // Yes - add to the unnamed colour list (no need for undo) 01325 // We force it unnamed again now to ensure it generates a new unique 01326 // ID for its destination document, rather than using the 01327 // unique-within-file id used during import. 01328 pColour->pCol->SetUnnamed(); 01329 pUnnamedColours->AddTail(pColour->pCol); 01330 } 01331 else 01332 { 01333 // It's a named colour - may be already in the doc, may be not 01334 IndexedColour* pIdenticalColour; 01335 pColourComponent->FindIdenticalColour(pColour->pCol, &pIdenticalColour); 01336 if (pIdenticalColour) 01337 { 01338 // Already in the doc so just move the existing colour 01339 // into the required position in the list by unlinking and relinking... 01340 ColourList *pColourList = pColourComponent->GetColourList (); 01341 if ( pColourList->RemoveItem ( pIdenticalColour ) != NULL ) 01342 { 01343 pColourComponent->AddNewColour(pIdenticalColour); 01344 pNewArray[i++] = pIdenticalColour; 01345 } 01346 01347 } 01348 else 01349 { 01350 pColourComponent->AddNewColour(pColour->pCol); 01351 pNewArray[i++] = pColour->pCol; 01352 } 01353 } 01354 01355 // Try next duplicate and delete this item. 01356 NewColour *pTmp = pColour; 01357 pColour = pColour->pNextDuplicate; 01358 delete pTmp; 01359 } 01360 01361 // Try the next colour 01362 pColour = (NewColour *) Colours.GetHead(); 01363 01364 // do progess bar stuff 01365 Done++; 01366 if(Done % 0xf == 0) 01367 ContinueSlowJob(Done); 01368 } 01369 01370 // Terminate the list of pointers 01371 pNewArray[i] = NULL; 01372 01373 // Add these colours|. 01374 ColourManager::UnHideColours(pColourComponent->GetColourList(), pNewArray); 01375 01376 // Destroy the list of added colours (UnHideColours copied it, so our copy is useless now) 01377 CCFree(pNewArray); 01378 pNewArray = NULL; 01379 01380 // Destroy the colour map 01381 delete pColourMap; 01382 pColourMap = NULL; 01383 01384 // finish the slow job 01385 ContinueSlowJob(NumNewColours); 01386 EndSlowJob(); 01387 01388 // All ok 01389 return TRUE; 01390 } 01391 01392 /******************************************************************************************** 01393 01394 > BOOL ImportedColours::DestroyColours() 01395 01396 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 01397 Created: 30/11/94 01398 Inputs: - 01399 Outputs: - 01400 Returns: - 01401 Purpose: None 01402 Errors: - 01403 SeeAlso: - 01404 01405 ********************************************************************************************/ 01406 01407 BOOL ImportedColours::DestroyColours() 01408 { 01409 NewColour *pColour = (NewColour *) Colours.GetHead(); 01410 01411 while (pColour != NULL) 01412 { 01413 // Remove this colour from the list, and delete the indexed colour it points to 01414 // (if it is not already in the document). 01415 Colours.RemoveItem(pColour); 01416 01417 while (pColour != NULL) 01418 { 01419 if (!pColour->AlreadyExistsInDoc) 01420 { 01421 // It's a brand new colour - delete it. 01422 // Except we don't because it causes an error. 01423 01424 // NB. This is a temporary bodge to stop us from getting Indexed colour 01425 // deleted while in use errors - they happen because the undo 01426 // system does not delete the nodes added by InsertNode() yet. 01427 // When it does, then we can uncomment this line. As it stands we 01428 // we get a memory leak of new colours when an import fails, but 01429 // what the hell - it's only a bodge. 01430 01431 //delete pColour->pCol; 01432 } 01433 01434 // Try next duplicate and delete this item. 01435 NewColour *pTmp = pColour; 01436 pColour = pColour->pNextDuplicate; 01437 delete pTmp; 01438 } 01439 01440 // Try the next colour 01441 pColour = (NewColour *) Colours.GetHead(); 01442 } 01443 01444 // All done 01445 return TRUE; 01446 } 01447 01448 /******************************************************************************************** 01449 01450 > IndexedColour *ImportedColours::GetColour(INT32 ReqRecordNumber) 01451 01452 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01453 Created: 30/5/96 01454 Inputs: ReqRecordNumber - the record number to search the list for 01455 Returns: Pointer to the indexed colour if successful; 01456 NULL if not found. 01457 Purpose: Searches for a previously imported colour definition. Used by the native/web 01458 filter to convert a colour reference in a record to an IndexedColour. This 01459 must have already been imported in the file as the rule is that reference to 01460 colours can only be made if the colour definition has already been output. 01461 Errors: - 01462 SeeAlso: ImportedColours; ColourListComponent::ImportColourDefinition; 01463 01464 ********************************************************************************************/ 01465 01466 IndexedColour *ImportedColours::GetColour(INT32 ReqRecordNumber) 01467 { 01468 // Work our way through the list of imported colours until we find the required record number 01469 NewColour *pColour = (NewColour *) Colours.GetHead(); 01470 while (pColour != NULL) 01471 { 01472 if (pColour->RecordNumber == ReqRecordNumber) 01473 return pColour->pCol; 01474 01475 // Try the next colour 01476 pColour = (NewColour *) Colours.GetNext(pColour); 01477 } 01478 01479 // Something went a bit wrong and we didn't find the requested record number 01480 // return NULL to the caller 01481 return NULL; 01482 } 01483 01484 /******************************************************************************************** 01485 01486 > BOOL ImportedColours::SortColoursByEntryNumber() 01487 01488 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01489 Created: 31/5/96 01490 Inputs: - 01491 Outputs: - 01492 Returns: True if the operation completed successfully 01493 False if it failed in some way. 01494 Purpose: Sorts the list of imported colours by the EntryNumber that is saved in the 01495 colour definition in the native file format so that we load the list back in 01496 the same order that it was in when the document was saved. This because when 01497 we save the colours we cannot save the list in the order they are defined in 01498 the colour list as we must save parent colours before children so that the 01499 children can reference the parent. 01500 Borrowed code from SuperGallery::ApplySortNow as we need a much simpler version. 01501 Errors: - 01502 SeeAlso: ImportedColours; ColourListComponent::ImportColourDefinition; 01503 ColourListComponent::EndImport; SuperGallery::ApplySortNow 01504 01505 ********************************************************************************************/ 01506 01507 BOOL ImportedColours::SortColoursByEntryNumber() 01508 { 01509 INT32 NumItems = 0; 01510 01511 // Count the number of items we have to sort 01512 NewColour *pColour = (NewColour *) Colours.GetHead(); 01513 while (pColour != NULL) 01514 { 01515 if (pColour->pCol->IsNamed()) // Is it an named colour? 01516 NumItems++; 01517 pColour = (NewColour *) Colours.GetNext(pColour); 01518 } 01519 01520 // Start progress indicators, with a percentage based upon the number of items. 01521 // We will update twice for each group (after qsort and shuffle-items stages) 01522 String_64 Description(_R(IDS_NATIVE_SORTCOLOURS)); 01523 BeginSlowJob(NumItems * 2, FALSE, &Description); 01524 INT32 NumItemsToSort = 0; 01525 01526 if (NumItems > 1) 01527 { 01528 // Get memory for an array of pointers to these items 01529 NewColour **SortArray = (NewColour **)CCMalloc(NumItems * sizeof(NewColour *)); 01530 if (SortArray == NULL) 01531 return FALSE; 01532 01533 // Fill in the array with pointers to display items to sort 01534 INT32 i = 0; 01535 NewColour *pColour = (NewColour *) Colours.GetHead(); 01536 while (pColour != NULL) 01537 { 01538 if (pColour->pCol->IsNamed()) // Is it an named colour? 01539 SortArray[i++] = pColour; 01540 pColour = (NewColour *) Colours.GetNext(pColour); 01541 } 01542 01543 // Sort the array of pointers 01544 qsort(SortArray, NumItems, sizeof(NewColour *), ImportedColours::SortComparator); 01545 01546 NumItemsToSort += NumItems; 01547 // Update percentage complete for the number of items processed 01548 ContinueSlowJob(NumItemsToSort); 01549 01550 // Now, take the sorted array, and rearrange the items to be in that order 01551 // Special case the first item 01552 NewColour *pPrevColour = (NewColour *) Colours.GetPrev(SortArray[0]); 01553 if (pPrevColour != NULL) 01554 { 01555 Colours.RemoveItem(SortArray[0]); 01556 Colours.InsertBefore(SortArray[1], SortArray[0]); 01557 } 01558 01559 // Then whip through the rest of the items 01560 for (i = 1; i < NumItems; i++) 01561 { 01562 pPrevColour = (NewColour *) Colours.GetPrev(SortArray[i]); 01563 if (pPrevColour != SortArray[i-1]) 01564 { 01565 Colours.RemoveItem(SortArray[i]); 01566 Colours.InsertAfter(SortArray[i-1], SortArray[i]); 01567 } 01568 } 01569 01570 // Free our temporary workspace 01571 CCFree(SortArray); 01572 } 01573 01574 // End the progress bar that we started 01575 EndSlowJob(); 01576 01577 // We seem to have sorted the items ok 01578 return TRUE; 01579 } 01580 01581 /******************************************************************************************** 01582 01583 > static INT32 __cdecl ImportedColours::SortComparator(const void *Item1, const void *Item2) 01584 01585 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01586 Created: 31/5/96 01587 Inputs: Item1, Item2 - the display nodes to be compared 01588 Returns: negative (I am lesser), 0 (we are equal), or positive (I am greater) 01589 result of comparing the items with the EntryNumber stored in each item in 01590 the loaded colour list. 01591 Purpose: 'qsort' comparator function, used when quicksorting the loaded colour list 01592 SeeAlso: ImportedColours::SortColoursByEntryNumber() 01593 SuperGallery::SortComparator; SuperGallery::ApplySortNow 01594 01595 ********************************************************************************************/ 01596 01597 INT32 __cdecl ImportedColours::SortComparator(const void *Item1, const void *Item2) 01598 { 01599 NewColour *pColourItem1 = *((NewColour **)Item1); 01600 NewColour *pColourItem2 = *((NewColour **)Item2); 01601 01602 if (pColourItem1 == NULL || pColourItem2 == NULL) 01603 { 01604 ERROR3("ImportedColours::SortComparator bad pointers!"); 01605 return 0; 01606 } 01607 01608 if (pColourItem1->EntryNumber < pColourItem2->EntryNumber) 01609 return(-1); 01610 01611 return((pColourItem1->EntryNumber == pColourItem2->EntryNumber) ? 0 : 1); 01612 }