Code

Adding simple debug
[inkscape.git] / src / color-profile.cpp
3 #include "xml/repr.h"
4 #include "color-profile.h"
5 #include "color-profile-fns.h"
6 #include "attributes.h"
7 #include "document.h"
9 //#define DEBUG_LCMS
11 #ifdef DEBUG_LCMS
12 #include "prefs-utils.h"
13 #include <gtk/gtkmessagedialog.h>
14 #endif // DEBUG_LCMS
16 using Inkscape::ColorProfile;
17 using Inkscape::ColorProfileClass;
19 namespace Inkscape
20 {
21 static void colorprofile_class_init( ColorProfileClass *klass );
22 static void colorprofile_init( ColorProfile *cprof );
24 static void colorprofile_release( SPObject *object );
25 static void colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr );
26 static void colorprofile_set( SPObject *object, unsigned key, gchar const *value );
27 static Inkscape::XML::Node *colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags );
28 }
30 #ifdef DEBUG_LCMS
31 extern guint update_in_progress;
32 #define DEBUG_MESSAGE(key, ...) \
33 {\
34     gint dump = prefs_get_int_attribute_limited("options.scislac", #key, 0, 0, 1);\
35     gint dumpD = prefs_get_int_attribute_limited("options.scislac", #key"D", 0, 0, 1);\
36     gint dumpD2 = prefs_get_int_attribute_limited("options.scislac", #key"D2", 0, 0, 1);\
37     dumpD &= ( (update_in_progress == 0) || dumpD2 );\
38     if ( dump )\
39     {\
40         g_message( __VA_ARGS__ );\
41 \
42     }\
43     if ( dumpD )\
44     {\
45         GtkWidget *dialog = gtk_message_dialog_new(NULL,\
46                                                    GTK_DIALOG_DESTROY_WITH_PARENT, \
47                                                    GTK_MESSAGE_INFO,    \
48                                                    GTK_BUTTONS_OK,      \
49                                                    __VA_ARGS__          \
50                                                    );\
51         g_signal_connect_swapped(dialog, "response",\
52                                  G_CALLBACK(gtk_widget_destroy),        \
53                                  dialog);                               \
54         gtk_widget_show_all( dialog );\
55     }\
56 }
57 #endif // DEBUG_LCMS
59 static SPObject *cprof_parent_class;
61 /**
62  * Register ColorProfile class and return its type.
63  */
64 GType Inkscape::colorprofile_get_type()
65 {
66     static GType type = 0;
67     if (!type) {
68         GTypeInfo info = {
69             sizeof(ColorProfileClass),
70             NULL, NULL,
71             (GClassInitFunc) colorprofile_class_init,
72             NULL, NULL,
73             sizeof(ColorProfile),
74             16,
75             (GInstanceInitFunc) colorprofile_init,
76             NULL,   /* value_table */
77         };
78         type = g_type_register_static( SP_TYPE_OBJECT, "ColorProfile", &info, static_cast<GTypeFlags>(0) );
79     }
80     return type;
81 }
83 /**
84  * ColorProfile vtable initialization.
85  */
86 static void Inkscape::colorprofile_class_init( ColorProfileClass *klass )
87 {
88     SPObjectClass *sp_object_class = reinterpret_cast<SPObjectClass *>(klass);
90     cprof_parent_class = static_cast<SPObject*>(g_type_class_ref(SP_TYPE_OBJECT));
92     sp_object_class->release = colorprofile_release;
93     sp_object_class->build = colorprofile_build;
94     sp_object_class->set = colorprofile_set;
95     sp_object_class->write = colorprofile_write;
96 }
98 /**
99  * Callback for ColorProfile object initialization.
100  */
101 static void Inkscape::colorprofile_init( ColorProfile *cprof )
103     cprof->href = 0;
104     cprof->local = 0;
105     cprof->name = 0;
106     cprof->intentStr = 0;
107     cprof->rendering_intent = Inkscape::RENDERING_INTENT_UNKNOWN;
108 #if ENABLE_LCMS
109     cprof->profHandle = 0;
110 #endif // ENABLE_LCMS
113 /**
114  * Callback: free object
115  */
116 static void Inkscape::colorprofile_release( SPObject *object )
118     ColorProfile *cprof = COLORPROFILE(object);
119     if ( cprof->href ) {
120         g_free( cprof->href );
121         cprof->href = 0;
122     }
124     if ( cprof->local ) {
125         g_free( cprof->local );
126         cprof->local = 0;
127     }
129     if ( cprof->name ) {
130         g_free( cprof->name );
131         cprof->name = 0;
132     }
134     if ( cprof->intentStr ) {
135         g_free( cprof->intentStr );
136         cprof->intentStr = 0;
137     }
139 #if ENABLE_LCMS
140     if ( cprof->profHandle ) {
141         cmsCloseProfile( cprof->profHandle );
142         cprof->profHandle = 0;
143     }
144 #endif // ENABLE_LCMS
147 /**
148  * Callback: set attributes from associated repr.
149  */
150 static void Inkscape::colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr )
152     ColorProfile *cprof = COLORPROFILE(object);
153     g_assert(cprof->href == 0);
154     g_assert(cprof->local == 0);
155     g_assert(cprof->name == 0);
156     g_assert(cprof->intentStr == 0);
158     if (((SPObjectClass *) cprof_parent_class)->build) {
159         (* ((SPObjectClass *) cprof_parent_class)->build)(object, document, repr);
160     }
161     sp_object_read_attr( object, "xlink:href" );
162     sp_object_read_attr( object, "local" );
163     sp_object_read_attr( object, "name" );
164     sp_object_read_attr( object, "rendering-intent" );
167 /**
168  * Callback: set attribute.
169  */
170 static void Inkscape::colorprofile_set( SPObject *object, unsigned key, gchar const *value )
172     ColorProfile *cprof = COLORPROFILE(object);
174     switch (key) {
175         case SP_ATTR_XLINK_HREF:
176             if ( cprof->href ) {
177                 g_free( cprof->href );
178                 cprof->href = 0;
179             }
180             if ( value ) {
181                 cprof->href = g_strdup( value );
182                 if ( *cprof->href ) {
183 #if ENABLE_LCMS
184                     cmsErrorAction( LCMS_ERROR_SHOW );
186                     // TODO open filename and URIs properly
187                     //FILE* fp = fopen_utf8name( filename, "r" );
188                     //LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
190                     if ( !g_path_is_absolute(cprof->href) ) {
191                         // Try to open relative
192                         gchar* docbase = SP_DOCUMENT_BASE( SP_OBJECT_DOCUMENT(object) );
193                         gchar* fullname = g_build_filename( docbase ? docbase : ".", cprof->href, NULL );
195                         cprof->profHandle = cmsOpenProfileFromFile( fullname, "r" );
196 #ifdef DEBUG_LCMS
197                         DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->profHandle );
198 #endif // DEBUG_LCMS
199                         g_free (fullname);
200                     } else {
201                         cprof->profHandle = cmsOpenProfileFromFile( cprof->href, "r" );
202 #ifdef DEBUG_LCMS
203                         DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", cprof->href, (void*)cprof->profHandle );
204 #endif // DEBUG_LCMS
205                     }
207 #endif // ENABLE_LCMS
208                 }
209             }
210             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
211             break;
213         case SP_ATTR_LOCAL:
214             if ( cprof->local ) {
215                 g_free( cprof->local );
216                 cprof->local = 0;
217             }
218             cprof->local = g_strdup( value );
219             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
220             break;
222         case SP_ATTR_NAME:
223             if ( cprof->name ) {
224                 g_free( cprof->name );
225                 cprof->name = 0;
226             }
227             cprof->name = g_strdup( value );
228 #ifdef DEBUG_LCMS
229             DEBUG_MESSAGE( lcmsTwo, "<color-profile> name set to '%s'", cprof->name );
230 #endif // DEBUG_LCMS
231             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
232             break;
234         case SP_ATTR_RENDERING_INTENT:
235             if ( cprof->intentStr ) {
236                 g_free( cprof->intentStr );
237                 cprof->intentStr = 0;
238             }
239             cprof->intentStr = g_strdup( value );
241             if ( value ) {
242                 if ( strcmp( value, "auto" ) == 0 ) {
243                     cprof->rendering_intent = RENDERING_INTENT_AUTO;
244                 } else if ( strcmp( value, "perceptual" ) == 0 ) {
245                     cprof->rendering_intent = RENDERING_INTENT_PERCEPTUAL;
246                 } else if ( strcmp( value, "relative-colorimetric" ) == 0 ) {
247                     cprof->rendering_intent = RENDERING_INTENT_RELATIVE_COLORIMETRIC;
248                 } else if ( strcmp( value, "saturation" ) == 0 ) {
249                     cprof->rendering_intent = RENDERING_INTENT_SATURATION;
250                 } else if ( strcmp( value, "absolute-colorimetric" ) == 0 ) {
251                     cprof->rendering_intent = RENDERING_INTENT_ABSOLUTE_COLORIMETRIC;
252                 } else {
253                     cprof->rendering_intent = RENDERING_INTENT_UNKNOWN;
254                 }
255             } else {
256                 cprof->rendering_intent = RENDERING_INTENT_UNKNOWN;
257             }
259             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
260             break;
262         default:
263             if (((SPObjectClass *) cprof_parent_class)->set) {
264                 (* ((SPObjectClass *) cprof_parent_class)->set)(object, key, value);
265             }
266             break;
267     }
271 /**
272  * Callback: write attributes to associated repr.
273  */
274 static Inkscape::XML::Node* Inkscape::colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags )
276     ColorProfile *cprof = COLORPROFILE(object);
278     if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
279         repr = sp_repr_new("svg:color-profile");
280     }
282     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) {
283         repr->setAttribute( "xlink:href", cprof->href );
284     }
286     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->local ) {
287         repr->setAttribute( "local", cprof->local );
288     }
290     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->name ) {
291         repr->setAttribute( "name", cprof->name );
292     }
294     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->intentStr ) {
295         repr->setAttribute( "rendering-intent", cprof->intentStr );
296     }
298     if (((SPObjectClass *) cprof_parent_class)->write) {
299         (* ((SPObjectClass *) cprof_parent_class)->write)(object, repr, flags);
300     }
302     return repr;
306 #if ENABLE_LCMS
309 static SPObject* bruteFind( SPObject* curr, gchar* const name )
311     SPObject* result = 0;
313     if ( curr ) {
314         if ( IS_COLORPROFILE(curr) ) {
315             ColorProfile* prof = COLORPROFILE(curr);
316             if ( prof ) {
317                 if ( prof->name && (strcmp(prof->name, name) == 0) ) {
318                     result = curr;
319                 }
320             }
321         } else {
322             if ( curr->hasChildren() ) {
323                 SPObject* child = curr->firstChild();
324                 while ( child && !result ) {
325                     result = bruteFind( child, name );
326                     if ( !result ) {
327                         child = child->next;
328                     }
329                 };
330             }
331         }
332     }
334     return result;
337 cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* intent, gchar* const name )
339     cmsHPROFILE prof = 0;
341     SPObject* root = SP_DOCUMENT_ROOT(document);
342     SPObject* thing = bruteFind( root, name );
343     if ( thing ) {
344         prof = COLORPROFILE(thing)->profHandle;
345     }
347     if ( intent ) {
348         *intent = thing ? COLORPROFILE(thing)->rendering_intent : (guint)RENDERING_INTENT_UNKNOWN;
349     }
351 #ifdef DEBUG_LCMS
352     DEBUG_MESSAGE( lcmsThree, "<color-profile> queried for profile of '%s'. Returning %p with intent of %d", name, prof, (intent? *intent:0) );
353 #endif // DEBUG_LCMS
355     return prof;
357 #endif // ENABLE_LCMS
359 /*
360   Local Variables:
361   mode:c++
362   c-file-style:"stroustrup"
363   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
364   indent-tabs-mode:nil
365   fill-column:99
366   End:
367 */
368 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :