blob: 5ee3a06afe8ee9867b73fd19edad2ee51e3601df [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 Julliardaf0bae51995-10-03 17:06:08 +00006 */
7
Alexandre Julliard234bc241994-12-10 13:02:28 +00008#include "color.h"
Alexandre Julliard15657091999-05-23 10:25:25 +00009#include "debugtools.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000010#include "palette.h"
11#include "windef.h"
Alexandre Julliardf0b23541993-09-29 12:21:49 +000012
Dimitrie O. Paun529da542000-11-27 23:54:25 +000013DEFAULT_DEBUG_CHANNEL(palette);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000014
Alexandre Julliardff8331e1995-09-18 11:19:54 +000015
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000016/***********************************************************************
17 * System color space.
Alexandre Julliard18f92e71996-07-17 20:02:21 +000018 *
19 * First 10 and last 10 colors in COLOR_sysPalette are
20 * "guarded". RealizePalette changes only the rest of colorcells. For
21 * currently inactive window it changes only DC palette mappings.
22 */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000023
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000024PALETTEENTRY *COLOR_sysPal = NULL; /* current system palette */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000025
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000026int COLOR_gapStart = 256;
27int COLOR_gapEnd = -1;
28int COLOR_gapFilled = 0;
29int COLOR_max = 256;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000030
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000031const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
Alexandre Julliardf0b23541993-09-29 12:21:49 +000032{
Alexandre Julliard18f92e71996-07-17 20:02:21 +000033 /* first 10 entries in the system palette */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000034 /* red green blue flags */
Alexandre Julliard18f92e71996-07-17 20:02:21 +000035 { 0x00, 0x00, 0x00, PC_SYS_USED },
36 { 0x80, 0x00, 0x00, PC_SYS_USED },
37 { 0x00, 0x80, 0x00, PC_SYS_USED },
38 { 0x80, 0x80, 0x00, PC_SYS_USED },
39 { 0x00, 0x00, 0x80, PC_SYS_USED },
40 { 0x80, 0x00, 0x80, PC_SYS_USED },
41 { 0x00, 0x80, 0x80, PC_SYS_USED },
42 { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
43 { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
44 { 0xa6, 0xca, 0xf0, PC_SYS_USED },
Alexandre Julliardf0b23541993-09-29 12:21:49 +000045
Alexandre Julliard18f92e71996-07-17 20:02:21 +000046 /* ... c_min/2 dynamic colorcells */
47
48 /* ... gap (for sparse palettes) */
49
50 /* ... c_min/2 dynamic colorcells */
51
52 { 0xff, 0xfb, 0xf0, PC_SYS_USED },
53 { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
54 { 0x80, 0x80, 0x80, PC_SYS_USED },
55 { 0xff, 0x00, 0x00, PC_SYS_USED },
56 { 0x00, 0xff, 0x00, PC_SYS_USED },
57 { 0xff, 0xff, 0x00, PC_SYS_USED },
58 { 0x00, 0x00, 0xff, PC_SYS_USED },
59 { 0xff, 0x00, 0xff, PC_SYS_USED },
60 { 0x00, 0xff, 0xff, PC_SYS_USED },
61 { 0xff, 0xff, 0xff, PC_SYS_USED } /* last 10 */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000062};
63
Alexandre Julliard18f92e71996-07-17 20:02:21 +000064/***********************************************************************
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000065 * COLOR_GetSystemPaletteTemplate
Alexandre Julliard18f92e71996-07-17 20:02:21 +000066 */
Alexandre Julliard23946ad1997-06-16 17:43:53 +000067const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void)
68{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000069 return COLOR_sysPalTemplate;
Alexandre Julliard23946ad1997-06-16 17:43:53 +000070}
71
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000072/***********************************************************************
73 * COLOR_GetSystemPaletteEntry
74 */
75
Alexandre Julliarda3960291999-02-26 11:11:13 +000076COLORREF COLOR_GetSystemPaletteEntry(UINT i)
Alexandre Julliard18f92e71996-07-17 20:02:21 +000077{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000078 return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000079}
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000080
81/***********************************************************************
82 * COLOR_IsSolid
83 *
84 * Check whether 'color' can be represented with a solid color.
85 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000086BOOL COLOR_IsSolid( COLORREF color )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000087{
88 int i;
Alexandre Julliard18f92e71996-07-17 20:02:21 +000089 const PALETTEENTRY *pEntry = COLOR_sysPal;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000090
Alexandre Julliard18f92e71996-07-17 20:02:21 +000091 if (color & 0xff000000) return TRUE; /* indexed color */
92
93 if (!color || (color == 0xffffff)) return TRUE; /* black or white */
94
95 for (i = 0; i < 256 ; i++, pEntry++)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000096 {
Alexandre Julliard18f92e71996-07-17 20:02:21 +000097 if( i < COLOR_gapStart || i > COLOR_gapEnd )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000098 if ((GetRValue(color) == pEntry->peRed) &&
99 (GetGValue(color) == pEntry->peGreen) &&
100 (GetBValue(color) == pEntry->peBlue)) return TRUE;
101 }
102 return FALSE;
103}
104
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000105/***********************************************************************
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000106 * COLOR_PaletteLookupPixel
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000107 */
108int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000109 int* mapping, COLORREF col, BOOL skipReserved )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000110{
111 int i, best = 0, diff = 0x7fffffff;
112 int r,g,b;
113
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000114 for( i = 0; i < size && diff ; i++ )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000115 {
116 if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
117 (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED) )
118 continue;
119
120 r = palPalEntry[i].peRed - GetRValue(col);
121 g = palPalEntry[i].peGreen - GetGValue(col);
122 b = palPalEntry[i].peBlue - GetBValue(col);
123
124 r = r*r + g*g + b*b;
125
126 if( r < diff ) { best = i; diff = r; }
127 }
128 return (mapping) ? mapping[best] : best;
129}
130
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000131/***********************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000132 * COLOR_PaletteLookupExactIndex
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000133 */
134int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
135 COLORREF col )
136{
137 int i;
138 BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
139 for( i = 0; i < size; i++ )
140 {
Alexandre Julliardf1aa3031996-08-05 17:42:43 +0000141 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000142 if( palPalEntry[i].peRed == r &&
143 palPalEntry[i].peGreen == g &&
144 palPalEntry[i].peBlue == b )
145 return i;
146 }
147 return -1;
148}
149
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000150/***********************************************************************
151 * COLOR_LookupNearestColor
152 */
153COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
154{
155 unsigned char spec_type = color >> 24;
156 int i;
157
158 /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
159
160 if( spec_type == 2 ) /* PALETTERGB */
161 color = *(COLORREF*)
162 (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
163
164 else if( spec_type == 1 ) /* PALETTEINDEX */
Jesper Skov5c3e4571998-11-01 19:27:22 +0000165 {
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000166 if( (i = color & 0x0000ffff) >= size )
167 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000168 WARN("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000169 color = *(COLORREF*)palPalEntry;
170 }
171 else color = *(COLORREF*)(palPalEntry + i);
Jesper Skov5c3e4571998-11-01 19:27:22 +0000172 }
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000173
174 color &= 0x00ffffff;
175 return (0x00ffffff & *(COLORREF*)
176 (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
177}