Added missing header.
[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 int COLOR_gapStart = 256;
41 int COLOR_gapEnd = -1;
42 int COLOR_gapFilled = 0;
43 int COLOR_max = 256;
44
45 const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] = 
46 {
47     /* first 10 entries in the system palette */
48     /* red  green blue  flags */
49     { 0x00, 0x00, 0x00, PC_SYS_USED },
50     { 0x80, 0x00, 0x00, PC_SYS_USED },
51     { 0x00, 0x80, 0x00, PC_SYS_USED },
52     { 0x80, 0x80, 0x00, PC_SYS_USED },
53     { 0x00, 0x00, 0x80, PC_SYS_USED },
54     { 0x80, 0x00, 0x80, PC_SYS_USED },
55     { 0x00, 0x80, 0x80, PC_SYS_USED },
56     { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
57     { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
58     { 0xa6, 0xca, 0xf0, PC_SYS_USED },
59
60     /* ... c_min/2 dynamic colorcells */
61
62     /* ... gap (for sparse palettes) */
63
64     /* ... c_min/2 dynamic colorcells */
65
66     { 0xff, 0xfb, 0xf0, PC_SYS_USED },
67     { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
68     { 0x80, 0x80, 0x80, PC_SYS_USED },
69     { 0xff, 0x00, 0x00, PC_SYS_USED },
70     { 0x00, 0xff, 0x00, PC_SYS_USED },
71     { 0xff, 0xff, 0x00, PC_SYS_USED },
72     { 0x00, 0x00, 0xff, PC_SYS_USED },
73     { 0xff, 0x00, 0xff, PC_SYS_USED },
74     { 0x00, 0xff, 0xff, PC_SYS_USED },
75     { 0xff, 0xff, 0xff, PC_SYS_USED }     /* last 10 */
76 };
77
78 /***********************************************************************
79  *           COLOR_GetSystemPaletteTemplate
80  */
81 const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
82 {
83     return COLOR_sysPalTemplate;
84 }
85
86 /***********************************************************************
87  *           COLOR_GetSystemPaletteEntry
88  */
89
90 COLORREF COLOR_GetSystemPaletteEntry(UINT i)
91 {
92     return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
93 }
94
95 /***********************************************************************
96  *           COLOR_IsSolid
97  *
98  * Check whether 'color' can be represented with a solid color.
99  */
100 BOOL COLOR_IsSolid( COLORREF color )
101 {
102     int i;
103     const PALETTEENTRY *pEntry = COLOR_sysPal;
104
105     if (color & 0xff000000) return TRUE;                /* indexed color */
106
107     if (!color || (color == 0xffffff)) return TRUE;     /* black or white */
108
109     for (i = 0; i < 256 ; i++, pEntry++)
110     {
111       if( i < COLOR_gapStart || i > COLOR_gapEnd )
112         if ((GetRValue(color) == pEntry->peRed) &&
113             (GetGValue(color) == pEntry->peGreen) &&
114             (GetBValue(color) == pEntry->peBlue)) return TRUE;
115     }
116     return FALSE;
117 }
118
119 /***********************************************************************
120  *           COLOR_PaletteLookupPixel
121  */
122 int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
123                               int* mapping, COLORREF col, BOOL skipReserved )
124 {
125     int i, best = 0, diff = 0x7fffffff;
126     int r,g,b;
127
128     for( i = 0; i < size && diff ; i++ )
129     {
130         if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
131             (skipReserved && palPalEntry[i].peFlags  & PC_SYS_RESERVED) )
132             continue;
133
134         r = palPalEntry[i].peRed - GetRValue(col);
135         g = palPalEntry[i].peGreen - GetGValue(col);
136         b = palPalEntry[i].peBlue - GetBValue(col);
137
138         r = r*r + g*g + b*b;
139
140         if( r < diff ) { best = i; diff = r; }
141     }
142     return (mapping) ? mapping[best] : best;
143 }
144
145 /***********************************************************************
146  *           COLOR_PaletteLookupExactIndex
147  */
148 int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
149                                    COLORREF col )
150 {
151     int i;
152     BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
153     for( i = 0; i < size; i++ )
154     {
155         if( palPalEntry[i].peFlags & PC_SYS_USED )      /* skips gap */
156             if( palPalEntry[i].peRed == r &&
157                 palPalEntry[i].peGreen == g &&
158                 palPalEntry[i].peBlue == b )
159                 return i;
160     }
161     return -1;
162 }
163
164 /***********************************************************************
165  *           COLOR_LookupNearestColor
166  */
167 COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
168 {
169   unsigned char         spec_type = color >> 24;
170   int                   i;
171
172   /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
173
174   if( spec_type == 2 ) /* PALETTERGB */
175     color = *(COLORREF*)
176              (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
177
178   else if( spec_type == 1 ) /* PALETTEINDEX */
179   {
180     if( (i = color & 0x0000ffff) >= size ) 
181       {
182         WARN("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
183         color = *(COLORREF*)palPalEntry;
184       }
185     else color = *(COLORREF*)(palPalEntry + i);
186   }
187
188   color &= 0x00ffffff;
189   return (0x00ffffff & *(COLORREF*)
190          (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
191 }