1 /** @file
2 * @brief EGE paint definition
3 */
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is Eek Color Definition.
18 *
19 * The Initial Developer of the Original Code is
20 * Jon A. Cruz.
21 * Portions created by the Initial Developer are Copyright (C) 2006
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
40 #include "config.h"
42 #ifdef HAVE_LIBINTL_H
43 #include <libintl.h>
44 #endif
46 #include <stdint.h>
47 #include <string>
48 #include <iostream>
49 #include <sstream>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <stdio.h>
53 #include <glibmm/stringutils.h>
55 #if !defined(_)
56 #define _(s) gettext(s)
57 #endif // !defined(_)
59 #include "ege-paint-def.h"
61 namespace ege
62 {
64 static std::string mimeTEXT("text/plain");
65 static std::string mimeX_COLOR("application/x-color");
66 static std::string mimeOSWB_COLOR("application/x-oswb-color");
68 PaintDef::PaintDef() :
69 descr(_("none")),
70 type(NONE),
71 r(0),
72 g(0),
73 b(0),
74 editable(false)
75 {
76 }
78 PaintDef::PaintDef( ColorType type ) :
79 descr(),
80 type(type),
81 r(0),
82 g(0),
83 b(0),
84 editable(false)
85 {
86 switch (type) {
87 case CLEAR:
88 descr = _("remove");
89 break;
90 case NONE:
91 descr = _("none");
92 break;
93 case RGB:
94 descr = "";
95 break;
96 }
97 }
99 PaintDef::PaintDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description ) :
100 descr(description),
101 type(RGB),
102 r(r),
103 g(g),
104 b(b),
105 editable(false)
106 {
107 }
109 PaintDef::~PaintDef()
110 {
111 }
113 PaintDef::PaintDef( PaintDef const &other )
114 {
115 if ( this != &other ) {
116 *this = other;
117 }
118 }
120 PaintDef& PaintDef::operator=( PaintDef const &other )
121 {
122 if ( this != & other )
123 {
124 type = other.type;
125 r = other.r;
126 g = other.g;
127 b = other.b;
128 descr = other.descr;
129 editable = other.editable;
130 }
131 return *this;
132 }
134 class PaintDef::HookData {
135 public:
136 HookData( ColorCallback cb, void* data ) {_cb = cb; _data = data;}
137 ColorCallback _cb;
138 void* _data;
139 };
142 std::vector<std::string> PaintDef::getMIMETypes()
143 {
144 std::vector<std::string> listing;
145 listing.push_back(mimeOSWB_COLOR);
146 listing.push_back(mimeX_COLOR);
147 listing.push_back(mimeTEXT);
148 return listing;
149 }
151 void PaintDef::getMIMEData(std::string const & type, char*& dest, int& len, int& format)
152 {
153 if ( type == mimeTEXT ) {
154 dest = new char[8];
155 snprintf( dest, 8, "#%02x%02x%02x", getR(), getG(), getB() );
156 dest[7] = 0;
157 len = 8;
158 format = 8;
159 } else if ( type == mimeX_COLOR ) {
160 uint16_t* tmp = new uint16_t[4];
161 tmp[0] = (getR() << 8) | getR();
162 tmp[1] = (getG() << 8) | getG();
163 tmp[2] = (getB() << 8) | getB();
164 tmp[3] = 0xffff;
165 dest = reinterpret_cast<char*>(tmp);
166 len = 8;
167 format = 16;
168 } else if ( type == mimeOSWB_COLOR ) {
169 std::string tmp("<paint>");
170 switch ( getType() ) {
171 case ege::PaintDef::NONE:
172 {
173 tmp += "<nocolor/>";
174 }
175 break;
176 case ege::PaintDef::CLEAR:
177 {
178 tmp += "<clear/>";
179 }
180 break;
181 default:
182 {
183 tmp += std::string("<color name=\"") + descr + "\">";
184 tmp += "<sRGB r=\"";
185 tmp += Glib::Ascii::dtostr(getR()/255.0);
186 tmp += "\" g=\"";
187 tmp += Glib::Ascii::dtostr(getG()/255.0);
188 tmp += "\" b=\"";
189 tmp += Glib::Ascii::dtostr(getB()/255.0);
190 tmp += "\"/>";
191 tmp += "</color>";
192 }
193 }
194 tmp += "</paint>";
195 len = tmp.size();
196 dest = new char[len];
197 // Note that this is not null-terminated:
198 memcpy(dest, tmp.c_str(), len);
199 format = 8;
200 } else {
201 // nothing
202 dest = 0;
203 len = 0;
204 }
205 }
207 bool PaintDef::fromMIMEData(std::string const & type, char const * data, int len, int /*format*/)
208 {
209 bool worked = false;
210 bool changed = false;
211 if ( type == mimeTEXT ) {
212 } else if ( type == mimeX_COLOR ) {
213 } else if ( type == mimeOSWB_COLOR ) {
214 std::string xml(data, len);
215 if ( xml.find("<nocolor/>") != std::string::npos ) {
216 if ( (this->type != ege::PaintDef::NONE)
217 || (this->r != 0)
218 || (this->g != 0)
219 || (this->b != 0) ) {
220 this->type = ege::PaintDef::NONE;
221 this->r = 0;
222 this->g = 0;
223 this->b = 0;
224 changed = true;
225 }
226 worked = true;
227 } else {
228 size_t pos = xml.find("<sRGB");
229 if ( pos != std::string::npos ) {
230 size_t endPos = xml.find(">", pos);
231 std::string srgb = xml.substr(pos, endPos);
232 this->type = ege::PaintDef::RGB;
233 size_t numPos = srgb.find("r=");
234 if (numPos != std::string::npos) {
235 double dbl = Glib::Ascii::strtod(srgb.substr(numPos + 3));
236 this->r = static_cast<int>(255 * dbl);
237 }
238 numPos = srgb.find("g=");
239 if (numPos != std::string::npos) {
240 double dbl = Glib::Ascii::strtod(srgb.substr(numPos + 3));
241 this->g = static_cast<int>(255 * dbl);
242 }
243 numPos = srgb.find("b=");
244 if (numPos != std::string::npos) {
245 double dbl = Glib::Ascii::strtod(srgb.substr(numPos + 3));
246 this->b = static_cast<int>(255 * dbl);
247 }
249 size_t pos = xml.find("<color ");
250 if ( pos != std::string::npos ) {
251 size_t endPos = xml.find(">", pos);
252 std::string colorTag = xml.substr(pos, endPos);
254 size_t namePos = colorTag.find("name=");
255 if (namePos != std::string::npos) {
256 char quote = colorTag[namePos + 5];
257 endPos = colorTag.find(quote, namePos + 6);
258 descr = colorTag.substr(namePos + 6, endPos - (namePos + 6));
259 }
260 }
261 changed = true;
262 worked = true;
263 }
264 }
265 }
266 if ( changed ) {
267 // beware of callbacks changing things
268 for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
269 {
270 if ( (*it)->_cb )
271 {
272 (*it)->_cb( (*it)->_data );
273 }
274 }
275 }
276 return worked;
277 }
279 void PaintDef::setRGB( unsigned int r, unsigned int g, unsigned int b )
280 {
281 if ( r != this->r || g != this->g || b != this->b ) {
282 this->r = r;
283 this->g = g;
284 this->b = b;
286 // beware of callbacks changing things
287 for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
288 {
289 if ( (*it)->_cb )
290 {
291 (*it)->_cb( (*it)->_data );
292 }
293 }
294 }
295 }
297 void PaintDef::addCallback( ColorCallback cb, void* data )
298 {
299 _listeners.push_back( new HookData(cb, data) );
300 }
302 void PaintDef::removeCallback( ColorCallback /*cb*/, void* /*data*/ )
303 {
304 }
307 } // namespace ege
309 /*
310 Local Variables:
311 mode:c++
312 c-file-style:"stroustrup"
313 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
314 indent-tabs-mode:nil
315 fill-column:99
316 End:
317 */
318 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :