///////////////////////////////////////////////////////////////////////////// // Name: MenuPalettes.h // Purpose: The class to create and store menu palettes // Author: Alex Thuering // Created: 04.11.2006 // RCS-ID: $Id: MenuPalettes.cpp,v 1.2 2006/12/06 14:53:37 ntalex Exp $ // Copyright: (c) Alex Thuering // Licence: GPL ///////////////////////////////////////////////////////////////////////////// #include "MenuPalettes.h" #include bool Palette::Create(IntHashSet& colours, const wxColour& transpColour) { if (colours.find(-1) != colours.end()) // => image can contain transparent pixels { m_transpColour = transpColour; colours.erase(-1); } coloursCount = colours.size(); unsigned char r[colours.size()], g[colours.size()], b[colours.size()]; int i = 0; for (IntHashSet::iterator it = colours.begin(); it != colours.end(); ++it) { unsigned int color = (unsigned int) *it; r[i] = (color>>16)&0xFF; g[i] = (color>>8)&0xFF; b[i] = color&0xFF; i++; } return wxPalette::Create(colours.size(), r, g, b); } bool Palette::Apply(const unsigned char* pixel, unsigned char *dest) const { if (coloursCount == 0) { // there are no colours => colour of this pixel can be only transparent dest[0] = m_transpColour.Red(); dest[1] = m_transpColour.Green(); dest[2] = m_transpColour.Blue(); } else if (!m_transpColour.Ok() || pixel[0] != m_transpColour.Red() || pixel[1] != m_transpColour.Green() || pixel[2] != m_transpColour.Blue()) // skip transparent pixels { // find matched colour int n = GetPixel(pixel[0], pixel[1], pixel[2]); return wxPalette::GetRGB(n, dest, dest +1, dest + 2); } return true; } WX_DECLARE_HASH_MAP(int, IntHashSet, wxIntegerHash, wxIntegerEqual, IntHashSetMap); WX_DECLARE_HASH_MAP(int, IntHashSetMap, wxIntegerHash, wxIntegerEqual, IntHashSet2DMap); ///////////////////////////// Menu Palettes ////////////////////////////////// MenuPalettes::MenuPalettes(MenuObject& obj, const wxColour& transpColour) { m_transpColour = transpColour; // palette 1 for buttons_normal => all colours + transport colour IntHashSet colours; for (int i=0; ichangeable) { wxColour& colour = param->normalColour; int value = colour.Ok() ? (colour.Red()<<16) + (colour.Green()<<8) + colour.Blue() : -1; colours.insert(value); } } colours.insert(-1); // first image can always contain transparent pixels m_palette1.Create(colours, transpColour); // palette(s) 2 for buttons_highlighted => a palette per colour from palette 1 IntHashSetMap coloursMap; for (int i=0; ichangeable) { wxColour& colour1 = param->normalColour; int key1 = colour1.Ok() ? (colour1.Red()<<16) + (colour1.Green()<<8) + colour1.Blue() : -1; wxColour& colour = param->highlightedColour; int value = colour.Ok() ? (colour.Red()<<16) + (colour.Green()<<8) + colour.Blue() : -1; coloursMap[key1].insert(value); } } coloursMap[-1].insert(-1); // second image can contain transparent pixels if pixel in first image is transparent for (IntHashSetMap::iterator it = coloursMap.begin(); it != coloursMap.end(); ++it) m_palette2[it->first].Create(it->second, transpColour); // palette(s) 2 for buttons_selected => a palette per colour from palette 1 and 2 IntHashSet2DMap colours2DMap; for (int i=0; ichangeable) { wxColour& colour1 = param->normalColour; int key1 = colour1.Ok() ? (colour1.Red()<<16) + (colour1.Green()<<8) + colour1.Blue() : -1; wxColour& colour2 = param->highlightedColour; int key2 = colour2.Ok() ? (colour2.Red()<<16) + (colour2.Green()<<8) + colour2.Blue() : -1; wxColour& colour = param->selectedColour; int value = colour.Ok() ? (colour.Red()<<16) + (colour.Green()<<8) + colour.Blue() : -1; colours2DMap[key1][key2].insert(value); } } colours2DMap[-1][-1].insert(-1); // third image can contain transparent pixels if pixel in first and second image is transparent for (IntHashSet2DMap::iterator it = colours2DMap.begin(); it != colours2DMap.end(); ++it) for (IntHashSetMap::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) m_palette3[it->first][it2->first].Create(it2->second, transpColour); } int MenuPalettes::GetKey(const unsigned char* pixel) { if (pixel[0] == m_transpColour.Red() && pixel[1] == m_transpColour.Green() && pixel[2] == m_transpColour.Blue()) return -1; // it's transparent colour return (pixel[0]<<16) + (pixel[1]<<8) + pixel[2]; } bool MenuPalettes::Apply(const unsigned char* pixel1, unsigned char *dest) { return m_palette1.Apply(pixel1, dest); } bool MenuPalettes::Apply(const unsigned char* pixel1, const unsigned char* pixel2, unsigned char *dest) { int key1 = GetKey(pixel1); return m_palette2[key1].Apply(pixel2, dest); } bool MenuPalettes::Apply(const unsigned char* pixel1, const unsigned char* pixel2, const unsigned char* pixel3, unsigned char *dest) { int key1 = GetKey(pixel1); int key2 = GetKey(pixel2); return m_palette3[key1][key2].Apply(pixel3, dest); }