xref: /haiku/src/libs/icon/style/Style.cpp (revision 9d6d3fcf5fe8308cd020cecf89dede440346f8c4)
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