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 * Abhishek Sharma
15 *
16 * Copyright (C) 2006 Bob Jamison
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Lesser General Public
20 * License as published by the Free Software Foundation; either
21 * version 2.1 of the License, or (at your option) any later version.
22 *
23 * This library is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public
29 * License along with this library; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 */
33 #ifndef EXTENSION_INTERNAL_ODG_OUT_H
34 #define EXTENSION_INTERNAL_ODG_OUT_H
36 #include <dom/dom.h>
37 #include <dom/io/stringstream.h>
38 #include <dom/uri.h>
40 #include <glibmm.h>
41 #include "extension/implementation/implementation.h"
44 #include <xml/repr.h>
46 #include <string>
47 #include <map>
49 #include <dom/util/ziptool.h>
50 #include <dom/io/domstream.h>
51 #include "sp-item.h"
53 namespace Inkscape
54 {
55 namespace Extension
56 {
57 namespace Internal
58 {
60 typedef org::w3c::dom::URI URI;
61 typedef org::w3c::dom::io::Writer Writer;
64 class StyleInfo
65 {
66 public:
68 StyleInfo()
69 {
70 init();
71 }
73 StyleInfo(const StyleInfo &other)
74 {
75 assign(other);
76 }
78 StyleInfo &operator=(const StyleInfo &other)
79 {
80 assign(other);
81 return *this;
82 }
84 void assign(const StyleInfo &other)
85 {
86 name = other.name;
87 stroke = other.stroke;
88 strokeColor = other.strokeColor;
89 strokeWidth = other.strokeWidth;
90 strokeOpacity = other.strokeOpacity;
91 fill = other.fill;
92 fillColor = other.fillColor;
93 fillOpacity = other.fillOpacity;
94 }
96 void init()
97 {
98 name = "none";
99 stroke = "none";
100 strokeColor = "none";
101 strokeWidth = "none";
102 strokeOpacity = "none";
103 fill = "none";
104 fillColor = "none";
105 fillOpacity = "none";
106 }
108 virtual ~StyleInfo()
109 {}
111 //used for eliminating duplicates in the styleTable
112 bool equals(const StyleInfo &other)
113 {
114 if (
115 stroke != other.stroke ||
116 strokeColor != other.strokeColor ||
117 strokeWidth != other.strokeWidth ||
118 strokeOpacity != other.strokeOpacity ||
119 fill != other.fill ||
120 fillColor != other.fillColor ||
121 fillOpacity != other.fillOpacity
122 )
123 return false;
124 return true;
125 }
127 Glib::ustring name;
128 Glib::ustring stroke;
129 Glib::ustring strokeColor;
130 Glib::ustring strokeWidth;
131 Glib::ustring strokeOpacity;
132 Glib::ustring fill;
133 Glib::ustring fillColor;
134 Glib::ustring fillOpacity;
136 };
141 class GradientStop
142 {
143 public:
144 GradientStop()
145 {}
146 GradientStop(unsigned long rgbArg, double opacityArg)
147 { rgb = rgbArg; opacity = opacityArg; }
148 virtual ~GradientStop()
149 {}
150 GradientStop(const GradientStop &other)
151 { assign(other); }
152 virtual GradientStop operator=(const GradientStop &other)
153 { assign(other); return *this; }
154 void assign(const GradientStop &other)
155 {
156 rgb = other.rgb;
157 opacity = other.opacity;
158 }
159 unsigned long rgb;
160 double opacity;
161 };
165 class GradientInfo
166 {
167 public:
169 GradientInfo()
170 {
171 init();
172 }
174 GradientInfo(const GradientInfo &other)
175 {
176 assign(other);
177 }
179 GradientInfo &operator=(const GradientInfo &other)
180 {
181 assign(other);
182 return *this;
183 }
185 void assign(const GradientInfo &other)
186 {
187 name = other.name;
188 style = other.style;
189 cx = other.cx;
190 cy = other.cy;
191 fx = other.fx;
192 fy = other.fy;
193 r = other.r;
194 x1 = other.x1;
195 y1 = other.y1;
196 x2 = other.x2;
197 y2 = other.y2;
198 stops = other.stops;
199 }
201 void init()
202 {
203 name = "none";
204 style = "none";
205 cx = 0.0;
206 cy = 0.0;
207 fx = 0.0;
208 fy = 0.0;
209 r = 0.0;
210 x1 = 0.0;
211 y1 = 0.0;
212 x2 = 0.0;
213 y2 = 0.0;
214 stops.clear();
215 }
217 virtual ~GradientInfo()
218 {}
220 //used for eliminating duplicates in the styleTable
221 bool equals(const GradientInfo &other)
222 {
223 if (
224 name != other.name ||
225 style != other.style ||
226 cx != other.cx ||
227 cy != other.cy ||
228 fx != other.fx ||
229 fy != other.fy ||
230 r != other.r ||
231 x1 != other.x1 ||
232 y1 != other.y1 ||
233 x2 != other.x2 ||
234 y2 != other.y2
235 )
236 return false;
237 if (stops.size() != other.stops.size())
238 return false;
239 for (unsigned int i=0 ; i<stops.size() ; i++)
240 {
241 GradientStop g1 = stops[i];
242 GradientStop g2 = other.stops[i];
243 if (g1.rgb != g2.rgb)
244 return false;
245 if (g1.opacity != g2.opacity)
246 return false;
247 }
248 return true;
249 }
251 Glib::ustring name;
252 Glib::ustring style;
253 double cx;
254 double cy;
255 double fx;
256 double fy;
257 double r;
258 double x1;
259 double y1;
260 double x2;
261 double y2;
262 std::vector<GradientStop> stops;
264 };
268 class OdfOutput : public Inkscape::Extension::Implementation::Implementation
269 {
271 public:
273 bool check (Inkscape::Extension::Extension * module);
275 void save (Inkscape::Extension::Output *mod,
276 SPDocument *doc,
277 gchar const *filename);
279 static void init (void);
281 private:
283 URI documentUri;
285 void reset();
287 //cc or dc metadata name/value pairs
288 std::map<Glib::ustring, Glib::ustring> metadata;
290 /* Style table
291 Uses a two-stage lookup to avoid style duplication.
292 Use like:
293 StyleInfo si = styleTable[styleLookupTable[id]];
294 but check for errors, of course
295 */
296 //element id -> style entry name
297 std::map<Glib::ustring, Glib::ustring> styleLookupTable;
298 //style entry name -> style info
299 std::vector<StyleInfo> styleTable;
301 //element id -> gradient entry name
302 std::map<Glib::ustring, Glib::ustring> gradientLookupTable;
303 //gradient entry name -> gradient info
304 std::vector<GradientInfo> gradientTable;
306 //for renaming image file names
307 std::map<Glib::ustring, Glib::ustring> imageTable;
309 void preprocess(ZipFile &zf, Inkscape::XML::Node *node);
311 bool writeManifest(ZipFile &zf);
313 bool writeMeta(ZipFile &zf);
315 bool writeStyle(ZipFile &zf);
317 bool processStyle(Writer &outs, SPItem *item, const Glib::ustring &id);
319 bool processGradient(Writer &outs, SPItem *item,
320 const Glib::ustring &id, Geom::Matrix &tf);
322 bool writeStyleHeader(Writer &outs);
324 bool writeStyleFooter(Writer &outs);
326 bool writeContentHeader(Writer &outs);
328 bool writeContentFooter(Writer &outs);
330 bool writeTree(Writer &couts, Writer &souts, Inkscape::XML::Node *node);
332 bool writeContent(ZipFile &zf, Inkscape::XML::Node *node);
334 };
339 } //namespace Internal
340 } //namespace Extension
341 } //namespace Inkscape
345 #endif /* EXTENSION_INTERNAL_ODG_OUT_H */