Code

added forward decl to fixed_g_ascii_strtod to fix compiler issue on WinXP
[inkscape.git] / src / helper / stock-items.cpp
1 #define __INK_STOCK_ITEMS__
3 /*
4  * Stock-items
5  *
6  * Stock Item management code
7  *
8  * Authors:
9  *  John Cliff <simarilius@yahoo.com>
10  *
11  * Copyright 2004 John Cliff
12  *
13  *
14  * Released under GNU GPL, read the file 'COPYING' for more information
15  */
17 #define noSP_SS_VERBOSE
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 #include "path-prefix.h"
25 #include <xml/repr.h>
26 #include "sp-gradient-fns.h"
27 #include "document-private.h"
28 #include "sp-pattern.h"
29 #include "marker.h"
30 #include "desktop-handles.h"
31 #include "inkscape.h"
33 #include "io/sys.h"
38 static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc);
39 static SPObject *sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc);
40 static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc);
43 // FIXME: these should be merged with the icon loading code so they
44 // can share a common file/doc cache.  This function should just 
45 // take the dir to look in, and the file to check for, and cache
46 // against that, rather than the existing copy/paste code seen here.
48 static SPObject * sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc)
49 {
50     static SPDocument *doc = NULL;
51     static unsigned int edoc = FALSE;
52     if (!current_doc) {
53         return NULL;
54     }
55     /* Try to load from document */
56     if (!edoc && !doc) {
57         gchar *markers = g_build_filename(INKSCAPE_MARKERSDIR, "/markers.svg", NULL);
58         if (Inkscape::IO::file_test(markers, G_FILE_TEST_IS_REGULAR)) {
59             doc = sp_document_new(markers, FALSE);
60         }
61         g_free(markers);
62         if (doc) {
63             sp_document_ensure_up_to_date(doc);
64         } else {
65             edoc = TRUE;
66         }
67     }
68     if (!edoc && doc) {
69         /* Get the marker we want */
70         SPObject *object = doc->getObjectById(name);
71         if (object && SP_IS_MARKER(object)) {
72             SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
73             Inkscape::XML::Node *mark_repr = SP_OBJECT_REPR(object)->duplicate();
74             SP_OBJECT_REPR(defs)->addChild(mark_repr, NULL);
75             SPObject *cloned_item = current_doc->getObjectByRepr(mark_repr);
76             Inkscape::GC::release(mark_repr);
77             return cloned_item;
78         }
79     }
80     return NULL;
81 }
84 static SPObject *
85 sp_pattern_load_from_svg(gchar const *name, SPDocument *current_doc)
86 {
87     static SPDocument *doc = NULL;
88     static unsigned int edoc = FALSE;
89     if (!current_doc) {
90         return NULL;
91     }
92     /* Try to load from document */
93     if (!edoc && !doc) {
94         gchar *patterns = g_build_filename(INKSCAPE_PATTERNSDIR, "/patterns.svg", NULL);
95         if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
96             doc = sp_document_new(patterns, FALSE);
97         }
98         if (!doc) {
99         gchar *patterns = g_build_filename(CREATE_PATTERNSDIR, "/patterns.svg", NULL);
100         if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
101             doc = sp_document_new(patterns, FALSE);
102         }
103         g_free(patterns);
104         if (doc) {
105             sp_document_ensure_up_to_date(doc);
106         } else {
107             edoc = TRUE;
108         }
109         }
110     }
111     if (!edoc && doc) {
112         /* Get the pattern we want */
113         SPObject *object = doc->getObjectById(name);
114         if (object && SP_IS_PATTERN(object)) {
115             SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
116             Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
117             SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
118             Inkscape::GC::release(pat_repr);
119             return object;
120         }
121     }
122     return NULL;
126 static SPObject *
127 sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc)
129     static SPDocument *doc = NULL;
130     static unsigned int edoc = FALSE;
131     if (!current_doc) {
132         return NULL;
133     }
134     /* Try to load from document */
135     if (!edoc && !doc) {
136         gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL);
137         if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
138             doc = sp_document_new(gradients, FALSE);
139         }
140         if (!doc) {
141         gchar *gradients = g_build_filename(CREATE_GRADIENTSDIR, "/gradients.svg", NULL);
142         if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
143             doc = sp_document_new(gradients, FALSE);
144         }
145         g_free(gradients);
146         if (doc) {
147             sp_document_ensure_up_to_date(doc);
148         } else {
149             edoc = TRUE;
150         }
151         }
152     }
153     if (!edoc && doc) {
154         /* Get the gradient we want */
155         SPObject *object = doc->getObjectById(name);
156         if (object && SP_IS_GRADIENT(object)) {
157             SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
158             Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
159             SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
160             Inkscape::GC::release(pat_repr);
161             return object;
162         }
163     }
164     return NULL;
167 // get_stock_item returns a pointer to an instance of the desired stock object in the current doc
168 // if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property
169 // This should be set to be the same as the id in the libary file.
171 SPObject *get_stock_item(gchar const *urn)
173     g_assert(urn != NULL);
174     
175     /* check its an inkscape URN */
176     if (!strncmp (urn, "urn:inkscape:", 13)) {
178         gchar const *e = urn + 13;
179         int a = 0;
180         gchar * name = g_strdup(e);
181         gchar *name_p = name;
182         while (*name_p != ':' && *name_p != '\0'){
183             name_p++;
184             a++;
185         }
186         
187         if (*name_p ==':') {
188             name_p++;
189         }
190         
191         gchar * base = g_strndup(e, a);
193         SPDesktop *desktop = inkscape_active_desktop();
194         SPDocument *doc = sp_desktop_document(desktop);
195         SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc);
197         SPObject *object = NULL;
198         if (!strcmp(base, "marker")) {
199             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
200                  child != NULL;
201                  child = SP_OBJECT_NEXT(child))
202             {
203                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
204                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
205                     SP_IS_MARKER(child))
206                 {
207                     object = child;
208                 }
209             }
210             
211         }
212         else if (!strcmp(base,"pattern"))  {
213             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)) ;
214                  child != NULL;
215                  child = SP_OBJECT_NEXT(child) )
216             {
217                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
218                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
219                     SP_IS_PATTERN(child))
220                 {
221                     object = child;
222                 }
223             }
224             
225         }
226         else if (!strcmp(base,"gradient"))  {
227             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
228                  child != NULL;
229                  child = SP_OBJECT_NEXT(child))
230             {
231                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
232                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
233                     SP_IS_GRADIENT(child))
234                 {
235                     object = child;
236                 }
237             }
238             
239         }
240         
241         if (object == NULL) {
242             
243             if (!strcmp(base, "marker"))  {
244                 object = sp_marker_load_from_svg(name_p, doc);
245             }
246             else if (!strcmp(base, "pattern"))  {
247                 object = sp_pattern_load_from_svg(name_p, doc);
248             }
249             else if (!strcmp(base, "gradient"))  {
250                 object = sp_gradient_load_from_svg(name_p, doc);
251             }
252         }
253         
254         g_free(base);
255         g_free(name);
256         
257         return object;
258     }
259     
260     else {
261         
262         SPDesktop *desktop = inkscape_active_desktop();
263         SPDocument *doc = sp_desktop_document(desktop);
264         SPObject *object = doc->getObjectById(urn);
266         return object;
267     }
270 /*
271   Local Variables:
272   mode:c++
273   c-file-style:"stroustrup"
274   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
275   indent-tabs-mode:nil
276   fill-column:99
277   End:
278 */
279 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :