Fix a typo.
[reactos.git] / reactos / subsys / win32k / objects / color.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$ */
20
21 #include <w32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
27
28 int COLOR_gapStart = 256;
29 int COLOR_gapEnd = -1;
30 int COLOR_gapFilled = 0;
31 int COLOR_max = 256;
32
33 #ifndef NO_MAPPING
34 static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
35 #endif
36 //static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
37
38
39 static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the palate and restore it */
40
41 const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
42 {
43 // first 10 entries in the system palette
44 // red green blue flags
45 { 0x00, 0x00, 0x00, PC_SYS_USED },
46 { 0x80, 0x00, 0x00, PC_SYS_USED },
47 { 0x00, 0x80, 0x00, PC_SYS_USED },
48 { 0x80, 0x80, 0x00, PC_SYS_USED },
49 { 0x00, 0x00, 0x80, PC_SYS_USED },
50 { 0x80, 0x00, 0x80, PC_SYS_USED },
51 { 0x00, 0x80, 0x80, PC_SYS_USED },
52 { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
53 { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
54 { 0xd4, 0xd0, 0xc7, PC_SYS_USED },
55
56 // ... c_min/2 dynamic colorcells
57 // ... gap (for sparse palettes)
58 // ... c_min/2 dynamic colorcells
59
60 { 0xff, 0xfb, 0xf0, PC_SYS_USED },
61 { 0x3a, 0x6e, 0xa5, PC_SYS_USED },
62 { 0x80, 0x80, 0x80, PC_SYS_USED },
63 { 0xff, 0x00, 0x00, PC_SYS_USED },
64 { 0x00, 0xff, 0x00, PC_SYS_USED },
65 { 0xff, 0xff, 0x00, PC_SYS_USED },
66 { 0x00, 0x00, 0xff, PC_SYS_USED },
67 { 0xff, 0x00, 0xff, PC_SYS_USED },
68 { 0x00, 0xff, 0xff, PC_SYS_USED },
69 { 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
70 };
71
72 const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
73 {
74 return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
75 }
76
77 BOOL STDCALL NtGdiAnimatePalette(HPALETTE hPal, UINT StartIndex,
78 UINT NumEntries, CONST PPALETTEENTRY PaletteColors)
79 {
80 if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
81 {
82 PPALGDI palPtr;
83 UINT pal_entries;
84 HDC hDC;
85 PDC dc;
86 PWINDOW_OBJECT Wnd;
87 const PALETTEENTRY *pptr = PaletteColors;
88
89 palPtr = (PPALGDI)PALETTE_LockPalette(hPal);
90 if (!palPtr) return FALSE;
91
92 pal_entries = palPtr->NumColors;
93 if (StartIndex >= pal_entries)
94 {
95 PALETTE_UnlockPalette(palPtr);
96 return FALSE;
97 }
98 if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
99
100 for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
101 /* According to MSDN, only animate PC_RESERVED colours */
102 if (palPtr->IndexedColors[StartIndex].peFlags & PC_RESERVED) {
103 memcpy( &palPtr->IndexedColors[StartIndex], pptr,
104 sizeof(PALETTEENTRY) );
105 PALETTE_ValidateFlags(&palPtr->IndexedColors[StartIndex], 1);
106 }
107 }
108
109 PALETTE_UnlockPalette(palPtr);
110
111 /* Immediately apply the new palette if current window uses it */
112 Wnd = UserGetDesktopWindow();
113 hDC = (HDC)UserGetWindowDC(Wnd);
114 dc = DC_LockDc(hDC);
115 if (NULL != dc)
116 {
117 if (dc->w.hPalette == hPal)
118 {
119 DC_UnlockDc(dc);
120 NtGdiRealizePalette(hDC);
121 }
122 else
123 DC_UnlockDc(dc);
124 }
125 UserReleaseDC(Wnd,hDC, FALSE);
126 }
127 return TRUE;
128 }
129
130 HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC hDC)
131 {
132 int i, r, g, b;
133 struct {
134 WORD Version;
135 WORD NumberOfEntries;
136 PALETTEENTRY aEntries[256];
137 } Palette;
138
139 Palette.Version = 0x300;
140 Palette.NumberOfEntries = 256;
141 if (NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries) == 0)
142 {
143 return 0;
144 }
145
146 for (r = 0; r < 6; r++)
147 for (g = 0; g < 6; g++)
148 for (b = 0; b < 6; b++)
149 {
150 i = r + g*6 + b*36 + 10;
151 Palette.aEntries[i].peRed = r * 51;
152 Palette.aEntries[i].peGreen = g * 51;
153 Palette.aEntries[i].peBlue = b * 51;
154 }
155
156 for (i = 216; i < 246; i++)
157 {
158 int v = (i - 216) << 3;
159 Palette.aEntries[i].peRed = v;
160 Palette.aEntries[i].peGreen = v;
161 Palette.aEntries[i].peBlue = v;
162 }
163
164 return NtGdiCreatePalette((LOGPALETTE *)&Palette);
165 }
166
167 HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
168 {
169 PPALGDI PalGDI;
170
171 HPALETTE NewPalette = PALETTE_AllocPalette(
172 PAL_INDEXED,
173 palette->palNumEntries,
174 (PULONG)palette->palPalEntry,
175 0, 0, 0);
176
177 PalGDI = (PPALGDI) PALETTE_LockPalette(NewPalette);
178 /* FIXME - Handle PalGDI == NULL!!!! */
179
180 PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors);
181 PalGDI->logicalToSystem = NULL;
182
183 PALETTE_UnlockPalette(PalGDI);
184
185 return NewPalette;
186 }
187
188 BOOL STDCALL NtGdiGetColorAdjustment(HDC hDC,
189 LPCOLORADJUSTMENT ca)
190 {
191 UNIMPLEMENTED;
192 return FALSE;
193 }
194
195 unsigned short GetNumberOfBits(unsigned int dwMask)
196 {
197 unsigned short wBits;
198 for (wBits = 0; dwMask; dwMask = dwMask & (dwMask - 1))
199 wBits++;
200 return wBits;
201 }
202
203 COLORREF STDCALL NtGdiGetNearestColor(HDC hDC, COLORREF Color)
204 {
205 COLORREF nearest = CLR_INVALID;
206 PDC dc;
207 PPALGDI palGDI;
208 LONG RBits, GBits, BBits;
209
210 dc = DC_LockDc(hDC);
211 if (NULL != dc)
212 {
213 HPALETTE hpal = dc->w.hPalette;
214 palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
215 if (!palGDI)
216 {
217 DC_UnlockDc(dc);
218 return nearest;
219 }
220
221 switch (palGDI->Mode)
222 {
223 case PAL_INDEXED:
224 nearest = COLOR_LookupNearestColor(palGDI->IndexedColors,
225 palGDI->NumColors, Color);
226 break;
227 case PAL_BGR:
228 case PAL_RGB:
229 nearest = Color;
230 break;
231 case PAL_BITFIELDS:
232 RBits = 8 - GetNumberOfBits(palGDI->RedMask);
233 GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
234 BBits = 8 - GetNumberOfBits(palGDI->BlueMask);
235 nearest = RGB(
236 (GetRValue(Color) >> RBits) << RBits,
237 (GetGValue(Color) >> GBits) << GBits,
238 (GetBValue(Color) >> BBits) << BBits);
239 break;
240 }
241 PALETTE_UnlockPalette(palGDI);
242 DC_UnlockDc(dc);
243 }
244
245 return nearest;
246 }
247
248 UINT STDCALL NtGdiGetNearestPaletteIndex(HPALETTE hpal,
249 COLORREF Color)
250 {
251 PPALGDI palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
252 UINT index = 0;
253
254 if (NULL != palGDI)
255 {
256 /* Return closest match for the given RGB color */
257 index = COLOR_PaletteLookupPixel(palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
258 PALETTE_UnlockPalette(palGDI);
259 }
260
261 return index;
262 }
263
264 UINT STDCALL NtGdiGetPaletteEntries(HPALETTE hpal,
265 UINT StartIndex,
266 UINT Entries,
267 LPPALETTEENTRY pe)
268 {
269 PPALGDI palGDI;
270 UINT numEntries;
271
272 palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
273 if (NULL == palGDI)
274 {
275 return 0;
276 }
277
278 numEntries = palGDI->NumColors;
279 if (numEntries < StartIndex + Entries)
280 {
281 Entries = numEntries - StartIndex;
282 }
283 if (NULL != pe)
284 {
285 if (numEntries <= StartIndex)
286 {
287 PALETTE_UnlockPalette(palGDI);
288 return 0;
289 }
290 memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(PALETTEENTRY));
291 for (numEntries = 0; numEntries < Entries; numEntries++)
292 {
293 if (pe[numEntries].peFlags & 0xF0)
294 {
295 pe[numEntries].peFlags = 0;
296 }
297 }
298 }
299
300 PALETTE_UnlockPalette(palGDI);
301 return Entries;
302 }
303
304 UINT STDCALL NtGdiGetSystemPaletteEntries(HDC hDC,
305 UINT StartIndex,
306 UINT Entries,
307 LPPALETTEENTRY pe)
308 {
309 //UINT i;
310 //PDC dc;
311 /*
312 if (!(dc = AccessUserObject(hdc))) return 0;
313
314 if (!pe)
315 {
316 Entries = dc->GDIInfo->ulNumPalReg;
317 goto done;
318 }
319
320 if (StartIndex >= dc->GDIInfo->ulNumPalReg)
321 {
322 Entries = 0;
323 goto done;
324 }
325
326 if (StartIndex + Entries >= dc->GDIInfo->ulNumPalReg) Entries = dc->GDIInfo->ulNumPalReg - StartIndex;
327
328 for (i = 0; i < Entries; i++)
329 {
330 *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
331 }
332
333 done:
334 // GDI_ReleaseObj(hdc);
335 return count; */
336 // FIXME UNIMPLEMENTED;
337 return 0;
338 }
339
340 UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC)
341 {
342 return SystemPaletteUse;
343 }
344
345 /*!
346 The RealizePalette function modifies the palette for the device associated with the specified device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified.
347
348 A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.
349
350 1= IF DRAWING TO A DEVICE
351 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
352 the system palette.
353 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
354
355 2= IF DRAWING TO A MEMORY DC\BITMAP
356 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
357 the dc palette.
358 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
359 */
360 UINT STDCALL NtGdiRealizePalette(HDC hDC)
361 {
362 /*
363 * This function doesn't do any real work now and there's plenty
364 * of bugd in it (calling SetPalette for high/true-color modes,
365 * using DEFAULT_PALETTE instead of the device palette, ...).
366 */
367
368 PALOBJ *palPtr, *sysPtr;
369 PPALGDI palGDI, sysGDI;
370 int realized = 0;
371 PDC dc;
372 HPALETTE systemPalette;
373 BOOLEAN success;
374 USHORT sysMode, palMode;
375
376 dc = DC_LockDc(hDC);
377 if (!dc)
378 return 0;
379
380 systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE);
381 palGDI = PALETTE_LockPalette(dc->w.hPalette);
382 palPtr = (PALOBJ*) palGDI;
383 /* FIXME - Handle palGDI == NULL!!!! */
384
385 // Step 1: Create mapping of system palette\DC palette
386 #ifndef NO_MAPPING
387 realized = PALETTE_SetMapping(palPtr, 0, palGDI->NumColors,
388 (dc->w.hPalette != hPrimaryPalette) ||
389 (dc->w.hPalette == NtGdiGetStockObject(DEFAULT_PALETTE)));
390 #else
391 realized = 0;
392 #endif
393
394 sysGDI = PALETTE_LockPalette(systemPalette);
395 sysPtr = (PALOBJ*) sysGDI;
396 /* FIXME - Handle sysGDI == NULL!!!!! */
397
398 // Step 2:
399 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
400 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
401 // context is a display DC, the physical palette for that device is modified.
402 if(dc->w.flags == DC_MEMORY)
403 {
404 // Memory managed DC
405 DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
406 } else {
407 if( ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette)
408 {
409 ASSERT(palGDI->NumColors <= 256);
410 success = ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette(
411 dc->PDev, palPtr, 0, 0, palGDI->NumColors);
412 }
413 }
414
415 // need to pass this to IntEngCreateXlate with palettes unlocked
416 sysMode = sysGDI->Mode;
417 palMode = palGDI->Mode;
418 PALETTE_UnlockPalette(sysGDI);
419 PALETTE_UnlockPalette(palGDI);
420
421 // Step 3: Create the XLATEOBJ for device managed DCs
422 if(dc->w.flags != DC_MEMORY)
423 {
424 // Device managed DC
425 palGDI->logicalToSystem = IntEngCreateXlate(sysMode, palMode, systemPalette, dc->w.hPalette);
426 }
427
428 DC_UnlockDc(dc);
429
430 return realized;
431 }
432
433 BOOL STDCALL NtGdiResizePalette(HPALETTE hpal,
434 UINT Entries)
435 {
436 /* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
437 UINT cPrevEnt, prevVer;
438 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
439 XLATEOBJ *XlateObj = NULL;
440
441 if(!palPtr) return FALSE;
442 cPrevEnt = palPtr->logpalette->palNumEntries;
443 prevVer = palPtr->logpalette->palVersion;
444 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
445 size += sizeof(int*) + sizeof(GDIOBJHDR);
446 XlateObj = palPtr->logicalToSystem;
447
448 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
449
450 if(XlateObj)
451 {
452 XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
453 if(NewXlateObj == NULL)
454 {
455 ERR("Can not resize logicalToSystem -- out of memory!");
456 GDI_ReleaseObj( hPal );
457 return FALSE;
458 }
459 palPtr->logicalToSystem = NewXlateObj;
460 }
461
462 if(cEntries > cPrevEnt)
463 {
464 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
465 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
466 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
467 }
468 palPtr->logpalette->palNumEntries = cEntries;
469 palPtr->logpalette->palVersion = prevVer;
470 // GDI_ReleaseObj( hPal );
471 return TRUE; */
472
473 UNIMPLEMENTED;
474 return FALSE;
475 }
476
477 /*!
478 * Select logical palette into device context.
479 * \param hDC handle to the device context
480 * \param hpal handle to the palette
481 * \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon
482 * is in the foreground. If this value is TRUE then map the colors in the logical palette to the device
483 * palette colors in the best way.
484 * \return old palette
485 *
486 * \todo implement ForceBackground == TRUE
487 */
488 HPALETTE STDCALL NtGdiSelectPalette(HDC hDC,
489 HPALETTE hpal,
490 BOOL ForceBackground)
491 {
492 PDC dc;
493 HPALETTE oldPal = NULL;
494 PPALGDI PalGDI;
495
496 // FIXME: mark the palette as a [fore\back]ground pal
497 dc = DC_LockDc(hDC);
498 if (NULL != dc)
499 {
500 /* Check if this is a valid palette handle */
501 PalGDI = PALETTE_LockPalette(hpal);
502 if (NULL != PalGDI)
503 {
504 /* Is this a valid palette for this depth? */
505 if ((dc->w.bitsPerPixel <= 8 && PAL_INDEXED == PalGDI->Mode)
506 || (8 < dc->w.bitsPerPixel && PAL_INDEXED != PalGDI->Mode))
507 {
508 PALETTE_UnlockPalette(PalGDI);
509 oldPal = dc->w.hPalette;
510 dc->w.hPalette = hpal;
511 }
512 else
513 {
514 PALETTE_UnlockPalette(PalGDI);
515 oldPal = NULL;
516 }
517 }
518 else
519 {
520 oldPal = NULL;
521 }
522 DC_UnlockDc(dc);
523 }
524
525 return oldPal;
526 }
527
528 BOOL STDCALL NtGdiSetColorAdjustment(HDC hDC,
529 CONST LPCOLORADJUSTMENT ca)
530 {
531 UNIMPLEMENTED;
532 return FALSE;
533 }
534
535 UINT STDCALL NtGdiSetPaletteEntries(HPALETTE hpal,
536 UINT Start,
537 UINT Entries,
538 CONST LPPALETTEENTRY pe)
539 {
540 PPALGDI palGDI;
541 WORD numEntries;
542
543 palGDI = PALETTE_LockPalette(hpal);
544 if (!palGDI) return 0;
545
546 numEntries = palGDI->NumColors;
547 if (Start >= numEntries)
548 {
549 PALETTE_UnlockPalette(palGDI);
550 return 0;
551 }
552 if (numEntries < Start + Entries)
553 {
554 Entries = numEntries - Start;
555 }
556 memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY));
557 PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors);
558 ExFreePool(palGDI->logicalToSystem);
559 palGDI->logicalToSystem = NULL;
560 PALETTE_UnlockPalette(palGDI);
561
562 return Entries;
563 }
564
565 UINT STDCALL
566 NtGdiSetSystemPaletteUse(HDC hDC, UINT Usage)
567 {
568 UINT old = SystemPaletteUse;
569
570 /* Device doesn't support colour palettes */
571 if (!(NtGdiGetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)) {
572 return SYSPAL_ERROR;
573 }
574
575 switch (Usage)
576 {
577 case SYSPAL_NOSTATIC:
578 case SYSPAL_NOSTATIC256:
579 case SYSPAL_STATIC:
580 SystemPaletteUse = Usage;
581 break;
582
583 default:
584 old=SYSPAL_ERROR;
585 break;
586 }
587
588 return old;
589 }
590
591 /*
592 Win 2k Graphics API, Black Book. by coriolis.com
593 Page 62, Note that Steps 3, 5, and 6 are not required for Windows NT(tm)
594 and Windows 2000(tm).
595
596 Step 5. UnrealizeObject(hTrackBrush);
597 */
598 BOOL STDCALL
599 NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
600 {
601
602 GDIOBJHDR * ptr;
603 DWORD objectType;
604 BOOL Ret = FALSE;
605
606 ptr = GDIOBJ_LockObj(hgdiobj, GDI_OBJECT_TYPE_DONTCARE);
607 if (ptr == 0)
608 {
609 SetLastWin32Error(ERROR_INVALID_HANDLE);
610 return Ret;
611 }
612 objectType = GDIOBJ_GetObjectType(hgdiobj);
613 switch(objectType)
614 {
615 /*
616 msdn.microsoft.com,
617 "Windows 2000/XP: If hgdiobj is a brush, UnrealizeObject does nothing,
618 and the function returns TRUE. Use SetBrushOrgEx to set the origin of
619 a brush."
620 */
621 case GDI_OBJECT_TYPE_BRUSH:
622 {
623 DPRINT("GDI_OBJECT_TYPE_BRUSH\n");
624 Ret = TRUE;
625 break;
626 }
627 default:
628 DPRINT1("Magic 0x%08x not implemented\n", objectType);
629 break;
630 }
631
632 GDIOBJ_UnlockObjByPtr(ptr);
633 return Ret;
634 }
635
636 BOOL STDCALL
637 NtGdiUpdateColors(HDC hDC)
638 {
639 PWINDOW_OBJECT Wnd;
640 BOOL calledFromUser, ret;
641 USER_REFERENCE_ENTRY Ref;
642
643 calledFromUser = UserIsEntered();
644
645 if (!calledFromUser){
646 UserEnterExclusive();
647 }
648
649 Wnd = UserGetWindowObject(IntWindowFromDC(hDC));
650 if (Wnd == NULL)
651 {
652 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
653
654 if (!calledFromUser){
655 UserLeave();
656 }
657
658 return FALSE;
659 }
660
661 UserRefObjectCo(Wnd, &Ref);
662 ret = co_UserRedrawWindow(Wnd, NULL, 0, RDW_INVALIDATE);
663 UserDerefObjectCo(Wnd);
664
665 if (!calledFromUser){
666 UserLeave();
667 }
668
669 return ret;
670 }
671
672 INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
673 XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved)
674 {
675 int i, best = 0, diff = 0x7fffffff;
676 int r, g, b;
677
678 for( i = 0; i < size && diff ; i++ )
679 {
680 #if 0
681 if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
682 continue;
683 #endif
684
685 r = abs((SHORT)palPalEntry[i].peRed - GetRValue(col));
686 g = abs((SHORT)palPalEntry[i].peGreen - GetGValue(col));
687 b = abs((SHORT)palPalEntry[i].peBlue - GetBValue(col));
688
689 r = r*r + g*g + b*b;
690
691 if( r < diff ) { best = i; diff = r; }
692 }
693
694 if (XlateObj == NULL)
695 return best;
696 else
697 return (XlateObj->pulXlate) ? (INT)XlateObj->pulXlate[best] : best;
698 }
699
700 COLORREF STDCALL COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
701 {
702 INT index;
703
704 index = COLOR_PaletteLookupPixel(palPalEntry, size, NULL, color, FALSE);
705 return RGB(
706 palPalEntry[index].peRed,
707 palPalEntry[index].peGreen,
708 palPalEntry[index].peBlue);
709 }
710
711 int STDCALL COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
712 COLORREF col )
713 {
714 int i;
715 BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
716 for( i = 0; i < size; i++ )
717 {
718 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
719 if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
720 }
721 return -1;
722 }
723 /* EOF */