Cleaned up some inter-dll dependencies in palette management.
[wine] / objects / color.c
1 /*
2  * Color functions
3  *
4  * Copyright 1993 Alexandre Julliard
5  * Copyright 1996 Alex Korobka
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "color.h"
23 #include "wine/debug.h"
24 #include "palette.h"
25 #include "windef.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(palette);
28
29
30 /***********************************************************************
31  * System color space. 
32  *
33  * First 10 and last 10 colors in COLOR_sysPalette are
34  * "guarded". RealizePalette changes only the rest of colorcells. For
35  * currently inactive window it changes only DC palette mappings.
36  */
37
38 PALETTEENTRY *COLOR_sysPal = NULL; /* current system palette */
39
40 const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] = 
41 {
42     /* first 10 entries in the system palette */
43     /* red  green blue  flags */
44     { 0x00, 0x00, 0x00, PC_SYS_USED },
45     { 0x80, 0x00, 0x00, PC_SYS_USED },
46     { 0x00, 0x80, 0x00, PC_SYS_USED },
47     { 0x80, 0x80, 0x00, PC_SYS_USED },
48     { 0x00, 0x00, 0x80, PC_SYS_USED },
49     { 0x80, 0x00, 0x80, PC_SYS_USED },
50     { 0x00, 0x80, 0x80, PC_SYS_USED },
51     { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
52     { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
53     { 0xa6, 0xca, 0xf0, PC_SYS_USED },
54
55     /* ... c_min/2 dynamic colorcells */
56
57     /* ... gap (for sparse palettes) */
58
59     /* ... c_min/2 dynamic colorcells */
60
61     { 0xff, 0xfb, 0xf0, PC_SYS_USED },
62     { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
63     { 0x80, 0x80, 0x80, PC_SYS_USED },
64     { 0xff, 0x00, 0x00, PC_SYS_USED },
65     { 0x00, 0xff, 0x00, PC_SYS_USED },
66     { 0xff, 0xff, 0x00, PC_SYS_USED },
67     { 0x00, 0x00, 0xff, PC_SYS_USED },
68     { 0xff, 0x00, 0xff, PC_SYS_USED },
69     { 0x00, 0xff, 0xff, PC_SYS_USED },
70     { 0xff, 0xff, 0xff, PC_SYS_USED }     /* last 10 */
71 };
72
73 /***********************************************************************
74  *           COLOR_GetSystemPaletteTemplate
75  */
76 const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
77 {
78     return COLOR_sysPalTemplate;
79 }
80
81 /***********************************************************************
82  *           COLOR_GetSystemPaletteEntry
83  */
84
85 COLORREF COLOR_GetSystemPaletteEntry(UINT i)
86 {
87     return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
88 }
89
90 /***********************************************************************
91  *           COLOR_PaletteLookupPixel
92  */
93 int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
94                               int* mapping, COLORREF col, BOOL skipReserved )
95 {
96     int i, best = 0, diff = 0x7fffffff;
97     int r,g,b;
98
99     for( i = 0; i < size && diff ; i++ )
100     {
101         if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
102             (skipReserved && palPalEntry[i].peFlags  & PC_SYS_RESERVED) )
103             continue;
104
105         r = palPalEntry[i].peRed - GetRValue(col);
106         g = palPalEntry[i].peGreen - GetGValue(col);
107         b = palPalEntry[i].peBlue - GetBValue(col);
108
109         r = r*r + g*g + b*b;
110
111         if( r < diff ) { best = i; diff = r; }
112     }
113     return (mapping) ? mapping[best] : best;
114 }
115
116 /***********************************************************************
117  *           COLOR_PaletteLookupExactIndex
118  */
119 int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
120                                    COLORREF col )
121 {
122     int i;
123     BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
124     for( i = 0; i < size; i++ )
125     {
126         if( palPalEntry[i].peFlags & PC_SYS_USED )      /* skips gap */
127             if( palPalEntry[i].peRed == r &&
128                 palPalEntry[i].peGreen == g &&
129                 palPalEntry[i].peBlue == b )
130                 return i;
131     }
132     return -1;
133 }
134
135 /***********************************************************************
136  *           COLOR_LookupNearestColor
137  */
138 COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
139 {
140   unsigned char         spec_type = color >> 24;
141   int                   i;
142
143   /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
144
145   if( spec_type == 2 ) /* PALETTERGB */
146     color = *(COLORREF*)
147              (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
148
149   else if( spec_type == 1 ) /* PALETTEINDEX */
150   {
151     if( (i = color & 0x0000ffff) >= size ) 
152       {
153         WARN("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
154         color = *(COLORREF*)palPalEntry;
155       }
156     else color = *(COLORREF*)(palPalEntry + i);
157   }
158
159   color &= 0x00ffffff;
160   return (0x00ffffff & *(COLORREF*)
161          (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
162 }