palette.cpp

Go to the documentation of this file.
00001 #ifndef PALETTE_IMPLEMENTATION_FILE
00002 #define PALETTE_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : palette                                                           *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1991-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
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     // copy part of the default colormap...
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 //hmmm: this really should be using the number actually currently mapped
00056 //      rather than the total supported by the screen....
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         // updates colormap of ours by adding a default color to it.
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     // no colors to allocate.
00094   if ( (number_in_graymap > 0) && graymap) return;
00095     // already allocated some colors.  in future this should be done better
00096     // by deallocating current gray scale colors...?
00097 
00098   number_in_graymap = number_of_colors;
00099 
00100   int gray_offset = 10000;
00101     // gray_offset: Chosen to lighten the images.
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;  // if more to allocate than possible?
00106 
00107 //LOG(isprintf("number cols %d, scale %d, max col int %d, map ratio %d", number_of_colors, scale_factor, 255*scale_factor + gray_offset, map_ratio));
00108 
00109   graymap = new Pixel[maximum_colors_on_screen];
00110 
00111   for (int i = 0; i < maximum_colors_on_screen; i += map_ratio) {
00112 //LOG(isprintf("i=%d, c=%d", i, gray_offset+i * scale_factor));
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     // the index must come after the three color values are set because the
00145     // color modifier functions reset the pixel index.
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 

Generated on Fri Nov 21 04:29:23 2008 for HOOPLE Libraries by  doxygen 1.5.1