colcontx.cpp

Go to the documentation of this file.
00001 // $Id: colcontx.cpp 1402 2006-07-04 09:26:38Z 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 // colcontx.cpp - ColourContext and derived classes
00099 
00100 /*
00101 */
00102 
00103 
00104 #include "camtypes.h"
00105 
00106 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 #include "colcontx.h"
00108 #include "colormgr.h"
00109 #include "colourix.h"
00110 #include "colplate.h"
00111 //#include "doccolor.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 //#include "jason.h"
00114 //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 #include "scunit.h"
00116 
00117 #if defined(EXCLUDE_FROM_RALPH) || defined(EXCLUDE_FROM_XARALX)
00118 #undef  NO_XARACMS
00119 #define NO_XARACMS
00120 #endif
00121 
00122 #ifndef NO_XARACMS
00123 #include "xaracms.h"
00124 #endif
00125 
00126 CC_IMPLEMENT_MEMDUMP(ColourContext,         ListItem)
00127 CC_IMPLEMENT_MEMDUMP(ColourContextRGBT,     ColourContext)
00128 CC_IMPLEMENT_MEMDUMP(ColourContextWebRGBT,  ColourContextRGBT)
00129 CC_IMPLEMENT_MEMDUMP(ColourContextCMYK,     ColourContext)
00130 CC_IMPLEMENT_MEMDUMP(ColourContextHSVT,     ColourContext)
00131 CC_IMPLEMENT_MEMDUMP(ColourContextGreyT,    ColourContext)
00132 
00133 #define new CAM_DEBUG_NEW
00134 
00135 /*  NOTE WELL ALL YE WHO ENTER HERE
00136  *
00137  *  If you are implementing a new context class, have a look at the implementation
00138  *  of RGBT, which is a simple base model. Note that you may also find it useful
00139  *  to look at CMYK, as it overrides the ConvertColourInternal to do special stuff.
00140  */
00141 
00142 
00143 
00144 /*  DefaultColourContexts
00145  *
00146  *  This is a 'global' array of default colour contexts for each of the
00147  *  possible 16 colour models Camelot can support. When defining/converting 
00148  *  colours, a default colour context is implicitly specified, if no colour
00149  *  context is given.
00150  *  Access is via the static function ColourContext::GetDefault()
00151  */
00152 
00153 ColourContextArray ColourContext::GlobalDefaultContext = 
00154 {
00155     { NULL, NULL, NULL, NULL,
00156     NULL, NULL, NULL, NULL,
00157     NULL, NULL, NULL, NULL,
00158     NULL, NULL, NULL, NULL }
00159 };
00160 
00161 
00162 
00163 /* NextColourContextHandle 
00164  *
00165  * This variable keeps track of the current handle - each colour context must have a 
00166  * unique handle - this is used in colour caches to identify the context in which
00167  * they are currently cached, so that they know when the cache is invalid.
00168  */
00169 
00170 ColourContextHandle ColourContext::NextColourContextHandle = 1;
00171 
00172 
00173 
00174 
00175 /********************************************************************************************
00176 
00177 >   void ColourContext::ColourContext(View *Scope)
00178 
00179     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00180     Created:    31/03/94
00181     Inputs:     Scope - The view within which this context is to be used, or NULL
00182                 for a global (non-view-specific) context
00183     Outputs:    -
00184     Returns:    -
00185     Purpose:    Constructor for a Colour context. This is shared code used by
00186                 all derived ColourContextXXXX classes. You cannot create
00187                 vanilla ColourContext objects (virtual functions abound)
00188 
00189     Notes:      The usage count for a colour context defaults to 0
00190                 ("not in use"). When using colour contexts, you should always
00191                 register them with the global ColContextList object (see
00192                 ColourContextList::AddContext for details)
00193 
00194                 When created, relevant conversion parameters (gamma correction
00195                 etc) are passed in to the constructor.The context stores these
00196                 parameters so it can quickly compare itself to another context,
00197                 but it may defer creation of tables and other essential stuff 
00198                 until the Init() function is called (when it is added to the
00199                 list of available colour contexts). Nobody but the context list
00200                 can call the Init() function.
00201 
00202                 The passed-in Scope may be NULL, in which case global scope is
00203                 used. However, if you're using this within the scope of any
00204                 view, note that you must set up ScopeView properly or colour
00205                 separated output of some colour models will be incorrect.
00206 
00207     Errors:     -
00208     SeeAlso:    ColourContextRGBT::ColourContextRGBT;
00209                 ColourContextCMYK::ColourContextCMYK;
00210                 ColourContextHSVT::ColourContextHSVT;
00211                 ColourContextList::AddContext
00212 
00213 ********************************************************************************************/
00214 
00215 ColourContext::ColourContext(View *Scope)
00216 {
00217     MyHandle = NextColourContextHandle++;
00218 
00219     ScopeView = Scope;
00220 
00221     UsageCount = 0;
00222 
00223     ColPlate = NULL;
00224 
00225 PORTNOTE("other","Removed HCMTRANSFORM usage")
00226 #ifndef EXCLUDE_FROM_XARALX
00227     CMSTransform = NULL;
00228 #endif
00229     // ColourModel and Model-specific data must be dealt with in the 
00230     // constructor/Init() for the derived ColourContextXXXX class
00231 }
00232 
00233 
00234 
00235 /********************************************************************************************
00236 
00237 >   void ColourContext::~ColourContext(void)
00238 
00239     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00240     Created:    31/03/94
00241 
00242     Purpose:    Colour context destructor
00243 
00244     Notes:      This destroys any attached ColourPlate descriptor
00245 
00246     SeeAlso:    ColourContextList::AddContext
00247 
00248 ********************************************************************************************/
00249 
00250 ColourContext::~ColourContext()
00251 {
00252     ENSURE(UsageCount == 0, "ColourContext deleted while still in use!");
00253 
00254     if (ColPlate != NULL)
00255     {
00256         delete ColPlate;
00257         ColPlate = NULL;
00258     }
00259 
00260 #ifndef NO_XARACMS
00261     if (CMSTransform != NULL)
00262     {
00263         if (GetApplication()->GetCMSManager() != NULL)
00264             GetApplication()->GetCMSManager()->DestroyTransform(CMSTransform);
00265         CMSTransform = NULL;
00266     }
00267 #endif
00268 }
00269 
00270 
00271 
00272 /********************************************************************************************
00273 
00274 >   BOOL ColourContext::Init(void)
00275 
00276     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00277     Created:    11/04/94
00278     Inputs:     -
00279     Outputs:    -
00280     Returns:    TRUE if it succeeds
00281                 FALSE if it fails (and it'll set an error description)
00282     Purpose:    Colour context initialiser. This is called by the ColourContextList
00283                 when it wishes to add a context to the list, and makes the context
00284                 ready for use. This allows the list to compare contexts, and only
00285                 initialise a given context when it knows the initialisation is
00286                 absolutely necessary (e.g. allocating a large chunk of memory or 
00287                 calculating a complex table is avoided until we are sure there are
00288                 no equivalent contexts already available)
00289                 This function is overridden by colour contexts which actually need to
00290                 do some initialisation other than just storing a few values away.
00291     Errors:     -
00292     SeeAlso:    ColourContextList::AddContext
00293 
00294 ********************************************************************************************/
00295 
00296 BOOL ColourContext::Init(void)
00297 {
00298     ENSURE(UsageCount == 0, "ColourContext initialised when in use?!?!");
00299 
00300     IncrementUsage();   // We are now in use. UsageCount is now 1
00301     return(TRUE);       // Initialisation succeeded
00302 }
00303 
00304 
00305 
00306 /********************************************************************************************
00307 
00308 >   void ColourContext::DecrementUsage(void)
00309 
00310     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00311     Created:    31/03/94
00312     Inputs:     -
00313     Outputs:    -
00314     Returns:    TRUE if the object is still in use
00315     Purpose:    Decrements usage-count for a colour context. This count allows us to
00316                 determine when we can delete unused contexts.
00317 
00318     Notes:      The usage count for a colour context defaults to 0
00319                 ("not in use"). When using colour contexts, you should always
00320                 register them with the global ColContextList object (see
00321                 ColourContextList::AddContext for details)
00322 
00323     Errors:     ENSURE fails if the usage count goes negative, indicating the context
00324                 is being 'released' more times than it is 'claimed'.
00325     SeeAlso:    ColourContext::IncrementUsage; ColourContextList::AddContext
00326 
00327 ********************************************************************************************/
00328 
00329 BOOL ColourContext::DecrementUsage(void)
00330 {
00331     ENSURE(UsageCount > 0, "ColourContext::DecrementUsage - Usage count is negative!");
00332     return((--UsageCount) != 0);
00333 }
00334 
00335 
00336 
00337 /********************************************************************************************
00338 
00339 >   virtual void ColourContext::PackColour(ColourGeneric *Source, ColourPacked *Result)
00340 
00341     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00342     Created:    31/03/94
00343     Inputs:     Source - A ColourGeneric structure defining the colour in the model
00344                 pertaining to this colour context.
00345                 Result - A Packed colour structure in the same model, into which the result
00346                 is copied.
00347 
00348     Outputs:    -
00349     Returns:    -
00350     Purpose:    Converts 128-bit colour representation to 32-bit packed form
00351 
00352     Notes:      This function operates on the colour using a generic component pattern
00353                 Colours such as ColourHSVT do not conform to this pattern and thus must
00354                 be unpacked with derived methods (ColourContextHSVT::UnpackColour)
00355                 However, this function will work on any 4-component model which uses 8bits
00356                 and 32-bits respectively for all 4 components, and the same 8.24 fixedpoint
00357                 32-bit representation. 
00358 
00359     Scope:      Private (used internally by friend class DocColour)
00360     Errors:     -
00361     SeeAlso:    ColourContext::UnpackColour
00362 
00363 ********************************************************************************************/
00364 
00365 void ColourContext::PackColour(ColourGeneric *Source, ColourPacked *Result)
00366 {
00367     PColourGeneric *bob = (PColourGeneric *) Result;
00368 
00369     bob->Component1 = PackColour256(Source->Component1);
00370     bob->Component2 = PackColour256(Source->Component2);
00371     bob->Component3 = PackColour256(Source->Component3);
00372     bob->Component4 = PackColour256(Source->Component4);
00373 }
00374 
00375 
00376 
00377 
00378 /********************************************************************************************
00379 
00380 >   virtual void ColourContext::UnpackColour(ColourPacked *Source, ColourGeneric *Result)
00381 
00382     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00383     Created:    31/03/94
00384     Inputs:     Source - A Packed Colour structure defining the colour in the model
00385                 pertaining to this colour context.
00386                 Result - A ColourGeneric structure in the same model, into which the 
00387                 result is copied.
00388     Outputs:    -
00389     Returns:    -
00390     Purpose:    Converts 32-bit packed colour representation to 128-bit form
00391 
00392     Notes:      This function operates on the colour using a generic component pattern
00393                 Colours such as ColourHSVT do not conform to this pattern and thus must
00394                 be unpacked with derived methods (ColourContextHSVT::UnpackColour)
00395                 However, this function will work on any 4-component model which uses 8bits
00396                 and 32-bits respectively for all 4 components, and the same 8.24 fixedpoint
00397                 32-bit representation. 
00398 
00399     Scope:      Private (used internally by friend class DocColour)
00400     Errors:     -
00401     SeeAlso:    ColourContext::PackColour
00402 
00403 ********************************************************************************************/
00404 
00405 void ColourContext::UnpackColour(ColourPacked *Source, ColourGeneric *Result)
00406 {
00407     PColourGeneric *bob = (PColourGeneric *) Source;
00408 
00409     UnpackColour256(bob->Component1, &Result->Component1);
00410     UnpackColour256(bob->Component2, &Result->Component2);
00411     UnpackColour256(bob->Component3, &Result->Component3);
00412     UnpackColour256(bob->Component4, &Result->Component4);
00413 }
00414 
00415 
00416 
00417 /********************************************************************************************
00418 
00419 >   virtual BOOL ColourContext::IsDifferent(ColourContext *Other) const
00420 
00421     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00422     Created:    13/04/94
00423     Inputs:     Other - a colour context to compare ourselves to
00424     Outputs:    -
00425     Returns:    TRUE if the other colour context object is different from
00426                 ourself, or FALSE if it is an exactly equivalent context.
00427     Purpose:    Determine if two colour contexts are not exactly equivalent
00428     Errors:     -
00429     SeeAlso:    -
00430 
00431 ********************************************************************************************/
00432 
00433 
00434 BOOL ColourContext::IsDifferent(ColourContext *Other) const
00435 {
00436     if (Other == this)
00437         return(FALSE);                      // Different object? (Nope)
00438 
00439     if (Other->ScopeView != ScopeView)
00440         return(TRUE);                       // Different Scope Views?
00441 
00442     return(Other->ColModel != ColModel);    // Different Colour Model?
00443 }
00444 
00445 
00446 
00447 
00448 /********************************************************************************************
00449 
00450 >   virtual void ColourContext::ConvertColourBase(ColourContext *SourceContext,
00451                                             ColourGeneric *Source, ColourGeneric *Result
00452                                             IndexedColour *SourceIxCol = NULL)
00453 
00454     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00455     Created:    31/03/94
00456     Inputs:     SourceContext - The context in which the source is defined 
00457 
00458                 Source - A ColourGeneric to convert
00459 
00460                 Result - A ColourGeneric structure to recieve the resulting converted colour,
00461                 as defined in this ColourContext.
00462 
00463                 SourceIxCol - NULL, or a pointer to the IndexedColour we are converting.
00464                 This is used only for handling spot colour separations, to determine if
00465                 the colour is a given spot colour or tint thereof.
00466 
00467     Outputs:    Result - will be returned with the converted colour
00468 
00469     Purpose:    Converts a Colour into this colour context, from the default colour context
00470                 implied by the given colour model
00471                 Post-processing (as described by the attached ColourPlate object) will
00472                 be applied to generate colour separations (etc) as required.
00473 
00474                 The converted colour will be supplied from a cache where possible
00475 
00476     Notes:      It is up to the caller to update caches etc if necessary
00477                 This is used as a base on which ConvertColourInternal methods are built
00478 
00479                 ColourContextCMYK overrides this base class method to provide direct
00480                 passthrough of CMYK colours into a CMYK output context. (passthrough
00481                 otherwise only occurs if the source & destination contexts are the
00482                 same object)
00483 
00484     Scope:      private to colcontx.cpp
00485     Errors:     -
00486     SeeAlso:    ColourContext::ConvertColour
00487 
00488 ********************************************************************************************/
00489 
00490 void ColourContext::ConvertColourBase(ColourContext *SourceContext,
00491                                         ColourGeneric *Source, ColourGeneric *Result,
00492                                         IndexedColour *SourceIxCol)
00493 {
00494 #ifndef NO_XARACMS
00495     // Last minute bodge for Composite preview of CMYK colours in RGB space
00496     // This is done here cos it's much faster, and gets around pre/post filter problems
00497     // with CMYK colours which aren't IndexedColours (like intermediate blend/gradfill DocColours)
00498     if (ColPlate != NULL && ColPlate->GetType() == COLOURPLATE_COMPOSITE &&
00499         GetColourModel() == COLOURMODEL_RGBT &&
00500         SourceContext->GetColourModel() == COLOURMODEL_CMYK)
00501     {
00502         // If it's a CMYK colour, then it's already in printer gamut, so we only apply
00503         // the backward colour correction factor to it.
00504         // Note that this means we chuck away the normal colour conversion system!
00505         XaraCMS* lpCMSMan = GetApplication()->GetCMSManager();
00506         if (lpCMSMan != NULL)
00507         {
00508             ColourCMYK Def;
00509             memcpy(&Def, Source, sizeof(ColourGeneric));
00510 
00511             lpCMSMan->ConvertColourForPaperView(&Def, (ColourRGBT *) Result);
00512             return;
00513         }
00514     }
00515 #endif
00516 
00517     // Copy the source colour into a temporary variable
00518     ColourGeneric FilteredSource;
00519     memcpy(&FilteredSource, Source, sizeof(ColourGeneric));
00520 
00521     // Call the SourceContext to allow it to pre-filter the colour. This is used to
00522     // provide colour separations and other doody features when converting CMYK colours
00523     // - when converting non-CMYK colours, this is usually done in the OutputFilter (below)
00524     if (ColPlate != NULL && !ColPlate->IsDisabled())
00525         SourceContext->ApplyInputFilter(ColPlate, this, &FilteredSource, SourceIxCol);
00526 
00527     // -----
00528     // Call levels expected:
00529     //  1 inline ConvertColour checks if can satisfy from cache
00530     //  2 function ConvertColourInternal does any short cuts it can, such
00531     //    as CMYK->CMYK passthrough
00532     //  3 Call ConvertColourBase, which
00533     //      a) Checks if in same colour model, and implements passthrough, or
00534     //      b) Converts colour properly via CIET space
00535 
00536     if (SourceContext == this)
00537     {
00538         // The SourceContext and Destination context are identical, so we can
00539         // just copy the definition directly across.
00540         memcpy(Result, &FilteredSource, sizeof(ColourGeneric));
00541     }
00542     else
00543     {
00544         DColourCIET IntermediateResult;
00545 
00546         SourceContext->ConvertToCIET(&FilteredSource, &IntermediateResult);
00547         ConvertFromCIET(&IntermediateResult, Result);
00548     }
00549 
00550 
00551     // Call the DestinationContext (derived class of this) to apply any output filtering -
00552     // non-CMYK colour conversions will separate the colour (as appropriate) here
00553     if (ColPlate != NULL && !ColPlate->IsDisabled())
00554         ApplyOutputFilter(ColPlate, SourceContext, Result, SourceIxCol);
00555 }
00556 
00557 
00558 
00559 
00560 /********************************************************************************************
00561 
00562 >   void ColourContext::ConvertColourInternal(DocColour *Source, ColourGeneric *Result)
00563 
00564     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00565     Created:    31/03/94
00566     Inputs:     Source - A Colour to convert
00567                 Result - A ColourGeneric structure to recieve the resulting converted colour,
00568                 as defined in this ColourContext.
00569     Outputs:    -
00570     Returns:    -
00571     Purpose:    Converts a Colour into this colour context.
00572                 The converted colour will be supplied from a cache where possible
00573 
00574     Notes:      This is used internally. It is only called by the inlined conversion
00575                 functions if they fail to return a cached result
00576     Errors:     -
00577     SeeAlso:    ColourContext::ConvertColour
00578 
00579 ********************************************************************************************/
00580 
00581 void ColourContext::ConvertColourInternal(DocColour *Source, ColourGeneric *Result)
00582 {
00583     if (Source->Info.SourceColourModel == COLOURMODEL_INDEXED)
00584     {
00585         IndexedColour *SrcIndexed = Source->SourceColour.Indexed.Colour;
00586 
00587         // Convert the indexed colour to our context
00588         ConvertColour(SrcIndexed, Result);
00589 
00590         // If IndexedColour, we do NOT want the colour cached at the DocColour
00591         // level (else if the IxCol changes, we'd have to search for all related
00592         // DocCols to fix their caches... erg!)
00593         return;
00594     }
00595 
00596     // Unpack the 32-bit colour into a 128-bit structure, and then invoke the
00597     // shared internal conversion routine.
00598     ColourGeneric SourceDefn;
00599 
00600     // If this DocColour should not be separated (it's a UI colour), then disable
00601     // any active colour plate to stop it separating the output - we'll save and restore
00602     // its previous state around the call to ConvertColourBase
00603     BOOL WasDisabled = TRUE;
00604     if (ColPlate != NULL)
00605     {
00606         WasDisabled = ColPlate->IsDisabled();
00607         ColPlate->SetDisabled(!Source->IsSeparable());
00608     }
00609 
00610         // Check if we're doing a spot colour plate. We either get the colour's source colour,
00611         // or if it shouldn't appear on the plate, we get White.
00612         if (ColPlate != NULL && !ColPlate->IsDisabled() && ColPlate->GetType() == COLOURPLATE_SPOT)
00613         {
00614             // We're doing a SPOT colour plate, but this colour is a local DocColour, so
00615             // it cannot possibly be a tint on this plate, so we just return white.
00616             GetGlobalDefault(Source->GetColourModel())->GetWhite(&SourceDefn);
00617         }
00618         else
00619         {
00620             // Unpack the colour
00621             GetGlobalDefault(Source->GetColourModel())->UnpackColour(&Source->SourceColour, &SourceDefn);
00622         }
00623 
00624         // Assume that the source context is a global default. Generally, this should be true,
00625         // as all source colours should be defined in terms of logical colour models.
00626         ConvertColourBase(GetGlobalDefault(Source->GetColourModel()),
00627                             &SourceDefn, Result);
00628 
00629     // And restore the previous ColourPlate "disabled" state
00630     if (ColPlate != NULL)
00631         ColPlate->SetDisabled(WasDisabled);
00632 
00633     PackColour(Result, &Source->CachedColour);  // And update the cache
00634 
00635     // Update cache flags - I am the context in which the cache is defined
00636     Source->Info.OCContextHandle  = MyHandle;
00637     Source->Info.CacheColourModel = ColModel;
00638 }
00639 
00640 
00641 
00642 /********************************************************************************************
00643 
00644 >   void ColourContext::ConvertColourInternal(DocColour *Source, ColourPacked *Result)
00645 
00646     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00647     Created:    14/04/94
00648     Inputs:     Source - A Colour to convert
00649                 Result - A PColourGeneric structure to recieve the resulting converted colour,
00650                 as defined in this ColourContext.
00651     Outputs:    -
00652     Returns:    -
00653     Purpose:    Converts a Colour into this colour context.
00654                 The converted colour will be supplied from a cache where possible (this check
00655                 is made by the caller function ConvertColour)
00656     Scope:      PRIVATE - for use only by 'friend' rendering classes:
00657                     OSRenderRegion, GRenderRegion
00658     Errors:     -
00659     SeeAlso:    ColourContext::ConvertColour
00660 
00661 ********************************************************************************************/
00662 
00663 void ColourContext::ConvertColourInternal(DocColour *Source, ColourPacked *Result)
00664 {
00665     ColourGeneric NewResult;
00666     ConvertColourInternal(Source, &NewResult);  // Convert
00667 
00668     PackColour(&NewResult, Result);             // Pack the colour into Result...
00669 
00670     if (Source->Info.SourceColourModel != COLOURMODEL_INDEXED)
00671     {
00672         // And (if not an IndexedColour) update the cache
00673         Source->Info.OCContextHandle  = MyHandle;
00674         Source->Info.CacheColourModel = ColModel;
00675         memcpy(&Source->CachedColour, Result, sizeof(ColourPacked));
00676     }
00677 }
00678 
00679 
00680 
00681 /********************************************************************************************
00682 
00683 >   void ColourContext::ConvertColour(IndexedColour *Source, ColourGeneric *Result)
00684 
00685     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00686     Created:    31/03/94
00687     Inputs:     Source - An IndexedColour to convert
00688                 Result - A ColourGeneric structure to recieve the resulting converted colour,
00689                 as defined in this ColourContext.
00690     Outputs:    -
00691     Returns:    -
00692     Purpose:    Converts an indexed colour into this colour context.
00693                 The converted colour will be supplied from a cache where possible
00694     Errors:     -
00695     SeeAlso:    -
00696 
00697 ********************************************************************************************/
00698 
00699 void ColourContext::ConvertColour(IndexedColour *Source, ColourGeneric *Result)
00700 {
00701     ENSURE(UsageCount > 0, "Colour context being used when not initialised!");
00702 
00703     if (Source->Info.OCContextHandle != MyHandle)   // Uncached so convert it into the cache
00704     {
00705         // Ask the colour to get its source colour for us. If this is a Linked/Tint colour,
00706         // this could well involve getting another colour's definition, converting it, and
00707         // generally giving us an extended tour of stack city.
00708         ColourGeneric SourceColour;
00709         Source->GetSourceColour(&SourceColour);
00710 
00711         // Check if we're doing a spot colour plate. We either get the colour's source colour,
00712         // or if it shouldn't appear on the plate, we get White.
00713         if (ColPlate != NULL && !ColPlate->IsDisabled())
00714         {
00715             switch(ColPlate->GetType())
00716             {
00717                 case COLOURPLATE_SPOT:
00718                     // If we're doing a spot plate and this isn't a descendant of the spot colour
00719                     // then we must eliminate it from this plate. We must also check that it's a "true"
00720                     // spot/tint, as opposed to a tint which is really a process colour.
00721                     if ((!Source->IsADescendantOf(ColPlate->GetSpotColour())) ||
00722                         (!Source->IsSpotOrTintOfSpot()))
00723                     {
00724                         // Fill it with whatever White is defined as in the source context
00725                         GetGlobalDefault(Source->GetColourModel())->GetWhite(&SourceColour);
00726                     }
00727                     break;
00728 
00729                 case COLOURPLATE_CYAN:
00730                 case COLOURPLATE_MAGENTA:
00731                 case COLOURPLATE_YELLOW:
00732                 case COLOURPLATE_KEY:
00733                     // If we're doing a process plate, eliminate any spot colours (or tints) from it
00734                     if (Source->IsSpotOrTintOfSpot())
00735                     {
00736                         // Fill it with whatever White is defined as in the source context
00737                         GetGlobalDefault(Source->GetColourModel())->GetWhite(&SourceColour);
00738                     }
00739                     break;
00740                 default:
00741                     break;
00742             }
00743         }
00744 
00745         ConvertColourBase(GetGlobalDefault(Source->GetColourModel()),
00746                             &SourceColour, &Source->CachedColour,
00747                             Source);
00748 
00749         Source->Info.OCContextHandle  = MyHandle;
00750         Source->Info.CacheColourModel = ColModel;
00751     }
00752 
00753     // Copy the result from our cache
00754     memcpy(Result, &Source->CachedColour, sizeof(ColourGeneric));
00755 }
00756 
00757 
00758 
00759 /********************************************************************************************
00760 
00761 >   void ColourContext::ConvertColour(ColourContext *SourceContext,
00762                                         ColourGeneric *SourceColour,
00763                                         ColourGeneric *Result)
00764 
00765     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00766     Created:    31/03/94
00767     Inputs:     SourceContext - The colour context in which the Source Colour is defined
00768                 Source - A ColourGeneric structure defining a colour to convert, in the
00769                 given SourceContext
00770                 Result - A ColourGeneric structure to recieve the resulting converted colour,
00771                 as defined in this ColourContext.
00772     Outputs:    -
00773     Returns:    -
00774     Purpose:    Converts a colour in any arbitrary colour context into this colour context.
00775                 The converted colour will be supplied from a cache where possible
00776     Errors:     -
00777     SeeAlso:    -
00778 
00779 ********************************************************************************************/
00780 
00781 void ColourContext::ConvertColour(ColourContext *SourceContext,
00782                                     ColourGeneric *SourceColour,
00783                                     ColourGeneric *Result)
00784 {
00785     ENSURE(UsageCount > 0, "Colour context being used when not initialised!");
00786 
00787     // This may look like an opportunity for optimisation, but
00788     // ConvertColourBase is actually an inline function
00789     ConvertColourBase(SourceContext, SourceColour, Result);
00790 }
00791 
00792 
00793 
00794 /********************************************************************************************
00795 
00796 >   virtual void ColourContext::CreateExternalTransform(void)
00797 
00798     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
00799     Created:    12/05/96
00800     Inputs:     -
00801     Returns:    -
00802     Purpose:    Create an external transform to be used during colour conversions from
00803                 RGB to the current RCS space. This function uses the Winoil CMS Manager
00804                 to create the transform. Both forward and backward transforms use logical
00805                 RGB descriptions.
00806 
00807 ********************************************************************************************/
00808 
00809 void ColourContext::CreateExternalTransform()
00810 {
00811     // We do nothing here. If no one creates an external transform, the default
00812     // internal one will be used. To create an external transform, call the derived class
00813     // function, not this one as you can see it does nothing.
00814 }
00815 
00816 
00817 /********************************************************************************************
00818 
00819 >   virtual void ColourContext::ApplyInputFilter(ColourPlate *FilterDescription,
00820                                                     ColourContext *DestContext,
00821                                                     ColourGeneric *OutputColour,
00822                                                     IndexedColour *SourceIxCol);
00823 
00824     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00825     Created:    22/1/96
00826     Inputs:     FilterDescription - A ColourPlate describing how the colour is to be filtered
00827     
00828                 DestContext - Points to the context to which the OutputColour will be
00829                 converted after we return it.
00830 
00831                 OutputColour - The colour to be filtered
00832 
00833                 SourceIxCol - NULL, or the original IndexedColour which is being converted.
00834                 This is used for handling spot colour separation correctly.
00835 
00836     Outputs:    OutputColour - Will be modified as appropriate to the current colour
00837                 filtering options (see Purpose)
00838 
00839     Purpose:    All colour conversions call this function for the SOURCE context
00840                 immediately before converting the colour. This gives the input colour
00841                 context the chance to apply a filtering process to the colour.
00842 
00843                 This is usually used to provide colour separations. Often, this function
00844                 will do nothing to the output colour - generally it is only used by CMYK
00845                 contexts in order to colour-separate the colour in CMYK space.
00846 
00847     SeeAlso:    ColourContext::ConvertColourBase
00848 
00849 ********************************************************************************************/
00850 
00851 void ColourContext::ApplyInputFilter(ColourPlate *FilterDescription, ColourContext *DestContext,
00852                                             ColourGeneric *OutputColour, IndexedColour *SourceIxCol)
00853 {
00854 //  ERROR3IF(FilterDescription == NULL || DestContext == NULL || OutputColour == NULL, "Illegal NULL params");
00855 //
00856 //  if (FilterDescription == NULL)
00857 //      return;
00858 //
00859 }
00860 
00861 
00862 
00863 /********************************************************************************************
00864 
00865 >   virtual void ColourContext::ApplyOutputFilter(ColourPlate *FilterDescription,
00866                                                     ColourContext *SourceContext,
00867                                                     ColourGeneric *OutputColour,
00868                                                     IndexedColour *SourceIxCol);
00869 
00870     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00871     Created:    22/1/96
00872     Inputs:     FilterDescription - A ColourPlate describing how the colour is to be filtered
00873     
00874                 SourceContext - Points to the context from which the OutputColour has just
00875                 been converted. 
00876 
00877                 OutputColour - The colour to be filtered
00878 
00879                 SourceIxCol - NULL, or the IndexedColour which was the source of the colour
00880                 being converted. This is only used for information when preparing spot colour
00881                 separations.
00882 
00883     Outputs:    OutputColour - Will be modified as appropriate to the current colour
00884                 filtering options (see Purpose)
00885 
00886     Purpose:    All colour conversions call this function for the DEST context immediately
00887                 prior to returning the converted colour to the caller. This gives the output
00888                 colour context the chance to apply an output filtering process to the output
00889                 colour.
00890 
00891                 This is usually used to provide colour separations, and may also be used
00892                 to apply some colour corrections. Often, this function will do nothing
00893                 to the output colour.
00894 
00895     SeeAlso:    ColourContext::ConvertColourBase
00896 
00897 ********************************************************************************************/
00898 
00899 void ColourContext::ApplyOutputFilter(ColourPlate *FilterDescription, ColourContext *SourceContext,
00900                                             ColourGeneric *OutputColour, IndexedColour *SourceIxCol)
00901 {
00902 //  ERROR3IF(FilterDescription == NULL || SourceContext == NULL || OutputColour == NULL, "Illegal NULL params");
00903 //
00904 //  if (FilterDescription == NULL)
00905 //      return;
00906 }
00907 
00908 
00909 
00910 /********************************************************************************************
00911 
00912 >   void ColourContext::SetColourPlate(ColourPlate *NewColourPlate)
00913 
00914     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00915     Created:    31/01/96
00916     Inputs:     NULL (to disable colour seps), or points to the new ColourPlate descriptor object
00917                 NOTE that the ColourPlate object now belongs to the ColourContext, and will be
00918                 deleted by the context when it is finished with it.
00919 
00920     Purpose:    Sets a colour separation/plate for this context
00921 
00922     Notes:      The ColourPlate object now belongs to the ColourContext, and will be
00923                 deleted by the context when it is finished with it.
00924 
00925                 (To remove the ColourPlate again in a way that does not delete the ColourPlate,
00926                 call ColourContext::DetachColourPlate rather than SetColourPlate(NULL))
00927 
00928                 The Context's cache handle will be changed so that all cached colours
00929                 in this output context are effectively 'flushed'.
00930 
00931     SeeAlso:    ColourPlate; ColourContext::ApplyOutputFilter; ColourContext::GetColourPlate;
00932                 ColourContext::DetachColourPlate
00933 
00934 ********************************************************************************************/
00935 
00936 void ColourContext::SetColourPlate(ColourPlate *NewColourPlate)
00937 {
00938     // Trying to set ColourPlate to the one we're already using - ignore them!
00939     if (ColPlate == NewColourPlate)
00940         return;
00941 
00942     // Delete our current ColourPlate
00943     if (ColPlate != NULL)
00944     {
00945         delete ColPlate;
00946         ColPlate = NULL;
00947     }
00948 
00949     // Remember our new ColourPlate filter descriptor
00950     ColPlate = NewColourPlate;
00951 
00952     // Change our context handle so that all cached colours in this context
00953     // are effectively "flushed"
00954     ColourPlateHasChanged();
00955 }
00956 
00957 
00958 
00959 /********************************************************************************************
00960 
00961 >   ColourPlate *ColourContext::DetachColourPlate(void)
00962 
00963     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00964     Created:    11/6/96
00965 
00966     Returns:    The pointer to the previously attached ColourPlate (may be NULL)
00967 
00968     Purpose:    Detaches the ColourPlate (if any) currently attached to this ColourContext.
00969                 The context will no longer use the colour plate descriptor, and will return
00970                 to default colour separation/correction actions.
00971                 
00972                 ** The caller is now responsible for deleting the returned object **
00973 
00974     Notes:      The Context's cache handle will be changed so that all cached colours
00975                 in this output context are effectively 'flushed'.
00976 
00977     SeeAlso:    ColourPlate; ColourContext::GetColourPlate; ColourContext::SetColourPlate
00978 
00979 ********************************************************************************************/
00980 
00981 ColourPlate *ColourContext::DetachColourPlate(void)
00982 {
00983     ColourPlate *OldColourPlate = ColPlate;
00984 
00985     if (ColPlate != NULL)
00986     {
00987         ColPlate = NULL;
00988 
00989         // Change our context handle so that all cached colours in this context
00990         // are effectively "flushed"
00991         ColourPlateHasChanged();
00992     }
00993 
00994     return(OldColourPlate);
00995 }
00996 
00997 
00998 
00999 /********************************************************************************************
01000 
01001 >   ColourPlate *ColourContext::GetColourPlate(void)
01002 
01003     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01004     Created:    31/01/96
01005 
01006     Returns:    NULL if Colour separation is disabled on this context, else a pointer
01007                 to a ColourPlate descriptor object which describes the current colour
01008                 separation/filtering options.
01009 
01010     Purpose:    Reads the colour separation/plate for this context
01011 
01012     SeeAlso:    ColourPlate; ColourContext::ApplyOutputFilter; ColourContext::SetColourPlate
01013 
01014 ********************************************************************************************/
01015 
01016 ColourPlate *ColourContext::GetColourPlate(void)
01017 {
01018     return(ColPlate);
01019 }
01020 
01021 
01022 
01023 /********************************************************************************************
01024 
01025 >   void ColourContext::ColourPlateHasChanged(void)
01026 
01027     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01028     Created:    9/5/96
01029 
01030     Purpose:    Effectively flushes the caches of all colours currently cached in this
01031                 ColourContext, so that on the next redraw they will re-convert. 
01032 
01033     Notes:      This is achieved by generating a new unique handle for this Context.
01034                 Note that after 65536 handles, we will start re-using handles, and
01035                 things will look bad if we inadvertently use the same handle for 2
01036                 contexts. This is an extremely unlikely occurrence, but please do
01037                 not call this function unless it is absolutely necessary, to minimise
01038                 the number of handle changes that occur.
01039 
01040                 This function is automatically called whenever you change the
01041                 ColourPlate attached to this context in any way.
01042 
01043     Scope:      Intended as an internal routine; also called by ColourPlate class
01044                 Should not be called by anyone else
01045 
01046     SeeAlso:    ColourContext::SetColourPlate; IndexedColour; DocColour
01047 
01048 ********************************************************************************************/
01049 
01050 void ColourContext::ColourPlateHasChanged(void)
01051 {
01052     // We need to change this context's "MyHandle" so that all cached colours for this
01053     // context are treated as non-cached again, and will be converted correctly for
01054     // the new output filter.
01055     MyHandle = NextColourContextHandle++;
01056 }
01057 
01058 
01059 
01060 /********************************************************************************************
01061 
01062 >   virtual BOOL ColourContext::SetComponentUnitGroup(UINT32 ComponentID,
01063                                                         UnitGroup* pComponentUnitGroup)
01064     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01065     Created:    02/05/96          
01066     Inputs:     ComponentIndex : the number of the component (1..GetComponentCount())
01067                 ComponentUnitGroup : pointer to the required UnitGroup for the component 
01068     Outputs:    -
01069     Returns:    TRUE if set OK
01070                 FALSE otherwise
01071     Purpose:    Allows the UnitGroup of the given component in the ColourModel to be set
01072     Errors:     ERROR2IF ComponentIndex < 1 or greater than number of components in model
01073 
01074 ********************************************************************************************/
01075 
01076 BOOL ColourContext::SetComponentUnitGroup(UINT32 ComponentID, UnitGroup* pComponentUnitGroup)
01077 {
01078     ERROR2IF(ComponentID < 1 || ComponentID > GetComponentCount(), FALSE, "Invalid Index");
01079     ERROR2IF(pComponentUnitGroup == NULL, FALSE, "Invalid UnitGroup");
01080 
01081     ERROR3IF(!pComponentUnitGroup->IS_KIND_OF(UnitGroup), "Invalid UnitGroup");
01082 
01083     UnitGroup** pUnitGroupArray = GetComponentUnitGroups();
01084     ERROR3IF(!(pUnitGroupArray[ComponentID - 1]->IS_KIND_OF(UnitGroup)), 
01085                 "ColourContext::GetComponentUnitGroup - Not UnitGroup array");
01086 
01087     pUnitGroupArray[ComponentID - 1] = pComponentUnitGroup;
01088     return TRUE;
01089 }
01090 
01091 
01092 
01093 /********************************************************************************************
01094 
01095 >   virtual UnitGroup *ColourContext::GetComponentUnitGroup(UINT32 ComponentID)
01096 
01097     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01098     Created:    02/05/96          
01099     Inputs:     ComponentID - the number of the component (1..GetComponentCount())
01100     Outputs:    -
01101     Returns:    A pointer to the desired UnitGroup
01102     Purpose:    Provides the UnitGroup of the given component in the ColourModel
01103     Errors:     ERROR2IF ComponentIndex < 1 or greater than number of components in model
01104     See Also:   ColourContextCMYK::GetComponentUnitGroups()
01105                 ColourContextGreyT::GetComponentUnitGroups()
01106                 ColourContextHSVT::GetComponentUnitGroups()
01107                 ColourContextRGBT::GetComponentUnitGroups()
01108 
01109 ********************************************************************************************/
01110 
01111 UnitGroup *ColourContext::GetComponentUnitGroup(UINT32 ComponentID)
01112 {
01113     ERROR2IF(ComponentID < 1 || ComponentID > GetComponentCount(), FALSE, "Invalid ID");
01114     UnitGroup** pUnitGroupArray = GetComponentUnitGroups();
01115     ERROR3IF(!(pUnitGroupArray[ComponentID - 1]->IS_KIND_OF(UnitGroup)), 
01116                 "ColourContext::GetComponentUnitGroup - Not UnitGroup array");
01117 
01118     return pUnitGroupArray[ComponentID - 1];
01119 }
01120 
01121 
01122 
01123 
01124 
01125 
01126 
01127 
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 
01136 
01137 
01138 /********************************************************************************************
01139 
01140 >   void ColourContextRGBT::ColourContextRGBT(View *Scope, double GammaValue = 1.0)
01141 
01142     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01143     Created:    31/03/94
01144     Inputs:     Scope - The view in which this context is to be used, or NULL
01145                 GammaValue - A gamma-correction gamma factor. You know... Gamma.
01146                 Heck, if you don't know what a gamma value is, then don't pass
01147                 anything in, because it has a good default value.
01148     Outputs:    -
01149     Returns:    -
01150     Purpose:    Constructor for an RGBT Colour context
01151 
01152     Notes:      Colour Contexts should not be created and used directly. See the
01153                 notes in the SeeAlso's for instructions on proper care and use.
01154 
01155     Errors:     -
01156     SeeAlso:    ColourContext::ColourContext; ColourContextList::AddContext
01157 
01158 ********************************************************************************************/
01159 
01160 ColourContextRGBT::ColourContextRGBT(View *Scope, double GammaValue)
01161                   : ColourContext(Scope)
01162 {
01163     ColModel = COLOURMODEL_RGBT;
01164     Gamma = GammaValue;
01165 
01166     CreateExternalTransform();
01167 }
01168 
01169 
01170 
01171 /********************************************************************************************
01172 
01173 >   ColourContextWebRGBT::ColourContextWebRGBT(View *Scope, double GammaValue)
01174                   : ColourContextRGBT(Scope, GammaValue)
01175 
01176     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
01177     Created:    ??/11/99
01178     Inputs:     Scope - The view in which this context is to be used, or NULL
01179                 GammaValue - A gamma-correction gamma factor. You know... Gamma.
01180                 Heck, if you don't know what a gamma value is, then don't pass
01181                 anything in, because it has a good default value.
01182     Outputs:    -
01183     Returns:    -
01184     Purpose:    Constructor for an RGBT Web Colour context
01185 
01186     Notes:      Colour Contexts should not be created and used directly. See the
01187                 notes in the SeeAlso's for instructions on proper care and use.
01188 
01189     Errors:     -
01190     SeeAlso:    ColourContext::ColourContext; ColourContextList::AddContext
01191 
01192 ********************************************************************************************/
01193 
01194 ColourContextWebRGBT::ColourContextWebRGBT(View *Scope, double GammaValue)
01195                   : ColourContextRGBT(Scope, GammaValue)
01196 {
01197     ColModel = COLOURMODEL_RGBT;
01198 }
01199 
01200 
01201 
01202 /********************************************************************************************
01203 
01204 >   void ColourContextRGBT::CreateExternalTransform(void)
01205 
01206     Author:     Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
01207     Created:    12/05/96
01208     Inputs:     -
01209     Returns:    -
01210     Purpose:    Create an external transform to be used during colour conversions from
01211                 RGB to the current RCS space. This function uses the Winoil CMS Manager
01212                 to create the transform. Both forward and backward transforms use logical
01213                 RGB descriptions.
01214 
01215 ********************************************************************************************/
01216 
01217 void ColourContextRGBT::CreateExternalTransform()
01218 {
01219 #ifndef NO_XARACMS
01220     CMSColourSpace cmsSpace;
01221     XaraCMS* lpCMSMan = GetApplication()->GetCMSManager();
01222 
01223     if (lpCMSMan != NULL)
01224     {
01225         // first read our internal colour calibration space
01226         lpCMSMan->GetLogicalProfile(&cmsSpace);
01227 
01228         // set this as the active colour profile
01229         UINT32 err = lpCMSMan->SetProfile(cmsSpace);
01230 
01231         // if we haven't got an error, create that transform
01232         if (err==0)
01233             CMSTransform = lpCMSMan->CreateTransform(DISPLAY_RCS);
01234     }
01235 #endif
01236 }
01237 
01238 
01239 /********************************************************************************************
01240 
01241 >   void ColourContextRGBT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result)
01242 
01243     Author:     Jason_