00001 // $Id: colclist.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 // colclist.cpp - the ColourContextList class 00099 00100 /* 00101 */ 00102 00103 00104 #include "camtypes.h" 00105 00106 #include "colcontx.h" 00107 //#include "doccolor.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 00110 00111 00112 CC_IMPLEMENT_MEMDUMP(ColourContextList, List) 00113 00114 // Declare smart memory handling in Debug builds 00115 #define new CAM_DEBUG_NEW 00116 00117 00118 00119 /* ColContextList 00120 * 00121 * This is a 'global' pointer to a list of colour context objects 00122 * It is used to ensure that no colour contexts are ever repeated (i.e. they 00123 * are shared wherever possible). Only users of this file have access to this 00124 * list. 00125 * Access is via the static function ColourContextList::GetList() 00126 */ 00127 00128 ColourContextList *ColourContextList::ColContextList = NULL; 00129 00130 00131 00132 /******************************************************************************************** 00133 00134 > static BOOL ColourContextList::InitColourContexts(void) 00135 00136 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00137 Created: 11/04/94 00138 Inputs: - 00139 Outputs: - 00140 Returns: TRUE if initialisation succeeded, else FALSE 00141 FALSE if it failed (most likely because of lack of memory) 00142 Purpose: Initialises the Colour Context system, setting up the global list 00143 of default colour contexts which are shared by all documents. 00144 Called from app.cpp (must not be called more than once) 00145 Errors: - 00146 00147 ********************************************************************************************/ 00148 00149 BOOL ColourContextList::InitColourContexts(void) 00150 { 00151 ENSURE(ColContextList == NULL, "ColourContextList::InitColourContexts called more than once!"); 00152 00153 // First, create the global Colour context list in which all colour contexts 00154 // should be registered. 00155 ColContextList = new ColourContextList; 00156 if (ColContextList == NULL) 00157 return(FALSE); 00158 00159 00160 // Now, create an instance of each available colour context to provide the 00161 // global set of default colour contexts. Add each to the CCList. 00162 ColourContext *tempcc; 00163 00164 tempcc = new ColourContextRGBT(NULL, 1.0); // --- RGBT 00165 if (tempcc == NULL) 00166 return(FALSE); 00167 00168 ColContextList->AddContext(&tempcc); 00169 ColourContext::SetGlobalDefault(COLOURMODEL_RGBT, tempcc); 00170 00171 00172 tempcc = new ColourContextCMYK(NULL); // --- CMYK 00173 if (tempcc == NULL) 00174 return(FALSE); 00175 00176 ColContextList->AddContext(&tempcc); 00177 ColourContext::SetGlobalDefault(COLOURMODEL_CMYK, tempcc); 00178 00179 tempcc = new ColourContextHSVT(NULL); // --- HSVT 00180 if (tempcc == NULL) 00181 return(FALSE); 00182 00183 ColContextList->AddContext(&tempcc); 00184 ColourContext::SetGlobalDefault(COLOURMODEL_HSVT, tempcc); 00185 00186 00187 tempcc = new ColourContextGreyT(NULL); // --- GreyT 00188 if (tempcc == NULL) 00189 return(FALSE); 00190 00191 ColContextList->AddContext(&tempcc); 00192 ColourContext::SetGlobalDefault(COLOURMODEL_GREYT, tempcc); 00193 00194 00195 #ifndef DISABLE_WEBRGBT 00196 tempcc = new ColourContextWebRGBT(NULL); // --- WebRBGT 00197 if (tempcc == NULL) 00198 return(FALSE); 00199 00200 ColContextList->AddContext(&tempcc); 00201 ColourContext::SetGlobalDefault(COLOURMODEL_WEBRGBT, tempcc); 00202 #endif 00203 // --- etc... 00204 00205 return(TRUE); 00206 } 00207 00208 00209 00210 /******************************************************************************************** 00211 00212 > static void ColourContextList::DeinitColourContexts(void) 00213 00214 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00215 Created: 11/04/94 00216 Inputs: - 00217 Outputs: - 00218 Returns: - 00219 Purpose: De-initialises the Colour Context system, deleting the global list 00220 of default colour contexts which are shared by all documents. 00221 It is assumed that by this time the contexts should not be in use! 00222 Called from app.cpp (must not be caled more than once) 00223 Errors: If any colour contexts are still in use when this function is 00224 called, you may get ENSURE failures. 00225 00226 ********************************************************************************************/ 00227 00228 void ColourContextList::DeinitColourContexts(void) 00229 { 00230 ENSURE(ColContextList != NULL, "ColourContextList::DeinitColourContexts: but I haven't been initialised yet!"); 00231 00232 ColourContextArray DefaultCCA; 00233 ColourContext *DefaultCC; 00234 00235 ColourContext::GetGlobalDefaults(&DefaultCCA); 00236 00237 // Delete any of the default colour contexts that actually exist... 00238 for (INT32 cm = 0; cm < MAX_COLOURMODELS; cm++) 00239 { 00240 // Get the default colour context object for this colour model number 00241 // I do this via a copy of the real array to avoid the GetDefaultContext() 00242 // call giving an ENSURE failure in the case of a NULL context pointer. 00243 DefaultCC = DefaultCCA.Context[cm]; 00244 00245 if (DefaultCC != NULL) 00246 { 00247 // Set the default to NULL to ensure fewer rampant pointers are 00248 // left lying around (just to be on the safe side) 00249 ColourContext::SetGlobalDefault((ColourModel) cm, NULL); 00250 00251 // Remove from the list. Note that we use RemoveItem to *force* 00252 // removal - RemoveContext only removes it if UsageCount == 0. 00253 ColContextList->RemoveItem(DefaultCC); 00254 00255 // Decrement usage. This *should* take it down to zero usage, as 00256 // it is hoped that by the time we are called, all other users will 00257 // have released their claims. We do this to stop the ENSURE from 00258 // triggering when we delete the object. 00259 DefaultCC->DecrementUsage(); 00260 00261 // And delete the object 00262 delete DefaultCC; 00263 } 00264 } 00265 00266 ENSURE(ColContextList->IsEmpty(), "ColourContextList::DeinitColourContexts: Some ColourContext(s) have not yet been released"); 00267 00268 // And delete the global list of contexts 00269 delete ColContextList; 00270 ColContextList = NULL; 00271 } 00272 00273 00274 00275 00276 /******************************************************************************************** 00277 00278 > void ColourContextList::AddContext(ColourContext **NewContext) 00279 00280 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00281 Created: 11/04/94 00282 Inputs: - 00283 Outputs: An equivalent colour context that may now be used 00284 Returns: - 00285 00286 Purpose: "Adds" the given colour context to the global list of available 00287 contexts. Note that if an identical context is already present in 00288 the list, the passed context will be DELETEd and the existing 00289 context will be returned in the given pointer. Thus, you must 00290 only ever access the context through the returned pointer, rather 00291 than the pointer that you originally allocated with 'new'. 00292 00293 i.e. to create and use a new context, you must: 00294 { 00295 ColourContext *MyContext; 00296 00297 MyContext = new ColourContextABCD(1.0); // Create new context 00298 if (MyContext == NULL) 00299 return(FAILED_MISERABLY); 00300 00301 ColContextList->AddContext(&MyContext); // MyContext may change! 00302 00303 MyContext->DoSomething... // Use the context 00304 00305 ColContextList->RemoveContext(&MyContext); // Have finished with it 00306 00307 // MyContext is now a NULL pointer, so don't use it! 00308 } 00309 00310 Notes: You must NOT delete the context when you finish with it. Instead, you 00311 must call ColourContextList::RemoveContext() when you have finished with 00312 the context. The context will be automatically deleted when it is no 00313 longer in use by anyone. 00314 00315 (Sharing of contexts is currently disabled - see the comment in the 00316 function for details) 00317 00318 Errors: - 00319 SeeAlso: ColourContext::ConvertColour; ColourContext::ConvertColourInternal 00320 00321 ********************************************************************************************/ 00322 00323 void ColourContextList::AddContext(ColourContext **NewContext) 00324 { 00325 ENSURE(NewContext != NULL && *NewContext != NULL, 00326 "ColourContextList::AddContext called with NULL parameter!"); 00327 00328 #if FALSE 00329 /* 00330 Jason 22/5/96 00331 We no longer merge contexts because this makes for danger with the new ColourPlate 00332 system - it's now too easy to change a colourcontext by altering its ColourPlate, 00333 in which case shared contexts will cause extreme grief. 00334 00335 ColourContext *Item; 00336 00337 Item = (ColourContext *) GetHead(); 00338 00339 while (Item) 00340 { 00341 if (!Item->IsDifferent(*NewContext)) // Have found identical context 00342 { 00343 delete *NewContext; // Delete the new context 00344 Item->IncrementUsage(); // Increment the new context's usage count 00345 *NewContext = Item; // And return the existing one for use 00346 return; 00347 } 00348 00349 Item = (ColourContext *) GetNext(Item); 00350 } 00351 00352 // We have searched the entore list now but still have no equivalent context 00353 // so it is necessary to add this context to the list, and return it. 00354 */ 00355 #endif 00356 00357 // However, we do check that the given context is not already in the list, 00358 // and ignore the caller if it's already there. 00359 ColourContext *Item; 00360 00361 Item = (ColourContext *) GetHead(); 00362 00363 while (Item) 00364 { 00365 if (Item == *NewContext) 00366 { 00367 Item->IncrementUsage(); // Increment the context's usage count 00368 return; 00369 } 00370 00371 Item = (ColourContext *) GetNext(Item); 00372 } 00373 00374 AddTail(*NewContext); 00375 (*NewContext)->Init(); 00376 00377 // And by leaving the contents of the passed pointer alone, we return it. 00378 } 00379 00380 00381 00382 /******************************************************************************************** 00383 00384 > void ColourContextList::RemoveContext(ColourContext **OldContext) 00385 00386 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00387 Created: 11/04/94 00388 Inputs: - 00389 Outputs: - 00390 Returns: - 00391 00392 Purpose: "Removes" the given colour context to the global list of available 00393 contexts. If the context is now no longer in use by anyone, it will 00394 be 'delete'd. The context pointer passed in will be set to NULL. 00395 Errors: - 00396 SeeAlso: ColourContextList::AddContext; ColourContext 00397 00398 ********************************************************************************************/ 00399 00400 void ColourContextList::RemoveContext(ColourContext **OldContext) 00401 { 00402 ENSURE(OldContext != NULL && *OldContext != NULL, 00403 "ColourContextList::RemoveContext called with NULL parameter!"); 00404 00405 if (!((*OldContext)->DecrementUsage())) // Not still in use, so discard it 00406 { 00407 RemoveItem(*OldContext); 00408 delete *OldContext; 00409 } 00410 00411 *OldContext = NULL; 00412 } 00413 00414