1 /**
2 * OpenDocument <drawing> input and output
3 *
4 * This is an an entry in the extensions mechanism to begin to enable
5 * the inputting and outputting of OpenDocument Format (ODF) files from
6 * within Inkscape. Although the initial implementations will be very lossy
7 * do to the differences in the models of SVG and ODF, they will hopefully
8 * improve greatly with time.
9 *
10 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
11 *
12 * Authors:
13 * Bob Jamison
14 *
15 * Copyright (C) 2006 Bob Jamison
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
21 *
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
32 #ifndef EXTENSION_INTERNAL_ODG_OUT_H
33 #define EXTENSION_INTERNAL_ODG_OUT_H
35 #include <dom/dom.h>
36 #include <dom/io/stringstream.h>
37 #include <dom/uri.h>
39 #include <glibmm.h>
40 #include "extension/implementation/implementation.h"
43 #include <xml/repr.h>
45 #include <string>
46 #include <map>
48 #include <dom/util/ziptool.h>
49 #include <dom/io/domstream.h>
52 namespace Inkscape
53 {
54 namespace Extension
55 {
56 namespace Internal
57 {
59 typedef org::w3c::dom::URI URI;
60 typedef org::w3c::dom::io::Writer Writer;
63 class StyleInfo
64 {
65 public:
67 StyleInfo()
68 {
69 init();
70 }
72 StyleInfo(const StyleInfo &other)
73 {
74 assign(other);
75 }
77 StyleInfo &operator=(const StyleInfo &other)
78 {
79 assign(other);
80 return *this;
81 }
83 void assign(const StyleInfo &other)
84 {
85 name = other.name;
86 stroke = other.stroke;
87 strokeColor = other.strokeColor;
88 strokeWidth = other.strokeWidth;
89 strokeOpacity = other.strokeOpacity;
90 fill = other.fill;
91 fillColor = other.fillColor;
92 fillOpacity = other.fillOpacity;
93 }
95 void init()
96 {
97 name = "none";
98 stroke = "none";
99 strokeColor = "none";
100 strokeWidth = "none";
101 strokeOpacity = "none";
102 fill = "none";
103 fillColor = "none";
104 fillOpacity = "none";
105 }
107 virtual ~StyleInfo()
108 {}
110 //used for eliminating duplicates in the styleTable
111 bool equals(const StyleInfo &other)
112 {
113 if (
114 stroke != other.stroke ||
115 strokeColor != other.strokeColor ||
116 strokeWidth != other.strokeWidth ||
117 strokeOpacity != other.strokeOpacity ||
118 fill != other.fill ||
119 fillColor != other.fillColor ||
120 fillOpacity != other.fillOpacity
121 )
122 return false;
123 return true;
124 }
126 Glib::ustring name;
127 Glib::ustring stroke;
128 Glib::ustring strokeColor;
129 Glib::ustring strokeWidth;
130 Glib::ustring strokeOpacity;
131 Glib::ustring fill;
132 Glib::ustring fillColor;
133 Glib::ustring fillOpacity;
135 };
140 class GradientStop
141 {
142 public:
143 GradientStop()
144 {}
145 GradientStop(unsigned long rgbArg, double opacityArg)
146 { rgb = rgbArg; opacity = opacityArg; }
147 virtual ~GradientStop()
148 {}
149 GradientStop(const GradientStop &other)
150 { assign(other); }
151 virtual GradientStop operator=(const GradientStop &other)
152 { assign(other); return *this; }
153 void assign(const GradientStop &other)
154 {
155 rgb = other.rgb;
156 opacity = other.opacity;
157 }
158 unsigned long rgb;
159 double opacity;
160 };
164 class GradientInfo
165 {
166 public:
168 GradientInfo()
169 {
170 init();
171 }
173 GradientInfo(const GradientInfo &other)
174 {
175 assign(other);
176 }
178 GradientInfo &operator=(const GradientInfo &other)
179 {
180 assign(other);
181 return *this;
182 }
184 void assign(const GradientInfo &other)
185 {
186 name = other.name;
187 style = other.style;
188 cx = other.cx;
189 cy = other.cy;
190 fx = other.fx;
191 fy = other.fy;
192 r = other.r;
193 x1 = other.x1;
194 y1 = other.y1;
195 x2 = other.x2;
196 y2 = other.y2;
197 stops = other.stops;
198 }
200 void init()
201 {
202 name = "none";
203 style = "none";
204 cx = 0.0;
205 cy = 0.0;
206 fx = 0.0;
207 fy = 0.0;
208 r = 0.0;
209 x1 = 0.0;
210 y1 = 0.0;
211 x2 = 0.0;
212 y2 = 0.0;
213 stops.clear();
214 }
216 virtual ~GradientInfo()
217 {}
219 //used for eliminating duplicates in the styleTable
220 bool equals(const GradientInfo &other)
221 {
222 if (
223 name != other.name ||
224 style != other.style ||
225 cx != other.cx ||
226 cy != other.cy ||
227 fx != other.fx ||
228 fy != other.fy ||
229 r != other.r ||
230 x1 != other.x1 ||
231 y1 != other.y1 ||
232 x2 != other.x2 ||
233 y2 != other.y2
234 )
235 return false;
236 if (stops.size() != other.stops.size())
237 return false;
238 for (unsigned int i=0 ; i<stops.size() ; i++)
239 {
240 GradientStop g1 = stops[i];
241 GradientStop g2 = other.stops[i];
242 if (g1.rgb != g2.rgb)
243 return false;
244 if (g1.opacity != g2.opacity)
245 return false;
246 }
247 return true;
248 }
250 Glib::ustring name;
251 Glib::ustring style;
252 double cx;
253 double cy;
254 double fx;
255 double fy;
256 double r;
257 double x1;
258 double y1;
259 double x2;
260 double y2;
261 std::vector<GradientStop> stops;
263 };
267 class OdfOutput : public Inkscape::Extension::Implementation::Implementation
268 {
270 public:
272 bool check (Inkscape::Extension::Extension * module);
274 void save (Inkscape::Extension::Output *mod,
275 SPDocument *doc,
276 const gchar *uri);
278 static void init (void);
280 private:
282 URI documentUri;
284 void reset();
286 //cc or dc metadata name/value pairs
287 std::map<Glib::ustring, Glib::ustring> metadata;
289 /* Style table
290 Uses a two-stage lookup to avoid style duplication.
291 Use like:
292 StyleInfo si = styleTable[styleLookupTable[id]];
293 but check for errors, of course
294 */
295 //element id -> style entry name
296 std::map<Glib::ustring, Glib::ustring> styleLookupTable;
297 //style entry name -> style info
298 std::vector<StyleInfo> styleTable;
300 //element id -> gradient entry name
301 std::map<Glib::ustring, Glib::ustring> gradientLookupTable;
302 //gradient entry name -> gradient info
303 std::vector<GradientInfo> gradientTable;
305 //for renaming image file names
306 std::map<Glib::ustring, Glib::ustring> imageTable;
308 void preprocess(ZipFile &zf, Inkscape::XML::Node *node);
310 bool writeManifest(ZipFile &zf);
312 bool writeMeta(ZipFile &zf);
314 bool writeStyle(ZipFile &zf);
316 bool processStyle(Writer &outs, SPItem *item, const Glib::ustring &id);
318 bool processGradient(Writer &outs, SPItem *item,
319 const Glib::ustring &id, NR::Matrix &tf);
321 bool writeStyleHeader(Writer &outs);
323 bool writeStyleFooter(Writer &outs);
325 bool writeContentHeader(Writer &outs);
327 bool writeContentFooter(Writer &outs);
329 bool writeTree(Writer &couts, Writer &souts, Inkscape::XML::Node *node);
331 bool writeContent(ZipFile &zf, Inkscape::XML::Node *node);
333 };
338 } //namespace Internal
339 } //namespace Extension
340 } //namespace Inkscape
344 #endif /* EXTENSION_INTERNAL_ODG_OUT_H */