00001 // $Id: gradtbl.cpp 1372 2006-06-27 11:23:21Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // Classes to implement the graduation tables required for special path filling attributes. 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 00106 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "colormgr.h" 00108 #include "colplate.h" 00109 //#include "doccolor.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 #include "devcolor.h" 00111 #include "grndrgn.h" 00112 #include "gradtbl.h" 00113 //#include "xaracms.h" 00114 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 #include "fillramp.h" 00116 00117 DECLARE_SOURCE("$Revision: 1372 $"); 00118 00119 CC_IMPLEMENT_DYNCREATE(GradTable, CCObject) 00120 CC_IMPLEMENT_DYNCREATE(TranspGradTable, CCObject) 00121 CC_IMPLEMENT_DYNCREATE(GradTable32, CCObject) 00122 00123 // This will get Camelot to display the filename and linenumber of any memory allocations 00124 // that are not released at program exit 00125 #define new CAM_DEBUG_NEW 00126 00127 00128 /******************************************************************************************** 00129 * NOTE * 00130 * There are now 2 functions in this file which build graduation tables. The tables are * 00131 * actually identical in meaning, but are encoded as (a) Gavin 8bpp dither patterns, and * 00132 * (b) RGBQUAD RGB structures or COLORREF RGB values - this is because the different * 00133 * places that use these tables demand the different formats, and converting all the code * 00134 * to use only one table format is non-trivial and/or inefficient. * 00135 *******************************************************************************************/ 00136 00137 00138 // FillStep 00139 // This constant is used when filling grad tables for COLOURPLATE_COMPOSITE modes. 00140 // 00141 // Each ConvertColour is mindbogglingly slow (over 52 multiplies) so to get some 00142 // speed without too much loss of quality, we calculate proper values for every 00143 // 16th entry of the table, and linearly interpolate between them. Note that we can't 00144 // increase the step size beyond about 16, or rainbow fills will start going wrong. 00145 // 00146 // Decreasing this constant to 1 will slow down Composite preview rendering an awful lot, 00147 // but may slightly improve display quality. 00148 // 00149 const DWORD FillStep = 16; // Number of interpolated colours between proper samples 00150 00151 00152 00153 /******************************************************************************************** 00154 00155 > GradTable::GradTable(BOOL LargeTable = FALSE) 00156 00157 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00158 Created: 14/9/94 00159 Purpose: Default constructor for a GradTable 00160 00161 Notes: Sets the default table size to 0x100 entries long 00162 00163 SeeAlso: GradTable::SetTableSize 00164 00165 ********************************************************************************************/ 00166 00167 GradTable::GradTable(BOOL LargeTable) 00168 { 00169 m_bLargeTable = LargeTable; 00170 m_pTable = NULL; 00171 } 00172 00173 00174 00175 /******************************************************************************************** 00176 00177 > GradTable::~GradTable() 00178 00179 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 00180 Created: 16/10/96 00181 Purpose: Destructor for a GradTable 00182 00183 ********************************************************************************************/ 00184 00185 GradTable::~GradTable() 00186 { 00187 if (m_pTable != NULL) 00188 { 00189 CCFree(m_pTable); 00190 m_pTable = NULL; 00191 } 00192 } 00193 00194 00195 00196 /******************************************************************************************** 00197 00198 > INT32 GradTable::GetTableSize(GDrawContext* GD, BOOL LargeTable) 00199 00200 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 00201 Created: 17/10/96 00202 Inputs: GD - pointer to GDraw context to use 00203 LargeTable - if true then use a long grad table 00204 Returns: The size in bytes of a grad table for the specified context 00205 00206 ********************************************************************************************/ 00207 00208 INT32 GradTable::GetTableSize(GDrawContext* GD, BOOL LargeTable) 00209 { 00210 if (LargeTable) 00211 { 00212 return(GD->GetLongGraduationTableSize()); 00213 } 00214 else 00215 { 00216 return(GD->GetGraduationTableSize()); 00217 } 00218 } 00219 00220 00221 00222 /******************************************************************************************** 00223 00224 > INT32 GradTable::GetTableLength(GDrawContext* GD, BOOL LargeTable) 00225 00226 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 00227 Created: 17/10/96 00228 Inputs: GD - pointer to GDraw context to use 00229 LargeTable - if true then use a long grad table 00230 Returns: The number of entries in a grad table for the specified context 00231 00232 ********************************************************************************************/ 00233 00234 INT32 GradTable::GetTableLength(GDrawContext* GD, BOOL LargeTable) 00235 { 00236 if (LargeTable) 00237 { 00238 return(GD->GetLongGraduationTableLength()); 00239 } 00240 else 00241 { 00242 return(GD->GetGraduationTableLength()); 00243 } 00244 } 00245 00246 00247 /******************************************************************************************** 00248 00249 > void GradTable::SetTableSize(BOOL LargeTable = FALSE) 00250 00251 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 00252 Created: 17/10/96 00253 00254 Inputs: LargeTable - if true then use a long grad table 00255 00256 Purpose: To set the size of this Grad table 00257 00258 Notes: The table defaults to small 00259 00260 ********************************************************************************************/ 00261 00262 void GradTable::SetTableSize(BOOL LargeTable) 00263 { 00264 // If we don't have the right table size or no table at all 00265 if ((LargeTable != m_bLargeTable) || (m_pTable == NULL)) 00266 { 00267 m_bLargeTable = LargeTable; 00268 00269 if (m_pTable != NULL) 00270 { 00271 CCFree(m_pTable); 00272 m_pTable = NULL; 00273 } 00274 00275 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00276 00277 if (GD != NULL) 00278 { 00279 INT32 Size = GetTableSize(GD, m_bLargeTable); 00280 00281 m_pTable = (GraduationTable*) CCMalloc(Size); 00282 00283 if (m_pTable != NULL) 00284 { 00285 m_pTable->Length = GetTableLength(GD, LargeTable); 00286 } 00287 } 00288 } 00289 } 00290 00291 00292 00293 /******************************************************************************************** 00294 00295 > BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00296 View *ContextView, EFFECTTYPE Effect, 00297 DWORD FirstEntry, DWORD LastEntry) 00298 00299 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Will) 00300 Created: 14/5/96 (14/9/94) 00301 00302 Inputs: StartCol, EndCol - Define the end colours of the graduation 00303 ContextView - Points to the view in which the gradation is to be displayed. 00304 (This is necessary for correction and separation etc. If proper 00305 colour handling is not needed, then you may pass NULL, but 00306 generally, this parameter should be sensible) 00307 00308 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00309 00310 TableSize - The number of entries you wish to make the table (0x100 or 00311 0x800) 00312 00313 Returns: FALSE if it fails 00314 00315 Purpose: Builds a GradTable from StartCol to EndCol, filling in the entire 00316 table with appropriate GDraw dither patterns. 00317 00318 == NOTE that this version of the call also implicitly sets the table size! == 00319 00320 SeeAlso: GradTable::SetTableSize 00321 00322 ********************************************************************************************/ 00323 00324 BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00325 View *ContextView, EFFECTTYPE Effect, 00326 BOOL LargeTable) 00327 { 00328 SetTableSize(LargeTable); 00329 00330 return(BuildTable(StartCol, EndCol, ContextView, Effect, 0, m_pTable->Length)); 00331 } 00332 00333 00334 00335 /******************************************************************************************** 00336 00337 > void GradTable::FillTable(DWORD StartIndex, DWORD EndIndex, 00338 PColourRGBT *StartDef, PColourRGBT *EndDef) 00339 00340 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00341 Created: 21/7/96 00342 00343 Inputs: StartIndex, EndIndex - Define the indices into the grad fill table 00344 between which you want to fill in the table. NOTE that Table[StartIndex] 00345 is filled in, while table[EndIndex] is NOT. 00346 StartDef, EndDef - Define the end colours of the graduation 00347 00348 Purpose: Builds a GradTable from StartIndex to EndIndex by linearly interpolating 00349 between the StartDef and EndDef RGB colours. 00350 00351 Notes: In order to correctly handle Rainbow fills, you must interpolate only small 00352 sections of the table - it is recommended that you fill no more than 16 00353 entries of the table at a time with this linear interpolation. 00354 00355 ********************************************************************************************/ 00356 00357 void GradTable::FillTable(DWORD StartIndex, DWORD EndIndex, 00358 PColourRGBT *StartDef, PColourRGBT *EndDef) 00359 { 00360 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00361 00362 // Place the StartDef in as the first entry 00363 GD->AddToGraduationTable(RGB(StartDef->Red, StartDef->Green, StartDef->Blue), 00364 FALSE, m_pTable, StartIndex); 00365 00366 // ...and start interpolating from the second entry 00367 DWORD MixStep = (1 << 24) / (EndIndex - StartIndex); 00368 DWORD MixFraction = MixStep; 00369 00370 DWORD R,G,B; 00371 for (DWORD Index = StartIndex + 1; Index < EndIndex; Index++) 00372 { 00373 // Calculate intermediate RGB values into 8bpp values 00374 R = (StartDef->Red * (0x01000000 - MixFraction)) + (EndDef->Red * MixFraction); 00375 R >>= 24; 00376 00377 G = (StartDef->Green * (0x01000000 - MixFraction)) + (EndDef->Green * MixFraction); 00378 G >>= 24; 00379 00380 B = (StartDef->Blue * (0x01000000 - MixFraction)) + (EndDef->Blue * MixFraction); 00381 B >>= 24; 00382 00383 // Get Gavin to fill in the dither entry for us (FALSE means it's an RGB Indexour) 00384 GD->AddToGraduationTable(RGB(R,G,B), FALSE, m_pTable, Index); 00385 00386 MixFraction += MixStep; 00387 } 00388 } 00389 00390 00391 00392 /******************************************************************************************** 00393 00394 > BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00395 View *ContextView, EFFECTTYPE Effect, 00396 DWORD FirstEntry, DWORD LastEntry) 00397 00398 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Will) 00399 Created: 14/5/96 (14/9/94) 00400 00401 Inputs: StartCol, EndCol - Define the end colours of the graduation 00402 ContextView - Points to the view in which the gradation is to be displayed. 00403 (This is necessary for correction and separation etc. If proper 00404 colour handling is not needed, then you may pass NULL, but 00405 generally, this parameter should be sensible) 00406 00407 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00408 00409 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 00410 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 00411 (i.e. to fill entire table use (0,TableSize) which will fill in entries 00412 0..Tablesize-1) 00413 00414 Returns: FALSE if it fails 00415 00416 Purpose: Builds a GradTable from StartCol to EndCol, filling in a portion of the 00417 table with appropriate GDraw dither patterns 00418 00419 Notes: GDraw requires the Start and End colours for the entire table to be 00420 set separately in the table structure. These will be set if FirstEntry==0 00421 and/or if LastEntry==TableSize, respectively. 00422 00423 No longer calls GDraw to build the table. The colours are generated 00424 by us (mainly so that we can support proper colour correction and 00425 separation by allowing the colour system to do its stuff) 00426 00427 This method could be somewhat more optimal than it is, if we start 00428 poking around more in the internals of the colour system. For the time 00429 being, I'm leaving it tidy, however. 00430 00431 Errors: ERROR2's if it runs out of memory 00432 00433 SeeAlso: GradTable::SetTableSize 00434 00435 ********************************************************************************************/ 00436 00437 BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00438 View *ContextView, EFFECTTYPE Effect, 00439 DWORD FirstEntry, DWORD LastEntry) 00440 { 00441 // The range should be within the table size. We only ERROR3, though, because 00442 // the physical table is always large enough for the maximum number of entries. 00443 00444 ERROR3IF(FirstEntry < 0 || FirstEntry > LastEntry || LastEntry > m_pTable->Length, 00445 "GradTable::BuildTable expects sensible First/Last Entry values"); 00446 00447 // Find a GDraw context to generate dithertable entries for us 00448 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00449 ERROR3IF(GD == NULL, "GradTable::BuildTable - No GDraw context?!"); 00450 00451 // Determine if either the start or end colour is a spot colour - if it is, we must 00452 // coerce the fill into a "mix" (rgb) rather than rainbow fill style 00453 if (Effect != EFFECT_RGB && (StartCol.GetSpotParent() != NULL || EndCol.GetSpotParent() != NULL)) 00454 Effect = EFFECT_RGB; 00455 00456 // Get colour contexts: we need 2 - first, an RGB context for the ContextView, which 00457 // will be used to get colour-corrected/separated/etc output colour in RGB; and second, 00458 // a generic RGB or HSV context to provide a "mixing colourspace" for the graduations. 00459 ColourContext *cc = NULL; 00460 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 00461 00462 if (Effect == EFFECT_RGB) 00463 cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 00464 else 00465 cc = ColourManager::GetColourContext(COLOURMODEL_HSVT); // HSV fade 00466 00467 // If we can't find RGB/HSV contexts, something is seriously broken 00468 ERROR3IF(cc == NULL || ccRGB == NULL, 00469 "GradTable::BuildTable - Can't find my colour context!"); 00470 00471 // Fill in the Start and End colours of the table, if we've hit them 00472 PColourRGBT Result; 00473 00474 if (FirstEntry == 0) 00475 { 00476 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &Result); 00477 m_pTable->StartColour = RGB(Result.Red, Result.Green, Result.Blue); 00478 } 00479 00480 if (LastEntry >= m_pTable->Length) 00481 { 00482 LastEntry = m_pTable->Length; 00483 ccRGB->ConvertColour(&EndCol, (ColourPacked *) &Result); 00484 m_pTable->EndColour = RGB(Result.Red, Result.Green, Result.Blue); 00485 } 00486 00487 const BOOL ValidColourPlate = (ccRGB->GetColourPlate() != NULL && !ccRGB->GetColourPlate()->IsDisabled()); 00488 00489 if (ValidColourPlate || 00490 FirstEntry > 0 || 00491 LastEntry < m_pTable->Length) 00492 { 00493 if (ValidColourPlate && ccRGB->GetColourPlate()->GetType() == COLOURPLATE_COMPOSITE) 00494 { 00495 // We're doing a composite print preview. 00496 PColourRGBT StartDef; 00497 PColourRGBT EndDef; 00498 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &EndDef); 00499 00500 DWORD StartIndex = FirstEntry; 00501 DWORD EndIndex; 00502 00503 DocColour TempCol; 00504 00505 while (StartIndex < LastEntry) 00506 { 00507 // Move the last run's end colour into Start 00508 memcpy(&StartDef, &EndDef, sizeof(PColourRGBT)); 00509 00510 // Calculate the end of this run 00511 EndIndex = StartIndex + FillStep; 00512 if (EndIndex > LastEntry) 00513 EndIndex = LastEntry; 00514 00515 // Calculate the colour at the end of this run, and convert into EndDef 00516 TempCol.Mix(&StartCol, &EndCol, 00517 ((double)(EndIndex - FirstEntry)) / ((double)(LastEntry - FirstEntry)), 00518 cc, (Effect == EFFECT_HSV_LONG), ccRGB); 00519 00520 ccRGB->ConvertColour(&TempCol, (ColourPacked *) &EndDef); 00521 00522 // Linearly interpolate all colours in the run 00523 FillTable(StartIndex, EndIndex, &StartDef, &EndDef); 00524 00525 // And step on to the next run 00526 StartIndex = EndIndex; 00527 } 00528 } 00529 else 00530 { 00531 // We have some type of colour separation on the go - we must convert all intermediate 00532 // colours through the colour system in order to ensure the results are correct. 00533 // This is quite slow, but acceptable (ish) when printing. 00534 double MixFraction = 0.0; 00535 // This next line requires the -1 because otherwise it doesn't reach the end colour 00536 // This is ok if LastEntry = StartEntry + 1 as MixStep will be calculated as zero 00537 // and the StartCol will be used to fill in the single entry required 00538 double denumerator = (double) (LastEntry - FirstEntry - 1); 00539 double MixStep = 0; 00540 if (denumerator != 0) 00541 { 00542 MixStep = 1.0 / denumerator; 00543 } 00544 00545 DocColour temp; 00546 for (DWORD col = FirstEntry; col < LastEntry; col++) 00547 { 00548 // Create a new colour which is an appropriate mixture of the start/end colours 00549 temp.Mix(&StartCol, &EndCol, MixFraction, cc, (Effect == EFFECT_HSV_LONG), ccRGB); 00550 00551 // Convert back to the raw RGB and place it in the palette. 00552 // Note that this will colour correct and separate in an appropriate manner. 00553 // Note also that we're using a special ConvertColour call which returns 8-bit 00554 // "packed" component values instead of FIXED24's. 00555 ccRGB->ConvertColour(&temp, (ColourPacked *) &Result); 00556 00557 // Get GDraw to fill in the dither entry for us (FALSE means it's an RGB colour) 00558 GD->AddToGraduationTable(RGB(Result.Red, Result.Green, Result.Blue), FALSE, m_pTable, col); 00559 00560 // And step to the next mix fraction value 00561 MixFraction += MixStep; 00562 } 00563 } 00564 } 00565 else 00566 { 00567 // We're doing a completely normal view, and building the entire 256-entry table, so 00568 // call GDraw to blindly interpolate between the colours, which is much (much) faster. 00569 GD->BuildGraduationTable(m_pTable->StartColour, m_pTable->EndColour, Effect, m_pTable); 00570 } 00571 00572 return(TRUE); 00573 } 00574 00575 00576 00577 /******************************************************************************************** 00578 00579 > BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00580 View *ContextView, EFFECTTYPE Effect, 00581 CProfileBiasGain& BiasGain, BOOL LargeTable) 00582 00583 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00584 Created: 4/2/2000 00585 Inputs: StartCol, EndCol - Define the end colours of the graduation 00586 pColList - Define the colours and positions of a colour ramp 00587 ContextView - Points to the view in which the gradation is to be displayed. 00588 (This is necessary for correction and separation etc. If proper 00589 colour handling is not needed, then you may pass NULL, but 00590 generally, this parameter should be sensible) 00591 00592 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00593 00594 BiasGain - The baisgain values that are to alter the fill table 00595 00596 TableSize - The number of entries you wish to make the table (0x100 or 00597 0x800) 00598 Returns: TRUE, error thrown otherwise (but only for input variables) 00599 Purpose: Generates a graduated fill table that is modified by biasgain values. 00600 SeeAlso: - 00601 00602 ********************************************************************************************/ 00603 00604 BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, 00605 View *ContextView, EFFECTTYPE Effect, 00606 CProfileBiasGain& BiasGain, BOOL LargeTable) 00607 { 00608 // Find a GDraw context to generate dithertable entries for us 00609 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00610 ERROR3IF(GD == NULL, "GradTable::BuildTable - No GDraw context?!"); 00611 00612 // Determine if either the start or end colour is a spot colour - if it is, we must 00613 // coerce the fill into a "mix" (rgb) rather than rainbow fill style 00614 if (Effect != EFFECT_RGB && (StartCol.GetSpotParent() != NULL || EndCol.GetSpotParent() != NULL)) 00615 Effect = EFFECT_RGB; 00616 00617 // Get colour contexts: we need 2 - first, an RGB context for the ContextView, which 00618 // will be used to get colour-corrected/separated/etc output colour in RGB; and second, 00619 // a generic RGB or HSV context to provide a "mixing colourspace" for the graduations. 00620 ColourContext *cc = NULL; 00621 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 00622 00623 if (Effect == EFFECT_RGB) 00624 cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 00625 else 00626 cc = ColourManager::GetColourContext(COLOURMODEL_HSVT); // HSV fade 00627 00628 // If we can't find RGB/HSV contexts, something is seriously broken 00629 ERROR3IF(cc == NULL || ccRGB == NULL, 00630 "GradTable::BuildTable - Can't find my colour context!"); 00631 00632 // Fill in the Start and End colours of the table, if we've hit them 00633 PColourRGBT Result; 00634 00635 // set our table size for this grad 00636 SetTableSize(LargeTable); 00637 00638 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &Result); 00639 m_pTable->StartColour = RGB(Result.Red, Result.Green, Result.Blue); 00640 00641 ccRGB->ConvertColour(&EndCol, (ColourPacked *) &Result); 00642 m_pTable->EndColour = RGB(Result.Red, Result.Green, Result.Blue); 00643 00644 BiasGain.SetIntervals (AFp (0), AFp (m_pTable->Length)); 00645 00646 const INT32 TableLength = m_pTable->Length; 00647 double MixFraction; 00648 DocColour temp; 00649 INT32 r, g, b; 00650 double res; 00651 00652 for (INT32 col = 0; col < TableLength; col++) 00653 { 00654 res = BiasGain.MapInterval( AFp( col ) ); 00655 00656 MixFraction = res / TableLength; 00657 00658 // Create a new colour which is an appropriate mixture of the start/end colours 00659 temp.Mix(&StartCol, &EndCol, MixFraction, cc, (Effect == EFFECT_HSV_LONG), ccRGB); 00660 temp.GetRGBValue (&r, &g, &b); 00661 00662 // Get GDraw to fill in the dither entry for us (FALSE means it's an RGB colour) 00663 GD->AddToGraduationTable(RGB(r, g, b), FALSE, m_pTable, col); 00664 } 00665 00666 return (TRUE); 00667 } 00668 00669 00670 00671 /******************************************************************************************** 00672 00673 > BOOL GradTable::BuildHighQualityRepeatTable(DocColour &StartCol, DocColour &EndCol, ColourRamp *pColourRamp, 00674 View *ContextView, EFFECTTYPE Effect) 00675 00676 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00677 Created: 4/2/2000 00678 Inputs: StartCol, EndCol - Define the end colours of the graduation 00679 pColourRamp - Define the colours and positions of a colour ramp 00680 ContextView - Points to the view in which the gradation is to be displayed. 00681 (This is necessary for correction and separation etc. If proper 00682 colour handling is not needed, then you may pass NULL, but 00683 generally, this parameter should be sensible) 00684 00685 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00686 00687 Returns: TRUE, error thrown otherwise (but only for input variables) 00688 Purpose: Generates a high quality repeating graduated fill table. Handles both 00689 those with fill ramps and those without. 00690 SeeAlso: - 00691 00692 ********************************************************************************************/ 00693 00694 BOOL GradTable::BuildHighQualityRepeatTable(DocColour &StartCol, DocColour &EndCol, ColourRamp *pColourRamp, 00695 View *ContextView, EFFECTTYPE Effect) 00696 { 00697 if (!pColourRamp) 00698 { 00699 // Find a GDraw context to generate dithertable entries for us 00700 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00701 ERROR3IF(GD == NULL, "GradTable::BuildHighQualityRepeatTable - No GDraw context?!"); 00702 00703 // Determine if either the start or end colour is a spot colour - if it is, we must 00704 // coerce the fill into a "mix" (rgb) rather than rainbow fill style 00705 if (Effect != EFFECT_RGB && (StartCol.GetSpotParent() != NULL || EndCol.GetSpotParent() != NULL)) 00706 Effect = EFFECT_RGB; 00707 00708 // Get colour contexts: we need 2 - first, an RGB context for the ContextView, which 00709 // will be used to get colour-corrected/separated/etc output colour in RGB; and second, 00710 // a generic RGB or HSV context to provide a "mixing colourspace" for the graduations. 00711 ColourContext *cc = NULL; 00712 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 00713 00714 if (Effect == EFFECT_RGB) 00715 cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 00716 else 00717 cc = ColourManager::GetColourContext(COLOURMODEL_HSVT); // HSV fade 00718 00719 // If we can't find RGB/HSV contexts, something is seriously broken 00720 ERROR3IF(cc == NULL || ccRGB == NULL, 00721 "GradTable::BuildHighQualityRepeatTable - Can't find my colour context!"); 00722 00723 // Fill in the Start and End colours of the table, if we've hit them 00724 PColourRGBT Result; 00725 00726 // set our table size for this grad 00727 SetTableSize(TRUE); 00728 00729 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &Result); 00730 ccRGB->ConvertColour(& EndCol, (ColourPacked *) &Result); 00731 m_pTable->StartColour = RGB(Result.Red, Result.Green, Result.Blue); 00732 m_pTable->EndColour = RGB(Result.Red, Result.Green, Result.Blue); 00733 00734 const INT32 TableLength = m_pTable->Length; 00735 double MixFraction = 0.0; 00736 double MixStep = 0; 00737 00738 if (TableLength != 0) 00739 MixStep = 2.0 / TableLength; 00740 00741 DocColour temp; 00742 INT32 r, g, b; 00743 00744 // NOTE: this loop could be optimised to avoid calculating the same colour value twice 00745 00746 for (INT32 col = 0 ; (col<<1)<TableLength ; col++) 00747 { 00748 // Create a new colour which is an appropriate mixture of the start/end colours 00749 temp.Mix(&StartCol, &EndCol, MixFraction, cc, (Effect == EFFECT_HSV_LONG), ccRGB); 00750 temp.GetRGBValue (&r, &g, &b); 00751 00752 // Get GDraw to fill in the dither entry for us (FALSE means it's an RGB colour) 00753 GD->AddToGraduationTable(RGB(r, g, b), FALSE, m_pTable, col); 00754 GD->AddToGraduationTable(RGB(r, g, b), FALSE, m_pTable, TableLength-col-1); 00755 00756 MixFraction += MixStep; 00757 } 00758 } 00759 else 00760 { 00761 // set our table size for this grad 00762 SetTableSize(TRUE); 00763 00764 ColRampItem *pCTI = pColourRamp->GetFirstCol(); 00765 if (pCTI!=NULL) 00766 { 00767 DocColour *pFirstCol=&StartCol, *pSecondCol; 00768 00769 DWORD fi=0 , si=0; 00770 00771 while (pCTI) 00772 { 00773 // whip out the colour definition 00774 pSecondCol = pCTI->GetColourAddr(); 00775 // calculate the index for the next colour 00776 si = (DWORD)((pCTI->GetPosition() * m_pTable->Length)+0.5); 00777 // build this section of the table 00778 if (!BuildTable(*pFirstCol, *pSecondCol, ContextView, Effect, fi, si)) 00779 return FALSE; 00780 // now skip round to the next 00781 pFirstCol = pSecondCol; 00782 fi = si; 00783 pCTI = pColourRamp->GetNextCol(pCTI); 00784 } 00785 00786 // do the final section 00787 return BuildTable(*pSecondCol, StartCol, ContextView, Effect, si, m_pTable->Length); 00788 } 00789 } 00790 00791 return (TRUE); 00792 } 00793 00794 /******************************************************************************************** 00795 00796 > BOOL GradTable::BuildHighQualityRepeatTable(DocColour &StartCol, DocColour &EndCol, 00797 View *ContextView, EFFECTTYPE Effect, 00798 CProfileBiasGain& BiasGain) 00799 00800 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00801 Created: 4/2/2000 00802 Inputs: StartCol, EndCol - Define the end colours of the graduation 00803 pColourRamp - Define the colours and positions of a colour ramp 00804 ContextView - Points to the view in which the gradation is to be displayed. 00805 (This is necessary for correction and separation etc. If proper 00806 colour handling is not needed, then you may pass NULL, but 00807 generally, this parameter should be sensible) 00808 00809 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00810 00811 BiasGain - the profile to build for 00812 00813 Returns: TRUE, error thrown otherwise (but only for input variables) 00814 Purpose: Generates a high quality repeating graduated fill table for the supplied profile. 00815 SeeAlso: - 00816 00817 ********************************************************************************************/ 00818 00819 BOOL GradTable::BuildHighQualityRepeatTable(DocColour &StartCol, DocColour &EndCol, 00820 View *ContextView, EFFECTTYPE Effect, 00821 CProfileBiasGain& BiasGain) 00822 { 00823 // Find a GDraw context to generate dithertable entries for us 00824 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 00825 ERROR3IF(GD == NULL, "GradTable::BuildHighQualityRepeatTable - No GDraw context?!"); 00826 00827 // Determine if either the start or end colour is a spot colour - if it is, we must 00828 // coerce the fill into a "mix" (rgb) rather than rainbow fill style 00829 if (Effect != EFFECT_RGB && (StartCol.GetSpotParent() != NULL || EndCol.GetSpotParent() != NULL)) 00830 Effect = EFFECT_RGB; 00831 00832 // Get colour contexts: we need 2 - first, an RGB context for the ContextView, which 00833 // will be used to get colour-corrected/separated/etc output colour in RGB; and second, 00834 // a generic RGB or HSV context to provide a "mixing colourspace" for the graduations. 00835 ColourContext *cc = NULL; 00836 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 00837 00838 if (Effect == EFFECT_RGB) 00839 cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 00840 else 00841 cc = ColourManager::GetColourContext(COLOURMODEL_HSVT); // HSV fade 00842 00843 // If we can't find RGB/HSV contexts, something is seriously broken 00844 ERROR3IF(cc == NULL || ccRGB == NULL, 00845 "GradTable::BuildHighQualityRepeatTable - Can't find my colour context!"); 00846 00847 // Fill in the Start and End colours of the table, if we've hit them 00848 PColourRGBT Result; 00849 00850 // set our table size for this grad 00851 SetTableSize(TRUE); 00852 00853 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &Result); 00854 m_pTable->StartColour = RGB(Result.Red, Result.Green, Result.Blue); 00855 00856 ccRGB->ConvertColour(&EndCol, (ColourPacked *) &Result); 00857 m_pTable->EndColour = RGB(Result.Red, Result.Green, Result.Blue); 00858 00859 const INT32 TableLength = m_pTable->Length; 00860 INT32 halfTableLength = TableLength/2; 00861 double MixFraction; 00862 00863 BiasGain.SetIntervals (AFp (0), AFp (m_pTable->Length/2)); 00864 00865 DocColour temp; 00866 INT32 r, g, b; 00867 double res; 00868 00869 BOOL secondHalf = FALSE; 00870 INT32 secondHalfVal =0; 00871 00872 // NOTE: this loop could be optimised to avoid calculating the same colour value twice 00873 00874 for (INT32 col = 0; col < TableLength; col++) 00875 { 00876 if (!secondHalf) 00877 { 00878 res = BiasGain.MapInterval( AFp( col) ); 00879 } 00880 else 00881 { 00882 res = BiasGain.MapInterval( AFp( secondHalfVal) ); 00883 } 00884 00885 MixFraction = res / halfTableLength; 00886 00887 // Create a new colour which is an appropriate mixture of the start/end colours 00888 temp.Mix(&StartCol, &EndCol, MixFraction, cc, (Effect == EFFECT_HSV_LONG), ccRGB); 00889 temp.GetRGBValue (&r, &g, &b); 00890 00891 // Get GDraw to fill in the dither entry for us (FALSE means it's an RGB colour) 00892 GD->AddToGraduationTable(RGB(r, g, b), FALSE, m_pTable, col); 00893 00894 if (!(col < halfTableLength)) 00895 { 00896 secondHalfVal = TableLength - col; 00897 secondHalf = TRUE; 00898 } 00899 } 00900 00901 return (TRUE); 00902 } 00903 00904 00905 00906 /******************************************************************************************** 00907 00908 > BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, ColourRamp *pColList, 00909 View *ContextView, EFFECTTYPE Effect, 00910 BOOL LargeTable) 00911 00912 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00913 Created: 25/2/97 00914 Inputs: StartCol, EndCol - Define the end colours of the graduation 00915 pColList - Define the colours and positions of a colour ramp 00916 ContextView - Points to the view in which the gradation is to be displayed. 00917 (This is necessary for correction and separation etc. If proper 00918 colour handling is not needed, then you may pass NULL, but 00919 generally, this parameter should be sensible) 00920 00921 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 00922 00923 TableSize - The number of entries you wish to make the table (0x100 or 00924 0x800) 00925 Returns: TRUE if record is written, FALSE if not 00926 Purpose: Writes a colour ramp fill record to the filter 00927 SeeAlso: - 00928 00929 ********************************************************************************************/ 00930 00931 BOOL GradTable::BuildTable(DocColour &StartCol, DocColour &EndCol, ColourRamp *pColRamp, 00932 View *ContextView, EFFECTTYPE Effect, 00933 BOOL LargeTable) 00934 { 00935 // set our table size for this grad 00936 SetTableSize(LargeTable); 00937 00938 // if we've been passed a colour table, lets use it 00939 if (pColRamp!=NULL) 00940 { 00941 ColRampItem *pCTI = pColRamp->GetFirstCol(); 00942 if (pCTI!=NULL) 00943 { 00944 DocColour *pFirstCol=&StartCol, *pSecondCol; 00945 00946 DWORD fi=0 , si=0; 00947 00948 while (pCTI) 00949 { 00950 // whip out the colour definition 00951 pSecondCol = pCTI->GetColourAddr(); 00952 // calculate the index for the next colour 00953 si = (DWORD)((pCTI->GetPosition() * m_pTable->Length)+0.5); 00954 // build this section of the table 00955 if (!BuildTable(*pFirstCol, *pSecondCol, ContextView, Effect, fi, si)) 00956 return FALSE; 00957 // now skip round to the next 00958 pFirstCol = pSecondCol; 00959 fi = si; 00960 pCTI = pColRamp->GetNextCol(pCTI); 00961 } 00962 00963 // do the final section 00964 return BuildTable(*pSecondCol, EndCol, ContextView, Effect, si, m_pTable->Length); 00965 } 00966 } 00967 00968 // otherwise do the normal double end linear fill. 00969 return (BuildTable(StartCol, EndCol, ContextView, Effect, 0, m_pTable->Length)); 00970 } 00971 00972 00973 /******************************************************************************************** 00974 00975 > BOOL GradTable::AddToTable(DocColour &Colour, ColourContext* CurrentColContext, 00976 BOOL HSVFlag, INT32 Index) 00977 00978 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00979 Created: 14/9/94 00980 00981 Inputs: NewCol - The colour to place into the GradTable 00982 ContextView - Points to the view in which the gradation is to be displayed. 00983 (This is necessary for correction and separation etc. If proper 00984 colour handling is not needed, then you may pass NULL, but 00985 generally, this parameter should be sensible) 00986 00987 Index - The index of the table entry to overwrite 00988 00989 Purpose: Adds a colour to a GradTable, at the specified index 00990 This is used for multi-stage fills. 00991 00992 Errors: - 00993 00994 ********************************************************************************************/ 00995 00996 BOOL GradTable::AddToTable(DocColour &NewCol, View *ContextView, DWORD Index) 00997 { 00998 ColourContextRGBT *cc = (ColourContextRGBT *) 00999 ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 01000 01001 ERROR3IF(cc == NULL, "Unable to find an RGB colour context for the view"); 01002 ERROR3IF(Index >= m_pTable->Length, "Illegal table index"); 01003 01004 PColourRGBT Result; 01005 cc->ConvertColour(&NewCol, (ColourPacked *) &Result); 01006 01007 COLORREF Col = RGB(Result.Red, Result.Green, Result.Blue); 01008 01009 // Get GDraw to fill in the table entry for us. FALSE => RGB colour 01010 return(GRenderRegion::GetStaticDrawContext()->AddToGraduationTable(Col, FALSE, m_pTable, Index)); 01011 } 01012 01013 01014 01015 01016 01017 /******************************************************************************************** 01018 01019 > TranspGradTable::TranspGradTable(BOOL LargeTable = FALSE) 01020 01021 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01022 Created: 17/10/96 01023 Purpose: Default constructor for a GradTable 01024 Errors: - 01025 01026 ********************************************************************************************/ 01027 01028 TranspGradTable::TranspGradTable(BOOL LargeTable) 01029 { 01030 m_pTable = NULL; 01031 m_bLargeTable = LargeTable; 01032 } 01033 01034 /******************************************************************************************** 01035 01036 > TranspGradTable::~TranspGradTable() 01037 01038 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01039 Created: 16/10/96 01040 Purpose: Destructor for a TranspGradTable 01041 01042 ********************************************************************************************/ 01043 01044 TranspGradTable::~TranspGradTable() 01045 { 01046 if (m_pTable != NULL) 01047 { 01048 CCFree(m_pTable); 01049 m_pTable = NULL; 01050 } 01051 } 01052 01053 01054 /******************************************************************************************** 01055 01056 > INT32 TranspGradTable::GetTableSize(GDrawContext* GD, BOOL LargeTable) 01057 01058 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01059 Created: 17/10/96 01060 Inputs: GD - pointer to GDraw context to use 01061 LargeTable - if true then use a long grad table 01062 Returns: The size in bytes of a grad table for the specified context 01063 01064 ********************************************************************************************/ 01065 01066 INT32 TranspGradTable::GetTableSize(GDrawContext* GD, BOOL LargeTable) 01067 { 01068 if (LargeTable) 01069 { 01070 return(GD->GetLongTransparentGraduationTableSize()); 01071 } 01072 else 01073 { 01074 return(GD->GetTransparentGraduationTableSize()); 01075 } 01076 } 01077 01078 01079 /******************************************************************************************** 01080 01081 > INT32 TranspGradTable::GetTableLength(GDrawContext* GD, BOOL LargeTable) 01082 01083 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01084 Created: 17/10/96 01085 Inputs: GD - pointer to GDraw context to use 01086 LargeTable - if true then use a long grad table 01087 Returns: The number of entries in a grad table for the specified context 01088 01089 ********************************************************************************************/ 01090 01091 INT32 TranspGradTable::GetTableLength(GDrawContext* GD, BOOL LargeTable) 01092 { 01093 if (LargeTable) 01094 { 01095 return(GD->GetLongTransparentGraduationTableLength()); 01096 } 01097 else 01098 { 01099 return(GD->GetTransparentGraduationTableLength()); 01100 } 01101 } 01102 01103 01104 /******************************************************************************************** 01105 01106 > void TranspGradTable::SetTableSize(BOOL LargeTable = FALSE) 01107 01108 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01109 Created: 17/10/96 01110 01111 Inputs: LargeTable - if true then use a long grad table 01112 01113 Purpose: To set the size of this Grad table 01114 01115 Notes: The table defaults to small 01116 01117 ********************************************************************************************/ 01118 01119 void TranspGradTable::SetTableSize(BOOL LargeTable) 01120 { 01121 // If we don't have the right table size or no table at all 01122 if ((LargeTable != m_bLargeTable) || (m_pTable == NULL)) 01123 { 01124 m_bLargeTable = LargeTable; 01125 01126 if (m_pTable != NULL) 01127 { 01128 CCFree(m_pTable); 01129 m_pTable = NULL; 01130 } 01131 01132 GDrawContext *GD = GRenderRegion::GetStaticDrawContext(); 01133 01134 if (GD != NULL) 01135 { 01136 INT32 Size = GetTableSize(GD, m_bLargeTable); 01137 01138 m_pTable = (TransparentGradTable*) CCMalloc(Size); 01139 } 01140 } 01141 } 01142 01143 01144 01145 /******************************************************************************************** 01146 01147 > BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp) 01148 01149 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01150 Created: 14/9/94 01151 Inputs: - 01152 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp. 01153 Errors: - 01154 01155 ********************************************************************************************/ 01156 01157 BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp) 01158 { 01159 SetTableSize(m_bLargeTable); 01160 01161 if (m_pTable == NULL) 01162 return(FALSE); 01163 01164 GDrawContext *pContext = GRenderRegion::GetStaticDrawContext(); 01165 01166 // If we are a large table then build it ourself 01167 if (IsLarge()) 01168 { 01169 const INT32 Length = GetTableLength(pContext, IsLarge()); 01170 01171 const INT32 TranspIncrement = ((EndTransp - StartTransp) << 24) / Length; 01172 01173 INT32 Transp = StartTransp; 01174 INT32 Index; 01175 01176 for (Index = 0; Index < Length; Index++) 01177 { 01178 m_pTable->Table[Index] = (Transp >> 24) & 0xFF; 01179 Transp += TranspIncrement; 01180 } 01181 01182 return(TRUE); 01183 } 01184 else 01185 { 01186 // Otherwise get a GDrawContext to build it 01187 return(pContext->BuildTransparencyTable(StartTransp, EndTransp, m_pTable)); 01188 } 01189 } 01190 01191 01192 01193 /******************************************************************************************** 01194 01195 > BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01196 01197 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01198 Created: 9/2/2000 01199 Inputs: - 01200 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp that reflects 01201 the supplied BiasGain values. 01202 Errors: - 01203 01204 ********************************************************************************************/ 01205 01206 BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01207 { 01208 SetTableSize(FALSE); 01209 01210 if (m_pTable == NULL) 01211 return(FALSE); 01212 01213 GDrawContext *pContext = GRenderRegion::GetStaticDrawContext(); 01214 01215 const INT32 Length = GetTableLength(pContext, FALSE); 01216 const double RLength = 1.0/Length; 01217 BiasGain.SetIntervals (AFp (0), AFp (Length)); 01218 01219 double MixFraction; 01220 double temp; 01221 INT32 Index; 01222 01223 for (Index = 0; Index < Length; Index++) 01224 { 01225 MixFraction = BiasGain.MapInterval( AFp( Index ) ); 01226 MixFraction *= RLength; 01227 temp = StartTransp * (1-MixFraction); 01228 temp += (EndTransp * MixFraction); 01229 m_pTable->Table[Index] = static_cast<BYTE> ( temp ); 01230 } 01231 01232 return(TRUE); 01233 } 01234 01235 01236 /******************************************************************************************** 01237 01238 > BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable) 01239 01240 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01241 Created: 12/3/97 01242 Inputs: StartTransp = the current start transparency level 01243 EndTransp = the current end transparency level 01244 pTranspTable = all the inbetween transparency table levels. 01245 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp with inbetween 01246 transparency levels held in pTranspTable 01247 Errors: - 01248 01249 ********************************************************************************************/ 01250 01251 BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable) 01252 { 01253 TranspRampItem *pTTI=NULL; 01254 if (pTranspTable!=NULL) 01255 pTTI=pTranspTable->GetFirstTransp(); 01256 01257 if (pTTI==NULL) 01258 return BuildTable(StartTransp,EndTransp); 01259 01260 SetTableSize(m_bLargeTable); 01261 01262 if (m_pTable == NULL) 01263 return FALSE; 01264 01265 INT32 ei, si=0; 01266 INT32 end, start=StartTransp; 01267 01268 GDrawContext *pContext = GRenderRegion::GetStaticDrawContext(); 01269 const INT32 Length = GetTableLength(pContext, IsLarge()); 01270 01271 while (pTTI) 01272 { 01273 ei = (INT32)((pTTI->GetPosition() * (Length-1)) + 0.5); 01274 end = pTTI->GetTransparency(); 01275 FillSection(si,ei,start,end); 01276 si = ei; 01277 start = end; 01278 pTTI = pTranspTable->GetNextTransp(pTTI); 01279 } 01280 ei = Length-1; 01281 end = EndTransp; 01282 FillSection(si,ei,start,end); 01283 01284 return TRUE; 01285 } 01286 01287 01288 01289 /******************************************************************************************** 01290 01291 > BOOL TranspGradTable::BuildHighQualityRepeatTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01292 01293 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01294 Created: 21/7/2000 01295 Inputs: StartTransp = the current start transparency level 01296 EndTransp = the current end transparency level 01297 BiasGain = the profile to build for 01298 Purpose: Builds a high quality repeating TransparentGradTable from StartTransp to 01299 EndTransp that reflects the supplied BiasGain values. 01300 Errors: - 01301 01302 ********************************************************************************************/ 01303 01304 BOOL TranspGradTable::BuildHighQualityRepeatTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01305 { 01306 SetTableSize(TRUE); 01307 01308 if (m_pTable == NULL) 01309 { 01310 return FALSE; 01311 } 01312 01313 GDrawContext *pContext = GRenderRegion::GetStaticDrawContext(); 01314 01315 INT32 TableLength = GetTableLength (pContext, IsLarge ()); 01316 INT32 halfTableLength = TableLength/2; 01317 01318 double MixFraction = 0.0; 01319 double temp; 01320 double res; 01321 INT32 Index; 01322 01323 BOOL secondHalf = FALSE; 01324 INT32 secondHalfVal =0; 01325 01326 BiasGain.SetIntervals (AFp (0), AFp (halfTableLength)); 01327 01328 for (Index = 0; Index < TableLength; Index++) 01329 { 01330 if (!secondHalf) 01331 { 01332 res = BiasGain.MapInterval( AFp( Index) ); 01333 } 01334 else 01335 { 01336 res = BiasGain.MapInterval( AFp( secondHalfVal) ); 01337 } 01338 01339 MixFraction = res / (halfTableLength); 01340 temp = StartTransp * (1-MixFraction); 01341 temp += (EndTransp * MixFraction); 01342 m_pTable->Table[Index] = static_cast<BYTE> ( temp ); 01343 01344 if (!(Index < halfTableLength)) 01345 { 01346 secondHalfVal = TableLength - Index; 01347 secondHalf = TRUE; 01348 } 01349 } 01350 01351 return (TRUE); 01352 } 01353 01354 01355 /******************************************************************************************** 01356 01357 > BOOL TranspGradTable::BuildHighQualityRepeatTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable) 01358 01359 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01360 Created: 21/7/2000 01361 Inputs: StartTransp = the current start transparency level 01362 EndTransp = the current end transparency level 01363 pTranspTable = the ramp to build for 01364 Purpose: Builds a high quality repeating TransparentGradTable from StartTransp to 01365 EndTransp. 01366 Errors: - 01367 01368 ********************************************************************************************/ 01369 01370 BOOL TranspGradTable::BuildHighQualityRepeatTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable) 01371 { 01372 if (!pTranspTable) 01373 { 01374 SetTableSize(TRUE); 01375 01376 if (m_pTable == NULL) 01377 return FALSE; 01378 01379 GDrawContext *pContext = GRenderRegion::GetStaticDrawContext(); 01380 01381 INT32 TableLength = GetTableSize (pContext, IsLarge ()); 01382 01383 double MixFraction = 0.0; 01384 double MixStep = 2.0/TableLength; 01385 double temp; 01386 01387 for (INT32 Index = 0; (Index<<1) < TableLength; Index++) 01388 { 01389 //MixFraction = BiasGain.MapInterval( AFp( Index ) ); 01390 //MixFraction /= Length; 01391 temp = StartTransp * (1-MixFraction); 01392 temp += (EndTransp * MixFraction); 01393 m_pTable->Table[Index] = 01394 m_pTable->Table[TableLength-Index-1] = static_cast<BYTE> ( temp ); 01395 01396 MixFraction += MixStep; 01397 } 01398 } 01399 else 01400 { 01401 ERROR3 ("Attempt to build a multi-stage transparent fill - NOT fully implemented yet!"); 01402 } 01403 01404 return TRUE; 01405 } 01406 01407 /******************************************************************************************** 01408 01409 > BOOL TranspGradTable::BuildTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01410 01411 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> (modified by CGS) 01412 Created: 24/10/96 (15/2/2000) 01413 Inputs: - 01414 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp 01415 This function forces the table to be 256 entries (for bitmap transparency) 01416 The function now (also) takes into account the applied transparency profile. 01417 Errors: - 01418 01419 ********************************************************************************************/ 01420 01421 BOOL TranspGradTable::BuildBitmapTable(INT32 StartTransp, INT32 EndTransp, CProfileBiasGain& BiasGain) 01422 { 01423 if (m_pTable != NULL) 01424 { 01425 CCFree(m_pTable); 01426 m_pTable = NULL; 01427 } 01428 01429 m_pTable = (TransparentGradTable*) CCMalloc(256); 01430 01431 if (m_pTable == NULL) 01432 return(FALSE); 01433 01434 const INT32 Length = 0x100; 01435 DWORD Index; 01436 01437 CProfileBiasGain DefaultBiasGain; 01438 01439 // make some optimisation decisions .... 01440 01441 if (!(BiasGain == DefaultBiasGain)) 01442 { 01443 double MixFraction; 01444 double temp; 01445 double RLength = 1.0/Length; 01446 01447 BiasGain.SetIntervals (AFp (0), AFp (0x100)); 01448 01449 for (Index= 0; Index < 0x100; Index++) 01450 { 01451 MixFraction = BiasGain.MapInterval( AFp( Index ) ); 01452 MixFraction *= RLength; 01453 01454 temp = StartTransp * (1-MixFraction); 01455 temp += (EndTransp * MixFraction); 01456 01457 m_pTable->Table[Index] = static_cast<BYTE> ( temp ); 01458 } 01459 01460 if (BiasGain.GetIsAFeatherProfile ()) 01461 { 01462 // were a feather profile - we need to do a bit of extra work to ensure that ilans 01463 // feather renders correctly. We MUST ensure that ilans white part of the bitmap 01464 // is rendered as 100% transparent. The following lines of code do this .... 01465 01466 // TODO: (Gavin) Why on earth is this setting Index-2 and Index-1 to 255 01467 // when the code below overwrites Index-2 anyway? 01468 m_pTable->Table[Index-2] = static_cast<BYTE> ( 255 ); 01469 m_pTable->Table[Index-1] = static_cast<BYTE> ( 255 ); 01470 } 01471 } 01472 else 01473 { 01474 INT32 Transp = (StartTransp << 24) + 0x00800000; 01475 INT32 TranspStep = (EndTransp - StartTransp) * 0x010101; 01476 BYTE *pTransp = &(m_pTable->Table[0]); 01477 01478 for (Index= 0; Index < 0x100; Index++) 01479 { 01480 pTransp[Index] = (BYTE)((Transp >> 24) & 0xFF); 01481 Transp += TranspStep; 01482 } 01483 } 01484 01485 // TODO: (Gavin) Why on earth is this setting 0xFE and not 0xFF? 01486 m_pTable->Table[0xFE] = static_cast <BYTE> ( EndTransp ); 01487 01488 return(TRUE); 01489 } 01490 01491 01492 01493 /******************************************************************************************** 01494 01495 > BOOL TranspGradTable::BuildBitmapTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable, CProfileBiasGain& BiasGain) 01496 01497 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> (modified by CGS) 01498 Created: 12/3/97 (15/2/2000) 01499 Inputs: - 01500 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp 01501 This function forces the table to be 256 entries (for bitmap transparency) 01502 The function now (also) takes into account the applied transparency profile. 01503 Errors: - 01504 01505 ********************************************************************************************/ 01506 01507 BOOL TranspGradTable::BuildBitmapTable(INT32 StartTransp, INT32 EndTransp, TransparencyRamp *pTranspTable, CProfileBiasGain& BiasGain) 01508 { 01509 TranspRampItem *pTTI=NULL; 01510 if (pTranspTable!=NULL) 01511 pTTI=pTranspTable->GetFirstTransp(); 01512 01513 if (pTTI==NULL) 01514 { 01515 return BuildBitmapTable(StartTransp, EndTransp, BiasGain); 01516 } 01517 01518 if (m_pTable != NULL) 01519 { 01520 CCFree(m_pTable); 01521 m_pTable = NULL; 01522 } 01523 01524 m_pTable = (TransparentGradTable*) CCMalloc(256); 01525 if (m_pTable == NULL) 01526 return(FALSE); 01527 01528 INT32 ei, si=0; 01529 INT32 end, start = StartTransp; 01530 while (pTTI) 01531 { 01532 ei = (INT32)(pTTI->GetPosition()*255.0 + 0.5); 01533 end = pTTI->GetTransparency(); 01534 FillSection(si,ei,start,end); 01535 si = ei; 01536 start = end; 01537 pTTI = pTranspTable->GetNextTransp(pTTI); 01538 } 01539 end = EndTransp; 01540 FillSection(si,255,start,end); 01541 01542 return TRUE; 01543 } 01544 01545 01546 01547 /******************************************************************************************** 01548 01549 > void TranspGradTable::FillSection(INT32 startindex, INT32 endindex, INT32 starttransp, INT32 endtransp) 01550 01551 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01552 Created: 14/9/94 01553 Inputs: StartIndex, EndIndex = range of indexes to fill 01554 starttransp 01555 endtransp 01556 Purpose: Builds a TransparentGradTable from StartTransp to EndTransp with inbetween 01557 transparency levels held in pTranspTable 01558 Errors: - 01559 01560 ********************************************************************************************/ 01561 01562 void TranspGradTable::FillSection(INT32 startindex, INT32 endindex, INT32 starttransp, INT32 endtransp) 01563 { 01564 INT32 den = endindex-startindex; 01565 if (den<0) 01566 return; 01567 01568 if (den==0) 01569 { 01570 m_pTable->Table[endindex] = (UINT32)endtransp; 01571 } 01572 else 01573 { 01574 INT32 t = (starttransp<<22) + 0x00200000; 01575 INT32 inc = ((endtransp-starttransp)<<22) / den; 01576 for (INT32 i=startindex; i<=endindex; i++) 01577 { 01578 m_pTable->Table[i] = (t>>22) & 0xFF; 01579 t+=inc; 01580 } 01581 } 01582 } 01583 01584 01585 01586 /******************************************************************************************** 01587 01588 > GradTable32::GradTable32() 01589 01590 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01591 Created: 14/9/94 01592 Purpose: Default constructor for a GradTable32 01593 Errors: - 01594 01595 ********************************************************************************************/ 01596 01597 GradTable32::GradTable32() 01598 { 01599 } 01600 01601 01602 /******************************************************************************************** 01603 01604 > GradTable32::~GradTable32() 01605 01606 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01607 Created: 16/10/96 01608 Purpose: Destructor for a GradTable32 01609 01610 ********************************************************************************************/ 01611 01612 GradTable32::~GradTable32() 01613 { 01614 } 01615 01616 /******************************************************************************************** 01617 01618 > void GradTable32::SetTableSize(BOOL LargeTable = FALSE) 01619 01620 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01621 Created: 14/5/96 01622 01623 Inputs: NewSize - The new size (number of entries) in this table. 01624 May only be 0x100 or 0x800 01625 01626 Purpose: To set the size of this Grad table 01627 01628 Notes: The default table size is 0x100 entries 01629 01630 ********************************************************************************************/ 01631 01632 void GradTable32::SetTableSize(BOOL LargeTable) 01633 { 01634 } 01635 01636 01637 01638 /******************************************************************************************** 01639 01640 > BOOL GradTable32::BuildTable(DocColour &StartCol, DocColour &EndCol, 01641 View *ContextView, EFFECTTYPE Effect, 01642 DWORD TableSize = 0x100) 01643 01644 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Will) 01645 Created: 14/5/96 (14/9/94) 01646 01647 Inputs: StartCol, EndCol - Define the end colours of the graduation 01648 ContextView - Points to the view in which the gradation is to be displayed. 01649 (This is necessary for correction and separation etc. If proper 01650 colour handling is not needed, then you may pass NULL, but 01651 generally, this parameter should be sensible) 01652 01653 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01654 01655 TableSize - The number of entries you wish to make the table (0x100 or 01656 0x800) 01657 01658 Returns: FALSE if it fails 01659 01660 Purpose: Builds a GradTable from StartCol to EndCol, filling in the entire 01661 table with appropriate GDraw dither patterns. 01662 01663 == NOTE that this version of the call also implicitly sets the table size! == 01664 01665 SeeAlso: GradTable::SetTableSize 01666 01667 ********************************************************************************************/ 01668 01669 BOOL GradTable32::BuildTable(DocColour &StartCol, DocColour &EndCol, 01670 View *ContextView, EFFECTTYPE Effect, 01671 DWORD TableSize) 01672 { 01673 ERROR3("GradTable32::BuildTable() is rampant so don't use it\n"); 01674 01675 return(FALSE); 01676 /* 01677 SetTableSize(TableSize); 01678 01679 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, 01680 0, Table.Length, 01681 (void *)Table.Table, TRUE)); 01682 */ 01683 } 01684 01685 01686 01687 /******************************************************************************************** 01688 01689 > BOOL GradTable32::BuildTable(DocColour &StartCol, DocColour &EndCol, 01690 View *ContextView, EFFECTTYPE Effect, 01691 DWORD FirstEntry, DWORD LastEntry) 01692 01693 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Will) 01694 Created: 14/5/96 (14/9/94) 01695 01696 Inputs: StartCol, EndCol - Define the end colours of the graduation 01697 ContextView - Points to the view in which the gradation is to be displayed. 01698 (This is necessary for correction and separation etc. If proper 01699 colour handling is not needed, then you may pass NULL, but 01700 generally, this parameter should be sensible) 01701 01702 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01703 01704 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 01705 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 01706 (i.e. to fill entire table use (0,TableSize) which will fill in entries 01707 0..Tablesize-1) 01708 01709 Returns: FALSE if it fails 01710 01711 Purpose: Builds a GradTable from StartCol to EndCol, filling in a portion of the 01712 table with appropriate GDraw dither patterns 01713 01714 Notes: GDraw requires the Start and End colours for the entire table to be 01715 set separately in the table structure. These will be set if FirstEntry==0 01716 and/or if LastEntry==TableSize, respectively. 01717 01718 SeeAlso: GradTable::SetTableSize 01719 01720 ********************************************************************************************/ 01721 01722 BOOL GradTable32::BuildTable(DocColour &StartCol, DocColour &EndCol, 01723 View *ContextView, EFFECTTYPE Effect, 01724 DWORD FirstEntry, DWORD LastEntry) 01725 { 01726 ERROR3("GradTable32::BuildTable() is rampant so don't use it\n"); 01727 01728 return(FALSE); 01729 /* 01730 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, 01731 FirstEntry, LastEntry, 01732 (void *)Table.Table, TRUE)); 01733 */ 01734 } 01735 01736 01737 01738 /******************************************************************************************** 01739 01740 > static BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01741 View *ContextView, EFFECTTYPE Effect, 01742 DWORD TableSize, COLORREF *pTable) 01743 01744 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01745 Created: 14/5/96 01746 01747 Inputs: StartCol, EndCol - Define the end colours of the graduation 01748 ContextView - Points to the view in which the gradation is to be displayed. 01749 (This is necessary for correction and separation etc. If proper 01750 colour handling is not needed, then you may pass NULL, but 01751 generally, this parameter should be sensible) 01752 01753 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01754 01755 TableSize - Number of entries in the table 01756 01757 Outputs: pTable - On return, will be filled in with appropriate colours 01758 01759 Returns: FALSE if it fails 01760 01761 Purpose: Builds a Graduated Table, filling in the given table with COLORREF 01762 entries. The entries will be colour corrected and/or separated as 01763 appropriate to the context view. 01764 01765 Errors: - 01766 01767 ********************************************************************************************/ 01768 01769 BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01770 View *ContextView, EFFECTTYPE Effect, 01771 DWORD TableSize, COLORREF *pTable) 01772 { 01773 CProfileBiasGain DefaultBiasGain; // we need a 'default' profile so we call 01774 // standardise the following call .... 01775 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, 0, TableSize, 01776 (void *) pTable, TRUE, DefaultBiasGain)); 01777 } 01778 01779 01780 01781 /******************************************************************************************** 01782 01783 > static BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01784 View *ContextView, EFFECTTYPE Effect, 01785 DWORD FirstEntry, DWORD LastEntry, 01786 COLORREF *pTable) 01787 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01788 Created: 14/5/96 01789 01790 Inputs: StartCol, EndCol - Define the end colours of the graduation 01791 ContextView - Points to the view in which the gradation is to be displayed. 01792 (This is necessary for correction and separation etc. If proper 01793 colour handling is not needed, then you may pass NULL, but 01794 generally, this parameter should be sensible) 01795 01796 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01797 01798 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 01799 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 01800 (i.e. to fill entire table use (0,TableSize) which will fill in entries 01801 0..Tablesize-1) 01802 01803 Outputs: pTable - On return, will be filled in with appropriate colours 01804 01805 Returns: FALSE if it fails 01806 01807 Purpose: Builds a Graduated Table from StartCol to EndCol, filling in the given 01808 table with COLORREF entries. The entries will be colour corrected 01809 and/or separated as appropriate to the context view. 01810 01811 Errors: Out of memory 01812 01813 ********************************************************************************************/ 01814 01815 BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01816 View *ContextView, EFFECTTYPE Effect, 01817 DWORD FirstEntry, DWORD LastEntry, 01818 COLORREF *pTable) 01819 { 01820 CProfileBiasGain DefaultBiasGain; // we need a 'default' profile so we call 01821 // standardise the following call .... 01822 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, FirstEntry, LastEntry, 01823 (void *) pTable, TRUE, DefaultBiasGain)); 01824 } 01825 01826 01827 01828 /******************************************************************************************** 01829 01830 > static BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01831 View *ContextView, EFFECTTYPE Effect, 01832 DWORD TableSize, RGBQUAD *pTable) 01833 01834 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01835 Created: 14/5/96 01836 01837 Inputs: StartCol, EndCol - Define the end colours of the graduation 01838 ContextView - Points to the view in which the gradation is to be displayed. 01839 (This is necessary for correction and separation etc. If proper 01840 colour handling is not needed, then you may pass NULL, but 01841 generally, this parameter should be sensible) 01842 01843 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01844 01845 TableSize - Number of entries in the table 01846 01847 Outputs: pTable - On return, will be filled in with appropriate colours 01848 01849 Returns: FALSE if it fails 01850 01851 Purpose: Builds a Graduated Table, filling in the given table with RGBQUAD 01852 entries. The entries will be colour corrected and/or separated as 01853 appropriate to the context view. 01854 01855 Errors: - 01856 01857 ********************************************************************************************/ 01858 01859 BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01860 View *ContextView, EFFECTTYPE Effect, 01861 DWORD TableSize, RGBQUAD *pTable) 01862 { 01863 CProfileBiasGain DefaultBiasGain; // we need a 'default' profile so we call 01864 // standardise the following call .... 01865 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, 0, TableSize, 01866 (void *) pTable, FALSE, DefaultBiasGain)); 01867 } 01868 01869 01870 01871 /******************************************************************************************** 01872 01873 > static BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01874 View *ContextView, EFFECTTYPE Effect, 01875 DWORD TableSize, RGBQUAD *pTable, 01876 CProfileBiasGain& BiasGain) 01877 01878 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 01879 Created: 14/2/2000 01880 01881 Inputs: StartCol, EndCol - Define the end colours of the graduation 01882 ContextView - Points to the view in which the gradation is to be displayed. 01883 (This is necessary for correction and separation etc. If proper 01884 colour handling is not needed, then you may pass NULL, but 01885 generally, this parameter should be sensible) 01886 01887 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01888 01889 TableSize - Number of entries in the table 01890 01891 BiasGain - The biasgain profile that is to alter the table 01892 01893 Outputs: pTable - On return, will be filled in with appropriate colours 01894 01895 Returns: FALSE if it fails 01896 01897 Purpose: Builds a Graduated Table, filling in the given table with RGBQUAD 01898 entries (taking into account the biasgain). The entries will be colour 01899 corrected and/or separated as appropriate to the context view. 01900 01901 Errors: - 01902 01903 ********************************************************************************************/ 01904 01905 BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01906 View *ContextView, EFFECTTYPE Effect, 01907 DWORD TableSize, RGBQUAD *pTable, 01908 CProfileBiasGain& BiasGain) 01909 { 01910 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, 0, TableSize, 01911 (void *) pTable, FALSE, BiasGain)); 01912 } 01913 01914 01915 01916 /******************************************************************************************** 01917 01918 > static BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01919 View *ContextView, EFFECTTYPE Effect, 01920 DWORD FirstEntry, DWORD LastEntry, 01921 RGBQUAD *pTable) 01922 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01923 Created: 14/5/96 01924 01925 Inputs: StartCol, EndCol - Define the end colours of the graduation 01926 ContextView - Points to the view in which the gradation is to be displayed. 01927 (This is necessary for correction and separation etc. If proper 01928 colour handling is not needed, then you may pass NULL, but 01929 generally, this parameter should be sensible) 01930 01931 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01932 01933 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 01934 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 01935 (i.e. to fill entire table use (0,TableSize) which will fill in entries 01936 0..Tablesize-1) 01937 01938 Outputs: pTable - On return, will be filled in with appropriate colours 01939 01940 Returns: FALSE if it fails 01941 01942 Purpose: Builds a Graduated Table from StartCol to EndCol, filling in the given 01943 table with RGBQUAD entries. The entries will be colour corrected 01944 and/or separated as appropriate to the context view. 01945 01946 Errors: Out of memory 01947 01948 ********************************************************************************************/ 01949 01950 BOOL GradTable32::BuildGraduatedPalette(DocColour &StartCol, DocColour &EndCol, 01951 View *ContextView, EFFECTTYPE Effect, 01952 DWORD FirstEntry, DWORD LastEntry, 01953 RGBQUAD *pTable) 01954 { 01955 CProfileBiasGain DefaultBiasGain; // we need a 'default' profile so we call 01956 // standardise the following call .... 01957 return(BuildPaletteInternal(StartCol, EndCol, ContextView, Effect, FirstEntry, LastEntry, 01958 (void *) pTable, FALSE, DefaultBiasGain)); 01959 } 01960 01961 01962 01963 /******************************************************************************************** 01964 01965 > static BOOL GradTable32::BuildPaletteInternal(DocColour &StartCol, DocColour &EndCol, 01966 View *ContextView, EFFECTTYPE Effect, 01967 DWORD FirstEntry, DWORD LastEntry, 01968 void *pTable, BOOL IsColorRef) 01969 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01970 Created: 14/5/96 01971 01972 Inputs: StartCol, EndCol - Define the end colours of the graduation 01973 ContextView - Points to the view in which the gradation is to be displayed. 01974 (This is necessary for correction and separation etc. If proper 01975 colour handling is not needed, then you may pass NULL, but 01976 generally, this parameter should be sensible) 01977 01978 Effect - EFFECT_FADE, EFFECT_HSV_SHORT, or EFFECT_HSV_LONG 01979 01980 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 01981 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 01982 (i.e. to fill entire table use (0,TableSize) which will fill in entries 01983 0..Tablesize-1) 01984 01985 IsColorRef - TRUE if the pTable pointer is a (COLORREF *) 01986 FALSE if the pTable pointer is an (RGBQUAD *) 01987 01988 Outputs: pTable - On return, will be filled in with appropriate colours, in the format 01989 indicated by the IsColorRef flag. 01990 01991 Returns: FALSE if it fails 01992 01993 Purpose: Builds a Graduated Table from StartCol to EndCol, filling in the given 01994 table with either COLORREF or RGBQUAD entries. 01995 The entries will be colour corrected and/or separated as appropriate to 01996 the context view. 01997 01998 This is an internal shared function used by all the other GradTable32 01999 grad palette building methods 02000 02001 Notes: This routine supplies a simple, generic mixing loop. However, for normal 02002 (no colour plate) rendering, this function will call the other internal 02003 methods which are optimised for specific cases - this gives about a 3x 02004 performance enhancement for normal rendering. 02005 02006 Errors: Out of memory 02007 02008 ********************************************************************************************/ 02009 02010 BOOL GradTable32::BuildPaletteInternal(DocColour &StartCol, DocColour &EndCol, 02011 View *ContextView, EFFECTTYPE Effect, 02012 DWORD FirstEntry, DWORD LastEntry, 02013 void *pTable, BOOL IsColorRef, 02014 CProfileBiasGain& BiasGain) 02015 { 02016 ERROR3IF(pTable == NULL, "Illegal NULL param"); 02017 02018 // The range should be withion the table size. We only ERROR3, though, because 02019 // the physical table is always large enough for the maximum number of entries. 02020 ERROR3IF(FirstEntry < 0 || FirstEntry > LastEntry, 02021 "GradTable32::BuildPaletteInternal expects sensible First/Last Entry values"); 02022 02023 // Determine if either the start or end colour is a spot colour - if it is, we must 02024 // coerce the fill into a "mix" (rgb) rather than rainbow fill style 02025 if (Effect != EFFECT_RGB && (StartCol.GetSpotParent() != NULL || EndCol.GetSpotParent() != NULL)) 02026 Effect = EFFECT_RGB; 02027 02028 02029 // --- Optimisation - are we trying to build a simple grad table under normal rendering 02030 // circumstances? If so, special case this to make it as fast as possible. This more than 02031 // doubles the speed of table generation. 02032 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 02033 ERROR3IF(ccRGB == NULL, "GradTable32::BuildPaletteInternal - Can't find my colour context!"); 02034 02035 if (ccRGB->GetColourPlate() == NULL || ccRGB->GetColourPlate()->IsDisabled()) 02036 { 02037 if (Effect == EFFECT_RGB) // RGB mix? 02038 { 02039 return(BuildPaletteInternalRGB(StartCol, EndCol, ContextView, 02040 FirstEntry, LastEntry, pTable, IsColorRef, BiasGain)); 02041 } 02042 02043 // HSV (rainbow) mix 02044 return(BuildPaletteInternalHSV(StartCol, EndCol, ContextView, Effect, 02045 FirstEntry, LastEntry, pTable, IsColorRef, BiasGain)); 02046 } 02047 02048 if (Effect == EFFECT_RGB && ccRGB->GetColourPlate()->GetType() == COLOURPLATE_COMPOSITE && 02049 (StartCol.GetColourModel() != COLOURMODEL_CMYK || EndCol.GetColourModel() != COLOURMODEL_CMYK)) 02050 { 02051 return(BuildPaletteInternalRGBComposite(StartCol, EndCol, ContextView, 02052 FirstEntry, LastEntry, pTable, IsColorRef)); 02053 } 02054 02055 02056 // --- OK, we're trying to do something special. Drop back to the generic (slow) code 02057 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; // Cast the table pointer to the two 02058 COLORREF *pRefTable = (COLORREF *) pTable; // possible types 02059 02060 // Get colour contexts: we need 2 - first, an RGB context (got above) for the ContextView, which 02061 // will be used to get colour-corrected/separated/etc output colour in RGB; and second, 02062 // a generic RGB or HSV context to provide a "mixing colourspace" for the graduations. 02063 ColourContext *cc = NULL; 02064 02065 if (Effect == EFFECT_RGB) 02066 cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 02067 else 02068 cc = ColourManager::GetColourContext(COLOURMODEL_HSVT); // HSV fade 02069 02070 // If we can't find RGB/HSV contexts, something is seriously broken 02071 ERROR3IF(cc == NULL, "GradTable32::BuildPaletteInternal - Can't find my colour context!"); 02072 02073 // Fill in the Start and End colours of the table, if we've hit them 02074 PColourRGBT Result; 02075 02076 // And build our graduated palette 02077 double MixFraction = 0.0; 02078 double MixStep = 1.0 / (double) (LastEntry - FirstEntry - 1); 02079 02080 DocColour temp; 02081 02082 for (DWORD col = FirstEntry; col < LastEntry; col++) 02083 { 02084 // Create a new colour which is an appropriate mixture of the start/end colours 02085 temp.Mix(&StartCol, &EndCol, MixFraction, cc, (Effect == EFFECT_HSV_LONG), ccRGB); 02086 02087 // Convert back to the raw RGB and place it in the palette. 02088 // Note that this will colour correct and separate in an appropriate manner. 02089 // Note also that we're using a special ConvertColour call which returns 8-bit 02090 // "packed" component values instead of FIXED24's. 02091 ccRGB->ConvertColour(&temp, (ColourPacked *) &Result); 02092 02093 // And add to the table 02094 if (IsColorRef) 02095 { 02096 pRefTable[col] = RGB(Result.Red, Result.Green, Result.Blue); 02097 } 02098 else 02099 { 02100 pRGBTable[col].rgbRed = Result.Red; 02101 pRGBTable[col].rgbGreen = Result.Green; 02102 pRGBTable[col].rgbBlue = Result.Blue; 02103 pRGBTable[col].rgbReserved = 0; 02104 } 02105 02106 // And step to the next mix fraction value 02107 MixFraction += MixStep; 02108 } 02109 02110 return(TRUE); 02111 } 02112 02113 02114 02115 /******************************************************************************************** 02116 02117 > static BOOL GradTable32::BuildPaletteInternalRGB(DocColour &StartCol, DocColour &EndCol, 02118 View *ContextView, 02119 DWORD FirstEntry, DWORD LastEntry, 02120 void *pTable, BOOL IsColorRef, 02121 CProfileBiasGain& BiasGain) 02122 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02123 Created: 10/9/96 02124 02125 Inputs: StartCol, EndCol - Define the end colours of the graduation 02126 ContextView - Points to the view in which the gradation is to be displayed. 02127 (This is necessary for correction and separation etc. If proper 02128 colour handling is not needed, then you may pass NULL, but 02129 generally, this parameter should be sensible) 02130 02131 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 02132 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 02133 (i.e. to fill entire table use (0,TableSize) which will fill in entries 02134 0..Tablesize-1) 02135 02136 IsColorRef - TRUE if the pTable pointer is a (COLORREF *) 02137 FALSE if the pTable pointer is an (RGBQUAD *) 02138 02139 BiasGain - The profile that controls how the table is built 02140 02141 Outputs: pTable - On return, will be filled in with appropriate colours, in the format 02142 indicated by the IsColorRef flag. 02143 02144 Returns: FALSE if it fails 02145 02146 Purpose: Builds a Graduated (RGB Mix) Table from StartCol to EndCol, filling in the given 02147 table with either COLORREF or RGBQUAD entries. 02148 02149 NOTE that the generated entries will NOT be colour corrected or separated in 02150 any way. You should not use this code when generating colour plates. 02151 02152 ********************************************************************************************/ 02153 02154 BOOL GradTable32::BuildPaletteInternalRGB(DocColour &StartCol, DocColour &EndCol, 02155 View *ContextView, 02156 DWORD FirstEntry, DWORD LastEntry, 02157 void *pTable, BOOL IsColorRef, CProfileBiasGain& BiasGain) 02158 { 02159 ERROR3IF(ContextView == NULL || pTable == NULL, "Illegal NULL params"); 02160 02161 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 02162 ERROR3IF(ccRGB == NULL, "No colour context"); 02163 02164 PColourRGBT StartDef; 02165 PColourRGBT EndDef; 02166 02167 if (StartCol.IsTransparent()) 02168 StartDef.Red = StartDef.Green = StartDef.Blue = 255L; // If transparent, use white 02169 else 02170 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &StartDef); 02171 02172 if (EndCol.IsTransparent()) 02173 EndDef.Red = EndDef.Green = EndDef.Blue = 255L; // If transparent, use white 02174 else 02175 ccRGB->ConvertColour(&EndCol, (ColourPacked *) &EndDef); 02176 02177 // Precalculate mixing fraction and step to minimise mul/div in the inner loop 02178 // We use an 8.24 bit fixed point notation (homebrew FIXED24s) 02179 DWORD MixStep = (1 << 24) / (LastEntry - FirstEntry); 02180 DWORD MixFraction = 0; 02181 02182 if (IsColorRef) 02183 { 02184 COLORREF *pRefTable = (COLORREF *) pTable; 02185 02186 DWORD R,G,B; 02187 for (DWORD col = FirstEntry; col < LastEntry; col++) 02188 { 02189 const DWORD InvFraction = 0x01000000 - MixFraction; 02190 02191 // Calculate intermediate RGB values into 8bpp values 02192 R = ((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction)) >> 24; 02193 G = ((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction)) >> 24; 02194 B = ((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction)) >> 24; 02195 02196 // Fill in this table entry 02197 pRefTable[col] = RGB(R, G, B); 02198 02199 MixFraction += MixStep; 02200 } 02201 } 02202 else 02203 { 02204 CProfileBiasGain DefaultBiasGain; // default 02205 if (BiasGain == DefaultBiasGain) 02206 { 02207 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; 02208 02209 DWORD InvFraction; 02210 02211 for (DWORD col = FirstEntry; col < LastEntry; col++) 02212 { 02213 InvFraction = 0x01000000 - MixFraction; 02214 02215 // Calculate intermediate RGB values into the 8bpp table values 02216 #if defined(__WXMSW__) 02217 pRGBTable[col].rgbRed = static_cast<BYTE> (((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction)) >> 24); 02218 pRGBTable[col].rgbGreen = static_cast<BYTE> (((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction)) >> 24); 02219 pRGBTable[col].rgbBlue = static_cast<BYTE> (((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction)) >> 24); 02220 #else 02221 pRGBTable[col].rgbBlue = static_cast<BYTE> (((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction)) >> 24); 02222 pRGBTable[col].rgbGreen = static_cast<BYTE> (((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction)) >> 24); 02223 pRGBTable[col].rgbRed = static_cast<BYTE> (((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction)) >> 24); 02224 #endif 02225 pRGBTable[col].rgbReserved = 0; 02226 02227 MixFraction += MixStep; 02228 } 02229 } 02230 else 02231 { 02232 BiasGain.SetIntervals (AFp (0), AFp (LastEntry)); 02233 02234 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; 02235 02236 double MixFraction; 02237 double InvFraction; 02238 double RLastEntry = 1.0/LastEntry; 02239 02240 for (DWORD col = FirstEntry; col < LastEntry; col++) 02241 { 02242 MixFraction = (INT32) BiasGain.MapInterval( AFp( col ) ); 02243 MixFraction *= RLastEntry; 02244 InvFraction = 1 - MixFraction; 02245 02246 // Calculate intermediate RGB values into the 8bpp table values 02247 #if defined(__WXMSW__) 02248 pRGBTable[col].rgbRed = static_cast<BYTE> (((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction))); 02249 pRGBTable[col].rgbGreen = static_cast<BYTE> (((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction))); 02250 pRGBTable[col].rgbBlue = static_cast<BYTE> (((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction))); 02251 #else 02252 pRGBTable[col].rgbBlue = static_cast<BYTE> (((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction))); 02253 pRGBTable[col].rgbGreen = static_cast<BYTE> (((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction))); 02254 pRGBTable[col].rgbRed = static_cast<BYTE> (((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction))); 02255 #endif 02256 pRGBTable[col].rgbReserved = 0; 02257 } 02258 } 02259 } 02260 02261 return(TRUE); 02262 } 02263 02264 02265 02266 /******************************************************************************************** 02267 02268 > static BOOL GradTable32::BuildPaletteInternalHSV(DocColour &StartCol, DocColour &EndCol, 02269 View *ContextView, EFFECTTYPE Effect, 02270 DWORD FirstEntry, DWORD LastEntry, 02271 void *pTable, BOOL IsColorRef, CProfileBiasGain& BiasGain) 02272 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02273 Created: 10/9/96 02274 02275 Inputs: StartCol, EndCol - Define the end colours of the graduation 02276 ContextView - Points to the view in which the gradation is to be displayed. 02277 (This is necessary for correction and separation etc. If proper 02278 colour handling is not needed, then you may pass NULL, but 02279 generally, this parameter should be sensible) 02280 02281 Effect - EFFECT_HSV_SHORT or EFFECT_HSV_LONG 02282 02283 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 02284 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 02285 (i.e. to fill entire table use (0,TableSize) which will fill in entries 02286 0..Tablesize-1) 02287 02288 IsColorRef - TRUE if the pTable pointer is a (COLORREF *) 02289 FALSE if the pTable pointer is an (RGBQUAD *) 02290 02291 BiasGain - The profile that controls how the table is built 02292 02293 Outputs: pTable - On return, will be filled in with appropriate colours, in the format 02294 indicated by the IsColorRef flag. 02295 02296 Returns: FALSE if it fails 02297 02298 Purpose: Builds a Graduated (HSV rainbow/alt-rainbow) Table from StartCol to EndCol, filling in 02299 the given table with either COLORREF or RGBQUAD entries. 02300 02301 NOTE that the generated entries will NOT be colour corrected or separated in 02302 any way. You should not use this code when generating colour plates. 02303 02304 ********************************************************************************************/ 02305 02306 BOOL GradTable32::BuildPaletteInternalHSV(DocColour &StartCol, DocColour &EndCol, 02307 View *ContextView, EFFECTTYPE Effect, 02308 DWORD FirstEntry, DWORD LastEntry, 02309 void *pTable, BOOL IsColorRef, CProfileBiasGain& BiasGain) 02310 { 02311 ERROR3IF(ContextView == NULL || pTable == NULL, "Illegal NULL params"); 02312 ERROR3IF(Effect != EFFECT_HSV_SHORT && Effect != EFFECT_HSV_LONG, "Unsupported HSV effect"); 02313 02314 ColourContext *ccHSV = ColourManager::GetColourContext(COLOURMODEL_HSVT, ContextView); 02315 ERROR3IF(ccHSV == NULL, "No colour context"); 02316 02317 PColourHSVT StartDef; 02318 PColourHSVT EndDef; 02319 02320 if (StartCol.IsTransparent()) 02321 { 02322 StartDef.Hue = 0; // If transparent, use white 02323 StartDef.Value = 255; 02324 StartDef.Saturation = 0; 02325 } 02326 else 02327 ccHSV->ConvertColour(&StartCol, (ColourPacked *) &StartDef); 02328 02329 if (EndCol.IsTransparent()) 02330 { 02331 EndDef.Hue = 0; // If transparent, use white 02332 EndDef.Value = 255; 02333 EndDef.Saturation = 0; 02334 } 02335 else 02336 ccHSV->ConvertColour(&EndCol, (ColourPacked *) &EndDef); 02337 02338 // When doing alt-rainbow, if one end colour has no specific hue (saturation near 0) 02339 // then use the other colour's hue (if any) 02340 // 02341 // TODO: WRONG!!! This should always be doing these two tests, not just when 02342 // the Effect equals EFFECT_HSV_LONG. Note also that the INT32 HSV colour 02343 // generation is incorrect, although I'm not too sure why. (Gavin). 02344 // 02345 if (Effect == EFFECT_HSV_LONG) 02346 { 02347 if (StartDef.Saturation < 2 && EndDef.Saturation >= 2) 02348 StartDef.Hue = EndDef.Hue; 02349 else if (StartDef.Saturation >= 2 && EndDef.Saturation < 2) 02350 EndDef.Hue = StartDef.Hue; 02351 } 02352 02353 // Now work out which way we have to do the mix (rainbow or alt-rainbow) 02354 BOOL BlendNormally = TRUE; 02355 02356 // Calc. the "simple" (non-wrapping) distance between the hues 02357 double StartHue = StartDef.Hue / 360.0; 02358 double EndHue = EndDef.Hue / 360.0; 02359 02360 const double SimpleDist = fabs(StartHue - EndHue); 02361 02362 // Determine whether we do a simple blend, or we have to "wrap" 02363 if (SimpleDist <= 0.5) 02364 BlendNormally = (Effect != EFFECT_HSV_LONG); 02365 else 02366 BlendNormally = (Effect == EFFECT_HSV_LONG); 02367 02368 // If we have to go the long way, then move the smaller of the two hue 02369 // values up by 360 degrees (1.0) - after blending we'll 'mod' the result 02370 // back down into gamut. 02371 if (!BlendNormally) 02372 { 02373 if (StartHue > EndHue) 02374 EndHue += 1.0; 02375 else 02376 StartHue += 1.0; 02377 } 02378 02379 // Precalculate mixing fraction and step to minimise mul/div in the inner loop 02380 // We use an 8.24 bit fixed point notation (homebrew FIXED24s) 02381 double MixStep = 1.0 / (double)(LastEntry - FirstEntry); 02382 double MixFraction = 0.0; 02383 02384 if (IsColorRef) 02385 { 02386 COLORREF *pRefTable = (COLORREF *) pTable; 02387 02388 double H, S, V; 02389 for (DWORD col = FirstEntry; col < LastEntry; col++) 02390 { 02391 const double InvFraction = 1.0 - MixFraction; 02392 02393 // Calculate intermediate RGB values into 8bpp values 02394 H = (StartHue * InvFraction) + (EndHue * MixFraction); // 0.0 - 1.0 02395 if (H > 1.0) 02396 H -= 1.0; // If necessary, "mod" the value back down into the 0..1 range 02397 02398 S = ((StartDef.Saturation * InvFraction) + (EndDef.Saturation * MixFraction)) / 255.0; // 0.0 - 1.0 02399 V = (StartDef.Value * InvFraction) + (EndDef.Value * MixFraction); // 0.0 - 255.0 02400 02401 // Convert the HSV value to an RGB table entry 02402 if (S == 0) 02403 { 02404 BYTE Val = (BYTE) V; 02405 pRefTable[col] = RGB(Val, Val, Val); 02406 } 02407 else 02408 { 02409 H *= 6.0; 02410 const INT32 I = (INT32) floor(H); 02411 const double F = H - I; 02412 const double P = V * (1.0 - S); 02413 const double Q = V * (1.0 - (S * F)); 02414 const double T = V * (1.0 - (S * (1.0 - F))); 02415 02416 switch (I) 02417 { 02418 case 1: pRefTable[col] = RGB(BYTE(Q), BYTE(V), BYTE(P)); break; 02419 case 2: pRefTable[col] = RGB(BYTE(P), BYTE(V), BYTE(T)); break; 02420 case 3: pRefTable[col] = RGB(BYTE(P), BYTE(Q), BYTE(V)); break; 02421 case 4: pRefTable[col] = RGB(BYTE(T), BYTE(P), BYTE(V)); break; 02422 case 5: pRefTable[col] = RGB(BYTE(V), BYTE(P), BYTE(Q)); break; 02423 default: pRefTable[col] = RGB(BYTE(V), BYTE(T), BYTE(P)); break; 02424 } 02425 } 02426 02427 MixFraction += MixStep; 02428 } 02429 } 02430 else 02431 { 02432 CProfileBiasGain DefaultBiasGain; // default 02433 if (BiasGain == DefaultBiasGain) 02434 { 02435 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; 02436 02437 double H, S, V; 02438 for (DWORD col = FirstEntry; col < LastEntry; col++) 02439 { 02440 const double InvFraction = 1.0 - MixFraction; 02441 02442 // Calculate intermediate RGB values into 8bpp values 02443 H = (StartHue * InvFraction) + (EndHue * MixFraction); // 0.0 - 1.0 02444 if (H > 1.0) 02445 H -= 1.0; // If necessary, "mod" the value back down into the 0..1 range 02446 02447 S = ((StartDef.Saturation * InvFraction) + (EndDef.Saturation * MixFraction)) / 255.0; // 0.0 - 1.0 02448 V = (StartDef.Value * InvFraction) + (EndDef.Value * MixFraction); // 0.0 - 255.0 02449 02450 // Convert the HSV value to an RGB table entry 02451 if (S == 0) 02452 { 02453 pRGBTable[col].rgbRed = pRGBTable[col].rgbGreen = pRGBTable[col].rgbBlue = (BYTE) V; 02454 } 02455 else 02456 { 02457 H *= 6.0; 02458 const INT32 I = (INT32) floor(H); 02459 const double F = H - I; 02460 const double P = V * (1.0 - S); 02461 const double Q = V * (1.0 - (S * F)); 02462 const double T = V * (1.0 - (S * (1.0 - F))); 02463 02464 // Define a wee macro to make this all a lot more readable 02465 #if 0 02466 #define SETRGBENTRY(P1,P2,P3) pRGBTable[col].rgbRed = (BYTE)P3; pRGBTable[col].rgbGreen = (BYTE)P2; pRGBTable[col].rgbBlue = (BYTE)P1; 02467 #else 02468 #define SETRGBENTRY(P1,P2,P3) pRGBTable[col].rgbRed = (BYTE)P1; pRGBTable[col].rgbGreen = (BYTE)P2; pRGBTable[col].rgbBlue = (BYTE)P3; 02469 #endif 02470 switch (I) 02471 { 02472 case 1: SETRGBENTRY(Q, V, P); break; 02473 case 2: SETRGBENTRY(P, V, T); break; 02474 case 3: SETRGBENTRY(P, Q, V); break; 02475 case 4: SETRGBENTRY(T, P, V); break; 02476 case 5: SETRGBENTRY(V, P, Q); break; 02477 default: SETRGBENTRY(V, T, P); break; 02478 } 02479 #undef SETRGBENTRY 02480 } 02481 02482 pRGBTable[col].rgbReserved = 0; 02483 02484 MixFraction += MixStep; 02485 } 02486 } 02487 else 02488 { 02489 BiasGain.SetIntervals (AFp (0), AFp (LastEntry)); 02490 02491 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; 02492 02493 double MixFraction; 02494 double InvFraction; 02495 double RLastEntry = 1.0/LastEntry; 02496 02497 double H, S, V; 02498 02499 for (DWORD col = FirstEntry; col < LastEntry; col++) 02500 { 02501 //const double InvFraction = 1.0 - MixFraction; 02502 02503 MixFraction = (INT32) BiasGain.MapInterval( AFp( col ) ); 02504 MixFraction *= RLastEntry; 02505 InvFraction = 1 - MixFraction; 02506 02507 // Calculate intermediate RGB values into 8bpp values 02508 H = (StartHue * InvFraction) + (EndHue * MixFraction); // 0.0 - 1.0 02509 if (H > 1.0) 02510 H -= 1.0; // If necessary, "mod" the value back down into the 0..1 range 02511 02512 S = ((StartDef.Saturation * InvFraction) + (EndDef.Saturation * MixFraction)) / 255.0; // 0.0 - 1.0 02513 V = (StartDef.Value * InvFraction) + (EndDef.Value * MixFraction); // 0.0 - 255.0 02514 02515 // Convert the HSV value to an RGB table entry 02516 if (S == 0) 02517 { 02518 pRGBTable[col].rgbRed = pRGBTable[col].rgbGreen = pRGBTable[col].rgbBlue = (BYTE) V; 02519 } 02520 else 02521 { 02522 H *= 6.0; 02523 const INT32 I = (INT32) floor(H); 02524 const double F = H - I; 02525 const double P = V * (1.0 - S); 02526 const double Q = V * (1.0 - (S * F)); 02527 const double T = V * (1.0 - (S * (1.0 - F))); 02528 02529 // Define a wee macro to make this all a lot more readable 02530 #define SETRGBENTRY(P1,P2,P3) pRGBTable[col].rgbRed = (BYTE)P1; pRGBTable[col].rgbGreen = (BYTE)P2; pRGBTable[col].rgbBlue = (BYTE)P3; 02531 switch (I) 02532 { 02533 case 1: SETRGBENTRY(Q, V, P); break; 02534 case 2: SETRGBENTRY(P, V, T); break; 02535 case 3: SETRGBENTRY(P, Q, V); break; 02536 case 4: SETRGBENTRY(T, P, V); break; 02537 case 5: SETRGBENTRY(V, P, Q); break; 02538 default: SETRGBENTRY(V, T, P); break; 02539 } 02540 #undef SETRGBENTRY 02541 } 02542 02543 pRGBTable[col].rgbReserved = 0; 02544 02545 MixFraction += MixStep; 02546 } 02547 } 02548 } 02549 02550 return(TRUE); 02551 } 02552 02553 02554 02555 /******************************************************************************************** 02556 02557 > static BOOL GradTable32::BuildPaletteInternalRGBComposite(DocColour &StartCol, DocColour &EndCol, 02558 View *ContextView, 02559 DWORD FirstEntry, DWORD LastEntry, 02560 void *pTable, BOOL IsColorRef) 02561 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02562 Created: 12/9/96 02563 02564 Inputs: StartCol, EndCol - Define the end colours of the graduation 02565 ContextView - Points to the view in which the gradation is to be displayed. 02566 (This is necessary for correction and separation etc. If proper 02567 colour handling is not needed, then you may pass NULL, but 02568 generally, this parameter should be sensible) 02569 02570 FirstEntry - The index of the first entry (inclusive) to fill in (0 is the first) 02571 LastEntry - The index of the last entry (exclusive) to fill in (TableSize is the last) 02572 (i.e. to fill entire table use (0,TableSize) which will fill in entries 02573 0..Tablesize-1) 02574 02575 IsColorRef - TRUE if the pTable pointer is a (COLORREF *) 02576 FALSE if the pTable pointer is an (RGBQUAD *) 02577 02578 Outputs: pTable - On return, will be filled in with appropriate colours, in the format 02579 indicated by the IsColorRef flag. 02580 02581 Returns: FALSE if it fails 02582 02583 Purpose: Builds a Graduated (RGB Mix) Table from StartCol to EndCol, filling in the given 02584 table with either COLORREF or RGBQUAD entries. 02585 02586 ** The table is constructed taking into account "Composite Print Preview" colour 02587 ** correction. You must only call this when generating a COLOURPLATE_COPMPOSITE 02588 ** colour plate, when doing RGB mixes of non-CMYK colours! 02589 02590 Notes: (Analogue of GradTable code in BuildTable() and Filltable()) 02591 For composite preview, I've only bothered to optimise the RGB mix case, as this 02592 is by far and away the most common one. 02593 02594 SeeAlso: GradTable32::BuildPaletteInternal 02595 02596 ********************************************************************************************/ 02597 02598 BOOL GradTable32::BuildPaletteInternalRGBComposite(DocColour &StartCol, DocColour &EndCol, 02599 View *ContextView, 02600 DWORD FirstEntry, DWORD LastEntry, 02601 void *pTable, BOOL IsColorRef) 02602 { 02603 ERROR3IF(ContextView == NULL || pTable == NULL, "Illegal NULL params"); 02604 02605 ColourContext *ccRGB = ColourManager::GetColourContext(COLOURMODEL_RGBT, ContextView); 02606 ColourContext *cc = ColourManager::GetColourContext(COLOURMODEL_RGBT); // RGB fade 02607 ERROR3IF(cc == NULL || ccRGB == NULL, "No colour context"); 02608 02609 ERROR3IF(ccRGB->GetColourPlate() == NULL || ccRGB->GetColourPlate()->IsDisabled() || 02610 ccRGB->GetColourPlate()->GetType() != COLOURPLATE_COMPOSITE, 02611 "BuildPaletteInternalRGBComposite called under incorrect conditions"); 02612 02613 ERROR3IF(StartCol.GetColourModel() == COLOURMODEL_CMYK && EndCol.GetColourModel() == COLOURMODEL_CMYK, 02614 "BuildPaletteInternalRGBComposite called for CMYK -> CMYK fill!"); 02615 02616 COLORREF *pRefTable = (COLORREF *) pTable; 02617 RGBQUAD *pRGBTable = (RGBQUAD *) pTable; 02618 02619 PColourRGBT StartDef; 02620 PColourRGBT EndDef; 02621 ccRGB->ConvertColour(&StartCol, (ColourPacked *) &EndDef); 02622 02623 DWORD StartIndex = FirstEntry; 02624 DWORD EndIndex; 02625 02626 DocColour TempCol; 02627 02628 while (StartIndex < LastEntry) 02629 { 02630 // Move the last run's end colour into Start 02631 memcpy(&StartDef, &EndDef, sizeof(PColourRGBT)); 02632 02633 // Calculate the end of this run 02634 EndIndex = StartIndex + FillStep; 02635 if (EndIndex > LastEntry) 02636 EndIndex = LastEntry; 02637 02638 // Calculate the colour at the end of this run, and convert into EndDef 02639 TempCol.Mix(&StartCol, &EndCol, 02640 ((double)(EndIndex - FirstEntry)) / ((double)(LastEntry - FirstEntry)), 02641 cc, FALSE, ccRGB); 02642 02643 ccRGB->ConvertColour(&TempCol, (ColourPacked *) &EndDef); 02644 02645 // Linearly interpolate all colours in the run (cf GradTable::FillTable code) 02646 // BLOCK 02647 { 02648 #define MFX 24 02649 02650 // optimised code by Mike 02651 02652 INT32 MixFracR = ((INT32)StartDef.Red) <<MFX; 02653 INT32 MixFracG = ((INT32)StartDef.Green)<<MFX; 02654 INT32 MixFracB = ((INT32)StartDef.Blue) <<MFX; 02655 02656 INT32 MixStepR = ((INT32)(EndDef.Red - StartDef.Red ))<<MFX; 02657 INT32 MixStepG = ((INT32)(EndDef.Green - StartDef.Green))<<MFX; 02658 INT32 MixStepB = ((INT32)(EndDef.Blue - StartDef.Blue ))<<MFX; 02659 02660 MixStepR = MixStepR / ((INT32)(EndIndex-StartIndex)); 02661 MixStepG = MixStepG / ((INT32)(EndIndex-StartIndex)); 02662 MixStepB = MixStepB / ((INT32)(EndIndex-StartIndex)); 02663 02664 if (IsColorRef) 02665 { 02666 for (DWORD Index=StartIndex; Index<EndIndex; Index++) 02667 { 02668 // Calculate intermediate RGB values into 8bpp values 02669 pRefTable[Index] = RGB(MixFracR>>MFX, MixFracG>>MFX, MixFracB>>MFX); 02670 MixFracR += MixStepR; 02671 MixFracG += MixStepG; 02672 MixFracB += MixStepB; 02673 } 02674 } 02675 else 02676 { 02677 for (DWORD Index=StartIndex; Index<EndIndex; Index++) 02678 { 02679 // Calculate intermediate RGB values into 8bpp values 02680 pRGBTable[Index].rgbRed = (BYTE)(MixFracR>>MFX); 02681 pRGBTable[Index].rgbGreen = (BYTE)(MixFracG>>MFX); 02682 pRGBTable[Index].rgbBlue = (BYTE)(MixFracB>>MFX); 02683 pRGBTable[Index].rgbReserved = 0; 02684 MixFracR += MixStepR; 02685 MixFracG += MixStepG; 02686 MixFracB += MixStepB; 02687 } 02688 } 02689 02690 #undef MFX 02691 /* 02692 // Place the StartDef in as the first entry 02693 02694 if (IsColorRef) 02695 pRefTable[StartIndex] = RGB(StartDef.Red, StartDef.Green, StartDef.Blue); 02696 else 02697 { 02698 pRGBTable[StartIndex].rgbRed = StartDef.Red; 02699 pRGBTable[StartIndex].rgbGreen = StartDef.Green; 02700 pRGBTable[StartIndex].rgbBlue = StartDef.Blue; 02701 pRGBTable[StartIndex].rgbReserved = 0; 02702 } 02703 02704 // ...and start interpolating from the second entry 02705 DWORD MixStep = (1 << 24) / (EndIndex - StartIndex); 02706 DWORD MixFraction = MixStep; 02707 02708 DWORD R,G,B; 02709 02710 if (IsColorRef) 02711 { 02712 for (DWORD Index = StartIndex + 1; Index < EndIndex; Index++) 02713 { 02714 // Calculate intermediate RGB values into 8bpp values 02715 const DWORD InvFraction = (0x01000000 - MixFraction); 02716 R = ((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction)) >> 24; 02717 G = ((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction)) >> 24; 02718 B = ((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction)) >> 24; 02719 02720 pRefTable[Index] = RGB(R, G, B); 02721 MixFraction += MixStep; 02722 } 02723 } 02724 else 02725 { 02726 for (DWORD Index = StartIndex + 1; Index < EndIndex; Index++) 02727 { 02728 // Calculate intermediate RGB values into 8bpp values 02729 const DWORD InvFraction = (0x01000000 - MixFraction); 02730 R = ((StartDef.Red * InvFraction) + (EndDef.Red * MixFraction)) >> 24; 02731 G = ((StartDef.Green * InvFraction) + (EndDef.Green * MixFraction)) >> 24; 02732 B = ((StartDef.Blue * InvFraction) + (EndDef.Blue * MixFraction)) >> 24; 02733 02734 // Fill in this table entry 02735 pRGBTable[Index].rgbRed = (BYTE)R; 02736 pRGBTable[Index].rgbGreen = (BYTE)G; 02737 pRGBTable[Index].rgbBlue = (BYTE)B; 02738 pRGBTable[Index].rgbReserved = 0; 02739 02740 MixFraction += MixStep; 02741 } 02742 } 02743 */ 02744 } 02745 02746 // And step on to the next run 02747 StartIndex = EndIndex; 02748 } 02749 02750 return(TRUE); 02751 }