blob: e6c4f9e89b59ceafbe9d44117b9464e5cd092f50 [file] [log] [blame]
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001/*
2 * Color functions
3 *
4 * Copyright 1993 Alexandre Julliard
Alexandre Julliard18f92e71996-07-17 20:02:21 +00005 * Copyright 1996 Alex Korobka
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 *
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
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000020 */
21
Alexandre Julliard234bc241994-12-10 13:02:28 +000022#include "color.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000023#include "wine/debug.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000024#include "palette.h"
25#include "windef.h"
Alexandre Julliardf0b23541993-09-29 12:21:49 +000026
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000027WINE_DEFAULT_DEBUG_CHANNEL(palette);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000028
Alexandre Julliardff8331e1995-09-18 11:19:54 +000029
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000030/***********************************************************************
31 * System color space.
Alexandre Julliard18f92e71996-07-17 20:02:21 +000032 *
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 */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000037
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000038PALETTEENTRY *COLOR_sysPal = NULL; /* current system palette */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000039
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000040int COLOR_gapStart = 256;
41int COLOR_gapEnd = -1;
42int COLOR_gapFilled = 0;
43int COLOR_max = 256;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000044
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000045const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
Alexandre Julliardf0b23541993-09-29 12:21:49 +000046{
Alexandre Julliard18f92e71996-07-17 20:02:21 +000047 /* first 10 entries in the system palette */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000048 /* red green blue flags */
Alexandre Julliard18f92e71996-07-17 20:02:21 +000049 { 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 },
Alexandre Julliardf0b23541993-09-29 12:21:49 +000059
Alexandre Julliard18f92e71996-07-17 20:02:21 +000060 /* ... 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 */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000076};
77
Alexandre Julliard18f92e71996-07-17 20:02:21 +000078/***********************************************************************
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000079 * COLOR_GetSystemPaletteTemplate
Alexandre Julliard18f92e71996-07-17 20:02:21 +000080 */
Alexandre Julliard23946ad1997-06-16 17:43:53 +000081const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
82{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000083 return COLOR_sysPalTemplate;
Alexandre Julliard23946ad1997-06-16 17:43:53 +000084}
85
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000086/***********************************************************************
87 * COLOR_GetSystemPaletteEntry
88 */
89
Alexandre Julliarda3960291999-02-26 11:11:13 +000090COLORREF COLOR_GetSystemPaletteEntry(UINT i)
Alexandre Julliard18f92e71996-07-17 20:02:21 +000091{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000092 return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000093}
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000094
95/***********************************************************************
96 * COLOR_IsSolid
97 *
98 * Check whether 'color' can be represented with a solid color.
99 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000100BOOL COLOR_IsSolid( COLORREF color )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000101{
102 int i;
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000103 const PALETTEENTRY *pEntry = COLOR_sysPal;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000104
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000105 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++)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000110 {
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000111 if( i < COLOR_gapStart || i > COLOR_gapEnd )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000112 if ((GetRValue(color) == pEntry->peRed) &&
113 (GetGValue(color) == pEntry->peGreen) &&
114 (GetBValue(color) == pEntry->peBlue)) return TRUE;
115 }
116 return FALSE;
117}
118
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000119/***********************************************************************
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000120 * COLOR_PaletteLookupPixel
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000121 */
122int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000123 int* mapping, COLORREF col, BOOL skipReserved )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000124{
125 int i, best = 0, diff = 0x7fffffff;
126 int r,g,b;
127
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000128 for( i = 0; i < size && diff ; i++ )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000129 {
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
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000145/***********************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000146 * COLOR_PaletteLookupExactIndex
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000147 */
148int 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 {
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000155 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000156 if( palPalEntry[i].peRed == r &&
157 palPalEntry[i].peGreen == g &&
158 palPalEntry[i].peBlue == b )
159 return i;
160 }
161 return -1;
162}
163
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000164/***********************************************************************
165 * COLOR_LookupNearestColor
166 */
167COLORREF 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 */
Jesper Skov5c3e4571998-11-01 19:27:22 +0000179 {
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000180 if( (i = color & 0x0000ffff) >= size )
181 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000182 WARN("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000183 color = *(COLORREF*)palPalEntry;
184 }
185 else color = *(COLORREF*)(palPalEntry + i);
Jesper Skov5c3e4571998-11-01 19:27:22 +0000186 }
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000187
188 color &= 0x00ffffff;
189 return (0x00ffffff & *(COLORREF*)
190 (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
191}