Code

Adding rendering-intent to <color-profile>
[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 using Inkscape::ColorProfile;
10 using Inkscape::ColorProfileClass;
12 namespace Inkscape
13 {
14 static void colorprofile_class_init( ColorProfileClass *klass );
15 static void colorprofile_init( ColorProfile *cprof );
17 static void colorprofile_release( SPObject *object );
18 static void colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr );
19 static void colorprofile_set( SPObject *object, unsigned key, gchar const *value );
20 static Inkscape::XML::Node *colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags );
21 }
23 static SPObject *cprof_parent_class;
25 /**
26  * Register ColorProfile class and return its type.
27  */
28 GType Inkscape::colorprofile_get_type()
29 {
30     static GType type = 0;
31     if (!type) {
32         GTypeInfo info = {
33             sizeof(ColorProfileClass),
34             NULL, NULL,
35             (GClassInitFunc) colorprofile_class_init,
36             NULL, NULL,
37             sizeof(ColorProfile),
38             16,
39             (GInstanceInitFunc) colorprofile_init,
40             NULL,   /* value_table */
41         };
42         type = g_type_register_static( SP_TYPE_OBJECT, "ColorProfile", &info, static_cast<GTypeFlags>(0) );
43     }
44     return type;
45 }
47 /**
48  * ColorProfile vtable initialization.
49  */
50 static void Inkscape::colorprofile_class_init( ColorProfileClass *klass )
51 {
52     SPObjectClass *sp_object_class = reinterpret_cast<SPObjectClass *>(klass);
54     cprof_parent_class = static_cast<SPObject*>(g_type_class_ref(SP_TYPE_OBJECT));
56     sp_object_class->release = colorprofile_release;
57     sp_object_class->build = colorprofile_build;
58     sp_object_class->set = colorprofile_set;
59     sp_object_class->write = colorprofile_write;
60 }
62 /**
63  * Callback for ColorProfile object initialization.
64  */
65 static void Inkscape::colorprofile_init( ColorProfile *cprof )
66 {
67     cprof->href = 0;
68     cprof->local = 0;
69     cprof->name = 0;
70     cprof->intentStr = 0;
71     cprof->rendering_intent = Inkscape::RENDERING_INTENT_UNKNOWN;
72 #if ENABLE_LCMS
73     cprof->profHandle = 0;
74 #endif // ENABLE_LCMS
75 }
77 /**
78  * Callback: free object
79  */
80 static void Inkscape::colorprofile_release( SPObject *object )
81 {
82     ColorProfile *cprof = COLORPROFILE(object);
83     if ( cprof->href ) {
84         g_free( cprof->href );
85         cprof->href = 0;
86     }
88     if ( cprof->local ) {
89         g_free( cprof->local );
90         cprof->local = 0;
91     }
93     if ( cprof->name ) {
94         g_free( cprof->name );
95         cprof->name = 0;
96     }
98     if ( cprof->intentStr ) {
99         g_free( cprof->intentStr );
100         cprof->intentStr = 0;
101     }
103 #if ENABLE_LCMS
104     if ( cprof->profHandle ) {
105         cmsCloseProfile( cprof->profHandle );
106         cprof->profHandle = 0;
107     }
108 #endif // ENABLE_LCMS
111 /**
112  * Callback: set attributes from associated repr.
113  */
114 static void Inkscape::colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr )
116     ColorProfile *cprof = COLORPROFILE(object);
117     g_assert(cprof->href == 0);
118     g_assert(cprof->local == 0);
119     g_assert(cprof->name == 0);
120     g_assert(cprof->intentStr == 0);
122     if (((SPObjectClass *) cprof_parent_class)->build) {
123         (* ((SPObjectClass *) cprof_parent_class)->build)(object, document, repr);
124     }
125     sp_object_read_attr( object, "xlink:href" );
126     sp_object_read_attr( object, "local" );
127     sp_object_read_attr( object, "name" );
128     sp_object_read_attr( object, "rendering-intent" );
131 /**
132  * Callback: set attribute.
133  */
134 static void Inkscape::colorprofile_set( SPObject *object, unsigned key, gchar const *value )
136     ColorProfile *cprof = COLORPROFILE(object);
138     switch (key) {
139         case SP_ATTR_XLINK_HREF:
140             if ( cprof->href ) {
141                 g_free( cprof->href );
142                 cprof->href = 0;
143             }
144             if ( value ) {
145                 cprof->href = g_strdup( value );
146                 if ( *cprof->href ) {
147 #if ENABLE_LCMS
148                     cmsErrorAction( LCMS_ERROR_SHOW );
150                     // TODO open filename and URIs properly
151                     //FILE* fp = fopen_utf8name( filename, "r" );
152                     //LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
154                     if ( !g_path_is_absolute(cprof->href) ) {
155                         // Try to open relative
156                         gchar* docbase = SP_DOCUMENT_BASE( SP_OBJECT_DOCUMENT(object) );
157                         gchar* fullname = g_build_filename( docbase ? docbase : ".", cprof->href, NULL );
159                         cprof->profHandle = cmsOpenProfileFromFile( fullname, "r" );
161                         g_free (fullname);
162                     } else {
163                         cprof->profHandle = cmsOpenProfileFromFile( cprof->href, "r" );
164                     }
166 #endif // ENABLE_LCMS
167                 }
168             }
169             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
170             break;
172         case SP_ATTR_LOCAL:
173             if ( cprof->local ) {
174                 g_free( cprof->local );
175                 cprof->local = 0;
176             }
177             cprof->local = g_strdup( value );
178             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
179             break;
181         case SP_ATTR_NAME:
182             if ( cprof->name ) {
183                 g_free( cprof->name );
184                 cprof->name = 0;
185             }
186             cprof->name = g_strdup( value );
187             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
188             break;
190         case SP_ATTR_RENDERING_INTENT:
191             if ( cprof->intentStr ) {
192                 g_free( cprof->intentStr );
193                 cprof->intentStr = 0;
194             }
195             cprof->intentStr = g_strdup( value );
197             if ( value ) {
198                 if ( strcmp( value, "auto" ) == 0 ) {
199                     cprof->rendering_intent = RENDERING_INTENT_AUTO;
200                 } else if ( strcmp( value, "perceptual" ) == 0 ) {
201                     cprof->rendering_intent = RENDERING_INTENT_PERCEPTUAL;
202                 } else if ( strcmp( value, "relative-colorimetric" ) == 0 ) {
203                     cprof->rendering_intent = RENDERING_INTENT_RELATIVE_COLORIMETRIC;
204                 } else if ( strcmp( value, "saturation" ) == 0 ) {
205                     cprof->rendering_intent = RENDERING_INTENT_SATURATION;
206                 } else if ( strcmp( value, "absolute-colorimetric" ) == 0 ) {
207                     cprof->rendering_intent = RENDERING_INTENT_ABSOLUTE_COLORIMETRIC;
208                 } else {
209                     cprof->rendering_intent = RENDERING_INTENT_UNKNOWN;
210                 }
211             } else {
212                 cprof->rendering_intent = RENDERING_INTENT_UNKNOWN;
213             }
215             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
216             break;
218         default:
219             if (((SPObjectClass *) cprof_parent_class)->set) {
220                 (* ((SPObjectClass *) cprof_parent_class)->set)(object, key, value);
221             }
222             break;
223     }
227 /**
228  * Callback: write attributes to associated repr.
229  */
230 static Inkscape::XML::Node* Inkscape::colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags )
232     ColorProfile *cprof = COLORPROFILE(object);
234     if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
235         repr = sp_repr_new("svg:color-profile");
236     }
238     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) {
239         repr->setAttribute( "xlink:href", cprof->href );
240     }
242     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->local ) {
243         repr->setAttribute( "local", cprof->local );
244     }
246     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->name ) {
247         repr->setAttribute( "name", cprof->name );
248     }
250     if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->intentStr ) {
251         repr->setAttribute( "rendering-intent", cprof->intentStr );
252     }
254     if (((SPObjectClass *) cprof_parent_class)->write) {
255         (* ((SPObjectClass *) cprof_parent_class)->write)(object, repr, flags);
256     }
258     return repr;
262 #if ENABLE_LCMS
265 static SPObject* bruteFind( SPObject* curr, gchar* const name )
267     SPObject* result = 0;
269     if ( curr ) {
270         if ( IS_COLORPROFILE(curr) ) {
271             ColorProfile* prof = COLORPROFILE(curr);
272             if ( prof ) {
273                 if ( prof->name && (strcmp(prof->name, name) == 0) ) {
274                     result = curr;
275                 }
276             }
277         } else {
278             if ( curr->hasChildren() ) {
279                 SPObject* child = curr->firstChild();
280                 while ( child && !result ) {
281                     result = bruteFind( child, name );
282                     if ( !result ) {
283                         child = child->next;
284                     }
285                 };
286             }
287         }
288     }
290     return result;
293 cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* intent, gchar* const name )
295     cmsHPROFILE prof = 0;
297     SPObject* root = SP_DOCUMENT_ROOT(document);
298     SPObject* thing = bruteFind( root, name );
299     if ( thing ) {
300         prof = COLORPROFILE(thing)->profHandle;
301     }
303     if ( intent ) {
304         *intent = thing ? COLORPROFILE(thing)->rendering_intent : (guint)RENDERING_INTENT_UNKNOWN;
305     }
307     return prof;
309 #endif // ENABLE_LCMS
311 /*
312   Local Variables:
313   mode:c++
314   c-file-style:"stroustrup"
315   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
316   indent-tabs-mode:nil
317   fill-column:99
318   End:
319 */
320 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :