colourix.cpp

Go to the documentation of this file.
00001 // $Id: colourix.cpp 1333 2006-06-16 20:34:16Z 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 // colourix.cpp - Indexed colour class
00099 
00100 /*
00101 */
00102 
00103 
00104 #include "camtypes.h"
00105 
00106 #include "colcontx.h"
00107 #include "colourix.h"
00108 #include "colormgr.h"
00109 //#include "doccolor.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "jason.h"
00112 
00113 CC_IMPLEMENT_DYNAMIC(IndexedColour, ListItem)
00114 
00115 // Declare smart memory handling in Debug builds
00116 #define new CAM_DEBUG_NEW
00117 
00118 
00119 #ifndef WEBSTER // there are never spot colours in WEBSTER Martin 15/07/97
00120 BOOL IndexedColour::SpotsAreProcess = FALSE;
00121 #else
00122 BOOL IndexedColour::SpotsAreProcess = TRUE;
00123 #endif
00124 
00125 /********************************************************************************************
00126 
00127 >   void IndexedColour::InitialiseInfoFields(void)
00128 
00129     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00130     Created:    30/03/94
00131     Inputs:     -
00132     Outputs:    -
00133     Returns:    -
00134     Purpose:    Private shared code for construction of IndexedColour objects
00135                 Initialises the 'Info' structure to default values
00136     Scope:      private
00137     Errors:     -
00138     SeeAlso:    -
00139 
00140 ********************************************************************************************/
00141 
00142 void IndexedColour::InitialiseInfoFields(ColourModel ColModel)
00143 {
00144     UsageCount = 0;                     // We are not in-use yet
00145     ChildUsage = 0;
00146 
00147     Name         = NULL;                // This colour has no name
00148 
00149     ParentColour = NULL;                // We are not linked to another colour by default
00150 
00151     Info.OCContextHandle    = 0;        // Set colour model, and remember we're not cached
00152     Info.SourceColourModel  = ColModel;
00153     Info.CacheColourModel   = COLOURMODEL_NOTCACHED;
00154 
00155     Info.InheritComponent1  =           // By default, override all components in linked colour
00156         Info.InheritComponent2 =
00157         Info.InheritComponent3 =
00158         Info.InheritComponent4 = FALSE;
00159 
00160     Info.ColourType         = COLOURTYPE_NORMAL;    // Is normal (not spot/tint/linked) colour
00161 
00162     Info.Deleted            = FALSE;                // Not a deleted (hidden) colour
00163 
00164     Info.IsNamed = FALSE;
00165 }
00166 
00167 
00168 
00169 /********************************************************************************************
00170 
00171 >   IndexedColour::IndexedColour()
00172 
00173     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00174     Created:    30/03/94
00175     Inputs:     -
00176     Outputs:    -
00177     Returns:    -
00178     Purpose:    Constructor for an IndexedColour object
00179                 Initialises the colour to the RGBT value for Opaque Black
00180     Errors:     -
00181     SeeAlso:    -
00182 
00183 ********************************************************************************************/
00184 
00185 IndexedColour::IndexedColour()
00186 {
00187     InitialiseInfoFields(COLOURMODEL_RGBT);
00188 
00189     SourceColour.Component1 = 0;    // Black & No-colour (in RGBT)
00190     SourceColour.Component2 = 0;
00191     SourceColour.Component3 = 0;
00192     SourceColour.Component4 = 1.0;  // 100% transparent
00193 }
00194 
00195 
00196 
00197 /********************************************************************************************
00198 
00199 >   IndexedColour::~IndexedColour()
00200 
00201     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00202     Created:    30/03/94
00203     Inputs:     -
00204     Outputs:    -
00205     Returns:    -
00206     Purpose:    Destructor for an IndexedColour object
00207     Errors:     -
00208     SeeAlso:    -
00209 
00210 ********************************************************************************************/
00211 
00212 IndexedColour::~IndexedColour()
00213 {
00214     ERROR3IF(UsageCount < 0, "IndexedColour UsageCount is negative");
00215 
00216 #ifdef _DEBUG
00217     if (UsageCount != 0)
00218     {
00219         if (IsNamed())
00220             TRACE( _T("\n>> Named IndexedColour %p ('%s') is still referenced %ld times\n"),
00221                     this, (TCHAR *)(*Name), (INT32)UsageCount);
00222         else
00223             TRACE( _T("\n>> Unnamed IndexedColour %p is still referenced %ld times\n"),
00224                     this, (INT32)UsageCount);
00225 
00226         // Now, ask SimpleCCObject to wugg through all current objects to see if we can find something
00227         // that could be the pointer back at us!
00228         extern void CheckForUsedPointer(void *ThePointer);
00229 
00230         TRACE( _T("  References to this object were found in:\n"));
00231         CheckForUsedPointer(this);
00232         TRACE( _T("\n"));
00233     }
00234 
00235     ERROR3IF(UsageCount > 0, "IndexedColour deleted while still in use");
00236 
00237     if (ChildUsage != 0)
00238     {
00239         if (IsNamed())
00240         {
00241             TRACEUSER( "Jason", _T("Jason: Named IndexedColour %p ('%s') is still LINKED %ld times\n"),
00242                     this, (TCHAR *)(*Name), (INT32)ChildUsage);
00243         }
00244         else
00245         {
00246             TRACEUSER( "Jason", _T("Jason: Unnamed IndexedColour %p is still LINKED %ld times\n"),
00247                     this, (INT32)ChildUsage);
00248         }
00249     }
00250 #endif
00251 
00252     // If we are linked to another colour, we need to de-reference it
00253     if (ParentColour != NULL)
00254         ParentColour->DecrementChildUsage();
00255 
00256     if (Name != NULL)
00257         delete Name;
00258 }
00259 
00260 
00261 
00262 /********************************************************************************************
00263 
00264 >   IndexedColour::IndexedColour(const IndexedColour& Col)
00265 
00266     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00267     Created:    05/05/94
00268     Inputs:     -
00269     Outputs:    -
00270     Returns:    -
00271     Purpose:    Copy constructor for an IndexedColour object
00272     Errors:     -
00273     SeeAlso:    -
00274 
00275 ********************************************************************************************/
00276 
00277 IndexedColour::IndexedColour(const IndexedColour& Col)
00278 {
00279     Info = Col.Info;
00280     memcpy(&SourceColour, &Col.SourceColour, sizeof(ColourGeneric));
00281     memcpy(&CachedColour, &Col.CachedColour, sizeof(ColourGeneric));
00282 
00283     // If we are copying a linked/tint colour, we make ourselves linked to their parent
00284     ParentColour = Col.ParentColour;
00285     if (ParentColour != NULL)
00286         ParentColour->IncrementChildUsage();
00287 
00288     UsageCount = 0;
00289     ChildUsage = 0;
00290     
00291     Info.IsNamed = FALSE;
00292     Name = NULL;
00293     
00294     // Nasty casting to get around this messy const problem.
00295     if (((IndexedColour *)&Col)->IsNamed())
00296         SetName(*(Col.Name));   // Copy the string, not the string-pointer
00297 }
00298 
00299 
00300 
00301 /********************************************************************************************
00302 
00303 >   IndexedColour::IndexedColour(const DocColour& Col)
00304 
00305     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00306     Created:    9/11/94
00307     Inputs:     Col - A DocColour from which to take the definition of this new IndexedCol
00308     Outputs:    -
00309     Returns:    -
00310     Purpose:    Copy constructor for an IndexedColour object.
00311     
00312     Notes:      If the DocColour is immediate (does not reference an IndexedColour) then
00313                 the indexedcolour uses its colour definition - NOTE that this creates an
00314                 UNNAMED colour by default (SetName it afterwards). 
00315 
00316                 If the DocColour references an IndexedColour, the referenced colour is copied
00317                 
00318                 Tints and Linked colours are copied and remain tints/linked (Gosh!)
00319 
00320                 Named/Unnamed colours will be copied as Named/Unnamed colours (Gosh!)
00321 
00322                 The name is copied verbatim (i.e it is not changed to 'Copy of X')
00323 
00324     Errors:     -
00325     SeeAlso:    IndexedColour::SetName
00326 
00327 ********************************************************************************************/
00328 
00329 IndexedColour::IndexedColour(const DocColour& Col)
00330 {
00331     // Find the parent IndexedColour, if any. Nasty cast to remove compiler warning
00332     IndexedColour *Def = ((DocColour *) &Col)->FindParentIndexedColour();
00333 
00334     if (Def != NULL)
00335     {
00336         // The DocColour references an IndexedColour, so copy the parent IndexedColour
00337         Info = Def->Info;
00338         memcpy(&SourceColour, &Def->SourceColour, sizeof(ColourGeneric));
00339         memcpy(&CachedColour, &Def->CachedColour, sizeof(ColourGeneric));
00340 
00341         // If we are copying a linked/tint colour, we need to link ourselves to its parent
00342         ParentColour = Def->ParentColour;
00343         if (ParentColour != NULL)
00344             ParentColour->IncrementChildUsage();
00345 
00346         UsageCount = 0;
00347         ChildUsage = 0;
00348     
00349         Info.IsNamed = FALSE;
00350         Name = NULL;
00351         if (Def->IsNamed())
00352             SetName(*(Def->Name));  // Copy the string, not the string-pointer
00353     }
00354     else
00355     {
00356         // This is an immediate DocColour, so copy its definition into our SourceColour
00357         InitialiseInfoFields(Col.GetColourModel());
00358         ((DocColour *) &Col)->GetSourceColour(&SourceColour);
00359     }
00360 }
00361 
00362 
00363 
00364 /********************************************************************************************
00365 
00366 >   IndexedColour::IndexedColour(ColourValue Red, ColourValue Green, ColourValue Blue,
00367                                     ColourValue Transparent = 0,
00368                                     UINT32 TransType = TRANSTYPE_DEFAULT)
00369 
00370     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00371     Created:    30/03/94
00372     Inputs:     Red; Green; Blue - The RGB definition of the colour
00373 
00374                 Transparent - The transparency of the colour - IGNORED!
00375                 TransType - The transparency type of the colour - IGNORED!
00376 
00377     Outputs:    -
00378     Returns:    -
00379     Purpose:    Constructor for an IndexedColour object
00380                 Initialises the colour to the given Extended RGBT value
00381 
00382     Notes:      Colours no longer support transparency. The transparency fields are
00383                 ignored.
00384 
00385     Errors:     -
00386     SeeAlso:    -
00387 
00388 ********************************************************************************************/
00389 
00390 IndexedColour::IndexedColour(ColourValue Red, ColourValue Green, ColourValue Blue,
00391                                 ColourValue Transparent, UINT32 TransType)
00392 {
00393     InitialiseInfoFields(COLOURMODEL_RGBT);
00394     SourceColour.Component1 = Red;
00395     SourceColour.Component2 = Green;
00396     SourceColour.Component3 = Blue;
00397     SourceColour.Component4 = Transparent;
00398 }
00399 
00400 
00401 
00402 /********************************************************************************************
00403 
00404 >   IndexedColour::IndexedColour(ColourModel ColModel, ColourGeneric *Col)
00405 
00406     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00407     Created:    30/03/94
00408     Inputs:     ColModel - The colour model in which Col is defined
00409                 Col - The definition, in the given colour model, of the colour
00410     Outputs:    -
00411     Returns:    -
00412     Purpose:    Constructor for an IndexedColour object
00413                 Initialises the colour to the given value in the given colour model
00414                 NOTE that if you have a ColourABCD structure, you can pass this in
00415                 as a single parameter, and inline functions will convert the call
00416                 into a call to this function on your behalf.
00417                 i.e. you can use IndexedColour((ColourRGBT *)Bob);  -- See colour.h
00418     Errors:     -
00419     SeeAlso:    -
00420 
00421 ********************************************************************************************/
00422 
00423 IndexedColour::IndexedColour(ColourModel ColModel, ColourGeneric *Col)
00424 {
00425     InitialiseInfoFields(ColModel);
00426     memcpy(&SourceColour, Col, sizeof(ColourGeneric));
00427 }
00428 
00429 
00430 
00431 /********************************************************************************************
00432 
00433 >   IndexedColour& IndexedColour::operator=(const IndexedColour& Other)
00434 
00435     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00436     Created:    12/10/94
00437     Inputs:     Other - colour to copy
00438     Outputs:    -
00439     Returns:    
00440     Purpose:    IndexedColour assignment operator
00441                 Copies the definition of one IndexedColour into another
00442     Notes:      The name field is copied verbatim - if you want it to say 'Copy of ...'
00443                 then you'll have to prepend this text yourself.
00444     Errors:     ERROR2 if you try to copy a colour over itself
00445 
00446 ********************************************************************************************/
00447 
00448 IndexedColour& IndexedColour::operator=(const IndexedColour& Other)
00449 {
00450     ERROR2IF(&Other == this, *this, "Attempt to copy an IndexedColour over itself!");
00451 
00452     Info = Other.Info;
00453     memcpy(&SourceColour, &Other.SourceColour, sizeof(ColourGeneric));
00454     memcpy(&CachedColour, &Other.CachedColour, sizeof(ColourGeneric));
00455 
00456     if (ParentColour != NULL)                   // Delink from old parent (if any)
00457         ParentColour->DecrementChildUsage();
00458 
00459     ParentColour = Other.ParentColour;
00460     if (ParentColour != NULL)                   // Link to new parent (if any)
00461         ParentColour->IncrementChildUsage();
00462 
00463 //  UsageCount = 0;     // These DO NOT CHANGE! We still have people referencing us
00464 //  ChildUsage = 0;     // and we must not forget about them!
00465 
00466     Info.IsNamed = FALSE;
00467     if (((IndexedColour *)&Other)->IsNamed())
00468         SetName(*(Other.Name));     // Copy the string, not the string-pointer
00469 
00470     return(*this);
00471 }
00472 
00473 
00474 
00475 /********************************************************************************************
00476 
00477 >   IndexedColourType IndexedColour::GetType(void) const
00478 
00479     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00480     Created:    13/10/94
00481     Returns:    The type of this colour:
00482                 MonoOn
00483                 COLOURTYPE_NORMAL, COLOURTYPE_SPOT, COLOURTYPE_TINT, COLOURTYPE_LINKED
00484                 MonoOff
00485     
00486     Purpose:    Determines the type of this colour
00487 
00488     Notes:      If this colour is linked to a deleted colour, then for sneaky undo reasons
00489                 it (internally) remains linked. However, it pretends to the outside world
00490                 that it is in fact a normal colour.
00491 
00492     SeeAlso:    IndexedColour::SetType; IndexedColour::FindLinkedParent;
00493                 IndexedColour::SetLinkedParent
00494 
00495 ********************************************************************************************/
00496 
00497 IndexedColourType IndexedColour::GetType(void) const
00498 {
00499     if ((Info.ColourType == (UINT32) COLOURTYPE_LINKED ||
00500          Info.ColourType == (UINT32) COLOURTYPE_TINT) &&
00501          ParentColour != NULL && ParentColour->IsDeleted())
00502     {
00503         return(COLOURTYPE_NORMAL);
00504     }
00505 
00506     // If the global "SpotsareProcess" flag is set, then spots pretend to be normal
00507     // Unnamed/Local colours also cannot be spots, so in case we accidentally get into the
00508     // wrong state, we make sure never to return a silly result.
00509     if (Info.ColourType == COLOURTYPE_SPOT && (SpotsAreProcess || !Info.IsNamed))
00510         return(COLOURTYPE_NORMAL);
00511 
00512     return((IndexedColourType) Info.ColourType);
00513 }
00514 
00515 
00516 
00517 /********************************************************************************************
00518 
00519 >   BOOL IndexedColour::IsSpotOrTintOfSpot(void) const
00520 
00521     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00522     Created:    12/6/96
00523 
00524     Returns:    TRUE if this colour is either a spot colour or a tint of a spot colour
00525 
00526     Purpose:    Determines if this colour is either a spot colour or a true tint of a
00527                 spot colour. (Tints can unfortunately be made from non-spot colour
00528                 parents, so you need to call this function to determine if a tint
00529                 really is cleanly derived from a spot colour, or if it must be treated
00530                 as a simple process colour)
00531 
00532                 Thus, this returns TRUE if the colour itself is a Spot, or
00533                 if it is a Tint and its parent returns TRUE from IsSpotOrTintOfSpot().
00534 
00535     Notes:      If a colour in the tint chain is deleted, then all children must
00536                 become process (non true-tint) colours, so this will return FALSE
00537 
00538 ********************************************************************************************/
00539 
00540 BOOL IndexedColour::IsSpotOrTintOfSpot(void) const
00541 {
00542     if (Info.Deleted)
00543         return(FALSE);
00544 
00545     IndexedColourType Type = GetType();
00546     if (Type == COLOURTYPE_SPOT)
00547         return(TRUE);                               // Is it a true spot colour?
00548 
00549     if (Type != COLOURTYPE_TINT || TintIsShade())
00550         return(FALSE);                              // It's not even a tint
00551 
00552     if (ParentColour == NULL)
00553         return(FALSE);                              // We have no parent colour
00554 
00555     // OK, we're a tint of something. Recurse to find out if that something
00556     // is a true tint or a spot colour.
00557     return(ParentColour->IsSpotOrTintOfSpot());
00558 }
00559 
00560 
00561 
00562 /********************************************************************************************
00563 
00564 >   ColourModel IndexedColour::GetColourModel(void) const
00565 
00566     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00567     Created:    30/03/94
00568     Inputs:     -
00569     Outputs:    -
00570     Returns:    The colour model in which the IndexedColour was defined
00571     
00572     Purpose:    To determine the colour model in which an IndexedColour is defined
00573 
00574     Notes:      If this colour is a TINT, the parent colour's colour model is returned,
00575                 as tints cannot be defined in a different model to their parents
00576 
00577     Errors:     -
00578     SeeAlso:    IndexedColour::GetSourceColour
00579 
00580 ********************************************************************************************/
00581 
00582 ColourModel IndexedColour::GetColourModel(void) const
00583 {
00584     // If we're a tint, return our parent's colour. NOTE that we do not call GetType()
00585     // as we want to ask our parent even if it is 'deleted' for UNDO reasons.
00586     if (Info.ColourType == COLOURTYPE_TINT && ParentColour != NULL)
00587         return(ParentColour->GetColourModel());
00588 
00589     return((ColourModel) Info.SourceColourModel);
00590 }
00591 
00592 
00593 
00594 /********************************************************************************************
00595 
00596 >   void IndexedColour::GetSourceColour(ColourGeneric *Result)
00597 
00598     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00599     Created:    30/03/94
00600     Inputs:     -
00601     Outputs:    -
00602     Returns:    The colour definition of this IndexedColour, in its native colour model
00603     Purpose:    Gets the definition of the IndexedColour.
00604 
00605     Notes:      If the colour is Tint/Linked, this may involve a recursive set of calls which
00606                 will convert and override each parent colour up the chain until the
00607                 resulting colour definition for this colour is eventually produced at
00608                 the end.
00609 
00610     Errors:     -
00611     SeeAlso:    IndexedColour::GetColourModel
00612 
00613 ********************************************************************************************/
00614 
00615 void IndexedColour::GetSourceColour(ColourGeneric *Result)
00616 {
00617     ERROR3IF(Result == &SourceColour,
00618              "Illegal attempt to GetSourceColour into a colour's own SourceColour field!");
00619 
00620     if (ParentColour == NULL || ParentColour == this ||
00621         (Info.ColourType != COLOURTYPE_LINKED && Info.ColourType != COLOURTYPE_TINT))
00622     {
00623         // We are not linked to a parent colour (or the link is scarily illegal to ourself!)
00624         // (ParentColour == NULL OR we are not tint/linked)
00625         // - simply copy our own colour definition, checking that this is not an internal
00626         // call to get a source colour definition into our own source colour!
00627         if (&SourceColour != Result)
00628             memcpy(Result, &SourceColour, sizeof(ColourGeneric));
00629     }
00630     else
00631     {
00632         ERROR3IF(ParentColour == NULL || ParentColour == this ||
00633                  ParentColour->IsADescendantOf(this),
00634                  "Consistency failure in IndexedColour parent linkage");
00635 
00636         // Ask our parent for its colour definition - recurse!
00637         ParentColour->GetSourceColour(Result);
00638 
00639         // Get our 'parent' colour context
00640         ColourContext *cc = ColourContext::GetGlobalDefault(GetColourModel());
00641         ERROR3IF(cc == NULL, "IndexedColour::GetSourceColour - illegal colour context in use?!");
00642 
00643         // Now, override the colour as necessary
00644         // NOTE that we do NOT call GetType(), as this might return COLOURTYPE_NORMAL for tints/linked
00645         // colours which have 'deleted' parents. This is due to nasty UNDO considerations - we retain
00646         // our linked parent internally when it is 'deleted'.
00647         if (Info.ColourType == COLOURTYPE_LINKED)
00648         {
00649             // If necessary, convert the Result colour into our own colour model
00650             if (ParentColour->GetColourModel() != GetColourModel())
00651             {
00652                 ColourContext *ccSource = ColourContext::GetGlobalDefault(ParentColour->GetColourModel());
00653 
00654                 if (ccSource != NULL)   // Shouldn't happen, but let's be safe
00655                 {
00656                     ColourGeneric Source;
00657                     memcpy(&Source, Result, sizeof(ColourGeneric));
00658 
00659                     cc->ConvertColour(ccSource, &Source, Result);
00660                 }
00661             }
00662 
00663 // **** ToDo !!!! Override by copying OR Inherit by scaling !!!!
00664 
00665             // This is a linked colour. Override the given components with our own values
00666             if (!Info.InheritComponent1)
00667                 Result->Component1 = SourceColour.Component1;
00668             if (!Info.InheritComponent2)
00669                 Result->Component2 = SourceColour.Component2;
00670             if (!Info.InheritComponent3)
00671                 Result->Component3 = SourceColour.Component3;
00672             if (!Info.InheritComponent4)
00673                 Result->Component4 = SourceColour.Component4;
00674         }
00675         else if (Info.ColourType == COLOURTYPE_TINT)
00676         {
00677             // This is a tint. Component 1 of our 'SourceColour' is the tinting value
00678             // We get our 'parent' colour context to work out how to apply the tint/shade
00679             if (TintIsShade())
00680                 cc->ApplyShade(SourceColour.Component1, SourceColour.Component2, Result);   // Shade it
00681             else
00682                 cc->ApplyTint(SourceColour.Component1, Result);                             // Tint it
00683         }
00684         else
00685         {
00686             ERROR3("Unknown/Illegal colour type in IndexedColour::GetSourceColour");
00687         }
00688     }
00689 }
00690 
00691 
00692 
00693 /********************************************************************************************
00694 
00695 >   BOOL IndexedColour::IsDifferent(const IndexedColour &Other)
00696 
00697     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00698     Created:    1/8/94
00699     Inputs:     Other - the other indexed colour to which 'this' will be compared
00700     Outputs:    -
00701     Returns:    TRUE if the two colours are considered different
00702                 FALSE if they are considered the same
00703     Purpose:    To determine if two indexed colours share a common definition.
00704 
00705                 This is defined as: Same Colour model, and source colour definitions
00706                 and both are linked to/tint of the same colour (or none), and the 'no colour'
00707                 (and if linked: inheritance bits; if tint: tinting values) and colour type
00708                 match exactly.
00709 
00710                 NOTE especially that this does NOT compare the names of the colours
00711 
00712 ********************************************************************************************/
00713 
00714 BOOL IndexedColour::IsDifferent(const IndexedColour &Other)
00715 {
00716     if (GetType() != Other.GetType())
00717         return(TRUE);
00718 
00719     if (GetColourModel() != Other.GetColourModel())
00720         return(TRUE);
00721 
00722     // If this is a linked colour, check if their inheritance flags match
00723     if (GetType() == COLOURTYPE_LINKED)
00724     {
00725         if (ParentColour != Other.ParentColour)
00726             return(TRUE);
00727 
00728         if (Info.InheritComponent1 != Other.Info.InheritComponent1 ||
00729             Info.InheritComponent2 != Other.Info.InheritComponent2 ||
00730             Info.InheritComponent3 != Other.Info.InheritComponent3 ||
00731             Info.InheritComponent4 != Other.Info.InheritComponent4)
00732             return(TRUE);
00733     }
00734 
00735     // If this is a tint, it has no components in the regular sense.
00736     // Return immediately with the result of comparing the tint values
00737     if (GetType() == COLOURTYPE_TINT)
00738     {
00739         if (ParentColour != Other.ParentColour)
00740             return(TRUE);
00741 
00742         if (TintIsShade() != Other.TintIsShade())
00743             return(TRUE);
00744 
00745         if (TintIsShade())
00746         {
00747             return(GetShadeValueX() != Other.GetShadeValueX() ||
00748                     GetShadeValueY() != Other.GetShadeValueY());
00749         }
00750 
00751         return(GetTintValue() != Other.GetTintValue());
00752     }
00753 
00754     if (GetColourModel() == COLOURMODEL_GREYT)
00755     {
00756         // We ignore the 2nd and 3rd components as they are not used.
00757         // (Should not be necessary, as these components should be zeroed anyway)
00758         if (SourceColour.Component1 != Other.SourceColour.Component1 ||
00759             SourceColour.Component4 != Other.SourceColour.Component4)
00760             return(TRUE);
00761     }
00762     else
00763     {   
00764         if (SourceColour.Component1 != Other.SourceColour.Component1 ||
00765             SourceColour.Component2 != Other.SourceColour.Component2 ||
00766             SourceColour.Component3 != Other.SourceColour.Component3 ||
00767             SourceColour.Component4 != Other.SourceColour.Component4)
00768             return(TRUE);
00769     }
00770 
00771     return(FALSE);
00772 }
00773 
00774 
00775 
00776 /********************************************************************************************
00777 
00778 >   BOOL IndexedColour::IsDifferent(const IndexedColour &Other, FIXED24 ErrorLimit)
00779 
00780     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00781     Created:    1/8/94
00782     Inputs:     Other - the other indexed colour to which 'this' will be compared
00783     Outputs:    -
00784     Returns:    TRUE if the two colours are considered different
00785                 FALSE if they are considered the same
00786     Purpose:    To determine if two indexed colours share a common definition.
00787 
00788                 This is defined as: Same Colour model, and source colour definitions
00789                 and both are linked to/tint of the same colour (or none), and the 'no colour'
00790                 (and if linked: inheritance bits; if tint: tinting values) and colour type
00791                 match within the limits specified by ErrorLimit.
00792 
00793                 This version of the function takes an accuracy parameter, to allow
00794                 'rough' comparisons to be made.  This is used when importing colours so 
00795                 that we don't have to store 32bit colour values in EPS files and so on
00796                 in order for them to be recognised as an existing colour when re-importing.
00797 
00798                 NOTE especially that this does NOT compare the names of the colours
00799 
00800 ********************************************************************************************/
00801 
00802 #define OUTSIDE_LIMIT(a,b) ((ABS((a) - (b))) > (ErrorLimit))
00803 
00804 BOOL IndexedColour::IsDifferent(const IndexedColour &Other, FIXED24 ErrorLimit)
00805 {
00806     if (GetType() != Other.GetType())
00807         return(TRUE);
00808 
00809     if (GetColourModel() != Other.GetColourModel())
00810         return(TRUE);
00811 
00812     // If this is a linked colour, check if their inheritance flags match
00813     if (GetType() == COLOURTYPE_LINKED)
00814     {
00815         if (ParentColour != Other.ParentColour)
00816             return(TRUE);
00817 
00818         if (Info.InheritComponent1 != Other.Info.InheritComponent1 ||
00819             Info.InheritComponent2 != Other.Info.InheritComponent2 ||
00820             Info.InheritComponent3 != Other.Info.InheritComponent3 ||
00821             Info.InheritComponent4 != Other.Info.InheritComponent4)
00822             return(TRUE);
00823     }
00824 
00825     // If this is a tint, it has no components in the regular sense.
00826     // Return immediately with the result of comparing the tint values
00827     if (GetType() == COLOURTYPE_TINT)
00828     {
00829         if (ParentColour != Other.ParentColour)
00830             return(TRUE);
00831 
00832         if (TintIsShade() != Other.TintIsShade())
00833             return(TRUE);
00834 
00835         if (TintIsShade())
00836         {
00837             return( OUTSIDE_LIMIT(GetShadeValueX(), Other.GetShadeValueX()) ||
00838                     OUTSIDE_LIMIT(GetShadeValueY(), Other.GetShadeValueY()) );
00839         }
00840 
00841         return( OUTSIDE_LIMIT(GetTintValue(), Other.GetTintValue()) );
00842     }
00843 
00844     // Special case for greyscales...
00845     if (GetColourModel() == COLOURMODEL_GREYT)
00846     {
00847         // We ignore the 2nd and 3rd components as they are not used.
00848         if (OUTSIDE_LIMIT(SourceColour.Component1, Other.SourceColour.Component1) ||
00849             OUTSIDE_LIMIT(SourceColour.Component4, Other.SourceColour.Component4))
00850             return(TRUE);
00851     }
00852     else
00853     {
00854         if (OUTSIDE_LIMIT(SourceColour.Component1, Other.SourceColour.Component1) ||
00855             OUTSIDE_LIMIT(SourceColour.Component2, Other.SourceColour.Component2) ||
00856             OUTSIDE_LIMIT(SourceColour.Component3, Other.SourceColour.Component3) ||
00857             OUTSIDE_LIMIT(SourceColour.Component4, Other.SourceColour.Component4))
00858             return(TRUE);
00859     }
00860     
00861     return(FALSE);
00862 }
00863 
00864 // Ensure we don't use this macro out of its intended scope - it uses 'ErrorLimit'!
00865 #undef OUTSIDE_LIMIT
00866 
00867 
00868 
00869 /********************************************************************************************
00870 
00871 >   String_64 *IndexedColour::GetName(BOOL ReturnTrueID = FALSE)
00872 
00873     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00874     Created:    02/04/94
00875 
00876     Inputs:     ReturnTrueID - FALSE (the default) to retrieve the 'normal' name. If this
00877                 colour is unnamed, the string "Unnamed" will be returned.
00878                 TRUE (*use with care*) to return a unique id for this colour. If unnamed,
00879                 this will return a unique name string like "_362180". This is only intended
00880                 for use by the import/export system.
00881 
00882     Outputs:    -
00883     Returns:    A pointer to a String_64 containing the name of this indexed colour
00884                 If it is named, the return value is always the name
00885                 If it is unnamed, then either "Unnamed" or a unique id "_1234567" will be
00886                 returned.
00887 
00888     Purpose:    To find the name of an IndexedColour (or the ID of an unnamed indexed colour)
00889     Errors:     -
00890 
00891 ********************************************************************************************/
00892 
00893 String_64 *IndexedColour::GetName(BOOL ReturnTrueID)
00894 {
00895     static String_64 Default(_R(IDS_LOCALCOLOUR));
00896 
00897     if (IsNamed())
00898     {
00899         if (Name != NULL)
00900             return(Name);
00901     }
00902     else
00903     {
00904         if (ReturnTrueID)
00905         {
00906             // If we're an unnamed colour, then we generate an "ID" (not a name, honest, guv!)
00907             // which is unique. This is used for export/import to recognise unnamed colours
00908 
00909             if (Name == NULL)
00910             {
00911                 Name = new String_64;
00912                 if (Name != NULL)
00913                     Name->_MakeMsg( TEXT("_#1%ld"), (UINT32)(UINT_PTR)(this) );
00914             }
00915 
00916             if (Name != NULL)
00917                 return(Name);
00918         }
00919     }
00920 
00921     return(&Default);
00922 }
00923 
00924 
00925 
00926 /********************************************************************************************
00927 
00928 >   void IndexedColour::SetName(const StringBase &NewName, [BOOL ForceNamed = TRUE])
00929 
00930     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00931     Created:    05/04/94
00932     Inputs:     NewName - A StringBase which will be *copied* as this colours new name.
00933                 NOTE that this name will be truncated to a maximum length of 63 characters,
00934                 and any underscore characters within it will be converted to spaces
00935 
00936                 ForceNamed - if TRUE (the default), this forces the colour to become 'named'
00937                 and will strip out underline characters from it.
00938                 If FALSE (*use with care*) this will leave the colour in its current state,
00939                 (i.e. won't make an unnamed colour named) and will retain underlines. This is
00940                 only intended for use by importers for handling export/import of unnamed
00941                 colours.
00942 
00943     Purpose:    To set the name of an IndexedColour.
00944                 The name will be truncated to a maximum length of 63 characters.
00945 
00946     Notes:      Any underscore characters in the name will be converted to spaces, on the
00947                 grounds that the export system uses underscores as a special name identifier
00948                 to recognise unnamed colours. Suffice to say we just don't allow underscores
00949 
00950                 If NewName is NULL, or if we fail to allocate space for the name to
00951                 be stored, the colour will revert to having no name.
00952 
00953                 Setting the name of an IndexedColour makes it a Named IndexedColour
00954                 (Trust me, that is less silly than it sounds! ;-)
00955     
00956     SeeAlso:    IndexedColour::SetUnnamed; IndexedColour::IsNamed
00957 
00958 ********************************************************************************************/
00959 
00960 void IndexedColour::SetName(const StringBase &NewName, BOOL ForceNamed)
00961 {
00962     if (ForceNamed)
00963         Info.IsNamed = TRUE;
00964 
00965     if (Name == NULL)
00966         Name = new String_64;       // If this fails, Name will just be NULL, which is safe
00967 
00968     if (Name != NULL)
00969     {
00970         if (ForceNamed)
00971         {
00972             const TCHAR *Src  = (const TCHAR *)NewName;
00973             TCHAR *Dest = (TCHAR *)(*Name);
00974 
00975             // Copy up to 63 chars across
00976             camStrncpy(Dest, Src, 63);
00977             
00978             // convert underscores into spaces
00979             Name->SwapChar(TCHAR('_'), TCHAR(' '));
00980         }
00981         else
00982         {
00983             NewName.Left(Name, 63);         // Truncate to 63 chars max, and copy
00984         }
00985     }
00986 }
00987 
00988 
00989 
00990 /********************************************************************************************
00991 
00992 >   void IndexedColour::SetUnnamed(void)
00993 
00994     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00995     Created:    05/04/94
00996 
00997     Purpose:    To UNset the name of an IndexedColour, forcing it back to being Unnamed
00998 
00999 ********************************************************************************************/
01000 
01001 void IndexedColour::SetUnnamed(void)
01002 {
01003     Info.IsNamed = FALSE;
01004 
01005     if (Name != NULL)
01006         delete Name;
01007 
01008     Name = NULL;
01009 }
01010 
01011 
01012 
01013 /********************************************************************************************
01014 
01015 >   BOOL IndexedColour::IsADescendantOf(IndexedColour *TestParent)
01016 
01017     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01018     Created:    17/11/94
01019     Inputs:     TestParent - the parent/ancestor colour we wish to test for
01020     Returns:    TRUE if this is indeed a descendant of the given colour
01021     
01022     Purpose:    Recursively backtracks through the chain of LinkedParent links to determine
01023                 if this colour is in any way (directly or indirectly) linked to the given
01024                 Parent colour, and might therefore be affected by any change to said colour.
01025 
01026     Notes:      To determine if a colour is the *direct* parent of another, use
01027                     if (TestParent == ThisColour->FindLinkedParent())
01028 
01029                 If the TestParent is THIS colour, the return value is TRUE (i.e Yes, a change
01030                 to the 'Parent' colour will affect 'this' colour!). {This is also an end-of-
01031                 recursion clause}
01032 
01033                 This method only calculates descendant information for LINKED/TINT colours.
01034                 Non-linked/tint colours will always spell the end of the search.
01035 
01036                 Is quite happy if TestParent is NULL - will always return FALSE in this case
01037 
01038 ********************************************************************************************/
01039 
01040 BOOL IndexedColour::IsADescendantOf(IndexedColour *TestParent)
01041 {
01042     if (TestParent == NULL)         // Silly test! Of course it's not!
01043         return(FALSE);
01044 
01045     if (this == TestParent)         // We are the colour being tested - we are related
01046         return(TRUE);
01047                                     // We cannot be descended, as we're a normal colour
01048     if (GetType() == COLOURTYPE_NORMAL || GetType() == COLOURTYPE_SPOT)
01049         return(FALSE);
01050 
01051     if (ParentColour == NULL)       // We have no parent, so cannot be descended from anything
01052         return(FALSE);
01053                                     // Ask our parent to check back in the family tree
01054     return(ParentColour->IsADescendantOf(TestParent));
01055 }
01056 
01057 
01058 
01059 /********************************************************************************************
01060 
01061 >   IndexedColour *IndexedColour::FindLinkedParent(void)
01062 
01063     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01064     Created:    12/10/94
01065     Returns:    The colour upon which this Tint or Linked colour is based.
01066                 (If this colour is not a Tint or Linked colour, or if it is a
01067                 deleted (hidden for undo) colour, the return value is NULL)
01068                 
01069     Notes:      If you need to know what colour this colour *was* linked to, as the
01070                 colour editor does when the user is randomly plonking about with the
01071                 colour type, then call FindLastLinkedParent instead.
01072 
01073     Purpose:    Finds the colour upon which a tint/based-on colour is based, if any.
01074                 Can also be used to determine if a colour is a tint/basedon colour.
01075 
01076     SeeAlso:    IndexedColour::FindLastLinkedParent
01077 
01078 ********************************************************************************************/
01079 
01080 IndexedColour *IndexedColour::FindLinkedParent(void)
01081 {
01082     if (IsDeleted())
01083         return(NULL);
01084 
01085     if (GetType() != COLOURTYPE_TINT && GetType() != COLOURTYPE_LINKED)
01086         return(NULL);
01087 
01088     return(FindLastLinkedParent());
01089 }
01090 
01091 
01092 
01093 /********************************************************************************************
01094 
01095 >   IndexedColour *IndexedColour::FindOldestAncestor(void)
01096 
01097     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01098     Created:    20/6/96
01099     Returns:    The utimate colour upon which this Tint or Linked colour is based.
01100                 Note that if this colour has no parent, it will return itself!
01101 
01102     Purpose:    Finds the colour upon which a tint/based-on colour is based, if any.
01103                 Can also be used to determine if a colour is a tint/basedon colour.
01104 
01105                 This is similar to FindLinkedParent, except it traverses all parent links
01106                 until it finds the ultimate parent of the entire linked-colour tree
01107                 in which this colour resides.
01108 
01109     SeeAlso:    IndexedColour::FindLinkedParent
01110 
01111 ********************************************************************************************/
01112 
01113 IndexedColour *IndexedColour::FindOldestAncestor(void)
01114 {
01115     IndexedColour *Ptr  = FindLinkedParent();
01116     IndexedColour *Last = this;
01117 
01118     while (Ptr != NULL)
01119     {
01120         Last = Ptr;
01121         Ptr = Ptr->FindLinkedParent();
01122     }
01123 
01124     return(Last);
01125 }
01126 
01127 
01128 
01129 /********************************************************************************************
01130 
01131 >   void IndexedColour::SetLinkedParent(IndexedColour *Parent,
01132                                         IndexedColourType NewType = COLOURTYPE_LINKED)
01133 
01134     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01135     Created:    12/10/94
01136     Inputs:     Parent - the new Linked/Tint parent IndexedColour, or
01137                          NULL to remove any existing link
01138 
01139                 NewType - The ColourType to set this to. Note that for NORMAL/SPOT, the
01140                 parent field must be NULL; For LINKED/TINT, it must point at a valid
01141                 Named IndexedColour. If this is not the case, an ERROR3 will occur.
01142 
01143     Purpose:    To make a colour linked to or a tint of another colour.
01144                 This links the colour to the parent.
01145                 
01146     Notes:      Generally, the colour's colour model and definition will be unaffected.
01147                 However, if the colour was previously linked/tint, and it is being made
01148                 into a standalone colour, the existing linked colour definition will be
01149                 read, and then placed into SourceColour as a standalone version of the
01150                 previous linked definition. (i.e. the colour's appearance will not change
01151                 but the link will be broken)
01152                 
01153                 If the colour was not already a COLOURTYPE_LINKED when it is being made
01154                 LINKED, all components will be set to override the parent.
01155                 
01156                 If the colour was not already a COLOURTYPE_TINT when it is being made
01157                 a TINT, it will be set to be a 100% tint (no tinting at all)
01158 
01159                 When making a COLOURTYPE_TINT colour, it will be a TINT, not a SHADE.
01160                 To make a shade, make it COLOURTYPE_TINT then call SetTintOrShade(TRUE);
01161                 If it was already a COLOURTYPE_TINT, the tint/shade state is unaffected.
01162 
01163                 The colour's output cache is flushed by this call
01164 
01165                 It is your responsibility to confirm overwriting the colour. It is also
01166                 your responsibility to inform the system that this colour has changed, by
01167                 calling ColourManager::ColourHasChanged
01168 
01169                 IMPORTANT NOTE: This method allows you to do things like making a colour
01170                 'normal' (supposedly not linked), but still set a parent colour. This is
01171                 a potentially dangerous practice so be very careful. (It is allowed so that
01172                 the colour editor can cunningly remember what a colour was last linked
01173                 to, in order to be far more helpful to the user).
01174                 
01175     Scope:      private? Generally speaking, you should not be calling this method, unless
01176                 you are the colour editor, or a load/import filter.
01177 
01178     SeeAlso:    IndexedColour::GetLinkedParent; IndexedColour::GetLastLinkedParent;
01179                 IndexedColour::SetInheritsComponent;
01180                 IndexedColour::SetType; IndexedColourType;
01181                 ColourManager::ColourHasChanged
01182 
01183     Errors:     ERROR3 if you try to do anythign totally stupid (circular linking,
01184                 linking to deleted colours, linking to unnamed colours, etc)
01185 
01186 ********************************************************************************************/
01187 
01188 void IndexedColour::SetLinkedParent(IndexedColour *Parent, IndexedColourType NewType)
01189 {
01190     if (this == Parent)
01191     {
01192         ERROR3("Illegal attempt to make an IndexedColour Linked to itself");
01193         return;
01194     }
01195 
01196     if (Parent != NULL && Parent->IsADescendantOf(this))
01197     {
01198         // Our new parent-to-be is already a linked child of us!
01199         ERROR3("Illegal attempt to generate circular reference in Colour linking"); 
01200         return;
01201     }
01202 
01203     if (Parent != NULL && !Parent->IsNamed())
01204     {
01205         ERROR3("Illegal attempt to use UNNAMED IndexedColour as a linked parent");
01206         return;
01207     }
01208 
01209     if (Parent!= NULL && Parent->IsDeleted())
01210     {
01211         ERROR3("Illegal attempt to use 'DELETED' IndexedColour as a linked parent");
01212         return;
01213     }
01214 
01215 
01216     switch(NewType)
01217     {
01218         case COLOURTYPE_LINKED:
01219             if (GetType() != COLOURTYPE_LINKED)
01220             {
01221                 Info.InheritComponent1  =       // Override all components for now
01222                     Info.InheritComponent2 =
01223                     Info.InheritComponent3 =
01224                     Info.InheritComponent4 = FALSE;
01225             }
01226             break;
01227 
01228 
01229         case COLOURTYPE_TINT:
01230             if (GetType() != COLOURTYPE_TINT)
01231             {
01232                 SetType(NewType);               // Set type now to stop the next call ENSURE'ing
01233                 SetTintOrShade(FALSE);          // Make it a real tint (not a shade "tint")
01234                 SetTintValue(FIXED24(1.0));     // 100% tint (the colour) for now
01235             }
01236 
01237             // Swapping from Tint to Shade (which are both COLOURTYPE_TINT will need to do this,
01238             // so we do it even if it is supposely chnaging to the same "type"
01239             if (Parent != NULL)
01240                 Info.SourceColourModel = (UINT32) Parent->GetColourModel();
01241             break;
01242 
01243 
01244         default:        // COLOURTYPE_NORMAL, COLOURTYPE_SPOT
01245             if (FindLastLinkedParent() != NULL)
01246             {
01247                 // If this was previously a tint/linked colour, then copy the resulting
01248                 // colour definition into this colour to make it standalone again.
01249 
01250                 ColourGeneric NewSourceColour;
01251                 GetSourceColour(&NewSourceColour);
01252                 memcpy(&SourceColour, &NewSourceColour, sizeof(ColourGeneric));
01253             }
01254             break;
01255     }
01256 
01257     if (ParentColour != NULL)
01258         ParentColour->DecrementChildUsage();
01259 
01260     ParentColour = Parent;          // Set the new linked/tint parent colour
01261 
01262     if (ParentColour != NULL)
01263         ParentColour->IncrementChildUsage();
01264 
01265     InvalidateCache();              // Invalidate the output colour cache
01266     SetType(NewType);               // And set the new type of the colour
01267 }
01268 
01269 
01270 
01271 /********************************************************************************************
01272 
01273 >   BOOL IndexedColour::SetType(IndexedColourType NewType)
01274 
01275     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01276     Created:    1/11/94
01277     Returns:    TRUE if this caused the type of this colour to be changed
01278                 FALSE if the new type is the same as the old type
01279     
01280     Purpose:    Sets the type of this colour:
01281                 MonoOn
01282                 COLOURTYPE_NORMAL, COLOURTYPE_SPOT, COLOURTYPE_TINT, COLOURTYPE_LINKED
01283                 MonoOff
01284 
01285     Notes:      If you wish to make a colour Linked or a Tint, then you should set its type
01286                 at the same time as its parent-link in SetLinkedParent(). If you wish to
01287                 make a linked/tint colour normal again, then you should also use
01288                 SetLinkedParent.
01289 
01290                 On second thoughts, you shouldn't be calling this method!
01291 
01292     Scope:      private
01293 
01294     SeeAlso:    IndexedColour::SetType; IndexedColour::FindLinkedParent;
01295                 IndexedColour::SetLinkedParent
01296 
01297 ********************************************************************************************/
01298 
01299 BOOL IndexedColour::SetType(IndexedColourType NewType)
01300 {
01301     BOOL Result = (NewType != (IndexedColourType) Info.ColourType);
01302 
01303     if ((INT32)NewType < 0 || (INT32)NewType > 3)
01304     {
01305         ERROR3("Attempt to set invalid colour type");
01306         return(FALSE);
01307     }
01308 
01309     Info.ColourType = (UINT32) NewType;
01310 
01311     if (Result)                 // If the colour has changed, invalidate the output cache
01312         InvalidateCache();
01313 
01314     return(Result);
01315 }
01316 
01317 
01318 
01319 /********************************************************************************************
01320 
01321 >   BOOL IndexedColour::InheritsComponent(UINT32 ComponentID)
01322 
01323     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01324     Created:    12/10/94
01325     Inputs:     ComponentID: a number [1..4] indicating which component of the colour
01326                 you wish to find out about.
01327 
01328     Returns:    TRUE if the component is inherited from the parent
01329                 FALSE if the component overrides the parent, or if the colour isn't linked
01330 
01331     Purpose:    To determine if a given component of a colour is inherited from its linked
01332                 parent colour. Always returns FALSE if a colour is not linked.
01333 
01334     Notes:      Should be used in conjunction with the appropriate ColourContext for this
01335                 colour's colour model to determine if *valid* components of a colour are
01336                 inherited from their parent colour. If asked about an invalid component,
01337                 the result will be indeterminate (generally FALSE, but somebody may have
01338                 set it to TRUE without checking if it is a valid component)
01339 
01340     SeeAlso:    IndexedColour::GetType(); ColourContext::GetComponentName;
01341                 IndexedColour::SetInheritsComponent
01342 
01343 ********************************************************************************************/
01344 
01345 BOOL IndexedColour::InheritsComponent(UINT32 ComponentID)
01346 {
01347     ERROR3IF(ComponentID < 1 || ComponentID > 4,
01348                 "Bad colour component index passed to IndexedColour::InheritsComponent");
01349 
01350     if (GetType() == COLOURTYPE_LINKED)
01351     {
01352         switch(ComponentID)
01353         {
01354             case 1:
01355                 return(Info.InheritComponent1);
01356 
01357             case 2:
01358                 return(Info.InheritComponent2);
01359 
01360             case 3:
01361                 return(Info.InheritComponent3);
01362 
01363             case 4:
01364                 return(Info.InheritComponent4);
01365         }
01366     }
01367 
01368     return(FALSE);
01369 }
01370 
01371 
01372 
01373 /********************************************************************************************
01374 
01375 >   BOOL IndexedColour::SetInheritsComponent(UINT32 ComponentID, BOOL Inherits)
01376 
01377     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01378     Created:    12/10/94
01379     Inputs:     ComponentID: a number [1..4] indicating which component of the colour
01380                 you wish to set inheritance information for.
01381                 Inherits -  TRUE if the component is to be inherited from the parent
01382                             FALSE if the component is to override the parent
01383 
01384     Returns:    TRUE if this results in the stored value actually changing
01385 
01386     Purpose:    To set if a given component of a colour is inherited from its linked
01387                 parent colour.
01388 
01389     Errors:     In a debug build, will give an ERROR3 if the colour is not linked
01390                 or if the index given is out of range.
01391                 In all builds, incorrect parameters will be ignored.
01392 
01393     Notes:      Should be used in conjunction with the appropriate ColourContext for this
01394                 colour's colour model to determine if a component is *valid* before you
01395                 try to set it.
01396 
01397     SeeAlso:    IndexedColour::GetType(); ColourContext::GetComponentName;
01398                 IndexedColour::InheritsComponent
01399 
01400 ********************************************************************************************/
01401 
01402 BOOL IndexedColour::SetInheritsComponent(UINT32 ComponentID, BOOL Inherits)
01403 {
01404     BOOL Result = FALSE;
01405     
01406     ERROR3IF(ComponentID < 1 || ComponentID > 4,
01407                 "Bad colour component index passed to IndexedColour::InheritsComponent");
01408 
01409     ERROR3IF(GetType() != COLOURTYPE_LINKED,
01410                 "Attempt to set Component Inheritance for non-Linked colour");
01411 
01412     UINT32 ItInherits = (Inherits) ? 1 : 0;
01413 
01414     if (GetType() == COLOURTYPE_LINKED)
01415     {
01416         switch(ComponentID)
01417         {
01418             case 1:
01419                 Result = (Info.InheritComponent1 != ItInherits);
01420                 Info.InheritComponent1 = ItInherits;
01421                 break;
01422 
01423             case 2:
01424                 Result = (Info.InheritComponent2 != ItInherits);
01425                 Info.InheritComponent2 = ItInherits;
01426                 break;
01427 
01428             case 3:
01429                 Result = (Info.InheritComponent3 != ItInherits);
01430                 Info.InheritComponent3 = ItInherits;
01431                 break;
01432 
01433             case 4:
01434                 Result = (Info.InheritComponent4 != ItInherits);
01435                 Info.InheritComponent4 = ItInherits;
01436                 break;
01437         }
01438     }
01439 
01440     if (Result)                 // If the colour has changed, invalidate the output cache
01441         InvalidateCache();
01442 
01443     return(Result);
01444 }
01445 
01446 
01447 
01448 /********************************************************************************************
01449 
01450 >   void IndexedColour::SetTintValue(FIXED24 NewTintValue)
01451 
01452     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01453     Created:    17/11/94
01454     Inputs:     NewTintValue - the new tint value, in the range 0.0 to 1.0
01455                 Any value outside this range will be clipped to 0.0 or 1.0
01456     Outputs:    -
01457     Returns:    -
01458     Purpose:    Sets a new tint value for a Tint colour. Will generate ENSURE failures in
01459                 the debug build if the colour is not a tint
01460 
01461                 This also forces a Tint to be a true tint (not a shade)
01462 
01463     Notes:      Internally, tint is currently stored in the SourceColour.Component1 field.
01464                 This should not be relied upon externally.
01465 
01466     SeeAlso:    IndexedColour::SetShadeValues
01467 
01468 ********************************************************************************************/
01469 
01470 void IndexedColour::SetTintValue(FIXED24 NewTintValue)
01471 {
01472     if (GetType() != COLOURTYPE_TINT)
01473     {
01474         ERROR3("Your puny attempt to set the tint value for a non-tint colour has been ignored");
01475         return;
01476     }
01477 
01478     Info.InheritComponent1 = FALSE;     // Force it to be a tint (not a shade)
01479 
01480     if (NewTintValue <= FIXED24(0.0))
01481         NewTintValue = 0;
01482 
01483     if (NewTintValue >= FIXED24(1.0))
01484         NewTintValue = FIXED24(1.0);
01485 
01486     SourceColour.Component1 = NewTintValue;
01487 
01488     InvalidateCache();      // The colour has changed, so invalidate the output cache
01489 }
01490 
01491 
01492 
01493 /********************************************************************************************
01494 
01495 >   FIXED24 IndexedColour::GetTintValue(void) const
01496 
01497     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01498     Created:    17/11/94
01499     Inputs:     -
01500     Outputs:    -
01501     Returns:    A FIXED24 value between 0.0 and 1.0 representing the Tint for this colour
01502 
01503                 Note that a spot colour returns 1.0 (a 100% tint - 100% ink density), and
01504                 any process (non-spot/tint) colour returns 0.0 (a 0% tint, i.e. no ink).
01505 
01506     Purpose:    Gets the current Tint value for the colour.
01507 
01508                 NOTE that the returned tint value simply indicates how much this colour
01509                 tints its parent colour (if at all). If you want to know how much ink will
01510                 actually be produced for this colour, then you want to use
01511                 GetAccumulatedTintValue() instead.
01512 
01513     Notes:      Internally, tint is currently stored in the SourceColour.Component1 field
01514                 This should not be relied upon externally.
01515 
01516     SeeAlso:    IndexedColour::GetAccumulatedTintValue
01517 
01518 ********************************************************************************************/
01519 
01520 FIXED24 IndexedColour::GetTintValue(void) const
01521 {
01522     if (GetType() == COLOURTYPE_SPOT)
01523         return(FIXED24(1.0));                   // Spot colour is a 100% tint
01524 
01525     if (GetType() != COLOURTYPE_TINT || TintIsShade())
01526         return(FIXED24(0.0));                   // Any process colour is a 0% tint
01527 
01528     return(SourceColour.Component1);            // Any tint is a (Tint)% tint
01529 }
01530 
01531 
01532 
01533 /********************************************************************************************
01534 
01535 >   FIXED24 IndexedColour::GetAccumulatedTintValue(void) const
01536 
01537     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01538     Created:    20/6/96
01539 
01540     Returns:    A FIXED24 value between 0.0 and 1.0 representing the accumulated Tint for
01541                 this colour. See Purpose for details.
01542 
01543     Purpose:    To determine the accumulated tint value of any colour.
01544 
01545                 If this is not a true tint colour, returns 0.0 (a 0% tint, i.e. white)
01546 
01547                 If this is a spot colour, returns 1.0 (i.e. 100% ink)
01548 
01549                 If this is a true tint of a spot ink, it returns the overall ink density
01550                 that should be used. With a simple tint-of-spot tint, this is the normal
01551                 tint value, but if there are a chain of tints, the tint values are
01552                 cumulative, i.e. a 50% tint of a 50% tint of Red gives a _25%_ ink density.
01553 
01554                 Thus, if you apply the GetAccumulatedTintVlaue() to the GetOldestAncestor()
01555                 colour, you will arrive at the right output colour. (This isn't actually
01556                 how screen values for tints are produced, but the cumulative tint is used
01557                 when mixing tints in blends, and most importantly when outputting separated
01558                 Spot ink plates!
01559 
01560     Notes:      The cumulative value is simply the tint values of each colour in turn in the
01561                 parent-colour chain multiplied together (where process colours are treated
01562                 as a tint value of 0.0 and the ultimate spot colour is 1.0)
01563 
01564 ********************************************************************************************/
01565 
01566 FIXED24 IndexedColour::GetAccumulatedTintValue(void)
01567 {
01568     double Tint = 1.0;
01569     IndexedColour *Ptr = this;
01570 
01571     while (Ptr != NULL && Tint > 0.0)
01572     {
01573         Tint *= Ptr->GetTintValue().MakeDouble();
01574 
01575         Ptr = Ptr->FindLinkedParent();
01576     }
01577 
01578     return(FIXED24(Tint));
01579 }
01580 
01581 
01582 
01583 /********************************************************************************************
01584 
01585 >   void IndexedColour::SetShadeValues(FIXED24 NewShadeValueX, FIXED24 NewShadeValueY)
01586 
01587     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01588     Created:    24/8/95
01589     Inputs:     NewShadeValueX - the new Shade Saturation value, in the range -1.0 to 1.0
01590                 NewShadeValueY - the new Shade Brightness value, in the range -1.0 to 1.0
01591     Outputs:    -
01592     Returns:    -
01593     Purpose:    Sets new shade values for a Shade colour. Will generate ENSURE failures in
01594                 the debug build if the colour is not a Tint/Shade
01595 
01596                 This also forces a Tint to be a shade (not a true tint)
01597 
01598     Notes:      Internally, tint/shade is currently stored in the SourceColour.Component1 field.
01599                 And now the Component2 field as well. Bodgy city dude.
01600                 This should not be relied upon externally.
01601 
01602     SeeAlso:    IndexedColour::SetTintValue
01603 
01604 ********************************************************************************************/
01605 
01606 void IndexedColour::SetShadeValues(FIXED24 NewShadeValueX, FIXED24 NewShadeValueY)
01607 {
01608     if (GetType() != COLOURTYPE_TINT)
01609     {
01610         ERROR3("Your puny attempt to set the shade values for a non-shade colour has been ignored");
01611         return;
01612     }
01613 
01614     Info.InheritComponent1 = TRUE;      // Force it to be a shade
01615 
01616 
01617     if (NewShadeValueX <= FIXED24(-1.0))
01618         NewShadeValueX = FIXED24(-1.0);
01619 
01620     if (NewShadeValueX >= FIXED24(1.0))
01621         NewShadeValueX = FIXED24(1.0);
01622 
01623     SourceColour.Component1 = NewShadeValueX;
01624 
01625 
01626     if (NewShadeValueY <= FIXED24(-1.0))
01627         NewShadeValueY = FIXED24(-1.0);
01628 
01629     if (NewShadeValueY >= FIXED24(1.0))
01630         NewShadeValueY = FIXED24(1.0);
01631 
01632     SourceColour.Component2 = NewShadeValueY;
01633 
01634 
01635     InvalidateCache();      // The colour has changed, so invalidate the output cache
01636 }
01637 
01638 
01639 
01640 /********************************************************************************************
01641 
01642 >   FIXED24 IndexedColour::GetShadeValueX(void) const
01643 
01644     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01645     Created:    24/8/95
01646     Inputs:     -
01647     Outputs:    -
01648     Returns:    A FIXED24 value between -1.0 and 1.0 representing the Shade for this colour
01649                 This value is the half of the shading settings for affecting Saturation
01650                 (If the colour is not a Tint/Shade, debug builds will ENSURE, and all builds will
01651                 return 1.0 (a 100% shade))
01652 
01653     Purpose:    Gets the current Shade Saturation value for the colour
01654 
01655     Notes:      Internally, tint/shade is currently stored in the SourceColour.Component1 field
01656                 And now the Component2 field as well. Bodgy city dude.
01657                 This should not be relied upon externally.
01658 
01659 ********************************************************************************************/
01660 
01661 FIXED24 IndexedColour::GetShadeValueX(void) const
01662 {
01663     if (GetType() != COLOURTYPE_TINT || !Info.InheritComponent1)
01664     {
01665         ERROR3("Attempt to read tint value for a non-shade colour");
01666         return(FIXED24(1.0));
01667     }
01668 
01669     return(SourceColour.Component1);
01670 }
01671 
01672 
01673 
01674 /********************************************************************************************
01675 
01676 >   FIXED24 IndexedColour::GetShadeValueY(void) const
01677 
01678     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01679     Created:    24/8/95
01680     Inputs:     -
01681     Outputs:    -
01682     Returns:    A FIXED24 value between -1.0 and 1.0 representing the Shade for this colour
01683                 This value is the half of the shading settings for affecting Brightness
01684                 (If the colour is not a Tint/Shade, debug builds will ENSURE, and all builds will
01685                 return 1.0 (a 100% shade))
01686 
01687     Purpose:    Gets the current Shade Brightness value for the colour
01688 
01689     Notes:      Internally, tint/shade is currently stored in the SourceColour.Component1 field
01690                 And now the Component2 field as well. Bodgy city dude.
01691                 This should not be relied upon externally.
01692 
01693 ********************************************************************************************/
01694 
01695 FIXED24 IndexedColour::GetShadeValueY(void) const
01696 {
01697     if (GetType() != COLOURTYPE_TINT || !Info.InheritComponent1)
01698     {
01699         ERROR3("Attempt to read tint value for a non-shade colour");
01700         return(FIXED24(1.0));
01701     }
01702 
01703     return(SourceColour.Component2);
01704 }
01705 
01706 
01707 
01708 /********************************************************************************************
01709 
01710 >   void IndexedColour::SetTintOrShade(BOOL IsATint)
01711 
01712     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01713     Created:    24/8/95
01714 
01715     Inputs:     IsATint - TRUE to make this Tint a true Tint, FALSE to make it a Shade
01716 
01717     Purpose:    Sets a COLOURTYPE_TINT colour to be either a Tint (fade-to-white) or
01718                 a shade (fade-to-black) colour. The tint/shade fraction is unchnaged (the
01719                 colour will just toggle between being darker and lighter!)
01720 
01721     Notes:      Internally, tint/shade is currently stored in the SourceColour.Component1 field
01722                 This should not be relied upon externally.
01723 
01724 ********************************************************************************************/
01725 
01726 void IndexedColour::SetTintOrShade(BOOL IsATint)
01727 {
01728     if (GetType() != COLOURTYPE_TINT)
01729     {
01730         ERROR3("Attempt to set tint/shade value for a non-tint colour");
01731         return;
01732     }
01733 
01734     Info.InheritComponent1 = IsATint ? 1 : 0;
01735 }
01736 
01737 
01738 
01739 /********************************************************************************************
01740 
01741 >   BOOL IndexedColour::TintIsShade(void) const
01742 
01743     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01744     Created:    24/8/95
01745 
01746     Returns:    TRUE if this COLOURTYPE_TINT colour is a true Tint, FALSE if it's a Shade
01747 
01748     Purpose:    Determines if a COLOURTYPE_TINT colour is really a tint or a shade
01749 
01750     Notes:      COLOURTYPE_TINT has two "subtypes" (tint-to white (tint) and tint-to-black
01751                 (shade)). These are differentiated by a single flag, and are otherwise
01752                 implemented identically. Thus, if it's type is "Tint" then it could be a
01753                 shade! (Nasty, but gets around a shortage of flag bits, and also allows
01754                 us to continue using screeds of old code which doesn't know the difference
01755                 between tints and shades and doesn't need to know)
01756 
01757                 Internally, tint/shade is currently stored in the SourceColour.Component1 field
01758                 This should not be relied upon externally.
01759 
01760 ********************************************************************************************/
01761 
01762 BOOL IndexedColour::TintIsShade(void) const
01763 {
01764     if (Info.ColourType != COLOURTYPE_TINT)
01765     {
01766         ERROR3("TintIsShade() called for non-tint/shade colour");
01767         return(FALSE);
01768     }
01769 
01770     return(Info.InheritComponent1);
01771 }
01772 
01773 
01774 
01775 /********************************************************************************************
01776 
01777 >   void IndexedColour::SwapWith(IndexedColour *Other)
01778 
01779     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01780     Created:    14/6/94
01781     Inputs:     Other - The colour to swap with
01782     Outputs:    -
01783     Returns:    -
01784     Purpose:    This swaps the definitions of the two IndexedColours.
01785 
01786     Notes:      This is used to provide undo/redo via the OpColourChange defined
01787                 in colormgr.cpp/.h, as when we undo a change to an IndexedColour,
01788                 the definition must remain at the same memory address so that all
01789                 references to it in the document do not need to be fixed.
01790                 
01791                 The implementation swaps the Info, SourceColour, & Name fields
01792                 (i.e. the colour definition) ONLY. That is, the usage count for
01793                 each object and the caches are not swapped. The caches for both
01794                 colours are in fact flushed, to guarantee their integrity.
01795 
01796 ********************************************************************************************/
01797 
01798 #define JASONSWAP(X,Y,VARTYPE)                  \
01799     {                                           \
01800         VARTYPE T;                              \
01801         memcpy(&(T), &(X), sizeof(VARTYPE));    \
01802         memcpy(&(X), &(Y), sizeof(VARTYPE));    \
01803         memcpy(&(Y), &(T), sizeof(VARTYPE));    \
01804     }
01805 
01806 void IndexedColour::SwapWith(IndexedColour *Other)
01807 {
01808     // Components to copy are:
01809     //      Info
01810     //      SourceColour
01811     //      ParentColour pointer
01812     //      Name POINTER
01813     //          CachedColour    -- We are discarding the cache anyway so ignore
01814     //          UsageCount      -- We wish to keep the usage counts intact, as it is
01815     //          ChildUsage          the number of refs to THIS object.
01816     // Thus, only the first 4 in this list are copied.
01817 
01818     JASONSWAP(Info, Other->Info, IndexedColourInfo);
01819     JASONSWAP(SourceColour, Other->SourceColour, ColourGeneric);
01820 
01821     // Swap the Name POINTER
01822     String_64 *NameTemp = Name;
01823     Name = Other->Name;
01824     Other->Name = NameTemp;
01825 
01826     // Swap the linked/tint Parent Colour pointer
01827     IndexedColour *ParentTemp = ParentColour;
01828     ParentColour = Other->ParentColour;
01829     Other->ParentColour = ParentTemp;
01830 
01831     // And invalidate the caches just to be on the safe side
01832     Info.CacheColourModel = Other->Info.CacheColourModel = COLOURMODEL_NOTCACHED;
01833     Info.OCContextHandle  = Other->Info.OCContextHandle  = 0;
01834 }
01835 
01836 #undef JASONSWAP
01837 
01838 
01839 
01840 /********************************************************************************************
01841 
01842 >   void IndexedColour::GetDebugDetails(StringBase* Str)
01843 
01844     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01845     Created:    4/5/94
01846     Inputs:     Str - string to receive the debug details
01847     Outputs:    -
01848     Returns:    -
01849     Purpose:    To get information on this colour for display in the Debug Tree
01850     Errors:     -
01851 
01852 ********************************************************************************************/
01853 
01854 void IndexedColour::GetDebugDetails(StringBase* Str)
01855 {
01856     String_256 TempStr;
01857     ColourContext *cc = ColourContext::GetGlobalDefault(GetColourModel());
01858     ColourGeneric col;
01859 
01860     String_8 UnnamedString(TEXT("N"));
01861     if (!IsNamed())
01862         UnnamedString = TEXT("U");
01863 
01864     GetSourceColour(&col);
01865     
01866     String_32 ModelName;
01867     cc->GetModelName(&ModelName);
01868 
01869     String_32 Type(TEXT(""));
01870     switch(GetType())
01871     {
01872         case COLOURTYPE_SPOT:
01873             Type._MakeMsg(TEXT(" Spot"));
01874             break;
01875 
01876         case COLOURTYPE_TINT:
01877             if (TintIsShade())
01878                 TempStr._MakeMsg( TEXT(" Shade, resulting in"));
01879             else
01880                 TempStr._MakeMsg( TEXT(" #1%ld% Tint, resulting in"),
01881                                     (INT32) (GetTintValue().MakeDouble()*100));
01882             break;
01883 
01884         case COLOURTYPE_LINKED:
01885             Type._MakeMsg(TEXT(" Linked, resulting in"));
01886             break;
01887 
01888         default:
01889             break;
01890     }
01891 
01892 
01893     TempStr._MakeMsg( TEXT(" #1%sIxCol (#2%s) =#3%s #4%s(#5%ld, #6%ld, #7%ld, #8%ld)\r\n"),
01894                         (TCHAR *) UnnamedString,
01895                         (TCHAR *) *(GetName(TRUE)),
01896                         (TCHAR *) Type,
01897                         (TCHAR *) ModelName,
01898                         (INT32) (col.Component1.MakeDouble()*100),
01899                         (INT32) (col.Component2.MakeDouble()*100),
01900                         (INT32) (col.Component3.MakeDouble()*100),
01901                         (INT32) (col.Component4.MakeDouble()*100));
01902 
01903     (*Str) += TempStr;
01904 }
01905 
01906 
01907 
01908 /********************************************************************************************
01909 
01910 >   static void IndexedColour::ForceSpotsToBeProcess(BOOL ForceOn)
01911 
01912     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01913     Created:    26/8/96
01914 
01915     Inputs:     ForceOn - TRUE to force spots to process, FALSE to let them be spots
01916 
01917     Purpose:    To set the global colour flag. When the flag is TRUE, all spot colours
01918                 in the entire program are forced to act as "normal" colours; when set
01919                 FALSE, all spot colours behave normally.
01920 
01921     Notes:      In many ways this would be better as a localised option, at least
01922                 limited to the selected document, but this is much more difficult to
01923                 achieve, and anyway, it's better that spot colours are effectively
01924                 disabled by this flag, so that it becomes obvious that spot colours
01925                 are no longer special.
01926 
01927                 This calls ColourManager::SelViewContextHasChanged() to make all
01928                 the appropriate colour interfaces update themselves correctly.
01929                 (Yeah, it's not quite the right name for what the message does,
01930                 but this is just as fundamental a change as context changing)
01931 
01932 ********************************************************************************************/
01933 
01934 void IndexedColour::ForceSpotsToBeProcess(BOOL ForceOn)
01935 {
01936     SpotsAreProcess = ForceOn;
01937     ColourManager::SelViewContextHasChanged();
01938 }
01939 

Generated on Sat Nov 10 03:44:53 2007 for Camelot by  doxygen 1.4.4