Code

Connector tool: make connectors avoid the convex hull of shapes.
[inkscape.git] / src / widgets / ege-paint-def.cpp
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>
54 #if !defined(_)
55 #define _(s) gettext(s)
56 #endif // !defined(_)
58 #include "ege-paint-def.h"
60 namespace ege
61 {
63 static std::string mimeTEXT("text/plain");
64 static std::string mimeX_COLOR("application/x-color");
65 static std::string mimeOSWB_COLOR("application/x-oswb-color");
67 static std::string doubleToStr(double d);
69 PaintDef::PaintDef() :
70     descr(_("none")),
71     type(NONE),
72     r(0),
73     g(0),
74     b(0),
75     editable(false)
76 {
77 }
79 PaintDef::PaintDef( ColorType type ) :
80     descr(),
81     type(type),
82     r(0),
83     g(0),
84     b(0),
85     editable(false)
86 {
87     switch (type) {
88         case CLEAR:
89             descr = _("remove");
90             break;
91         case NONE:
92             descr = _("none");
93             break;
94         case RGB:
95             descr = "";
96             break;
97     }
98 }
100 PaintDef::PaintDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description ) :
101     descr(description),
102     type(RGB),
103     r(r),
104     g(g),
105     b(b),
106     editable(false)
110 PaintDef::~PaintDef()
114 PaintDef::PaintDef( PaintDef const &other )
116     if ( this != &other ) {
117         *this = other;
118     }
121 PaintDef& PaintDef::operator=( PaintDef const &other )
123     if ( this != & other )
124     {
125         type = other.type;
126         r = other.r;
127         g = other.g;
128         b = other.b;
129         descr = other.descr;
130         editable = other.editable;
131     }
132     return *this;
135 class PaintDef::HookData {
136 public:
137     HookData( ColorCallback cb, void* data ) {_cb = cb; _data = data;}
138     ColorCallback _cb;
139     void* _data;
140 };
143 std::vector<std::string> PaintDef::getMIMETypes()
145     std::vector<std::string> listing;
146     listing.push_back(mimeOSWB_COLOR);
147     listing.push_back(mimeX_COLOR);
148     listing.push_back(mimeTEXT);
149     return listing;
152 void PaintDef::getMIMEData(std::string const & type, char*& dest, int& len, int& format)
154     if ( type == mimeTEXT ) {
155         dest = new char[8];
156         snprintf( dest, 8, "#%02x%02x%02x", getR(), getG(), getB() );
157         dest[7] = 0;
158         len = 8;
159         format = 8;
160     } else if ( type == mimeX_COLOR ) {
161         uint16_t* tmp = new uint16_t[4];
162         tmp[0] = (getR() << 8) | getR();
163         tmp[1] = (getG() << 8) | getG();
164         tmp[2] = (getB() << 8) | getB();
165         tmp[3] = 0xffff;
166         dest = reinterpret_cast<char*>(tmp);
167         len = 8;
168         format = 16;
169     } else if ( type == mimeOSWB_COLOR ) {
170         std::string tmp("<paint>");
171         switch ( getType() ) {
172             case ege::PaintDef::NONE:
173             {
174                 tmp += "<nocolor/>";
175             }
176             break;
177             case ege::PaintDef::CLEAR:
178             {
179                 tmp += "<clear/>";
180             }
181             break;
182             default:
183             {
184                 tmp += std::string("<color name=\"") + descr + "\">";
185                 tmp += "<sRGB r=\"";
186                 tmp += doubleToStr(getR()/255.0);
187                 tmp += "\" g=\"";
188                 tmp += doubleToStr(getG()/255.0);
189                 tmp += "\" b=\"";
190                 tmp += doubleToStr(getB()/255.0);
191                 tmp += "\"/>";
192                 tmp += "</color>";
193             }
194         }
195         tmp += "</paint>";
196         len = tmp.size();
197         dest = new char[len];
198         // Note that this is not null-terminated:
199         memcpy(dest, tmp.c_str(), len);
200         format = 8;
201     } else {
202         // nothing
203         dest = 0;
204         len = 0;
205     }
208 bool PaintDef::fromMIMEData(std::string const & type, char const * data, int len, int /*format*/)
210     bool worked = false;
211     bool changed = false;
212     if ( type == mimeTEXT ) {
213     } else if ( type == mimeX_COLOR ) {
214     } else if ( type == mimeOSWB_COLOR ) {
215         std::string xml(data, len);
216         if ( xml.find("<nocolor/>") != std::string::npos ) {
217             if ( (this->type != ege::PaintDef::NONE)
218                  || (this->r != 0)
219                  || (this->g != 0)
220                  || (this->b != 0) ) {
221                 this->type = ege::PaintDef::NONE;
222                 this->r = 0;
223                 this->g = 0;
224                 this->b = 0;
225                 changed = true;
226             }
227             worked = true;
228         } else {
229             size_t pos = xml.find("<sRGB");
230             if ( pos != std::string::npos ) {
231                 size_t endPos = xml.find(">", pos);
232                 std::string srgb = xml.substr(pos, endPos);
233                 this->type = ege::PaintDef::RGB;
234                 size_t numPos = srgb.find("r=");
235                 if (numPos != std::string::npos) {
236                     char* endPtr = 0;
237                     double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
238                     this->r = static_cast<int>(255 * dbl);
239                 }
240                 numPos = srgb.find("g=");
241                 if (numPos != std::string::npos) {
242                     char* endPtr = 0;
243                     double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
244                     this->g = static_cast<int>(255 * dbl);
245                 }
246                 numPos = srgb.find("b=");
247                 if (numPos != std::string::npos) {
248                     char* endPtr = 0;
249                     double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
250                     this->b = static_cast<int>(255 * dbl);
251                 }
253                 size_t pos = xml.find("<color ");
254                 if ( pos != std::string::npos ) {
255                     size_t endPos = xml.find(">", pos);
256                     std::string colorTag = xml.substr(pos, endPos);
258                     size_t namePos = colorTag.find("name=");
259                     if (namePos != std::string::npos) {
260                         char quote = colorTag[namePos + 5];
261                         endPos = colorTag.find(quote, namePos + 6);
262                         descr = colorTag.substr(namePos + 6, endPos - (namePos + 6));
263                     }
264                 }
265                 changed = true;
266                 worked = true;
267             }
268         }
269     }
270     if ( changed ) {
271         // beware of callbacks changing things
272         for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
273         {
274             if ( (*it)->_cb )
275             {
276                 (*it)->_cb( (*it)->_data );
277             }
278         }
279     }
280     return worked;
283 void PaintDef::setRGB( unsigned int r, unsigned int g, unsigned int b )
285     if ( r != this->r || g != this->g || b != this->b ) {
286         this->r = r;
287         this->g = g;
288         this->b = b;
290         // beware of callbacks changing things
291         for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
292         {
293             if ( (*it)->_cb )
294             {
295                 (*it)->_cb( (*it)->_data );
296             }
297         }
298     }
301 void PaintDef::addCallback( ColorCallback cb, void* data )
303     _listeners.push_back( new HookData(cb, data) );
306 void PaintDef::removeCallback( ColorCallback /*cb*/, void* /*data*/ )
310 static std::string doubleToStr(double d)
312     // TODO ensure "." is used for decimal separator.
313     std::stringstream out;
314     out << d;
315     return out.str();
318 } // namespace ege
320 /*
321   Local Variables:
322   mode:c++
323   c-file-style:"stroustrup"
324   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
325   indent-tabs-mode:nil
326   fill-column:99
327   End:
328 */
329 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :