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_Williams (Xara Group Ltd) <camelotdev@xara.com> 01244 Created: 31/03/94 01245 Inputs: Source - A Colour defined in this RGBT context 01246 Result - pointer to a structure to recieve the resulting colour as 01247 defined in CIE space 01248 Outputs: - 01249 Returns: - 01250 Purpose: Converts the given colour from our RGBT colourspace to CIET colourspace 01251 This conversion will include Gamma correction etc as defined by 01252 this colour context. 01253 Notes: - 01254 Errors: - 01255 SeeAlso: ColourContextRGBT::ConvertFromCIET 01256 01257 ********************************************************************************************/ 01258 01259 void ColourContextRGBT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 01260 { 01261 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 01262 01263 ColourRGBT *bob = (ColourRGBT *) Source; 01264 01265 #ifndef NO_XARACMS 01266 // If we've got a CMS manager, use it, else use the version 1.1 bodge 01267 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 01268 01269 if (lpCMSMan != NULL) 01270 { 01271 // The new colour calibration method 01272 CMSColour icol, ocol; 01273 icol.c0 = bob->Red.MakeDouble(); 01274 icol.c1 = bob->Green.MakeDouble(); 01275 icol.c2 = bob->Blue.MakeDouble(); 01276 01277 // If we have no colour transform, or if we don't want the colour corrected/separated, 01278 // then we will just do a "logical" conversion. 01279 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 01280 lpCMSMan->ConvRGBtoCIEXYZ(icol, ocol); 01281 else 01282 lpCMSMan->GTransform(CMSTransform, cmsForward, icol, ocol); 01283 01284 Result->X = ocol.c0; 01285 Result->Y = ocol.c1; 01286 Result->Z = ocol.c2; 01287 } 01288 else 01289 #endif 01290 { 01291 // The old rgb method 01292 Result->X = bob->Red.MakeDouble(); 01293 Result->Y = bob->Green.MakeDouble(); 01294 Result->Z = bob->Blue.MakeDouble(); 01295 } 01296 01297 Result->Transparent = 0.0;//bob->Transparent; 01298 } 01299 01300 01301 01302 01303 /******************************************************************************************** 01304 01305 > void ColourContextRGBT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 01306 01307 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01308 Created: 31/03/94 01309 Inputs: Source - A Colour defined in the CIET colourspace 01310 Result - pointer to a structure to recieve the resulting colour as 01311 defined in the RGBT space described by this colour context. 01312 Outputs: - 01313 Returns: - 01314 Purpose: Converts the given colour to our RGBT colourspace from CIET colourspace 01315 This conversion will include Gamma correction etc as defined by 01316 this colour context. 01317 Notes: - 01318 Errors: - 01319 SeeAlso: ColourContextRGBT::ConvertToCIET 01320 01321 ********************************************************************************************/ 01322 01323 void ColourContextRGBT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 01324 { 01325 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 01326 01327 ColourRGBT *bob = (ColourRGBT *) Result; 01328 01329 #ifndef NO_XARACMS 01330 // If we've got a CMS manager, use it, else use the version 1.1 bodge 01331 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 01332 01333 if (lpCMSMan != NULL) 01334 { 01335 // The new colour calibration method 01336 CMSColour icol, ocol; 01337 icol.c0 = Source->X; 01338 icol.c1 = Source->Y; 01339 icol.c2 = Source->Z; 01340 01341 // If we have no colour transform, or if we don't want the colour corrected/separated, 01342 // then we will just do a "logical" conversion. 01343 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 01344 lpCMSMan->ConvCIEXYZtoRGB(icol, ocol); 01345 else 01346 lpCMSMan->GTransform(CMSTransform, cmsReverse, icol, ocol); 01347 01348 bob->Red = ocol.c0; 01349 bob->Green = ocol.c1; 01350 bob->Blue = ocol.c2; 01351 } 01352 else 01353 #endif 01354 { 01355 // The old rgb method 01356 bob->Red = Source->X; 01357 bob->Green = Source->Y; 01358 bob->Blue = Source->Z; 01359 } 01360 01361 bob->Transparent = 0;//Source->Transparent; 01362 } 01363 01364 01365 01366 /******************************************************************************************** 01367 01368 > virtual BOOL ColourContextRGBT::IsDifferent(ColourContext *Other) const 01369 01370 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01371 Created: 13/04/94 01372 Inputs: Other - a colour context to comapre ourselves to 01373 Outputs: - 01374 Returns: TRUE if the other colour context object is different from 01375 ourself, or TRUE if it is an exactly equivalent context. 01376 Purpose: Determine if two colour contexts are not exactly equivalent 01377 Errors: - 01378 SeeAlso: ColourContext::IsDifferent 01379 01380 ********************************************************************************************/ 01381 01382 01383 BOOL ColourContextRGBT::IsDifferent(ColourContext *Other) const 01384 { 01385 if(ColourContext::IsDifferent(Other)) // Different on generic ColourContext basis 01386 return(TRUE); 01387 01388 // These must both be RGBT contexts, so check if they are equivalent 01389 return(Gamma != ((ColourContextRGBT *)Other)->Gamma); 01390 } 01391 01392 01393 01394 /******************************************************************************************** 01395 01396 > void ColourContextRGBT::GetModelName(StringBase *Result) 01397 01398 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01399 Created: 1/6/94 01400 Inputs: - 01401 Outputs: Result returns continaing a String of the name of the context. 01402 This string is guaranteed to fit within a String_32 - this is the 01403 minimum size you should allocate. (Most names, in English at least, 01404 are shorter than this (10 chars max, e.g. 'RGB' 'HSV' 'Greyscale') 01405 so allow at least 10 chars of space in your displays as well) 01406 Returns: - 01407 Purpose: Returns the name of this context's colour model 01408 01409 ********************************************************************************************/ 01410 01411 void ColourContextRGBT::GetModelName(StringBase *Result) 01412 { 01413 ENSURE(Result != NULL, "ColourContext::GetModelName called with NULL result pointer!"); 01414 01415 *Result = String_32(_R(IDS_COLMODEL_RGBT)); 01416 } 01417 01418 01419 01420 /******************************************************************************************** 01421 01422 > void ColourContextWebRGBT::GetModelName(StringBase *Result) 01423 01424 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01425 Created: ??/11/99 01426 Inputs: - 01427 Outputs: Result returns continaing a String of the name of the context. 01428 This string is guaranteed to fit within a String_32 - this is the 01429 minimum size you should allocate. (Most names, in English at least, 01430 are shorter than this (10 chars max, e.g. 'RGB' 'HSV' 'Greyscale') 01431 so allow at least 10 chars of space in your displays as well) 01432 Returns: - 01433 Purpose: Returns the name of this context's colour model 01434 01435 ********************************************************************************************/ 01436 01437 void ColourContextWebRGBT::GetModelName(StringBase *Result) 01438 { 01439 ENSURE(Result != NULL, "ColourContext::GetModelName called with NULL result pointer!"); 01440 01441 *Result = String_32(_R(IDS_COLMODEL_WEBRGBT)); 01442 } 01443 01444 01445 01446 /******************************************************************************************** 01447 01448 > BOOL ColourContextRGBT::GetComponentName(INT32 ComponentID, StringBase *Result, 01449 BOOL LongName = FALSE) 01450 01451 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01452 Created: 26/7/94 01453 Inputs: ComponentID - Index [1..4] of the component you want the name of 01454 (Result is an output) 01455 LongName - TRUE to get the long name, FALSE to get the short name 01456 (e.g. "Magenta" vs "M", "Saturation" vs "Sat") 01457 01458 Outputs: Result returns containing a String of the name of the given component 01459 of colours defined in this context. 01460 This string is guaranteed to fit within a String_32 - this is the 01461 minimum size you should allocate. (Most names, in English at least, 01462 are shorter than this (10 chars max, e.g. 'Red' 'Hue' 'Saturation') 01463 so allow at least 10 chars of space in your displays as well) 01464 01465 Note that Result can be passed in NULL in order to only determine if the 01466 context supports a given component. 01467 01468 Returns: FALSE if this component is not used by this model. 01469 Purpose: Returns the name of one of this context's colour components 01470 01471 Notes: The components are given in the same order as they appear in the 01472 high-precision ColourXYZ structures defined in colmodel.h 01473 01474 ********************************************************************************************/ 01475 01476 BOOL ColourContextRGBT::GetComponentName(INT32 ComponentID, StringBase *Result, BOOL LongName) 01477 { 01478 UINT32 StringID = 0; 01479 BOOL Used = TRUE; 01480 01481 switch(ComponentID) 01482 { 01483 case 1: 01484 StringID = (LongName) ? _R(IDS_COLCOMPL_RED) : _R(IDS_COLCOMP_RED); 01485 break; 01486 01487 case 2: 01488 StringID = (LongName) ? _R(IDS_COLCOMPL_GREEN) : _R(IDS_COLCOMP_GREEN); 01489 break; 01490 01491 case 3: 01492 StringID = (LongName) ? _R(IDS_COLCOMPL_BLUE) : _R(IDS_COLCOMP_BLUE); 01493 break; 01494 #ifdef TRANSPARENTCOLOUR 01495 default: 01496 StringID = _R(IDS_COLCOMP_TRANS); 01497 break; 01498 #else 01499 default: 01500 Used = FALSE; 01501 break; 01502 #endif 01503 } 01504 01505 if (Result != NULL && StringID != 0) 01506 *Result = String_32(StringID); 01507 01508 return(Used); 01509 } 01510 01511 01512 01513 /******************************************************************************************** 01514 01515 > virtual UnitGroup **ColourContextRGBT::GetComponentUnitGroups() 01516 01517 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01518 Created: 02/05/96 01519 Inputs: - 01520 Outputs: - 01521 Returns: A pointer to the UnitGroup array 01522 Purpose: Provides an array of UnitGroups primarily for use by the base class 01523 (ColourContext) members Set/GetComponentUnitGroup(). 01524 Errors: - 01525 See Also: ColourContext::GetComponentUnitGroup() 01526 ColourContext::SetComponentUnitGroup() 01527 01528 ********************************************************************************************/ 01529 01530 UnitGroup **ColourContextRGBT::GetComponentUnitGroups() 01531 { 01532 return m_pUnitGroupArray; 01533 } 01534 01535 01536 UnitGroup *ColourContextRGBT::m_pUnitGroupArray[] = 01537 { 01538 &(StandardUnit::PercentGroup), 01539 &(StandardUnit::PercentGroup), 01540 &(StandardUnit::PercentGroup) 01541 }; 01542 01543 01544 01545 /******************************************************************************************** 01546 01547 > UINT32 ColourContextRGBT::GetComponentCount() 01548 01549 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01550 Created: 02/05/96 01551 Returns: The number of components 01552 Purpose: Provides number of components in the colour context's colour model 01553 01554 ********************************************************************************************/ 01555 01556 UINT32 ColourContextRGBT::GetComponentCount() 01557 { 01558 return MAX_COMPONENTS; 01559 } 01560 01561 01562 /******************************************************************************************** 01563 01564 > virtual void ColourContextRGBT::ApplyTint(ColourValue TintFraction, 01565 ColourGeneric *SourceAndResult) 01566 01567 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01568 Created: 17/11/94 01569 Inputs: TintFraction - The fraction (as a FIXED24 ColourValue) by which the colour 01570 should be tinted. This value is expected to lie between 0.0 and 1.0 inclusive 01571 01572 SourceAndResult - The source colour to be tinted, as defined in this 01573 colour model 01574 01575 Outputs: SourceAndResult is tinted by the given TintFraction 01576 If TintFraction <= 0.0, White is output 01577 If TintFraction >= 1.0, The source colour is output 01578 01579 Returns: - 01580 Purpose: Tints a colour (mixes it with white) 01581 01582 Notes: If the tinting value is out of range, either source-colour ow white (as 01583 appropriate) will be output. 01584 01585 ********************************************************************************************/ 01586 01587 void ColourContextRGBT::ApplyTint(ColourValue TintFraction, ColourGeneric *SourceAndResult) 01588 { 01589 ColourRGBT *Result = (ColourRGBT *) SourceAndResult; 01590 01591 if (TintFraction <= FIXED24(0.0)) // 0% tint = White 01592 { 01593 Result->Red = Result->Green = Result->Blue = FIXED24(1.0); 01594 return; 01595 } 01596 01597 if (TintFraction >= FIXED24(1.0)) // The Result colour is identical to the source 01598 return; 01599 01600 // Otherwise, tint the colour... 01601 Result->Red = FIXED24(1.0) - (TintFraction - (Result->Red * TintFraction)); 01602 Result->Green = FIXED24(1.0) - (TintFraction - (Result->Green * TintFraction)); 01603 Result->Blue = FIXED24(1.0) - (TintFraction - (Result->Blue * TintFraction)); 01604 } 01605 01606 01607 /******************************************************************************************** 01608 01609 > void ColourContextRGBT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 01610 ColourGeneric *SourceAndResult) 01611 01612 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01613 Created: 24/8/95 01614 Inputs: XFraction - The fraction (as a FIXED24 ColourValue) by which the colour 01615 should be saturated. This value is expected to lie between -1.0 and 1.0 inclusive 01616 Values below 0.0 mean tint towards 0, while values above mean tint towards 1. 01617 0.0 means no tinting 01618 01619 YFraction - The fraction (as a FIXED24 ColourValue) by which the colour 01620 should be shaded. This value is expected to lie between -1.0 and 1.0 inclusive 01621 Values below 0.0 mean shade towards 0, while values above mean shade towards 1. 01622 0.0 means no shading 01623 01624 SourceAndResult - The source colour to be tinted, as defined in this 01625 colour model 01626 01627 Outputs: SourceAndResult is shaded by the given Fractions 01628 Any invalid value is clipped to 0.0 01629 01630 Returns: - 01631 Purpose: Shades a colour (tweaks the saturation and value in a relative way) 01632 01633 Notes: Contexts other than HSV currently convert the colour to and from HSV 01634 form in order to apply the shade. This is a tad inefficient, but a 01635 quick'n'easy bodge that will get it going nice and quickly. 01636 01637 ********************************************************************************************/ 01638 01639 void ColourContextRGBT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 01640 ColourGeneric *SourceAndResult) 01641 { 01642 ColourHSVT HSVDef; 01643 ColourContext *cc = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT); 01644 ERROR3IF(cc == NULL, "No default HSV colour context?!"); 01645 01646 cc->ConvertColour(this, SourceAndResult, (ColourGeneric *) &HSVDef); 01647 cc->ApplyShade(XFraction, YFraction, (ColourGeneric *) &HSVDef); 01648 ConvertColour(cc, (ColourGeneric *) &HSVDef, SourceAndResult); 01649 } 01650 01651 01652 01653 /******************************************************************************************** 01654 01655 > virtual void ColourContextRGBT::ApplyOutputFilter(ColourPlate *FilterDescription, 01656 ColourContext *SourceContext, 01657 ColourGeneric *OutputColour, 01658 IndexedColour *SourceIxCol) 01659 01660 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01661 Created: 22/1/96 01662 Inputs: FilterDescription - A ColourPlate describing how the colour is to be filtered 01663 01664 SourceContext - Points to the context from which the OutputColour has just 01665 been converted. 01666 01667 OutputColour - The colour to be filtered 01668 01669 SourceIxCol - NULL, or the IndexedColour which was the source of the colour 01670 being converted. This is only used for information when preparing spot colour 01671 separations. 01672 01673 Outputs: OutputColour - Will be modified as appropriate to the current colour 01674 filtering options (see Purpose) 01675 01676 Purpose: All colour conversions call this function immediately prior to returning 01677 the converted colour to the caller. This gives the output colour context 01678 the chance to apply an output filtering process to the output colour. 01679 01680 This is usually used to provide colour separations, and may also be used 01681 to apply some colour corrections. Often, this function will do nothing 01682 to the output colour. 01683 01684 SeeAlso: ColourContext::ConvertColourBase 01685 01686 ********************************************************************************************/ 01687 01688 void ColourContextRGBT::ApplyOutputFilter(ColourPlate *FilterDescription, ColourContext *SourceContext, 01689 ColourGeneric *OutputColour, IndexedColour *SourceIxCol) 01690 { 01691 ERROR3IF(FilterDescription == NULL || SourceContext == NULL || OutputColour == NULL, "Illegal NULL params"); 01692 01693 // No FilterDescription means no filtering, so we return immeidately 01694 // If the source colour was CMYK, we mustn't filter it, except when doing a composite preview, as 01695 // the filtering (separation) of CMYK all happens in ApplyInputFilter 01696 if (FilterDescription == NULL || 01697 (SourceContext->GetColourModel() == COLOURMODEL_CMYK && 01698 FilterDescription->GetType() != COLOURPLATE_COMPOSITE)) 01699 { 01700 return; 01701 } 01702 01703 ColourRGBT *OutputRGB = (ColourRGBT *)OutputColour; 01704 FIXED24 temp; 01705 01706 01707 /*----------------------------------------------------------------------------------------------- 01708 Local Macro GETCOLOURINCMYK(ColourCMYK RESULT) 01709 01710 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01711 Date: 3/7/96 01712 Inputs: RESULT - will be filled in with a CMYK definition for OutputRGB 01713 Purpose: Converts our OutputRGB variable into a CMYK form. 01714 01715 Notes: This only works in the scope in which it is used below. It is merely to save 01716 writing the code out longhand, and to make the repeated section of the code below 01717 more readable. 01718 01719 Special care is taken with the conversion - We try to find a CMYK context from 01720 our ScopeView, so that we use the correct colour-separation profile for the current 01721 output device. We also do the conversion manually (to & from CIE space) rather 01722 than just calling ConvertColour because (a) it's more efficient, and (b) we don't 01723 want the CMYK context to do anything like colour separation on the colour! 01724 01725 This macro ius undefined at the end of the switch statement which uses it 01726 01727 ----------------------------------------------------------------------------------------------- 01728 */ 01729 #define GETCOLOURINCMYK(RESULT) \ 01730 { \ 01731 ColourContextCMYK *ccCMYK; \ 01732 if (ScopeView != NULL) \ 01733 ccCMYK = (ColourContextCMYK *) ScopeView->GetColourContext(COLOURMODEL_CMYK); \ 01734 else \ 01735 ccCMYK = (ColourContextCMYK *) ColourManager::GetColourContext(COLOURMODEL_CMYK); \ 01736 \ 01737 DColourCIET IntermediateResult; \ 01738 ConvertToCIET(OutputColour, &IntermediateResult); \ 01739 ccCMYK->ConvertFromCIET(&IntermediateResult, (ColourGeneric *)&(RESULT)); \ 01740 } 01741 //----------------------------------------------------------------------------------------------- 01742 01743 01744 // Separate the colour as appropriate 01745 switch(FilterDescription->GetType()) 01746 { 01747 case COLOURPLATE_CYAN: 01748 { 01749 ColourCMYK cmyk; // Get OutputRGB as defined in cmyk 01750 GETCOLOURINCMYK(cmyk); 01751 01752 if (FilterDescription->IsNegative()) // Negate the plate if necessary 01753 OutputRGB->Red = cmyk.Cyan; 01754 else 01755 OutputRGB->Red = 1.0 - cmyk.Cyan; 01756 01757 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 01758 OutputRGB->Green = OutputRGB->Blue = OutputRGB->Red; 01759 else 01760 OutputRGB->Green = OutputRGB->Blue = 1.0; 01761 } 01762 break; 01763 01764 case COLOURPLATE_MAGENTA: 01765 { 01766 ColourCMYK cmyk; // Get OutputRGB as defined in cmyk 01767 GETCOLOURINCMYK(cmyk); 01768 01769 if (FilterDescription->IsNegative()) // Negate the plate if necessary 01770 OutputRGB->Green = cmyk.Magenta; 01771 else 01772 OutputRGB->Green = 1.0 - cmyk.Magenta; 01773 01774 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 01775 OutputRGB->Red = OutputRGB->Blue = OutputRGB->Green; 01776 else 01777 OutputRGB->Red = OutputRGB->Blue = 1.0; 01778 } 01779 break; 01780 01781 case COLOURPLATE_YELLOW: 01782 { 01783 ColourCMYK cmyk; // Get OutputRGB as defined in cmyk 01784 GETCOLOURINCMYK(cmyk); 01785 01786 if (FilterDescription->IsNegative()) // Negate the plate if necessary 01787 OutputRGB->Blue = cmyk.Yellow; 01788 else 01789 OutputRGB->Blue = 1.0 - cmyk.Yellow; 01790 01791 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 01792 OutputRGB->Green = OutputRGB->Red = OutputRGB->Blue; 01793 else 01794 OutputRGB->Green = OutputRGB->Red = 1.0; 01795 } 01796 break; 01797 01798 case COLOURPLATE_KEY: 01799 { 01800 ColourCMYK cmyk; // Get OutputRGB as defined in cmyk 01801 GETCOLOURINCMYK(cmyk); 01802 01803 // The FilterDescription->IsMonochrome() flag has no effect on this plate! 01804 01805 if (FilterDescription->IsNegative()) 01806 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = cmyk.Key; 01807 else 01808 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = 1.0 - cmyk.Key; 01809 } 01810 break; 01811 01812 case COLOURPLATE_SPOT: 01813 // NOTE: 01814 // Spot colours are partially handled by the IndexedColour variants of 01815 // ConvertColour, so will be separated appropriately by the time they 01816 // reach us here. However, non-IndexedColours will not be, so we must 01817 // sit on them to make them white, so that DocColour and GenericColour 01818 // conversions are eliminated properly from spot plates. 01819 // However, if a spot colour gets this far, we need to generate an ink 01820 // density value for output, as well as applying the negate flag. 01821 // 01822 // Actually, I have decreed that all spot plates will always be monochrome, 01823 // because that makes coding DocColour::Mix much easier, and anyway it makes 01824 // a load more sense for the very good reason that if you don't believe me 01825 // I'll get my Dad to come around and beat up your dad. 01826 01827 if (SourceIxCol == NULL) 01828 { 01829 // It's not an IndexedColour, so can't appear on this plate - make it white 01830 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = 1.0; 01831 } 01832 else 01833 { 01834 // We have a source IndexedColour, so we know it's been separated. 01835 // We just have to get a decent ink density value out of the IxCol 01836 if (SourceIxCol == FilterDescription->GetSpotColour()) 01837 { 01838 // The spot colour itself is always considered a 100% tint (100% ink) 01839 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = 0.0; 01840 } 01841 else if (SourceIxCol->IsADescendantOf(FilterDescription->GetSpotColour())) 01842 { 01843 // It's not the spot colour, but it is a child - check that it's a tint 01844 ERROR3IF(SourceIxCol->GetType() != COLOURTYPE_TINT || 01845 SourceIxCol->TintIsShade(), 01846 "Spot colour children must all be tints!"); 01847 01848 // Tint gives the amount of ink - we have to inverse this in RGB 01849 // to get the appropriate grey level. Note that we get the accumulated 01850 // tint value rather than the simple tint, which is the true output ink 01851 // density. 01852 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = 01853 1.0 - SourceIxCol->GetAccumulatedTintValue(); 01854 } 01855 } 01856 01857 // If negative, then photographically invert the colour 01858 if (FilterDescription->IsNegative()) 01859 { 01860 OutputRGB->Red = 1.0 - OutputRGB->Red; 01861 OutputRGB->Green = 1.0 - OutputRGB->Green; 01862 OutputRGB->Blue = 1.0 - OutputRGB->Blue; 01863 } 01864 break; 01865 01866 case COLOURPLATE_COMPOSITE: 01867 #ifndef NO_XARACMS 01868 // Go to and from (printer) cmyk just for a laugh. 01869 // (NOTE that ConvertColourBase won't actually call us in this case any more) 01870 if (SourceIxCol != NULL && SourceIxCol->GetColourModel() == COLOURMODEL_CMYK) 01871 { 01872 // If it's a CMYK colour, then it's already in printer gamut, so we only apply 01873 // the backward colour correction factor to it. 01874 // Note that this means we chuck away the entire colour conversion result! 01875 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 01876 if (lpCMSMan != NULL) 01877 { 01878 ColourCMYK Def; 01879 SourceIxCol->GetSourceColour((ColourGeneric *) &Def); 01880 01881 lpCMSMan->ConvertColourForPaperView(&Def, OutputRGB); 01882 } 01883 } 01884 else 01885 { 01886 // If it's a non-CMYK colour, then we go to and from printer gamut just for a laugh 01887 // Find the CMS manager, and get it to do all the work 01888 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 01889 if (lpCMSMan != NULL) 01890 lpCMSMan->ConvertColourForPaperView(OutputRGB); 01891 } 01892 #endif 01893 // ... drop through to the default case to apply monochrome/negate 01894 01895 default: 01896 // If monochrome, convert the image to a greyscale 01897 if (FilterDescription->IsMonochrome()) 01898 { 01899 FIXED24 temp = (OutputRGB->Red * 0.305) + (OutputRGB->Green * 0.586) + (OutputRGB->Blue * 0.109); 01900 OutputRGB->Red = OutputRGB->Green = OutputRGB->Blue = temp; 01901 } 01902 01903 // If negative, then photographically invert the colour 01904 if (FilterDescription->IsNegative()) 01905 { 01906 OutputRGB->Red = 1.0 - OutputRGB->Red; 01907 OutputRGB->Green = 1.0 - OutputRGB->Green; 01908 OutputRGB->Blue = 1.0 - OutputRGB->Blue; 01909 } 01910 break; 01911 } 01912 01913 // And un-define our macro again to make sure it's not used out of its scope 01914 #undef GETCOLOURINCMYK 01915 } 01916 01917 01918 01919 /******************************************************************************************** 01920 01921 > virtual void ColourContextRGBT::GetWhite(ColourGeneric *Result); 01922 01923 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01924 Created: 8/6/96 01925 01926 Outputs: Result - Will be filled in with White, however that is defined in 01927 this context's colour model. (i.e. RGB(1,1,1) or CMYK(0,0,0,0), etc) 01928 01929 Purpose: An easy way to get a colour definition in this colour model which 01930 is white (paper colour). 01931 01932 ********************************************************************************************/ 01933 01934 void ColourContextRGBT::GetWhite(ColourGeneric *Result) 01935 { 01936 ColourRGBT *rgb = (ColourRGBT *) Result; 01937 rgb->Red = rgb->Green = rgb->Blue = 1.0; 01938 rgb->Transparent = 0; 01939 } 01940 01941 01942 01943 01944 01945 01946 01947 01948 01949 01950 /******************************************************************************************** 01951 01952 > void ColourContextCMYK::ColourContextCMYK(View *Scope) 01953 01954 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01955 Created: 14/04/94 01956 Inputs: Scope - The view in which this context is to be used, or NULL 01957 Outputs: - 01958 Returns: - 01959 Purpose: Constructor for a "logical" CMYK Colour context 01960 01961 A logical context represents an "ideal" CMYK printer. This is used 01962 internally when converting colours between logical colour models, 01963 and only used externally when no printer device profile is available. 01964 01965 Notes: Colour Contexts should not be created and used directly. See the 01966 notes in the SeeAlso's for instructions on proper care and use. 01967 01968 Errors: - 01969 SeeAlso: ColourContext::ColourContext; ColourContextList::AddContext 01970 01971 ********************************************************************************************/ 01972 01973 ColourContextCMYK::ColourContextCMYK(View *Scope) 01974 : ColourContext(Scope) 01975 { 01976 ColModel = COLOURMODEL_CMYK; 01977 CreateExternalTransform(); 01978 } 01979 01980 01981 01982 /******************************************************************************************** 01983 01984 > void ColourContextCMYK::ColourContextCMYK(View *Scope, StringBase *ProfileName) 01985 01986 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01987 Created: 6/6/96 01988 Inputs: Scope - The view in which this context is to be used, or NULL 01989 ProfileName - A string indicating the XaraCMS device profile which 01990 describes the printer device this context represents 01991 Outputs: - 01992 Returns: - 01993 Purpose: Constructor for a CMYK Colour context 01994 01995 Notes: Colour Contexts should not be created and used directly. See the 01996 notes in the SeeAlso's for instructions on proper care and use. 01997 01998 XaraCMS::GetPrinterProfile() can be used to find the default printer 01999 profile name. 02000 02001 Errors: - 02002 SeeAlso: ColourContext::ColourContext; ColourContextList::AddContext 02003 02004 ********************************************************************************************/ 02005 02006 ColourContextCMYK::ColourContextCMYK(View *Scope, StringBase *NewProfileName) 02007 : ColourContext(Scope) 02008 { 02009 ColModel = COLOURMODEL_CMYK; 02010 02011 if (NewProfileName == NULL) 02012 { 02013 ERROR3("Illegal NULL param"); 02014 ProfileName.Empty(); 02015 } 02016 else 02017 ProfileName = *NewProfileName; 02018 02019 CreateExternalTransform(); 02020 } 02021 02022 02023 02024 /******************************************************************************************** 02025 02026 > void ColourContextCMYK::CreateExternalTransform(void) 02027 02028 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02029 Created: 12/05/96 02030 Inputs: - 02031 Returns: - 02032 Purpose: Create an external transform to be used during colour conversions from 02033 CMYK to the current RCS space. This function uses the Winoil CMS Manager 02034 to create the transform. Both forward and backward transforms use a physical 02035 printer profile description. 02036 02037 ********************************************************************************************/ 02038 02039 void ColourContextCMYK::CreateExternalTransform() 02040 { 02041 #ifndef NO_XARACMS 02042 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 02043 02044 // If we have a CMS and we are not a logical context, set up a transform 02045 if (lpCMSMan != NULL && !ProfileName.IsEmpty()) 02046 { 02047 TCHAR* pProfile = (TCHAR*)ProfileName; 02048 02049 // set this as the active colour profile 02050 UINT32 err = lpCMSMan->SetProfile(ptPrinter, pProfile); 02051 02052 // if we haven't got an error, create that transform 02053 if (err==0) 02054 CMSTransform = lpCMSMan->CreateTransform(PRINT_RCS); 02055 } 02056 #endif 02057 } 02058 02059 02060 02061 /******************************************************************************************** 02062 02063 > void ColourContextCMYK::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 02064 02065 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02066 Created: 31/03/94 02067 Inputs: Source - A Colour defined in this CMYK context 02068 Result - pointer to a structure to recieve the resulting colour as 02069 defined in CIE space 02070 Outputs: - 02071 Returns: - 02072 Purpose: Converts the given colour from our CMYK colourspace to CIET colourspace 02073 02074 Notes: - 02075 Errors: - 02076 SeeAlso: ColourContextCMYK::ConvertFromCIET 02077 02078 ********************************************************************************************/ 02079 02080 void ColourContextCMYK::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 02081 { 02082 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 02083 02084 ColourCMYK *bob = (ColourCMYK *) Source; 02085 02086 #ifndef NO_XARACMS 02087 // If we've got a CMS manager, use it, else use the version 1.1 bodge 02088 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 02089 02090 if (lpCMSMan != NULL) 02091 { 02092 // The new colour calibration method 02093 CMSColour icol, ocol; 02094 icol.c0 = bob->Cyan.MakeDouble(); 02095 icol.c1 = bob->Magenta.MakeDouble(); 02096 icol.c2 = bob->Yellow.MakeDouble(); 02097 icol.c3 = bob->Key.MakeDouble(); 02098 02099 // If we have no colour transform, or if we don't want the colour corrected/separated, 02100 // then we will just do a "logical" conversion. 02101 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 02102 lpCMSMan->ConvCMYKtoCIEXYZ(icol, ocol); 02103 else 02104 lpCMSMan->GTransform(CMSTransform, cmsForward, icol, ocol); 02105 02106 Result->X = ocol.c0; 02107 Result->Y = ocol.c1; 02108 Result->Z = ocol.c2; 02109 } 02110 else 02111 #endif 02112 { 02113 // The old rgb method 02114 Result->X = ( 1.0 - ( min( 1.0, ( bob->Cyan + bob->Key ).MakeDouble() ) ) ); // R 02115 Result->Y = ( 1.0 - ( min( 1.0, ( bob->Magenta + bob->Key ).MakeDouble() ) ) ); // G 02116 Result->Z = ( 1.0 - ( min( 1.0, ( bob->Yellow + bob->Key ).MakeDouble() ) ) ); // B 02117 } 02118 02119 Result->Transparent = 0.0; // CMYK values are not transparent 02120 } 02121 02122 02123 02124 02125 /******************************************************************************************** 02126 02127 > void ColourContextCMYK::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 02128 02129 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02130 Created: 14/04/94 02131 Inputs: Source - A Colour defined in the CIET colourspace 02132 Result - pointer to a structure to recieve the resulting colour as 02133 defined in the CMYK space described by this colour context. 02134 Outputs: - 02135 Returns: - 02136 Purpose: Converts the given colour to our CMYK colourspace from CIET colourspace 02137 Notes: - 02138 Errors: - 02139 SeeAlso: ColourContextCMYK::ConvertToCIET 02140 02141 ********************************************************************************************/ 02142 02143 void ColourContextCMYK::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 02144 { 02145 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 02146 02147 ColourCMYK *cmyk = (ColourCMYK *) Result; 02148 02149 #ifndef NO_XARACMS 02150 // If we've got a CMS manager, use it, else use the version 1.1 bodge 02151 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 02152 02153 if (lpCMSMan != NULL) 02154 { 02155 // The new colour calibration method 02156 CMSColour icol, ocol; 02157 icol.c0 = Source->X; 02158 icol.c1 = Source->Y; 02159 icol.c2 = Source->Z; 02160 02161 // If we have no colour transform, or if we don't want the colour corrected/separated, 02162 // then we will just do a "logical" conversion. 02163 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 02164 lpCMSMan->ConvCIEXYZtoCMYK(icol, ocol); 02165 else 02166 lpCMSMan->GTransform(CMSTransform, cmsReverse, icol, ocol); 02167 02168 cmyk->Cyan = FIXED24(ocol.c0); 02169 cmyk->Magenta= FIXED24(ocol.c1); 02170 cmyk->Yellow = FIXED24(ocol.c2); 02171 cmyk->Key = FIXED24(ocol.c3); 02172 02173 /* 02174 #ifdef _DEBUG 02175 { 02176 // Check that the colour will round-trip from CIE to CMYK and back to CIE correctly 02177 DColourCIET temp; 02178 ConvertToCIET(Result, &temp); 02179 INT32 t1 = (INT32)(Source->X*1000.0); 02180 INT32 t2 = (INT32)(Source->Y*1000.0); 02181 INT32 t3 = (INT32)(Source->Z*1000.0); 02182 INT32 t4 = (INT32)INT32(temp.X*1000.0); 02183 INT32 t5 = (INT32)INT32(temp.Y*1000.0); 02184 INT32 t6 = (INT32)INT32(temp.Z*1000.0); 02185 CMSColour orgb, orgb2; 02186 lpCMSMan->ConvCIEXYZtoRGB(icol, orgb); 02187 if (t1==t4 && t2==t5 && t3==t6) 02188 { 02189 TRACE( _T("CIE-CMYK-CIE roundtrip OK : RGB(%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f,%.3f)\n"), orgb.c0, orgb.c1, orgb.c2, ocol.c0, ocol.c1, ocol.c2, ocol.c3); 02190 } 02191 else 02192 { 02193 TRACE( _T("CIE-CMYK-CIE roundtrip error: RGB(%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f,%.3f)\n"), orgb.c0, orgb.c1, orgb.c2, ocol.c0, ocol.c1, ocol.c2, ocol.c3); 02194 TRACE( _T(" CIEIn[%d,%d,%d] CIEOut[%d,%d,%d]\n"), t1, t2, t3, t4, t5, t6); 02195 } 02196 02197 // ERROR3IF((INT32)(temp.X*1000.0)!=(INT32)(Source->X*1000.0) || 02198 // (INT32)(temp.Y*1000.0)!=(INT32)(Source->Y*1000.0) || 02199 // (INT32)(temp.Z*1000.0)!=(INT32)(Source->Z*1000.0), 02200 // "CMYK does not round-trip!"); 02201 } 02202 #endif 02203 */ 02204 02205 } 02206 else 02207 #endif 02208 { 02209 // The old rgb method 02210 ColourRGBT rgb; 02211 rgb.Red = FIXED24(Source->X); 02212 rgb.Green = FIXED24(Source->Y); 02213 rgb.Blue = FIXED24(Source->Z); 02214 02215 // If all components are 0 then we know it's BLACK. 02216 if (rgb.Red <= 0 && rgb.Green <= 0 && rgb.Blue <= 0) 02217 { 02218 cmyk->Cyan = cmyk->Magenta = cmyk->Yellow = 0; 02219 cmyk->Key = 1.0; 02220 } 02221 else 02222 { 02223 // Invert the Colour Vector 02224 cmyk->Cyan = 1.0 - rgb.Red; 02225 cmyk->Magenta = 1.0 - rgb.Green; 02226 cmyk->Yellow = 1.0 - rgb.Blue; 02227 02228 double smallest; 02229 02230 smallest = min(cmyk->Cyan.MakeDouble(), cmyk->Magenta.MakeDouble()); 02231 smallest = min(smallest, cmyk->Yellow.MakeDouble()); 02232 smallest = max(smallest-0.5, 0.0); 02233 02234 // Key starts being generated beyond threshold 02235 cmyk->Key = smallest; 02236 02237 // Subtract KEY component. 02238 cmyk->Cyan -= cmyk->Key; 02239 cmyk->Magenta -= cmyk->Key; 02240 cmyk->Yellow -= cmyk->Key; 02241 } 02242 } 02243 } 02244 02245 02246 02247 /******************************************************************************************** 02248 02249 > BOOL ColourContextCMYK::GetProfileTables(BYTE* Tables) 02250 02251 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02252 Created: 14/04/94 02253 Inputs: Tables = a byte pointer to a 5*256 byte buffer 02254 Outputs: TRUE if the Tables buffer has been filled 02255 FALSE otherwise. 02256 Purpose: Uses the CMSManager to extract the profile data from our current CMSTransform 02257 02258 ********************************************************************************************/ 02259 02260 BOOL ColourContextCMYK::GetProfileTables(BYTE* Tables) 02261 { 02262 PORTNOTE("other","Removed HCMTRANSFORM usage") 02263 #ifndef EXCLUDE_FROM_XARALX 02264 if (CMSTransform==NULL) 02265 return FALSE; 02266 #endif 02267 02268 #ifdef NO_XARACMS 02269 return FALSE; 02270 #else 02271 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 02272 if (lpCMSMan==NULL) 02273 return FALSE; 02274 02275 return lpCMSMan->GetProfileTables(CMSTransform, Tables); 02276 #endif 02277 } 02278 02279 02280 02281 /******************************************************************************************** 02282 02283 > void ColourContextCMYK::GetModelName(StringBase *Result) 02284 02285 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02286 Created: 1/6/94 02287 Inputs: - 02288 Outputs: Result returns continaing a String of the name of the context. 02289 This string is guaranteed to fit within a String_32 - this is the 02290 minimum size you should allocate. (Most names, in English at least, 02291 are shorter than this (10 chars max, e.g. 'RGB' 'HSV' 'Greyscale') 02292 so allow at least 10 chars of space in your displays as well) 02293 Returns: - 02294 Purpose: Returns the name of this context's colour model 02295 Notes: 02296 02297 ********************************************************************************************/ 02298 02299 void ColourContextCMYK::GetModelName(StringBase *Result) 02300 { 02301 ENSURE(Result != NULL, "ColourContext::GetModelName called with NULL result pointer!"); 02302 02303 *Result = String_32(_R(IDS_COLMODEL_CMYK)); 02304 } 02305 02306 02307 02308 /******************************************************************************************** 02309 02310 > BOOL ColourContextCMYK::GetComponentName(INT32 ComponentID, StringBase *Result, 02311 BOOL LongName = FALSE) 02312 02313 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02314 Created: 26/7/94 02315 Inputs: ComponentID - Index [1..4] of the component you want the name of 02316 (Result is an output) 02317 LongName - TRUE to get the long name, FALSE to get the short name 02318 (e.g. "Magenta" vs "M", "Saturation" vs "Sat") 02319 02320 Outputs: Result returns containing a String of the name of the given component 02321 of colours defined in this context. 02322 This string is guaranteed to fit within a String_32 - this is the 02323 minimum size you should allocate. (Most names, in English at least, 02324 are shorter than this (10 chars max, e.g. 'Red' 'Hue' 'Saturation') 02325 so allow at least 10 chars of space in your displays as well) 02326 02327 Note that Result can be passed in NULL in order to only determine if the 02328 context supports a given component. 02329 02330 Returns: FALSE if this component is not used by this model. 02331 Purpose: Returns the name of one of this context's colour components 02332 02333 Notes: The components are given in the same order as they appear in the 02334 high-precision ColourXYZ structures defined in colmodel.h 02335 02336 ********************************************************************************************/ 02337 02338 BOOL ColourContextCMYK::GetComponentName(INT32 ComponentID, StringBase *Result, BOOL LongName) 02339 { 02340 UINT32 StringID = 0; 02341 BOOL Used = TRUE; 02342 02343 switch(ComponentID) 02344 { 02345 case 1: 02346 StringID = (LongName) ? _R(IDS_COLCOMPL_CYAN) : _R(IDS_COLCOMP_CYAN); 02347 break; 02348 02349 case 2: 02350 StringID = (LongName) ? _R(IDS_COLCOMPL_MAGENTA) : _R(IDS_COLCOMP_MAGENTA); 02351 break; 02352 02353 case 3: 02354 StringID = (LongName) ? _R(IDS_COLCOMPL_YELLOW) : _R(IDS_COLCOMP_YELLOW); 02355 break; 02356 02357 default: 02358 StringID = (LongName) ? _R(IDS_COLCOMPL_KEY) : _R(IDS_COLCOMP_KEY); 02359 break; 02360 } 02361 02362 if (Result != NULL && StringID != 0) 02363 *Result = String_32(StringID); 02364 02365 return(Used); 02366 } 02367 02368 02369 /******************************************************************************************** 02370 02371 > virtual UnitGroup **ColourContextCMYK::GetComponentUnitGroups() 02372 02373 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 02374 Created: 02/05/96 02375 Inputs: - 02376 Outputs: - 02377 Returns: A pointer to the UnitGroup array 02378 Purpose: Provides an array of UnitGroups primarily for use by the base class 02379 (ColourContext) members Set/GetComponentUnitGroup(). 02380 Errors: - 02381 See Also: ColourContext::GetComponentUnitGroup() 02382 ColourContext::SetComponentUnitGroup() 02383 02384 ********************************************************************************************/ 02385 02386 UnitGroup **ColourContextCMYK::GetComponentUnitGroups() 02387 { 02388 return m_pUnitGroupArray; 02389 } 02390 02391 02392 UnitGroup* ColourContextCMYK::m_pUnitGroupArray[] = 02393 { 02394 &(StandardUnit::PercentGroup), 02395 &(StandardUnit::PercentGroup), 02396 &(StandardUnit::PercentGroup), 02397 &(StandardUnit::PercentGroup) 02398 }; 02399 02400 02401 02402 /******************************************************************************************** 02403 02404 > UINT32 ColourContextCMYK::GetComponentCount() 02405 02406 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 02407 Created: 02/05/96 02408 Returns: The number of components 02409 Purpose: Provides number of components in the colour context's colour model 02410 02411 ********************************************************************************************/ 02412 02413 UINT32 ColourContextCMYK::GetComponentCount() 02414 { 02415 return MAX_COMPONENTS; 02416 } 02417 02418 02419 02420 /******************************************************************************************** 02421 02422 > virtual void ColourContextCMYK::ApplyTint(ColourValue TintFraction, 02423 ColourGeneric *SourceAndResult) 02424 02425 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02426 Created: 17/11/94 02427 Inputs: TintFraction - The fraction (as a FIXED24 ColourValue) by which the colour 02428 should be tinted. This value is expected to lie between 0.0 and 1.0 inclusive 02429 02430 SourceAndResult - The source colour to be tinted, as defined in this 02431 colour model 02432 02433 Outputs: SourceAndResult is tinted by the given TintFraction 02434 If TintFraction <= 0.0, White is output 02435 If TintFraction >= 1.0, The source colour is output 02436 02437 Returns: - 02438 Purpose: Tints a colour (mixes it with white) 02439 02440 Notes: If the tinting value is out of range, either source-colour ow white (as 02441 appropriate) will be output. 02442 02443 ********************************************************************************************/ 02444 02445 void ColourContextCMYK::ApplyTint(ColourValue TintFraction, ColourGeneric *SourceAndResult) 02446 { 02447 ColourCMYK *Result = (ColourCMYK *) SourceAndResult; 02448 02449 if (TintFraction <= FIXED24(0.0)) // 0% tint = White 02450 { 02451 Result->Cyan = Result->Magenta = Result->Yellow = Result->Key = 0; 02452 return; 02453 } 02454 02455 if (TintFraction >= FIXED24(1.0)) // The Result colour is identical to the source 02456 return; 02457 02458 // Otherwise, tint the colour... 02459 Result->Cyan = (Result->Cyan * TintFraction); 02460 Result->Magenta = (Result->Magenta * TintFraction); 02461 Result->Yellow = (Result->Yellow * TintFraction); 02462 Result->Key = (Result->Key * TintFraction); 02463 } 02464 02465 02466 02467 /******************************************************************************************** 02468 02469 > void ColourContextCMYK::ApplyShade(ColourValue XFraction, ColourValue YFraction, 02470 ColourGeneric *SourceAndResult) 02471 02472 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02473 Created: 24/8/95 02474 Inputs: XFraction - The fraction (as a FIXED24 ColourValue) by which the colour 02475 should be saturated. This value is expected to lie between -1.0 and 1.0 inclusive 02476 Values below 0.0 mean tint towards 0, while values above mean tint towards 1. 02477 0.0 means no tinting 02478 02479 YFraction - The fraction (as a FIXED24 ColourValue) by which the colour 02480 should be shaded. This value is expected to lie between -1.0 and 1.0 inclusive 02481 Values below 0.0 mean shade towards 0, while values above mean shade towards 1. 02482 0.0 means no shading 02483 02484 SourceAndResult - The source colour to be tinted, as defined in this 02485 colour model 02486 02487 Outputs: SourceAndResult is shaded by the given Fractions 02488 Any invalid value is clipped to 0.0 02489 02490 Returns: - 02491 Purpose: Shades a colour (tweaks the saturation and value in a relative way) 02492 02493 Notes: Contexts other than HSV currently convert the colour to and from HSV 02494 form in order to apply the shade. This is a tad inefficient, but a 02495 quick'n'easy bodge that will get it going nice and quickly. 02496 02497 ********************************************************************************************/ 02498 02499 void ColourContextCMYK::ApplyShade(ColourValue XFraction, ColourValue YFraction, 02500 ColourGeneric *SourceAndResult) 02501 { 02502 ColourHSVT HSVDef; 02503 ColourContext *cc = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT); 02504 ERROR3IF(cc == NULL, "No default HSV colour context?!"); 02505 02506 cc->ConvertColour(this, SourceAndResult, (ColourGeneric *) &HSVDef); 02507 cc->ApplyShade(XFraction, YFraction, (ColourGeneric *) &HSVDef); 02508 ConvertColour(cc, (ColourGeneric *) &HSVDef, SourceAndResult); 02509 } 02510 02511 02512 02513 /******************************************************************************************** 02514 02515 > virtual void ColourContextCMYK::ApplyInputFilter(ColourPlate *FilterDescription, 02516 ColourContext *DestContext, 02517 ColourGeneric *OutputColour, 02518 IndexedColour *SourceIxCol); 02519 02520 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02521 Created: 22/1/96 02522 Inputs: FilterDescription - A ColourPlate describing how the colour is to be filtered 02523 02524 DestContext - Points to the context to which the OutputColour will be 02525 converted after we return it (in case this information is useful) 02526 02527 OutputColour - The colour to be filtered 02528 02529 SourceIxCol - NULL, or the original IndexedColour which is being converted. 02530 This is used for handling spot colour separation correctly. 02531 02532 Outputs: OutputColour - Will be modified as appropriate to the current colour 02533 filtering options (see Purpose) 02534 02535 Purpose: All colour conversions call this function for the SOURCE context 02536 immediately before converting the colour. This gives the input colour 02537 context the chance to apply a filtering process to the colour. 02538 02539 This is usually used to provide colour separations. Often, this function 02540 will do nothing to the output colour - generally it is only used by CMYK 02541 contexts in order to colour-separate the colour in CMYK space. 02542 02543 SeeAlso: ColourContext::ConvertColourBase 02544 02545 ********************************************************************************************/ 02546 02547 void ColourContextCMYK::ApplyInputFilter(ColourPlate *FilterDescription, ColourContext *DestContext, 02548 ColourGeneric *OutputColour, IndexedColour *SourceIxCol) 02549 { 02550 ERROR3IF(FilterDescription == NULL || DestContext == NULL || OutputColour == NULL, "Illegal NULL params"); 02551 02552 if (FilterDescription == NULL) 02553 return; 02554 02555 ColourCMYK *OutputCMYK = (ColourCMYK *)OutputColour; 02556 FIXED24 temp; 02557 02558 // Separate the colour as appropriate 02559 switch(FilterDescription->GetType()) 02560 { 02561 case COLOURPLATE_CYAN: 02562 { 02563 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02564 OutputCMYK->Cyan = 1.0 - OutputCMYK->Cyan; 02565 02566 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02567 { 02568 OutputCMYK->Key = OutputCMYK->Cyan; 02569 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02570 } 02571 else 02572 OutputCMYK->Key = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02573 } 02574 break; 02575 02576 case COLOURPLATE_MAGENTA: 02577 { 02578 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02579 OutputCMYK->Magenta = 1.0 - OutputCMYK->Magenta; 02580 02581 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02582 { 02583 OutputCMYK->Key = OutputCMYK->Magenta; 02584 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02585 } 02586 else 02587 OutputCMYK->Key = OutputCMYK->Cyan = OutputCMYK->Yellow = 0.0; 02588 } 02589 break; 02590 02591 case COLOURPLATE_YELLOW: 02592 { 02593 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02594 OutputCMYK->Yellow = 1.0 - OutputCMYK->Yellow; 02595 02596 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02597 { 02598 OutputCMYK->Key = OutputCMYK->Yellow; 02599 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02600 } 02601 else 02602 OutputCMYK->Key = OutputCMYK->Magenta = OutputCMYK->Cyan = 0.0; 02603 } 02604 break; 02605 02606 case COLOURPLATE_KEY: 02607 { 02608 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02609 02610 // The FilterDescription->IsMonochrome() flag has no effect on this plate! 02611 02612 if (FilterDescription->IsNegative()) 02613 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02614 } 02615 break; 02616 02617 case COLOURPLATE_SPOT: 02618 // NOTE: 02619 // Real spot colours are generally sorted out by the higher level ConvertColour 02620 // calls. However, 2 cases may seep through to this level: 02621 // 1) Colours which are not indexed colours (which can't be spots, so are always 02622 // just converted to white) 02623 // 2) Spot colours which *do* appear on this plate must be made into monochrome 02624 // ink density values (which we put into the Key component). 02625 02626 // In all cases, we're going monochrome in the Key only, so clear C/M/Y now. 02627 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0; 02628 if (SourceIxCol == NULL) 02629 { 02630 // It's not an IndexedColour, so can't appear on this plate - make it white 02631 OutputCMYK->Key = 0; 02632 } 02633 else 02634 { 02635 // We have a source IndexedColour, so we know it's been separated. 02636 // We just have to get a decent ink density value out of the IxCol 02637 if (SourceIxCol == FilterDescription->GetSpotColour()) 02638 { 02639 // The spot colour itself is always considered a 100% tint (100% ink) 02640 OutputCMYK->Key = 1.0; 02641 } 02642 else if (SourceIxCol->IsADescendantOf(FilterDescription->GetSpotColour())) 02643 { 02644 // It's not the spot colour, but it is a child - check that it's a tint 02645 ERROR3IF(SourceIxCol->GetType() != COLOURTYPE_TINT || 02646 SourceIxCol->TintIsShade(), 02647 "Spot colour children must all be tints!"); 02648 02649 // Tint gives the amount of ink, which we stick into the Key plate. 02650 // Note that we get the accumulated tint value rather than the simple 02651 // tint, which is the true output ink density. 02652 OutputCMYK->Key = SourceIxCol->GetAccumulatedTintValue(); 02653 } 02654 } 02655 02656 // If negative, then photographically invert the colour 02657 if (FilterDescription->IsNegative()) 02658 { 02659 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 1.0; 02660 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02661 } 02662 break; 02663 02664 // case COLOURPLATE_COMPOSITE: 02665 // -- We don't need to do anything here 02666 // break; 02667 02668 default: 02669 // If monochrome, convert the image to a greyscale 02670 if (FilterDescription->IsMonochrome()) 02671 { 02672 // It is extremely unlikely that anyone will ever need to do this. 02673 // (If you want a monochrome preview, you should really use a greyscale ColourContext) 02674 ERROR3("Unimplemented: Filtering of composite CMYK colour to monochrome!"); 02675 } 02676 02677 // If negative, then photographically invert the colour 02678 if (FilterDescription->IsNegative()) 02679 { 02680 OutputCMYK->Cyan = 1.0 - OutputCMYK->Cyan; 02681 OutputCMYK->Magenta = 1.0 - OutputCMYK->Magenta; 02682 OutputCMYK->Yellow = 1.0 - OutputCMYK->Yellow; 02683 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02684 } 02685 break; 02686 } 02687 } 02688 02689 02690 02691 /******************************************************************************************** 02692 02693 > virtual void ColourContextCMYK::ApplyOutputFilter(ColourPlate *FilterDescription, 02694 ColourContext *SourceContext, 02695 ColourGeneric *OutputColour, 02696 IndexedColour *SourceIxCol) 02697 02698 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02699 Created: 22/1/96 02700 Inputs: FilterDescription - A ColourPlate describing how the colour is to be filtered 02701 02702 SourceContext - Points to the context from which the OutputColour has just 02703 been converted. 02704 02705 OutputColour - The colour to be filtered 02706 02707 SourceIxCol - NULL, or the IndexedColour which was the source of the colour 02708 being converted. This is only used for information when preparing spot colour 02709 separations. 02710 02711 Outputs: OutputColour - Will be modified as appropriate to the current colour 02712 filtering options (see Purpose) 02713 02714 Purpose: All colour conversions call this function immediately prior to returning 02715 the converted colour to the caller. This gives the output colour context 02716 the chance to apply an output filtering process to the output colour. 02717 02718 This is usually used to provide colour separations, and may also be used 02719 to apply some colour corrections. Often, this function will do nothing 02720 to the output colour. 02721 02722 SeeAlso: ColourContext::ConvertColourBase 02723 02724 ********************************************************************************************/ 02725 02726 void ColourContextCMYK::ApplyOutputFilter(ColourPlate *FilterDescription, ColourContext *SourceContext, 02727 ColourGeneric *OutputColour, IndexedColour *SourceIxCol) 02728 { 02729 ERROR3IF(FilterDescription == NULL || SourceContext == NULL || OutputColour == NULL, "Illegal NULL params"); 02730 02731 // No FilterDescription means no filtering; If the source colour was CMYK, we msutn't filter it 02732 // as the ApplyInputFilter will have dealt with it 02733 if (FilterDescription == NULL || SourceContext->GetColourModel() == COLOURMODEL_CMYK) 02734 return; 02735 02736 ColourCMYK *OutputCMYK = (ColourCMYK *)OutputColour; 02737 FIXED24 temp; 02738 02739 // Separate the colour as appropriate 02740 switch(FilterDescription->GetType()) 02741 { 02742 case COLOURPLATE_CYAN: 02743 { 02744 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02745 OutputCMYK->Cyan = 1.0 - OutputCMYK->Cyan; 02746 02747 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02748 { 02749 // Move the Cyan value into the Key component 02750 OutputCMYK->Key = OutputCMYK->Cyan; 02751 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02752 } 02753 else 02754 OutputCMYK->Key = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02755 } 02756 break; 02757 02758 case COLOURPLATE_MAGENTA: 02759 { 02760 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02761 OutputCMYK->Magenta = 1.0 - OutputCMYK->Magenta; 02762 02763 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02764 { 02765 // Move the Cyan value into the Key component 02766 OutputCMYK->Key = OutputCMYK->Magenta; 02767 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02768 } 02769 else 02770 OutputCMYK->Key = OutputCMYK->Cyan = OutputCMYK->Yellow = 0.0; 02771 } 02772 break; 02773 02774 case COLOURPLATE_YELLOW: 02775 { 02776 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02777 OutputCMYK->Yellow = 1.0 - OutputCMYK->Yellow; 02778 02779 if (FilterDescription->IsMonochrome()) // Make the plate a greyscale if necessary 02780 { 02781 // Move the Cyan value into the Key component 02782 OutputCMYK->Key = OutputCMYK->Yellow; 02783 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02784 } 02785 else 02786 OutputCMYK->Key = OutputCMYK->Cyan = OutputCMYK->Magenta = 0.0; 02787 } 02788 break; 02789 02790 case COLOURPLATE_KEY: 02791 { 02792 if (FilterDescription->IsNegative()) // Negate the plate if necessary 02793 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02794 02795 // The monochrome flag has no effect on a key plate! 02796 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02797 } 02798 break; 02799 02800 case COLOURPLATE_SPOT: 02801 // NOTE: 02802 // Spot colours are partially handled by the IndexedColour variants of 02803 // ConvertColour, so will never reach us here if they have been 02804 // eliminated from the plate. 02805 // However, if a spot colour gets this far, we need to generate an ink 02806 // density value for output, as well as applying the negate flag. 02807 // 02808 // Actually, I have decreed that all spot plates will always be monochrome, 02809 // because that makes coding DocColour::Mix much easier, and anyway it makes 02810 // a load more sense for the very good reason that if you don't believe me 02811 // I'll get my Dad to come around and beat up your dad. 02812 02813 if (SourceIxCol != NULL) // && FilterDescription->IsMonochrome()) 02814 { 02815 if (SourceIxCol == FilterDescription->GetSpotColour()) 02816 { 02817 // The spot colour itself is always considered a 100% tint (100% ink) 02818 OutputCMYK->Key = 1.0; 02819 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02820 } 02821 else if (SourceIxCol->IsADescendantOf(FilterDescription->GetSpotColour())) 02822 { 02823 // It's not the spot colour, but it is a child - check that it's a tint 02824 ERROR3IF(SourceIxCol->GetType() != COLOURTYPE_TINT || 02825 SourceIxCol->TintIsShade(), 02826 "Spot colour children must all be tints!"); 02827 02828 // Tint gives the amount of ink. Note that we get the accumlated 02829 // tint value (true ink density) rather than the simple tint. 02830 OutputCMYK->Key = SourceIxCol->GetAccumulatedTintValue(); 02831 OutputCMYK->Cyan = OutputCMYK->Magenta = OutputCMYK->Yellow = 0.0; 02832 } 02833 } 02834 02835 // If negative, then photographically invert the colour 02836 if (FilterDescription->IsNegative()) 02837 { 02838 OutputCMYK->Cyan = 1.0 - OutputCMYK->Cyan; 02839 OutputCMYK->Magenta = 1.0 - OutputCMYK->Magenta; 02840 OutputCMYK->Yellow = 1.0 - OutputCMYK->Yellow; 02841 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02842 } 02843 break; 02844 02845 case COLOURPLATE_COMPOSITE: 02846 #ifndef NO_XARACMS 02847 { 02848 /* 02849 // Go to and from (printer) cmyk just for a laugh 02850 // Find the CMS manager, and get it to do all the work 02851 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 02852 if (lpCMSMan != NULL) 02853 lpCMSMan->ConvertColourForPaperView(OutputRGB); 02854 */ 02855 ERROR3("Composite preview to a CMYK colour context is barmy!"); 02856 } 02857 #endif 02858 // ... drop through to the default case to apply monochrome/negate 02859 02860 default: 02861 // If monochrome, convert the image to a greyscale 02862 if (FilterDescription->IsMonochrome()) 02863 { 02864 // Will anyone ever need this? It seems unlikely - but we may well get Key coming 02865 // through here, which is entirely sensible, so we only error if there is colour info. 02866 ERROR3IF(OutputCMYK->Cyan != 0 || OutputCMYK->Magenta != 0 || OutputCMYK->Yellow != 0, 02867 "Monochrome output of colour CMYK to CMYK colour context is unimplemented"); 02868 } 02869 02870 // If negative, then photographically invert the colour 02871 if (FilterDescription->IsNegative()) 02872 { 02873 OutputCMYK->Cyan = 1.0 - OutputCMYK->Cyan; 02874 OutputCMYK->Magenta = 1.0 - OutputCMYK->Magenta; 02875 OutputCMYK->Yellow = 1.0 - OutputCMYK->Yellow; 02876 OutputCMYK->Key = 1.0 - OutputCMYK->Key; 02877 } 02878 break; 02879 } 02880 } 02881 02882 02883 02884 /******************************************************************************************** 02885 02886 > virtual BOOL ColourContextCMYK::IsDifferent(ColourContext *Other) const 02887 02888 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02889 Created: 6/6/96 02890 Inputs: Other - a colour context to comapre ourselves to 02891 Outputs: - 02892 Returns: TRUE if the other colour context object is different from 02893 ourself, or TRUE if it is an exactly equivalent context. 02894 Purpose: Determine if two colour contexts are not exactly equivalent 02895 Errors: - 02896 SeeAlso: ColourContext::IsDifferent 02897 02898 ********************************************************************************************/ 02899 02900 BOOL ColourContextCMYK::IsDifferent(ColourContext *Other) const 02901 { 02902 if (ColourContext::IsDifferent(Other)) // Different on generic ColourContext basis 02903 return(TRUE); 02904 02905 // These must both be CMYK contexts, so check if they are equivalent 02906 return(ProfileName.IsIdentical(((ColourContextCMYK *)Other)->ProfileName)); 02907 } 02908 02909 02910 02911 /******************************************************************************************** 02912 02913 > virtual void ColourContextCMYK::GetWhite(ColourGeneric *Result); 02914 02915 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02916 Created: 8/6/96 02917 02918 Outputs: Result - Will be filled in with White, however that is defined in 02919 this context's colour model. (i.e. RGB(1,1,1) or CMYK(0,0,0,0), etc) 02920 02921 Purpose: An easy way to get a colour definition in this colour model which 02922 is white (paper colour). 02923 02924 ********************************************************************************************/ 02925 02926 void ColourContextCMYK::GetWhite(ColourGeneric *Result) 02927 { 02928 ColourCMYK *cmyk = (ColourCMYK *) Result; 02929 cmyk->Cyan = cmyk->Magenta = cmyk->Yellow = cmyk->Key = 0; 02930 } 02931 02932 02933 02934 /******************************************************************************************** 02935 02936 > virtual void ColourContextCMYK::ConvertColourBase(ColourContextCMYK *SourceContext, 02937 ColourGeneric *Source, ColourGeneric *Result 02938 IndexedColour *SourceIxCol = NULL) 02939 02940 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02941 Created: 31/03/94 02942 Inputs: SourceContext - The context in which the source is defined 02943 02944 Source - A ColourGeneric to convert 02945 02946 Result - A ColourGeneric structure to recieve the resulting converted colour, 02947 as defined in this ColourContextCMYK. 02948 02949 SourceIxCol - NULL, or a pointer to the IndexedColour we are converting. 02950 This is used only for handling spot colour separations, to determine if 02951 the colour is a given spot colour or tint thereof. 02952 02953 Outputs: Result - will be returned with the converted colour 02954 02955 Purpose: SEE ColourContext::ConvertColourbase 02956 This method is identical to that function, except that it also passes the 02957 colour directly through (rather than converting to/from CIET) if the source 02958 and destination contexts are both CMYK (even if they are different contexts, 02959 CMYK colours are always passed through without colour correction) 02960 02961 Scope: private to colcontx.cpp 02962 Errors: - 02963 SeeAlso: ColourContextCMYK::ConvertColour 02964 02965 ********************************************************************************************/ 02966 02967 void ColourContextCMYK::ConvertColourBase(ColourContext *SourceContext, 02968 ColourGeneric *Source, ColourGeneric *Result, 02969 IndexedColour *SourceIxCol) 02970 { 02971 // Copy the source colour into a temporary variable 02972 ColourGeneric FilteredSource; 02973 memcpy(&FilteredSource, Source, sizeof(ColourGeneric)); 02974 02975 // Call the SourceContext to allow it to pre-filter the colour. This is used to 02976 // provide colour separations and other doody features when converting CMYK colours 02977 // - when converting non-CMYK colours, this is usually done in the OutputFilter (below) 02978 if (ColPlate != NULL && !ColPlate->IsDisabled()) 02979 SourceContext->ApplyInputFilter(ColPlate, this, &FilteredSource, SourceIxCol); 02980 02981 // ----- 02982 // Call levels expected: 02983 // 1 inline ConvertColour checks if can satisfy from cache 02984 // 2 function ConvertColourInternal does any short cuts it can, such 02985 // as CMYK->CMYK passthrough 02986 // 3 Call ConvertColourBase, which 02987 // a) Checks if in same colour model, and implements passthrough, or 02988 // b) Converts colour properly via CIET space 02989 02990 if (SourceContext == this || SourceContext->GetColourModel() == COLOURMODEL_CMYK) 02991 { 02992 // The SourceContext and Destination context are identical, so we can 02993 // just copy the definition directly across. 02994 memcpy(Result, &FilteredSource, sizeof(ColourGeneric)); 02995 } 02996 else 02997 { 02998 DColourCIET IntermediateResult; 02999 03000 SourceContext->ConvertToCIET(&FilteredSource, &IntermediateResult); 03001 ConvertFromCIET(&IntermediateResult, Result); 03002 } 03003 03004 03005 // Call the DestinationContext (derived class of this) to apply any output filtering - 03006 // non-CMYK colour conversions will separate the colour (as appropriate) here 03007 if (ColPlate != NULL && !ColPlate->IsDisabled()) 03008 ApplyOutputFilter(ColPlate, SourceContext, Result, SourceIxCol); 03009 } 03010 03011 03012 03013 03014 03015 03016 03017 03018 03019 03020 03021 03022 03023 03024 03025 03026 03027 03028 /******************************************************************************************** 03029 03030 > void ColourContextHSVT::ColourContextHSVT(View *Scope) 03031 03032 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03033 Created: 22/04/94 03034 Inputs: Scope - The view in which this context is to be used, or NULL 03035 Outputs: - 03036 Returns: - 03037 Purpose: Constructor for an HSVT Colour context 03038 03039 Notes: Colour Contexts should not be created and used directly. See the 03040 notes in the SeeAlso's for instructions on proper care and use. 03041 03042 Errors: - 03043 SeeAlso: ColourContext::ColourContext; ColourContextList::AddContext 03044 03045 ********************************************************************************************/ 03046 03047 ColourContextHSVT::ColourContextHSVT(View *Scope) 03048 : ColourContext(Scope) 03049 { 03050 ColModel = COLOURMODEL_HSVT; 03051 03052 CreateExternalTransform(); 03053 } 03054 03055 /******************************************************************************************** 03056 03057 > void ColourContextHSVT::CreateExternalTransform(void) 03058 03059 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03060 Created: 12/05/96 03061 Inputs: - 03062 Returns: - 03063 Purpose: Create an external transform to be used during colour conversions from 03064 HSV to the current RCS space. This function uses the Winoil CMS Manager 03065 to create the transform. Both forward and backward transforms use a physical 03066 printer profile description. 03067 03068 ********************************************************************************************/ 03069 03070 void ColourContextHSVT::CreateExternalTransform() 03071 { 03072 #ifndef NO_XARACMS 03073 CMSColourSpace cmsSpace; 03074 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03075 03076 if (lpCMSMan != NULL) 03077 { 03078 // first read our internal colour calibration space 03079 lpCMSMan->GetLogicalProfile(&cmsSpace); 03080 // set this as the active colour profile 03081 UINT32 err = lpCMSMan->SetProfile(cmsSpace); 03082 // if we haven't got an error, create that transform 03083 if (err==0) 03084 CMSTransform = lpCMSMan->CreateTransform(DISPLAY_RCS); 03085 } 03086 #endif 03087 } 03088 03089 03090 03091 /******************************************************************************************** 03092 03093 > void ColourContextHSVT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 03094 03095 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03096 Created: 22/04/94 03097 Inputs: Source - A Colour defined in this HSVT context 03098 Result - pointer to a structure to recieve the resulting colour as 03099 defined in CIE space 03100 Outputs: - 03101 Returns: - 03102 Purpose: Converts the given colour from our HSVT colourspace to CIET colourspace 03103 Notes: - 03104 Errors: - 03105 SeeAlso: ColourContextHSVT::ConvertFromCIET 03106 03107 ********************************************************************************************/ 03108 03109 void ColourContextHSVT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 03110 { 03111 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 03112 03113 // First, let's convert the HSV into RGB 03114 FIXED24 H,S,V, R,G,B, F, P,Q,T; // Sorry, I just have to override the style guide here! 03115 03116 H = ((ColourHSVT *)Source)->Hue; 03117 S = ((ColourHSVT *)Source)->Saturation; 03118 V = ((ColourHSVT *)Source)->Value; 03119 03120 if (S == FIXED24(0)) 03121 { 03122 R = V; 03123 G = V; 03124 B = V; 03125 } 03126 else 03127 { 03128 H *= 6; 03129 INT32 I = H.MakeInt(); 03130 F = H - I; 03131 P = V * (1.0 - S); 03132 Q = V * (1.0 - (S * F)); 03133 T = V * (1.0 - (S * (1.0 - F))); 03134 03135 switch (I) 03136 { 03137 case 1: R = Q; G = V; B = P; break; 03138 case 2: R = P; G = V; B = T; break; 03139 case 3: R = P; G = Q; B = V; break; 03140 case 4: R = T; G = P; B = V; break; 03141 case 5: R = V; G = P; B = Q; break; 03142 default: R = V; G = T; B = P; break; 03143 } 03144 } 03145 03146 #ifndef NO_XARACMS 03147 // Now, convert the RGB to CIE 03148 // If we've got a CMS manager, use it, else use the version 1.1 bodge 03149 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03150 03151 if (lpCMSMan != NULL) 03152 { 03153 // The new colour calibration method 03154 CMSColour icol, ocol; 03155 icol.c0 = R.MakeDouble(); 03156 icol.c1 = G.MakeDouble(); 03157 icol.c2 = B.MakeDouble(); 03158 03159 // If we have no colour transform, or if we don't want the colour corrected/separated, 03160 // then we will just do a "logical" conversion. 03161 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 03162 lpCMSMan->ConvRGBtoCIEXYZ(icol, ocol); 03163 else 03164 lpCMSMan->GTransform(CMSTransform, cmsForward, icol, ocol); 03165 03166 Result->X = ocol.c0; 03167 Result->Y = ocol.c1; 03168 Result->Z = ocol.c2; 03169 Result->Transparent = 0.0;//bob->Transparent; 03170 } 03171 else 03172 #endif 03173 { 03174 // The old rgb system 03175 Result->X = R.MakeDouble(); 03176 Result->Y = G.MakeDouble(); 03177 Result->Z = B.MakeDouble(); 03178 Result->Transparent = 0;//((ColourHSVT *)Source)->Transparent; 03179 } 03180 } 03181 03182 03183 03184 03185 /******************************************************************************************** 03186 03187 > void ColourContextHSVT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 03188 03189 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03190 Created: 22/04/94 03191 Inputs: Source - A Colour defined in the CIET colourspace 03192 Result - pointer to a structure to recieve the resulting colour as 03193 defined in the HSVT space described by this colour context. 03194 Outputs: - 03195 Returns: - 03196 Purpose: Converts the given colour to our HSVT colourspace from CIET colourspace 03197 Notes: - 03198 Errors: - 03199 SeeAlso: ColourContextHSVT::ConvertToCIET 03200 03201 ********************************************************************************************/ 03202 03203 void ColourContextHSVT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 03204 { 03205 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 03206 03207 // First, we'll convert from CIE to RGB 03208 double R, G, B; 03209 03210 #ifndef NO_XARACMS 03211 // If we've got a CMS manager, use it, else use the version 1.1 bodge 03212 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03213 03214 if (lpCMSMan != NULL) 03215 { 03216 // The new colour calibration method 03217 CMSColour icol, ocol; 03218 icol.c0 = Source->X; 03219 icol.c1 = Source->Y; 03220 icol.c2 = Source->Z; 03221 03222 // If we have no colour transform, or if we don't want the colour corrected/separated, 03223 // then we will just do a "logical" conversion. 03224 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 03225 lpCMSMan->ConvCIEXYZtoRGB(icol, ocol); 03226 else 03227 lpCMSMan->GTransform(CMSTransform, cmsReverse, icol, ocol); 03228 03229 R = ocol.c0; 03230 G = ocol.c1; 03231 B = ocol.c2; 03232 } 03233 else 03234 #endif 03235 { 03236 // The old rgb system 03237 R = Source->X; 03238 G = Source->Y; 03239 B = Source->Z; 03240 } 03241 03242 03243 // Now, convert the RGB value into HSV 03244 double Min, Max, Delta, H, S, V; 03245 Min = min(R, G); 03246 Min = min(Min, B); 03247 Max = max(R, G); 03248 Max = max(Max, B); 03249 03250 V = Max; 03251 Delta = Max - Min; 03252 03253 if (fabs(Delta) > 0.000001) 03254 { 03255 if (Max > 0.0) 03256 S = Delta / Max; 03257 else 03258 S = 0.0; 03259 03260 if (R == Max) 03261 H = (G - B) / Delta; 03262 else if (G == Max) 03263 H = 2.0 + (B - R) / Delta; 03264 else 03265 H = 4 + (R - G) / Delta; 03266 03267 03268 H = H / 6.0; 03269 if (H < 0.0) H += 1.0; 03270 } 03271 else 03272 { 03273 H = S = 0.0; 03274 } 03275 03276 ((ColourHSVT *)Result)->Hue = H; 03277 ((ColourHSVT *)Result)->Saturation = S; 03278 ((ColourHSVT *)Result)->Value = V; 03279 ((ColourHSVT *)Result)->Transparent = 0; //Source->Transparent; 03280 } 03281 03282 03283 03284 /******************************************************************************************** 03285 03286 > virtual void ColourContextHSVT::PackColour(ColourGeneric *Source, ColourPacked *Result) 03287 03288 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03289 Created: 22/04/94 03290 Inputs: Source - A ColourHSVT structure defining the colour in the model 03291 pertaining to this colour context (HSVT) 03292 Result - A Packed colour structure in the same model, into which the result 03293 is copied. 03294 03295 Outputs: - 03296 Returns: - 03297 Purpose: Converts 128-bit colour representation to 32-bit packed form 03298 03299 Overrides the base class to provide special packing of HSV colours, 03300 which use a 9-bit component for packed Hue, and a different component 03301 ordering within the PColourHSVT structure. 03302 03303 Scope: Private (used internally by friend class DocColour) 03304 Errors: - 03305 SeeAlso: ColourContextHSVT::UnpackColour 03306 03307 ********************************************************************************************/ 03308 03309 void ColourContextHSVT::PackColour(ColourGeneric *Source, ColourPacked *Result) 03310 { 03311 PColourHSVT *bob = (PColourHSVT *) Result; 03312 03313 bob->Hue = PackColour360(Source->Component1); 03314 bob->Saturation = PackColour256(Source->Component2); 03315 bob->Value = PackColour256(Source->Component3); 03316 bob->Transparent = 0; //PackColour128(Source->Transparent); 03317 } 03318 03319 03320 03321 /******************************************************************************************** 03322 03323 > virtual void ColourContextHSVT::UnpackColour(ColourPacked *Source, ColourGeneric *Result) 03324 03325 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03326 Created: 22/04/94 03327 Inputs: Source - A Packed Colour structure defining the colour in the model 03328 pertaining to this colour context (HSVT) 03329 Result - A ColourGeneric structure in the same model, into which the 03330 result is copied. 03331 Outputs: - 03332 Returns: - 03333 Purpose: Converts 32-bit packed colour representation to 128-bit form 03334 03335 Overrides the base class to provide special packing of HSV colours, 03336 which use a 9-bit component for packed Hue, and a different component 03337 ordering within the PColourHSVT structure. 03338 03339 Scope: Private (used internally by friend class DocColour) 03340 Errors: - 03341 SeeAlso: ColourContextHSVT::PackColour 03342 03343 ********************************************************************************************/ 03344 03345 void ColourContextHSVT::UnpackColour(ColourPacked *Source, ColourGeneric *Result) 03346 { 03347 PColourHSVT *bob = (PColourHSVT *) Source; 03348 03349 UnpackColour360(bob->Hue, &Result->Component1); 03350 UnpackColour256(bob->Saturation, &Result->Component2); 03351 UnpackColour256(bob->Value, &Result->Component3); 03352 Result->Component4 = 0;//UnpackColour128(bob->Transparent, &Result->Transparent); 03353 } 03354 03355 03356 03357 /******************************************************************************************** 03358 03359 > void ColourContextHSVT::GetModelName(StringBase *Result) 03360 03361 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03362 Created: 1/6/94 03363 Inputs: - 03364 Outputs: Result returns continaing a String of the name of the context. 03365 This string is guaranteed to fit within a String_32 - this is the 03366 minimum size you should allocate. (Most names, in English at least, 03367 are shorter than this (10 chars max, e.g. 'RGB' 'HSV' 'Greyscale') 03368 so allow at least 10 chars of space in your displays as well) 03369 Returns: - 03370 Purpose: Returns the name of this context's colour model 03371 Notes: 03372 03373 ********************************************************************************************/ 03374 03375 void ColourContextHSVT::GetModelName(StringBase *Result) 03376 { 03377 ENSURE(Result != NULL, "ColourContext::GetModelName called with NULL result pointer!"); 03378 03379 *Result = String_32(_R(IDS_COLMODEL_HSVT)); 03380 } 03381 03382 03383 03384 /******************************************************************************************** 03385 03386 > BOOL ColourContextHSVT::GetComponentName(INT32 ComponentID, StringBase *Result, 03387 BOOL LongName = FALSE) 03388 03389 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03390 Created: 26/7/94 03391 Inputs: ComponentID - Index [1..4] of the component you want the name of 03392 (Result is an output) 03393 LongName - TRUE to get the long name, FALSE to get the short name 03394 (e.g. "Magenta" vs "M", "Saturation" vs "Sat") 03395 03396 Outputs: Result returns containing a String of the name of the given component 03397 of colours defined in this context. 03398 This string is guaranteed to fit within a String_32 - this is the 03399 minimum size you should allocate. (Most names, in English at least, 03400 are shorter than this (10 chars max, e.g. 'Red' 'Hue' 'Saturation') 03401 so allow at least 10 chars of space in your displays as well) 03402 03403 Note that Result can be passed in NULL in order to only determine if the 03404 context supports a given component. 03405 03406 Returns: FALSE if this component is not used by this model. 03407 Purpose: Returns the name of one of this context's colour components 03408 03409 Notes: The components are given in the same order as they appear in the 03410 high-precision ColourXYZ structures defined in colmodel.h 03411 03412 ********************************************************************************************/ 03413 03414 BOOL ColourContextHSVT::GetComponentName(INT32 ComponentID, StringBase *Result, BOOL LongName) 03415 { 03416 UINT32 StringID = 0; 03417 BOOL Used = TRUE; 03418 03419 switch(ComponentID) 03420 { 03421 case 1: 03422 StringID = (LongName) ? _R(IDS_COLCOMPL_HUE) : _R(IDS_COLCOMP_HUE); 03423 break; 03424 03425 case 2: 03426 StringID = (LongName) ? _R(IDS_COLCOMPL_SATURATION) : _R(IDS_COLCOMP_SATURATION); 03427 break; 03428 03429 case 3: 03430 StringID = (LongName) ? _R(IDS_COLCOMPL_VALUE) : _R(IDS_COLCOMP_VALUE); 03431 break; 03432 03433 #ifdef TRANSPARENTCOLOUR 03434 default: 03435 StringID = _R(IDS_COLCOMP_TRANS); 03436 break; 03437 #else 03438 default: 03439 Used = FALSE; 03440 break; 03441 #endif 03442 } 03443 03444 if (Result != NULL && StringID != 0) 03445 *Result = String_32(StringID); 03446 03447 return(Used); 03448 } 03449 03450 03451 03452 /******************************************************************************************** 03453 03454 > virtual UnitGroup **ColourContextHSVT::GetComponentUnitGroups() 03455 03456 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 03457 Created: 02/05/96 03458 Inputs: - 03459 Outputs: - 03460 Returns: A pointer to the UnitGroup array 03461 Purpose: Provides an array of UnitGroups primarily for use by the base class 03462 (ColourContext) members Set/GetComponentUnitGroup(). 03463 Errors: - 03464 See Also: ColourContext::GetComponentUnitGroup() 03465 ColourContext::SetComponentUnitGroup() 03466 03467 ********************************************************************************************/ 03468 03469 UnitGroup **ColourContextHSVT::GetComponentUnitGroups() 03470 { 03471 return m_pUnitGroupArray; 03472 } 03473 03474 03475 UnitGroup* ColourContextHSVT::m_pUnitGroupArray[] = 03476 { 03477 &(StandardUnit::AngleGroup), 03478 &(StandardUnit::PercentGroup), 03479 &(StandardUnit::PercentGroup) 03480 }; 03481 03482 03483 03484 /******************************************************************************************** 03485 03486 > virtual UINT32 ColourContextHSVT::GetComponentCount() 03487 03488 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 03489 Created: 02/05/96 03490 Returns: The number of components 03491 Purpose: Provides number of components in the colour context's colour model 03492 03493 ********************************************************************************************/ 03494 03495 UINT32 ColourContextHSVT::GetComponentCount() 03496 { 03497 return MAX_COMPONENTS; 03498 } 03499 03500 03501 03502 /******************************************************************************************** 03503 03504 > virtual void ColourContextHSVT::ApplyTint(ColourValue TintFraction, 03505 ColourGeneric *SourceAndResult) 03506 03507 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03508 Created: 17/11/94 03509 Inputs: TintFraction - The fraction (as a FIXED24 ColourValue) by which the colour 03510 should be tinted. This value is expected to lie between 0.0 and 1.0 inclusive 03511 03512 SourceAndResult - The source colour to be tinted, as defined in this 03513 colour model 03514 03515 Outputs: SourceAndResult is tinted by the given TintFraction 03516 If TintFraction <= 0.0, White is output 03517 If TintFraction >= 1.0, The source colour is output 03518 03519 Returns: - 03520 Purpose: Tints a colour (mixes it with white) 03521 03522 Notes: If the tinting value is out of range, either source-colour ow white (as 03523 appropriate) will be output. 03524 03525 ********************************************************************************************/ 03526 03527 void ColourContextHSVT::ApplyTint(ColourValue TintFraction, ColourGeneric *SourceAndResult) 03528 { 03529 ColourHSVT *Result = (ColourHSVT *) SourceAndResult; 03530 03531 if (TintFraction <= FIXED24(0.0)) // 0% tint = White 03532 { 03533 Result->Saturation = 0; 03534 Result->Value = FIXED24(1.0); 03535 return; 03536 } 03537 03538 if (TintFraction >= FIXED24(1.0)) // The Result colour is identical to the source 03539 return; 03540 03541 // Otherwise, tint the colour... 03542 // Hue remains constant 03543 Result->Saturation = Result->Saturation * TintFraction; 03544 Result->Value = FIXED24(1.0) - (TintFraction - (Result->Value * TintFraction)); 03545 } 03546 03547 03548 03549 /******************************************************************************************** 03550 03551 > void ColourContextHSVT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 03552 ColourGeneric *SourceAndResult) 03553 03554 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03555 Created: 24/8/95 03556 Inputs: XFraction - The fraction (as a FIXED24 ColourValue) by which the colour 03557 should be saturated. This value is expected to lie between -1.0 and 1.0 inclusive 03558 Values below 0.0 mean tint towards 0, while values above mean tint towards 1. 03559 0.0 means no tinting 03560 03561 YFraction - The fraction (as a FIXED24 ColourValue) by which the colour 03562 should be shaded. This value is expected to lie between -1.0 and 1.0 inclusive 03563 Values below 0.0 mean shade towards 0, while values above mean shade towards 1. 03564 0.0 means no shading 03565 03566 SourceAndResult - The source colour to be tinted, as defined in this 03567 colour model 03568 03569 Outputs: SourceAndResult is shaded by the given Fractions 03570 Any invalid value is clipped to 0.0 03571 03572 Returns: - 03573 Purpose: Shades a colour (tweaks the saturation and value in a relative way) 03574 03575 ********************************************************************************************/ 03576 03577 void ColourContextHSVT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 03578 ColourGeneric *SourceAndResult) 03579 { 03580 ColourHSVT *Result = (ColourHSVT *) SourceAndResult; 03581 03582 ERROR3IF(XFraction < FIXED24(-1.0) || XFraction > FIXED24(1.0), "Illegal X Shading value"); 03583 ERROR3IF(YFraction < FIXED24(-1.0) || YFraction > FIXED24(1.0), "Illegal Y Shading value"); 03584 03585 // Adjust the Saturation according to XFraction 03586 if (XFraction != FIXED24(0.0)) 03587 { 03588 if (XFraction < FIXED24(0.0)) 03589 { 03590 XFraction = -XFraction; 03591 Result->Saturation = Result->Saturation * (FIXED24(1.0) - XFraction); 03592 } 03593 else 03594 Result->Saturation = XFraction + Result->Saturation * (FIXED24(1.0) - XFraction); 03595 } 03596 03597 03598 // Adjust the Value according to YFraction 03599 if (YFraction != FIXED24(0.0)) 03600 { 03601 if (YFraction < FIXED24(0.0)) 03602 { 03603 YFraction = -YFraction; 03604 Result->Value = Result->Value * (FIXED24(1.0) - YFraction); 03605 } 03606 else 03607 Result->Value = YFraction + Result->Value * (FIXED24(1.0) - YFraction); 03608 } 03609 } 03610 03611 03612 03613 /******************************************************************************************** 03614 03615 > virtual void ColourContextHSVT::GetWhite(ColourGeneric *Result); 03616 03617 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03618 Created: 8/6/96 03619 03620 Outputs: Result - Will be filled in with White, however that is defined in 03621 this context's colour model. (i.e. RGB(1,1,1) or CMYK(0,0,0,0), etc) 03622 03623 Purpose: An easy way to get a colour definition in this colour model which 03624 is white (paper colour). 03625 03626 ********************************************************************************************/ 03627 03628 void ColourContextHSVT::GetWhite(ColourGeneric *Result) 03629 { 03630 ColourHSVT *hsvt = (ColourHSVT *) Result; 03631 hsvt->Hue = hsvt->Saturation = 0; 03632 hsvt->Value = 1.0; 03633 hsvt->Transparent = 0; 03634 } 03635 03636 03637 03638 03639 03640 03641 03642 03643 03644 03645 03646 03647 03648 03649 03650 03651 /******************************************************************************************** 03652 03653 > void ColourContextGreyT::ColourContextGreyT(View *Scope) 03654 03655 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03656 Created: 2/6/94 03657 Inputs: Scope - The view in which this context is to be used, or NULL 03658 Outputs: - 03659 Returns: - 03660 Purpose: Constructor for an GreyT Colour context 03661 03662 Notes: Colour Contexts should not be created and used directly. See the 03663 notes in the SeeAlso's for instructions on proper care and use. 03664 03665 Errors: - 03666 SeeAlso: ColourContext::ColourContext; ColourContextList::AddContext 03667 03668 ********************************************************************************************/ 03669 03670 ColourContextGreyT::ColourContextGreyT(View *Scope) 03671 : ColourContext(Scope) 03672 { 03673 ColModel = COLOURMODEL_GREYT; 03674 03675 CreateExternalTransform(); 03676 } 03677 03678 03679 03680 /******************************************************************************************** 03681 03682 > void ColourContextGreyT::CreateExternalTransform(void) 03683 03684 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03685 Created: 12/05/96 03686 Inputs: - 03687 Returns: - 03688 Purpose: Create an external transform to be used during colour conversions from 03689 Grey to the current RCS space. This function uses the Winoil CMS Manager 03690 to create the transform. Both forward and backward transforms use logical 03691 RGB descriptions. 03692 03693 ********************************************************************************************/ 03694 03695 void ColourContextGreyT::CreateExternalTransform() 03696 { 03697 #ifndef NO_XARACMS 03698 CMSColourSpace cmsSpace; 03699 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03700 03701 if (lpCMSMan != NULL) 03702 { 03703 // first read our internal colour calibration space 03704 lpCMSMan->GetLogicalProfile(&cmsSpace); 03705 03706 // set this as the active colour profile 03707 UINT32 err = lpCMSMan->SetProfile(cmsSpace); 03708 03709 // if we haven't got an error, create that transform 03710 if (err==0) 03711 CMSTransform = lpCMSMan->CreateTransform(DISPLAY_RCS); 03712 } 03713 #endif 03714 } 03715 03716 03717 /******************************************************************************************** 03718 03719 > void ColourContextGreyT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 03720 03721 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03722 Created: 2/6/94 03723 Inputs: Source - A Colour defined in this GreyT context 03724 Result - pointer to a structure to recieve the resulting colour as 03725 defined in CIE space 03726 Outputs: - 03727 Returns: - 03728 Purpose: Converts the given colour from our GreyT colourspace to CIET colourspace 03729 Notes: - 03730 Errors: - 03731 SeeAlso: ColourContextGreyT::ConvertFromCIET 03732 03733 ********************************************************************************************/ 03734 03735 void ColourContextGreyT::ConvertToCIET(ColourGeneric *Source, DColourCIET *Result) 03736 { 03737 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 03738 03739 #ifndef NO_XARACMS 03740 // If we've got a CMS manager, use it, else use the version 1.1 bodge 03741 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03742 03743 if (lpCMSMan != NULL) 03744 { 03745 // The new colour calibration method 03746 CMSColour icol, ocol; 03747 03748 icol.c2 = ((ColourGreyT *)Source)->Intensity.MakeDouble(); 03749 icol.c0 = icol.c1 = icol.c2; 03750 03751 // If we have no colour transform, or if we don't want the colour corrected/separated, 03752 // then we will just do a "logical" conversion. 03753 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 03754 lpCMSMan->ConvRGBtoCIEXYZ(icol, ocol); 03755 else 03756 lpCMSMan->GTransform(CMSTransform, cmsForward, icol, ocol); 03757 03758 Result->X = ocol.c0; 03759 Result->Y = ocol.c1; 03760 Result->Z = ocol.c2; 03761 } 03762 else 03763 #endif 03764 { 03765 // The old rgb system 03766 Result->X = Result->Y = Result->Z = ((ColourGreyT *)Source)->Intensity.MakeDouble(); 03767 } 03768 03769 Result->Transparent = 0.0;//((ColourGreyT *)Source)->Transparent; 03770 } 03771 03772 03773 03774 03775 /******************************************************************************************** 03776 03777 > void ColourContextGreyT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 03778 03779 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03780 Created: 22/04/94 03781 Inputs: Source - A Colour defined in the CIET colourspace 03782 Result - pointer to a structure to recieve the resulting colour as 03783 defined in the GreyT space described by this colour context. 03784 Outputs: - 03785 Returns: - 03786 Purpose: Converts the given colour to our GreyT colourspace from CIET colourspace 03787 Notes: - 03788 Errors: - 03789 SeeAlso: ColourContextGreyT::ConvertToCIET 03790 03791 ********************************************************************************************/ 03792 03793 void ColourContextGreyT::ConvertFromCIET(DColourCIET *Source, ColourGeneric *Result) 03794 { 03795 ENSURE(UsageCount > 0, "Colour context being used when not initialised!"); 03796 03797 #ifndef NO_XARACMS 03798 // If we've got a CMS manager, use it, else use the version 1.1 bodge 03799 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager(); 03800 03801 if (lpCMSMan != NULL) 03802 { 03803 CMSColour icol, ocol; 03804 03805 icol.c0 = Source->X; 03806 icol.c1 = Source->Y; 03807 icol.c2 = Source->Z; 03808 03809 // If we have no colour transform, or if we don't want the colour corrected/separated, 03810 // then we will just do a "logical" conversion. 03811 if (CMSTransform == NULL || (ColPlate != NULL && ColPlate->IsDisabled())) 03812 lpCMSMan->ConvCIEXYZtoRGB(icol, ocol); 03813 else 03814 lpCMSMan->GTransform(CMSTransform, cmsReverse, icol, ocol); 03815 03816 // The loadings below are taken from Gerry, the expert on colour loadings 03817 // in this particular office. No expense was spared to research these 03818 // values properly... ;-) 03819 double inten; 03820 inten = (ocol.c0 * 0.305) + (ocol.c1 * 0.586) + (ocol.c2 * 0.109); 03821 ((ColourGreyT *)Result)->Intensity = inten; 03822 } 03823 else 03824 #endif 03825 { 03826 double R, G, B; 03827 R = Source->X; 03828 G = Source->Y; 03829 B = Source->Z; 03830 03831 // The loadings below are taken from Gerry, the expert on colour loadings 03832 // in this particular office. No expense was spared to research these 03833 // values properly... ;-) 03834 ((ColourGreyT *)Result)->Intensity = (R * 0.305) + (G * 0.586) + (B * 0.109); 03835 } 03836 03837 // Set the transparency field 03838 ((ColourGreyT *)Result)->Transparent = 0;//Source->Transparent; 03839 03840 // And ensure that the reserved fields are cleared 03841 ((ColourGreyT *)Result)->Reserved1 = ((ColourGreyT *)Result)->Reserved2 = 0; 03842 } 03843 03844 03845 03846 /******************************************************************************************** 03847 03848 > void ColourContextGreyT::GetModelName(StringBase *Result) 03849 03850 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03851 Created: 1/6/94 03852 Inputs: - 03853 Outputs: Result returns continaing a String of the name of the context. 03854 This string is guaranteed to fit within a String_32 - this is the 03855 minimum size you should allocate. (Most names, in English at least, 03856 are shorter than this (10 chars max, e.g. 'RGB' 'HSV' 'Greyscale') 03857 so allow at least 10 chars of space in your displays as well) 03858 Returns: - 03859 Purpose: Returns the name of this context's colour model 03860 Notes: 03861 03862 ********************************************************************************************/ 03863 03864 void ColourContextGreyT::GetModelName(StringBase *Result) 03865 { 03866 ENSURE(Result != NULL, "ColourContext::GetModelName called with NULL result pointer!"); 03867 03868 *Result = String_32(_R(IDS_COLMODEL_GREY)); 03869 } 03870 03871 03872 03873 /******************************************************************************************** 03874 03875 > BOOL ColourContextGreyT::GetComponentName(INT32 ComponentID, StringBase *Result, 03876 BOOL LongName = FALSE) 03877 03878 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03879 Created: 26/7/94 03880 Inputs: ComponentID - Index [1..4] of the component you want the name of 03881 (Result is an output) 03882 LongName - TRUE to get the long name, FALSE to get the short name 03883 (e.g. "Magenta" vs "M", "Saturation" vs "Sat") 03884 03885 Outputs: Result returns containing a String of the name of the given component 03886 of colours defined in this context. 03887 This string is guaranteed to fit within a String_32 - this is the 03888 minimum size you should allocate. (Most names, in English at least, 03889 are shorter than this (10 chars max, e.g. 'Red' 'Hue' 'Saturation') 03890 so allow at least 10 chars of space in your displays as well) 03891 03892 Note that Result can be passed in NULL in order to only determine if the 03893 context supports a given component. 03894 03895 Returns: FALSE if this component is not used by this model. 03896 Purpose: Returns the name of one of this context's colour components 03897 03898 Notes: The components are given in the same order as they appear in the 03899 high-precision ColourXYZ structures defined in colmodel.h 03900 03901 ********************************************************************************************/ 03902 03903 BOOL ColourContextGreyT::GetComponentName(INT32 ComponentID, StringBase *Result, BOOL LongName) 03904 { 03905 UINT32 StringID = 0; 03906 BOOL Used = TRUE; 03907 03908 switch(ComponentID) 03909 { 03910 case 1: 03911 StringID = (LongName) ? _R(IDS_COLCOMPL_INTENSITY) : _R(IDS_COLCOMP_INTENSITY); 03912 break; 03913 03914 #ifdef TRANSPARENTCOLOUR 03915 case 2: 03916 case 3: 03917 Used = FALSE; // These components are not used 03918 break; 03919 03920 default: 03921 StringID = _R(IDS_COLCOMP_TRANS); 03922 break; 03923 #else 03924 default: 03925 Used = FALSE; 03926 break; 03927 #endif 03928 } 03929 03930 if (Result != NULL && StringID != 0) 03931 *Result = String_32(StringID); 03932 03933 return(Used); 03934 } 03935 03936 03937 03938 /******************************************************************************************** 03939 03940 > virtual UnitGroup **ColourContextGreyT::GetComponentUnitGroups() 03941 03942 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 03943 Created: 02/05/96 03944 Inputs: - 03945 Outputs: - 03946 Returns: A pointer to the UnitGroup array 03947 Purpose: Provides an array of UnitGroups primarily for use by the base class 03948 (ColourContext) members Set/GetComponentUnitGroup(). 03949 Errors: - 03950 See Also: ColourContext::GetComponentUnitGroup() 03951 ColourContext::SetComponentUnitGroup() 03952 03953 ********************************************************************************************/ 03954 03955 UnitGroup **ColourContextGreyT::GetComponentUnitGroups() 03956 { 03957 return m_pUnitGroupArray; 03958 } 03959 03960 03961 UnitGroup* ColourContextGreyT::m_pUnitGroupArray[] = 03962 { 03963 &(StandardUnit::PercentGroup) 03964 }; 03965 03966 03967 03968 /******************************************************************************************** 03969 03970 > virtual UINT32 ColourContextGreyT::GetComponentCount() 03971 03972 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 03973 Created: 02/05/96 03974 Returns: The number of components 03975 Purpose: Provides number of components in the colour context's colour model 03976 03977 ********************************************************************************************/ 03978 03979 UINT32 ColourContextGreyT::GetComponentCount() 03980 { 03981 return MAX_COMPONENTS; 03982 } 03983 03984 03985 03986 /******************************************************************************************** 03987 03988 > virtual void ColourContextGreyT::ApplyTint(ColourValue TintFraction, 03989 ColourGeneric *SourceAndResult) 03990 03991 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 03992 Created: 17/11/94 03993 Inputs: TintFraction - The fraction (as a FIXED24 ColourValue) by which the colour 03994 should be tinted. This value is expected to lie between 0.0 and 1.0 inclusive 03995 03996 SourceAndResult - The source colour to be tinted, as defined in this 03997 colour model 03998 03999 Outputs: SourceAndResult is tinted by the given TintFraction 04000 If TintFraction <= 0.0, White is output 04001 If TintFraction >= 1.0, The source colour is output 04002 04003 Returns: - 04004 Purpose: Tints a colour (mixes it with white) 04005 04006 Notes: If the tinting value is out of range, either source-colour ow white (as 04007 appropriate) will be output. 04008 04009 ********************************************************************************************/ 04010 04011 void ColourContextGreyT::ApplyTint(ColourValue TintFraction, ColourGeneric *SourceAndResult) 04012 { 04013 ColourGreyT *Result = (ColourGreyT *) SourceAndResult; 04014 04015 if (TintFraction <= FIXED24(0.0)) // 0% tint = White 04016 { 04017 Result->Intensity = FIXED24(1.0); 04018 return; 04019 } 04020 04021 if (TintFraction >= FIXED24(1.0)) // The Result colour is identical to the source 04022 return; 04023 04024 // Otherwise, tint the colour... 04025 Result->Intensity = FIXED24(1.0) - (TintFraction - (Result->Intensity * TintFraction)); 04026 } 04027 04028 04029 04030 /******************************************************************************************** 04031 04032 > void ColourContextGreyT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 04033 ColourGeneric *SourceAndResult) 04034 04035 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 04036 Created: 24/8/95 04037 Inputs: XFraction - The fraction (as a FIXED24 ColourValue) by which the colour 04038 should be saturated. This value is expected to lie between -1.0 and 1.0 inclusive 04039 Values below 0.0 mean tint towards 0, while values above mean tint towards 1. 04040 0.0 means no tinting 04041 04042 YFraction - The fraction (as a FIXED24 ColourValue) by which the colour 04043 should be shaded. This value is expected to lie between -1.0 and 1.0 inclusive 04044 Values below 0.0 mean shade towards 0, while values above mean shade towards 1. 04045 0.0 means no shading 04046 04047 SourceAndResult - The source colour to be tinted, as defined in this 04048 colour model 04049 04050 Outputs: SourceAndResult is shaded by the given Fractions 04051 Any invalid value is clipped to 0.0 04052 04053 Returns: - 04054 Purpose: Shades a colour (tweaks the saturation and value in a relative way) 04055 04056 Notes: Contexts other than HSV currently convert the colour to and from HSV 04057 form in order to apply the shade. This is a tad inefficient, but a 04058 quick'n'easy bodge that will get it going nice and quickly. 04059 04060 ********************************************************************************************/ 04061 04062 void ColourContextGreyT::ApplyShade(ColourValue XFraction, ColourValue YFraction, 04063 ColourGeneric *SourceAndResult) 04064 { 04065 ColourHSVT HSVDef; 04066 ColourContext *cc = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT); 04067 ERROR3IF(cc == NULL, "No default HSV colour context?!"); 04068 04069 cc->ConvertColour(this, SourceAndResult, (ColourGeneric *) &HSVDef); 04070 cc->ApplyShade(XFraction, YFraction, (ColourGeneric *) &HSVDef); 04071 ConvertColour(cc, (ColourGeneric *) &HSVDef, SourceAndResult); 04072 } 04073 04074 04075 04076 /******************************************************************************************** 04077 04078 > virtual void ColourContextGreyT::GetWhite(ColourGeneric *Result); 04079 04080 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 04081 Created: 8/6/96 04082 04083 Outputs: Result - Will be filled in with White, however that is defined in 04084 this context's colour model. (i.e. RGB(1,1,1) or CMYK(0,0,0,0), etc) 04085 04086 Purpose: An easy way to get a colour definition in this colour model which 04087 is white (paper colour). 04088 04089 ********************************************************************************************/ 04090 04091 void ColourContextGreyT::GetWhite(ColourGeneric *Result) 04092 { 04093 ColourGreyT *grey = (ColourGreyT *) Result; 04094 grey->Intensity = 1.0; 04095 04096 grey->Reserved1 = grey->Reserved2 = grey->Transparent = 0; 04097 } 04098