Correction of unstable testing cases
[occt.git] / src / WNT / WNT_GraphicDevice.cxx
CommitLineData
b311480e 1// Copyright (c) 1996-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19/***********************************************************************
20 FONCTION :
21 ----------
22 Classe WNT_GraphicDevice.cxx :
23
24 HISTORIQUE DES MODIFICATIONS :
25 --------------------------------
26 03-01-95 : EUG -> Creation.
27 20-11-97 : FMN -> Portage WIN95
28 MAR-98 : EUG -> Porting Win95
29 JUN-98 : EUG -> Modifications to provide access to this class
30 from CCL (second constructor + Init () method)
31 SEP-98 : DCB -> Avoid memory crash when color indices do not follow
32 each other or do not begin with '1'
33 JAN-99 : EUG -> Modifications to provide treating display window
34 as graphic device
35************************************************************************/
36
37/*----------------------------------------------------------------------*/
38/*
39 * Includes
40 */
41
42// include windows.h first to have all definitions available
43#include <windows.h>
44
45#include <WNT.h>
46#include <WNT_GraphicDevice.ixx>
47#include <Aspect_ColorMapEntry.hxx>
48#include <Aspect_GraphicDriver.hxx>
49#include <Aspect_Units.hxx>
50
51#include <stdio.h>
52
53/*----------------------------------------------------------------------*/
54/*
55 * Constantes
56 */
57
58#define PAL ((PLOGPALETTE)myLogPal)
59#define MAX_PAL_ERROR (3*256*256L)
60#define DEFAULT_GAMMA 1.4
61
62static int __fastcall _createColorRamp ( HPALETTE* );
63static BOOL s_SysPalInUse;
64
65extern HWINSTA ( WINAPI *NTOpenWindowStation ) ( LPTSTR, BOOL, DWORD );
66extern BOOL ( WINAPI *NTSetProcessWindowStation ) ( HWINSTA );
67extern HDESK ( WINAPI *NTOpenDesktop ) ( LPTSTR, DWORD, BOOL, DWORD );
68extern BOOL ( WINAPI *NTSetThreadDesktop ) ( HDESK );
69extern BOOL ( WINAPI *NTCloseDesktop ) ( HDESK );
70extern BOOL ( WINAPI *NTCloseWindowStation ) ( HWINSTA );
71
72extern OSVERSIONINFO WNT_osVer;
73
74//=======================================================================
75//function : WNT_GraphicDevice
76//purpose :
77//=======================================================================
78
79WNT_GraphicDevice::WNT_GraphicDevice (
80 const Standard_Boolean aColorCube,
81 const Aspect_Handle aDevContext
82 )
83{
84
85 Init ( aColorCube, aDevContext );
86
87} // end constructor ( 1 )
88
89//=======================================================================
90//function : WNT_GraphicDevice
91//purpose :
92//=======================================================================
93
94WNT_GraphicDevice::WNT_GraphicDevice (
95 const Standard_Boolean aColorCube,
96 const Standard_Integer aDevContext
97 )
98{
99
100 Init ( aColorCube, ( Aspect_Handle )aDevContext );
101
102} // end constructor ( 2 )
103
104//=======================================================================
105//function : Init
106//purpose :
107//=======================================================================
108
109void WNT_GraphicDevice::Init (
110 const Standard_Boolean aColorCube,
111 const Aspect_Handle aDevContext
112 )
113{
114
115 HDC hDC;
116 BOOL palDev;
117 HWND hwnd = NULL;
118 HBITMAP hBmp = NULL;
119 int numRes, palSize, nPlanes, nBits;
120
121 hDC = ( aDevContext == NULL ) ? GetDC ( NULL ) :
122 ( HDC )aDevContext, hwnd = WindowFromDC ( ( HDC )aDevContext );
123
124// It is found that the error occurs in the place in the source code that is
125// responsible for connecting to the desktop and window pointed by the environment
126// variable CSF_DISPLAY.
127// For the moment it is unclear at all what this code is needed for. Therefore it
128// is removed from the sources in order to fix this bug. This allowed to run the
129// code without problems on both win32 and win64 platforms.
130// It is needed to carry out special investigations about this subject. Probably it
131// can be used to connect to a virtual desktop in order to make snapshots on the
132// Windows station on which no user is logged in.
133//
134// if ( aDevContext == 0 && WNT_osVer.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
135
136// HWINSTA hWst = NULL;
137// HDESK hDsk = NULL;
138// DWORD dwLen, dwLenOrig;
139// LPTSTR buff = NULL;
140// LPTSTR sNam = NULL;
141// LPTSTR dNam = NULL;
142// BOOL fSts = FALSE;
143
144// dwLenOrig = GetEnvironmentVariable( TEXT( "CSF_DISPLAY" ), NULL, 0 );
145
146// if ( dwLenOrig == 0 )
147
148// dwLen = sizeof ( TEXT( "WinSta0\\Default" ) );
149
150// else
151
152// dwLen = dwLenOrig + sizeof ( TCHAR );
153
154// buff = ( LPTSTR )HeapAlloc (
155// GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, dwLen
156// );
157
158// if ( dwLenOrig != 0 )
159
160// GetEnvironmentVariable ( TEXT( "CSF_DISPLAY" ), buff, dwLen );
161
162// else
163
164// lstrcpy ( buff, TEXT( "WinSta0\\Default" ) );
165
166// dwLen = 0;
167
168// while ( buff[ dwLen ] != TEXT( '\\' ) && buff[ dwLen ] != TEXT( '\x00' ) ) ++dwLen;
169
170// sNam = ( LPTSTR )HeapAlloc (
171// GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
172// dwLen * sizeof ( TCHAR ) + sizeof ( TCHAR )
173// );
174
175// dwLenOrig = 0;
176
177// while ( dwLenOrig != dwLen ) {
178
179// sNam[ dwLenOrig ] = buff[ dwLenOrig ];
180// ++dwLenOrig;
181
182// } // end while
183
184// sNam[ dwLenOrig ] = TEXT( '\x00' );
185
186// if ( buff[ dwLen ] == TEXT( '\x00' ) ) goto leave;
187
188// lstrcpy ( buff, &buff[ dwLen + 1 ] );
189
190// dNam = ( LPTSTR )HeapAlloc (
191// GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS,
192// lstrlen ( buff ) * sizeof ( TCHAR ) + sizeof ( TCHAR )
193// );
194
195// lstrcpy ( dNam, buff );
196
197// if ( ( hWst = ( *NTOpenWindowStation ) ( sNam, FALSE, MAXIMUM_ALLOWED ) ) == NULL ||
198// !( *NTSetProcessWindowStation ) ( hWst )
199// ) goto leave;
200
201// if ( ( hDsk = ( *NTOpenDesktop ) ( dNam, 0, FALSE, MAXIMUM_ALLOWED ) ) == NULL ||
202// !( *NTSetThreadDesktop ) ( hDsk )
203// )
204
205// if ( GetLastError () == ERROR_BUSY ) {
206
207// if ( hDsk != NULL ) ( *NTCloseDesktop ) ( hDsk );
208// if ( hWst != NULL ) ( *NTCloseWindowStation ) ( hWst );
209
210// } else goto leave;
211
212// fSts = TRUE;
213//leave:
214// if ( sNam != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )sNam );
215// if ( dNam != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )dNam );
216// if ( buff != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )buff );
217
218// if ( !fSts ) {
219
220// if ( hDsk != NULL ) ( *NTCloseDesktop ) ( hDsk );
221// if ( hWst != NULL ) ( *NTCloseWindowStation ) ( hWst );
222
223// Aspect_GraphicDeviceDefinitionError :: Raise ( "Access to station is denied" );
224
225// } // end if
226
227// } // end if
228
229 palDev = ( GetDeviceCaps ( hDC, RASTERCAPS ) & RC_PALETTE ) ? TRUE : FALSE;
230 numRes = GetDeviceCaps ( hDC, NUMRESERVED );
231 palSize = ( palDev ) ? GetDeviceCaps ( hDC, SIZEPALETTE ) : 0;
232 nPlanes = GetDeviceCaps ( hDC, PLANES );
233 nBits = GetDeviceCaps ( hDC, BITSPIXEL );
234 myWidth = GetDeviceCaps ( hDC, HORZRES );
235 myHeight = GetDeviceCaps ( hDC, VERTRES );
236 myMWidth = ( float )GetDeviceCaps ( hDC, HORZSIZE ) / ( 1. MILLIMETER );
237 myMHeight = ( float )GetDeviceCaps ( hDC, VERTSIZE ) / ( 1. MILLIMETER );
238
239 if ( aDevContext != NULL && hwnd != NULL ) {
240
241 RECT r;
242
243 GetClientRect ( hwnd, &r );
244
245 myMWidth = myMWidth * r.right / myWidth;
246 myMHeight = myMHeight * r.bottom / myHeight;
247 myWidth = r.right;
248 myHeight = r.bottom;
249
250 } else {
251
252 BITMAP bm;
253
254 hBmp = ( HBITMAP )GetCurrentObject ( hDC, OBJ_BITMAP );
255
256 if ( GetObject ( hBmp, sizeof ( BITMAP ), &bm ) ) {
257
258 myMWidth = myMWidth * bm.bmWidth / myWidth;
259 myMHeight = myMHeight * bm.bmHeight / myHeight;
260// Tempory correction for Windows 98
261 if ( WNT_osVer.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) {
262//
263 myWidth = bm.bmWidth;
264 myHeight = bm.bmHeight;
265
266 } else hBmp = NULL;
267// Tempory correction for Windows 98
268 }
269//
270
271 } // end else
272
273 if ( aDevContext == NULL ) ReleaseDC ( NULL, hDC );
274
275 myNumColors = ( 1 << ( nBits * nPlanes ) );
276
277 if ( palDev ) myNumColors -= numRes;
278
279 myFreeIndex = 0;
280 myOpenGLPalette = aColorCube;
281
282 if ( palDev ) {
283
284 if ( hwnd == NULL && hBmp == NULL ) {
285
286 myLogPal = HeapAlloc (
287 GetProcessHeap (), HEAP_ZERO_MEMORY,
288 sizeof( LOGPALETTE ) +
289 sizeof( PALETTEENTRY ) * myNumColors
290 );
291
292 if ( !myLogPal )
293
294 Aspect_GraphicDeviceDefinitionError :: Raise ( "Out of memory" );
295
296 PAL -> palVersion = 0x300;
297 PAL -> palNumEntries = 1;
298
299 myPalette = CreatePalette ( PAL );
300
301 if ( !myPalette ) {
302
303 HeapFree ( GetProcessHeap (), 0, myLogPal );
304 Aspect_GraphicDeviceDefinitionError :: Raise ( "Unable to create user palette" );
305
306 } // end if
307
308 myFreeIndex = 0;
309
310 if ( myOpenGLPalette && !_createColorRamp ( ( HPALETTE* )&myPalette ) )
311
312 Aspect_GraphicDeviceDefinitionError :: Raise ( "Colorcube creation failed" );
313
314 } else {
315
316 myPalette = GetCurrentObject ( hDC, OBJ_PAL );
317 myLogPal = NULL;
318
319 } // end else
320
321 } else { // not a palette device
322
323 myPalette = 0;
324 myLogPal = NULL;
325
326 } // end else ( palDev . . . )
327
328 myHighlightColor = RGB( 255, 255, 255 );
329
330} // end WNT_GraphicDevice :: Init
331
332void WNT_GraphicDevice :: Destroy () {
333
334 if ( myPalette && myLogPal != NULL ) {
335
336 DeletePalette ( myPalette );
337 HeapFree ( GetProcessHeap (), 0, myLogPal );
338
339 } // end if
340
341} // end WNT_GraphicDevice :: Destroy
342
343WNT_ColorRef WNT_GraphicDevice :: SetColor (
344 const Quantity_Color& aColor,
345 const Standard_Boolean aHighlight
346 ) {
347
348 Standard_Real r, g, b;
349 Standard_Integer red, green, blue;
350
351 aColor.Values ( r, g, b, Quantity_TOC_RGB );
352
353 red = ( Standard_Integer )( 255. * r );
354 green = ( Standard_Integer )( 255. * g );
355 blue = ( Standard_Integer )( 255. * b );
356
357 return SetColor ( red, green, blue, aHighlight );
358
359} // end WNT_GraphicDevice :: SetColor( 1 )
360
361WNT_ColorRef WNT_GraphicDevice :: SetColor (
362 const Standard_Integer aRed,
363 const Standard_Integer aGreen,
364 const Standard_Integer aBlue,
365 const Standard_Boolean aHighlight
366 ) {
367
368 int i;
369 WNT_ColorRef retVal;
370 BYTE red, green, blue;
371
372 red = ( BYTE )aRed;
373 green = ( BYTE )aGreen;
374 blue = ( BYTE )aBlue;
375
376 if ( !myPalette )
377
378 retVal = RGB( red, green, blue );
379
380 else if ( myOpenGLPalette )
381
382 retVal = PALETTEINDEX(
383 GetNearestPaletteIndex (
384 ( HPALETTE )myPalette, RGB( red, green, blue )
385 )
386 );
387
388 else {
389
390 if ( myFreeIndex < myNumColors ) {
391
392 for ( i = 0; i < myFreeIndex; ++i ) // avoid color duplication
393
394 if ( PAL -> palPalEntry[ i ].peRed == red &&
395 PAL -> palPalEntry[ i ].peGreen == green &&
396 PAL -> palPalEntry[ i ].peBlue == blue
397 )
398
399 break;
400
401 if ( i == myFreeIndex ) { // add new color entry
402
403 PAL -> palPalEntry[ i ].peRed = red;
404 PAL -> palPalEntry[ i ].peGreen = green;
405 PAL -> palPalEntry[ i ].peBlue = blue;
406 PAL -> palPalEntry[ i ].peFlags = 0;
407 ++myFreeIndex;
408 ResizePalette ( ( HPALETTE )myPalette, myFreeIndex );
409 SetPaletteEntries ( ( HPALETTE )myPalette, i, 1, &PAL -> palPalEntry[ i ] );
410
411 } // end if
412
413 retVal = PALETTEINDEX( i );
414
415 } else // get closest color
416
417 retVal = PALETTEINDEX(
418 GetNearestPaletteIndex (
419 ( HPALETTE )myPalette, RGB( red, green, blue )
420 )
421 );
422
423 } // end else ( !myPalette . . . )
424
425 if ( aHighlight )
426
427 myHighlightColor = retVal;
428
429 return retVal;
430
431} // end WNT_GraphicDevice :: SetColor(2)
432
433void WNT_GraphicDevice :: SetColor ( const WNT_Long& aPixel ) {
434
435 if ( myPalette && !myOpenGLPalette && myFreeIndex < myNumColors ) {
436
437 int idx;
438 BYTE red, green, blue;
439
440 blue = (BYTE) (aPixel & 0xFF);
441 green = (BYTE) (( aPixel >> 8 ) & 0xFF);
442 red = (BYTE) (( aPixel >> 16 ) & 0xFF);
443
444 idx = myFreeIndex;
445
446 for ( int i = 2; i < myFreeIndex; ++i ) // avoid color duplication
447
448 if ( PAL -> palPalEntry[ i ].peRed == red &&
449 PAL -> palPalEntry[ i ].peGreen == green &&
450 PAL -> palPalEntry[ i ].peBlue == blue
451 )
452
453 return;
454
455 PAL -> palPalEntry[ idx ].peRed = red;
456 PAL -> palPalEntry[ idx ].peGreen = green;
457 PAL -> palPalEntry[ idx ].peBlue = blue;
458 PAL -> palPalEntry[ idx ].peFlags = 0;
459 ++myFreeIndex;
460 ResizePalette ( ( HPALETTE )myPalette, myFreeIndex );
461 SetPaletteEntries ( ( HPALETTE )myPalette, idx, 1, &PAL -> palPalEntry[ idx ] );
462
463 } // end if ( myPalette . . . )
464
465} // end WNT_GraphicDevice :: SetColor(3)
466
467void WNT_GraphicDevice :: MapColors (
468 const Handle( Aspect_ColorMap )& aColorMap,
469 Handle( WNT_HColorTable )& aColorTable
470 ) {
471
472 Aspect_ColorMapEntry entry;
473 Quantity_Color color;
474 COLORREF dwColor;
475 Standard_Real r, g, b;
476 int i, index;
477
478 if ( myOpenGLPalette || !IsPaletteDevice () ) // readonly palette or no palette
479
480 for ( i = 1; i <= aColorMap -> Size (); ++i ) {
481
482 entry = aColorMap -> Entry ( i );
483 color = entry.Color ();
484 aColorTable -> SetValue ( entry.Index (), SetColor ( color ) );
485
486 } // end for
487
488 else { // writable palette
489
490 for ( i = 1; i <= aColorMap -> Size (); ++i ) {
491
492 entry = aColorMap -> Entry ( i );
493 color = entry.Color ();
494 dwColor = aColorTable -> Value ( i );
495 index = dwColor & 0x01000000 ? dwColor & 0x00FFFFFF : 0xFFFFFFFF;
496
497 if ( index != 0xFFFFFFFF && index < myFreeIndex ) {
498
499 color.Values ( r, g, b, Quantity_TOC_RGB );
500 PAL -> palPalEntry[ index ].peRed = ( BYTE )( 255. * r );
501 PAL -> palPalEntry[ index ].peGreen = ( BYTE )( 255. * g );
502 PAL -> palPalEntry[ index ].peBlue = ( BYTE )( 255. * b );
503
504 } else
505
506 aColorTable -> SetValue ( i, SetColor ( color ) );
507
508 } // end for
509
510 SetPaletteEntries (
511 ( HPALETTE )myPalette, 0, myFreeIndex, &PAL -> palPalEntry[ 0 ]
512 );
513
514 } // end else
515
516} // WNT_GraphicDevice :: MapColors
517
518Handle( Aspect_GraphicDriver ) WNT_GraphicDevice :: GraphicDriver () const {
519
520 Handle( Aspect_GraphicDriver ) dummy;
521
522 return dummy;
523
524} // WNT_GraphicDevice :: GraphicDriver
525//***//
526//*** Function to create RGB color map for use with OpenGL. ***//
527//*** For OpenGL RGB rendering we need to know red, green, & blue ***//
528//*** component bit sizes and positions. This program creates an RGB color ***//
529//*** cube with a default gamma of 1.4. ***//
530//*** Unfortunately, because the standard 20 colors in the system palette ***//
531//*** cannot be changed, if we select this palette into a display DC, ***//
532//*** we will not realize all of the logical palette. The function ***//
533//*** changes some of the entries in the logical palette to match enties in ***//
534//*** the system palette using a least-squares calculation to find which ***//
535//*** entries to replace. ***//
536//***//
537static int __fastcall _createColorRamp ( HPALETTE* pal ) {
538
539 int i, j;
540 int sysPalSize, logPalSize;
541 int red_max, green_max, blue_max,
542 red_mask, green_mask, blue_mask;
543 int iPf;
544 HDC hDC;
545 PIXELFORMATDESCRIPTOR pfd;
546 PPALETTEENTRY sysPal, colorRamp;
547 PBYTE gRed, gGreen, gBlue;
548 BYTE inc;
549 LONG error, min_error, error_index, delta;
550 double dv, gamma;
551 char buff[ 32 ];
552
553 ZeroMemory ( ( PVOID )&pfd, sizeof ( PIXELFORMATDESCRIPTOR ) );
554
555 pfd.nSize = sizeof ( PIXELFORMATDESCRIPTOR );
556 pfd.nVersion = 1;
557 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
558 PFD_DOUBLEBUFFER;
559 pfd.iPixelType = PFD_TYPE_RGBA;
560 pfd.cColorBits = 24;
561 pfd.cDepthBits = 32;
562 pfd.iLayerType = PFD_MAIN_PLANE;
563
564 hDC = GetDC ( NULL );
565
566 iPf = ChoosePixelFormat ( hDC, &pfd );
567 i = DescribePixelFormat (
568 hDC, iPf, sizeof ( PIXELFORMATDESCRIPTOR ), &pfd
569 );
570
571 if ( !i ) {
572
573 ReleaseDC ( NULL, hDC );
574
575 return 0;
576
577 } // end if
578
579 sysPalSize = GetDeviceCaps ( hDC, NUMCOLORS );
580 logPalSize = 1 << pfd.cColorBits;
581 sysPal = new PALETTEENTRY[ sysPalSize + logPalSize ];
582 colorRamp = sysPal + sysPalSize;
583 GetSystemPaletteEntries ( hDC, 0, sysPalSize, sysPal );
584
585 ReleaseDC ( NULL, hDC );
586
587 red_max = 1 << pfd.cRedBits;
588 green_max = 1 << pfd.cGreenBits;
589 blue_max = 1 << pfd.cBlueBits;
590
591 red_mask = red_max - 1;
592 green_mask = green_max - 1;
593 blue_mask = blue_max - 1;
594
595 gRed = new BYTE[ red_max + green_max + blue_max ];
596 gGreen = gRed + red_max;
597 gBlue = gGreen + green_max;
598
599 inc = ( BYTE )( 255.0F / ( float )red_mask );
600
601 if ( GetEnvironmentVariable ( "CSF_GammaValue", buff, 32 ) ) {
602
91322f44 603 gamma = Atof ( buff );
7fd59977 604
605 if ( gamma == 0.0 )
606
607 gamma = DEFAULT_GAMMA;
608
609 } else
610
611 gamma = DEFAULT_GAMMA;
612
613 for ( i = 0; i < red_max; ++i ) {
614
615 gRed[ i ] = ( i * inc ) & 0xFF;
616 dv = ( 255. * pow ( gRed[ i ] / 255., 1. / gamma ) ) + 0.5;
617 gRed[ i ] = ( BYTE )dv;
618
619 } // end for
620
621 inc = ( BYTE )( 255.0F / ( float )green_mask );
622
623 for ( i = 0; i < green_max; ++i ) {
624
625 gGreen[ i ] = ( i * inc ) & 0xFF;
626 dv = ( 255. * pow ( gGreen[ i ] / 255., 1. / gamma ) ) + 0.5;
627 gGreen[ i ] = ( BYTE )dv;
628
629 } // end for
630
631 inc = ( BYTE )( 255.0F / ( float )blue_mask );
632
633 for ( i = 0; i < blue_max; ++i ) {
634
635 gBlue[ i ] = ( i * inc ) & 0xFF;
636 dv = ( 255. * pow ( gBlue[ i ] / 255., 1. / gamma ) ) + 0.5;
637 gBlue[ i ] = ( BYTE )dv;
638
639 } // end for
640
641 for ( i = 0; i < logPalSize; ++i ) {
642
643 colorRamp[ i ].peRed =
644 gRed[ ( i >> pfd.cRedShift ) & red_mask ];
645 colorRamp[ i ].peGreen =
646 gGreen[ ( i >> pfd.cGreenShift ) & green_mask ];
647 colorRamp[ i ].peBlue =
648 gBlue[ ( i >> pfd.cBlueShift ) & blue_mask ];
649 colorRamp[ i ].peFlags = 0;
650
651 } // end for
652
653 if ( pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ) {
654
655 s_SysPalInUse = TRUE;
656
657 for ( i = 1; i < logPalSize - 1; ++i ) colorRamp[ i ].peFlags = PC_NOCOLLAPSE;
658
659 } else {
660
661 for ( i = 0; i < sysPalSize; ++i )
662
663 for ( j = 0; j < logPalSize; ++j )
664
665 if ( sysPal[ i ].peRed == colorRamp[ j ].peRed &&
666 sysPal[ i ].peGreen == colorRamp[ j ].peRed &&
667 sysPal[ i ].peBlue == colorRamp[ j ].peRed
668 )
669
670 sysPal[ i ].peFlags = colorRamp[ i ].peFlags = 1;
671
672 else
673
674 sysPal[ i ].peFlags = colorRamp[ i ].peFlags = 0;
675
676 for ( i = 0; i < sysPalSize; ++i ) {
677
678 if ( sysPal[ i ].peFlags ) continue;
679
680 min_error = MAX_PAL_ERROR;
681
682 for ( j = 0; j < logPalSize; ++j ) {
683
684 if ( colorRamp[ j ].peFlags ) continue;
685
686 delta = colorRamp[ j ].peRed - sysPal[ i ].peRed;
687 error = delta * delta;
688 delta = colorRamp[ j ].peGreen - sysPal[ i ].peGreen;
689 error += delta * delta;
690 delta = colorRamp[ j ].peBlue - sysPal[ i ].peBlue;
691 error += delta * delta;
692
693 if ( error < min_error ) {
694
695 error_index = j;
696 min_error = error;
697
698 } // end if
699
700 } // end for ( j . . . )
701
702 colorRamp[ error_index ].peRed = sysPal[ i ].peRed;
703 colorRamp[ error_index ].peGreen = sysPal[ i ].peGreen;
704 colorRamp[ error_index ].peBlue = sysPal[ i ].peBlue;
705 colorRamp[ error_index ].peFlags = PC_EXPLICIT;
706
707 } // end for ( i . . . )
708
709 } // end else
710
711 ResizePalette ( *pal, logPalSize );
712 SetPaletteEntries ( *pal, 0, logPalSize, colorRamp );
713
714 delete [] gRed;
715 delete [] sysPal;
716
717 return 1;
718
719} // end createColorRamp
720
721int WNT_SysPalInUse ( void ) {
722
723 return s_SysPalInUse;
724
725} // end WNT_SysPalInUse