00001 #ifndef PALETTE_IMPLEMENTATION_FILE
00002 #define PALETTE_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "palette.h"
00019 #include "wp_implementation.h"
00020
00021 #include <basis/function.h>
00022 #include <basis/guards.h>
00023
00024 #include <stdlib.h>
00025
00026 static bool color_initted = false;
00027 color BLACK(0, 0, 0);
00028 color WHITE(MAXIMUM_COLOR_INTENSITY, MAXIMUM_COLOR_INTENSITY,
00029 MAXIMUM_COLOR_INTENSITY);
00030
00031 const int MAXIMUM_DEFAULT_COLORS = 64;
00032
00033 palette::palette(window_handle parent, int install_gray)
00034 : _parent(parent, parent),
00035 graymap(NIL),
00036 number_in_graymap(0),
00037 maximum_colors_on_screen(0)
00038 {
00039 #ifdef __XWINDOWS__
00040 _colormap = XCreateColormap(_parent.display(), _parent.window(),
00041 DefaultVisual(_parent.display(), DefaultScreen(_parent.display())),
00042 AllocNone);
00043 if (!_colormap) non_continuable_error("palette", "palette", "NIL colormap");
00044 XSetWindowColormap(_parent.display(), _parent.window(), _colormap);
00045 maximum_colors_on_screen = DisplayCells
00046 (_parent.display(), DefaultScreen(_parent.display()));
00047
00048 if (!color_initted) {
00049 add(BLACK);
00050
00051 Colormap default_colors = DefaultColormap
00052 (_parent.display(), DefaultScreen(_parent.display()));
00053 int colors_to_steal = minimum
00054 (maximum_colors_on_screen, MAXIMUM_DEFAULT_COLORS);
00055
00056
00057 for (int i = 0; i < colors_to_steal; i++) {
00058 XColor color_i;
00059 color_i.pixel = i;
00060 XQueryColor(_parent.display(), default_colors, &color_i);
00061 color to_stuff(color_i.red, color_i.green, color_i.blue);
00062 add(to_stuff);
00063
00064 }
00065 add(WHITE);
00066 if (install_gray) install_gray_colormap(install_gray);
00067 color_initted = true;
00068 }
00069 #elif defined(MS_WINDOWS)
00070 #elif defined(OS_2)
00071 #endif
00072 }
00073
00074 palette::~palette() { if (graymap) delete [] graymap; }
00075
00076 void palette::apply(window_handle to_apply_to)
00077 {
00078 nub to_attach(to_apply_to, to_apply_to);
00079 XSetWindowColormap(to_attach.display(), to_attach.window(), _colormap);
00080 }
00081
00082 int palette::size_of_colormap() const { return maximum_colors_on_screen; }
00083
00084 window_color palette::translate(color &to_add_or_find)
00085 {
00086 bool result;
00087 return add(to_add_or_find, result);
00088 }
00089
00090 void palette::install_gray_colormap(int number_of_colors)
00091 {
00092 if (number_of_colors <= 0) return;
00093
00094 if ( (number_in_graymap > 0) && graymap) return;
00095
00096
00097
00098 number_in_graymap = number_of_colors;
00099
00100 int gray_offset = 10000;
00101
00102 int scale_factor
00103 = (MAXIMUM_COLOR_INTENSITY - gray_offset) / maximum_colors_on_screen;
00104 int map_ratio = maximum_colors_on_screen / number_of_colors;
00105 if (!map_ratio) map_ratio = 1;
00106
00107
00108
00109 graymap = new Pixel[maximum_colors_on_screen];
00110
00111 for (int i = 0; i < maximum_colors_on_screen; i += map_ratio) {
00112
00113 int rgb_color_value = gray_offset + i * scale_factor;
00114 color pix_color(rgb_color_value, rgb_color_value, rgb_color_value);
00115 window_color mapped = translate(pix_color);
00116 int inner_bound = minimum(maximum_colors_on_screen, i + map_ratio);
00117 for (int j = i; j < inner_bound; j++) graymap[j] = mapped.pixel;
00118 }
00119 }
00120
00121 bool palette::add(color &to_add)
00122 { bool result; add(to_add, result); return result; }
00123
00124 window_color palette::add(color &to_add, bool &success)
00125 {
00126 FUNCDEF("add");
00127 #ifdef __XWINDOWS__
00128 window_color to_return;
00129 if (to_add.index() >= 0) {
00130 to_return.pixel = to_add.index();
00131 to_return.flags = DoRed | DoGreen | DoBlue;
00132 XQueryColor(_parent.display(), _colormap, &to_return);
00133 return to_return;
00134 }
00135 to_return.red = to_add.red();
00136 to_return.green = to_add.green();
00137 to_return.blue = to_add.blue();
00138 success = XAllocColor(_parent.display(), _colormap, &to_return);
00139 if (!success) LOG("could not add color");
00140 to_add.red(to_return.red);
00141 to_add.green(to_return.green);
00142 to_add.blue(to_return.blue);
00143 to_add.index(to_return.pixel);
00144
00145
00146 #elif defined(MS_WINDOWS)
00147 #elif defined(OS_2)
00148 #endif
00149 return to_return;
00150 }
00151
00152 void palette::make_map(Pixel *map)
00153 {
00154 if (!number_in_graymap) return;
00155 for (int i = 0; i < maximum_colors_on_screen; i++) map[i] = graymap[i];
00156 }
00157
00158 color palette::lookup(const char *color_name)
00159 {
00160 FUNCDEF("lookup");
00161 #ifdef __XWINDOWS__
00162 Colormap temp = DefaultColormap(_parent.display(), _parent.screen());
00163 window_color approx;
00164 window_color exact;
00165 if (XLookupColor(_parent.display(), temp, color_name, &exact, &approx)) {
00166 color to_return(approx.red, approx.green, approx.blue);
00167 add(to_return);
00168 return to_return;
00169 } else {
00170 LOG(isprintf("cannot find color %s", color_name));
00171 return BLACK;
00172 }
00173 #elif defined(MS_WINDOWS)
00174 #elif defined(OS_2)
00175 #endif
00176 }
00177
00178
00179 #endif //PALETTE_IMPLEMENTATION_FILE
00180