1 /* 2 * Copyright 2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "Style.h" 10 11 #include <new> 12 13 #ifdef ICON_O_MATIC 14 # include <Message.h> 15 16 # include "ui_defines.h" 17 #else 18 # define kWhite (rgb_color){ 255, 255, 255, 255 } 19 #endif // ICON_O_MATIC 20 21 #include "Gradient.h" 22 23 using std::nothrow; 24 25 // constructor 26 Style::Style() 27 #ifdef ICON_O_MATIC 28 : IconObject("<style>"), 29 Observer(), 30 #else 31 : 32 #endif 33 34 fColor(kWhite), 35 fGradient(NULL), 36 fColors(NULL), 37 38 fGammaCorrectedColors(NULL), 39 fGammaCorrectedColorsValid(false) 40 { 41 } 42 43 // constructor 44 Style::Style(const rgb_color& color) 45 #ifdef ICON_O_MATIC 46 : IconObject("<style>"), 47 Observer(), 48 #else 49 : 50 #endif 51 52 fColor(color), 53 fGradient(NULL), 54 fColors(NULL), 55 56 fGammaCorrectedColors(NULL), 57 fGammaCorrectedColorsValid(false) 58 { 59 } 60 61 // constructor 62 Style::Style(const Style& other) 63 #ifdef ICON_O_MATIC 64 : IconObject(other), 65 Observer(), 66 #else 67 : 68 #endif 69 70 fColor(other.fColor), 71 fGradient(NULL), 72 fColors(NULL), 73 74 fGammaCorrectedColors(NULL), 75 fGammaCorrectedColorsValid(false) 76 { 77 SetGradient(other.fGradient); 78 } 79 80 #ifdef ICON_O_MATIC 81 // constructor 82 Style::Style(BMessage* archive) 83 : IconObject(archive), 84 Observer(), 85 86 fColor(kWhite), 87 fGradient(NULL), 88 fColors(NULL), 89 90 fGammaCorrectedColors(NULL), 91 fGammaCorrectedColorsValid(false) 92 { 93 if (!archive) 94 return; 95 96 if (archive->FindInt32("color", (int32*)&fColor) < B_OK) 97 fColor = kWhite; 98 99 BMessage gradientArchive; 100 if (archive->FindMessage("gradient", &gradientArchive) == B_OK) { 101 ::Gradient gradient(&gradientArchive); 102 SetGradient(&gradient); 103 } 104 } 105 #endif // ICON_O_MATIC 106 107 // destructor 108 Style::~Style() 109 { 110 SetGradient(NULL); 111 } 112 113 #ifdef ICON_O_MATIC 114 // ObjectChanged 115 void 116 Style::ObjectChanged(const Observable* object) 117 { 118 if (object == fGradient && fColors) { 119 fGradient->MakeGradient((uint32*)fColors, 256); 120 fGammaCorrectedColorsValid = false; 121 Notify(); 122 } 123 } 124 125 // #pragma mark - 126 127 // Archive 128 status_t 129 Style::Archive(BMessage* into, bool deep) const 130 { 131 status_t ret = IconObject::Archive(into, deep); 132 133 if (ret == B_OK) 134 ret = into->AddInt32("color", (uint32&)fColor); 135 136 if (ret == B_OK && fGradient) { 137 BMessage gradientArchive; 138 ret = fGradient->Archive(&gradientArchive, deep); 139 if (ret == B_OK) 140 ret = into->AddMessage("gradient", &gradientArchive); 141 } 142 143 return ret; 144 } 145 146 // operator == 147 bool 148 Style::operator==(const Style& other) const 149 { 150 if (fGradient) { 151 if (other.fGradient) 152 return *fGradient == *other.fGradient; 153 else 154 return false; 155 } else { 156 if (!other.fGradient) 157 return *(uint32*)&fColor == *(uint32*)&other.fColor; 158 else 159 return false; 160 } 161 } 162 163 #endif // ICON_O_MATIC 164 165 // SetColor 166 void 167 Style::SetColor(const rgb_color& color) 168 { 169 if (*(uint32*)&fColor == *(uint32*)&color) 170 return; 171 172 fColor = color; 173 Notify(); 174 } 175 176 // SetGradient 177 void 178 Style::SetGradient(const ::Gradient* gradient) 179 { 180 if (!fGradient && !gradient) 181 return; 182 183 if (gradient) { 184 if (!fGradient) { 185 fGradient = new (nothrow) ::Gradient(*gradient); 186 if (fGradient) { 187 #ifdef ICON_O_MATIC 188 fGradient->AddObserver(this); 189 #endif 190 // generate gradient 191 fColors = new agg::rgba8[256]; 192 fGradient->MakeGradient((uint32*)fColors, 256); 193 fGammaCorrectedColorsValid = false; 194 195 Notify(); 196 } 197 } else { 198 if (*fGradient != *gradient) { 199 *fGradient = *gradient; 200 } 201 } 202 } else { 203 #ifdef ICON_O_MATIC 204 fGradient->RemoveObserver(this); 205 #endif 206 delete[] fColors; 207 delete[] fGammaCorrectedColors; 208 fColors = NULL; 209 fGammaCorrectedColors = NULL; 210 fGradient = NULL; 211 Notify(); 212 } 213 } 214 215 // GammaCorrectedColors 216 const agg::rgba8* 217 Style::GammaCorrectedColors(const GammaTable& table) const 218 { 219 if (!fColors) 220 return NULL; 221 222 if (!fGammaCorrectedColors) 223 fGammaCorrectedColors = new agg::rgba8[256]; 224 225 if (!fGammaCorrectedColorsValid) { 226 for (int32 i = 0; i < 256; i++) { 227 fGammaCorrectedColors[i].r = table.dir(fColors[i].r); 228 fGammaCorrectedColors[i].g = table.dir(fColors[i].g); 229 fGammaCorrectedColors[i].b = table.dir(fColors[i].b); 230 fGammaCorrectedColors[i].a = fColors[i].a; 231 fGammaCorrectedColors[i].premultiply(); 232 } 233 fGammaCorrectedColorsValid = true; 234 } 235 236 return fGammaCorrectedColors; 237 } 238 239