2 * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
3 * Copyright (C) 2006-2007 Fridrich Strba (fridrich.strba@bluewin.ch)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02111-1301 USA
20 * For further information visit http://libwpg.sourceforge.net
23 /* "This product is not manufactured, approved, or supported by
24 * Corel Corporation or Corel Corporation Limited."
27 #include "OdgExporter.hxx"
28 #include "filter/DocumentElement.hxx"
29 #include "filter/DocumentHandler.hxx"
30 #include <rtl/math.hxx>
33 OdgExporter::OdgExporter(DocumentHandler
*pHandler
):
35 m_fillRule(AlternatingFill
),
42 OdgExporter::~OdgExporter()
46 void OdgExporter::startDocument(double width
, double height
)
52 mpHandler
->startDocument();
53 TagOpenElement
tmpOfficeDocumentContent("office:document");
54 tmpOfficeDocumentContent
.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
55 tmpOfficeDocumentContent
.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
56 tmpOfficeDocumentContent
.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
57 tmpOfficeDocumentContent
.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
58 tmpOfficeDocumentContent
.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
59 tmpOfficeDocumentContent
.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
60 tmpOfficeDocumentContent
.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
61 tmpOfficeDocumentContent
.addAttribute("office:version", "1.0");
62 tmpOfficeDocumentContent
.write(mpHandler
);
64 TagOpenElement("office:styles").write(mpHandler
);
65 TagCloseElement("office:styles").write(mpHandler
);
67 TagOpenElement("office:automatic-styles").write(mpHandler
);
69 TagOpenElement
tmpStylePageLayoutOpenElement("style:page-layout");
70 tmpStylePageLayoutOpenElement
.addAttribute("style:name", "PM0");
71 tmpStylePageLayoutOpenElement
.write(mpHandler
);
73 TagOpenElement
tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties");
74 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:margin-top", "0cm");
75 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:margin-bottom", "0cm");
76 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:margin-left", "0cm");
77 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:margin-right", "0cm");
79 sValue
= doubleToString(2.54 * width
); sValue
.append("cm");
80 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:page-width", sValue
);
81 sValue
= doubleToString(2.54 * height
); sValue
.append("cm");
82 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("fo:page-height", sValue
);
83 tmpStylePageLayoutPropertiesOpenElement
.addAttribute("style:print-orientation", "portrait");
84 tmpStylePageLayoutPropertiesOpenElement
.write(mpHandler
);
86 TagCloseElement("style:page-layout-properties").write(mpHandler
);
88 TagCloseElement("style:page-layout").write(mpHandler
);
90 TagOpenElement
tmpStyleStyleOpenElement("style:style");
91 tmpStyleStyleOpenElement
.addAttribute("style:name", "dp1");
92 tmpStyleStyleOpenElement
.addAttribute("style:family", "drawing-page");
93 tmpStyleStyleOpenElement
.write(mpHandler
);
95 TagOpenElement
tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties");
96 tmpStyleDrawingPagePropertiesOpenElement
.addAttribute("draw:background-size", "border");
97 tmpStyleDrawingPagePropertiesOpenElement
.addAttribute("draw:fill", "none");
98 tmpStyleDrawingPagePropertiesOpenElement
.write(mpHandler
);
100 TagCloseElement("style:drawing-page-properties").write(mpHandler
);
102 TagCloseElement("style:style").write(mpHandler
);
105 void OdgExporter::endDocument()
107 TagCloseElement("office:automatic-styles").write(mpHandler
);
109 TagOpenElement("office:master-styles").write(mpHandler
);
111 TagOpenElement
tmpStyleMasterPageOpenElement("style:master-page");
112 tmpStyleMasterPageOpenElement
.addAttribute("style:name", "Default");
113 tmpStyleMasterPageOpenElement
.addAttribute("style:page-layout-name", "PM0");
114 tmpStyleMasterPageOpenElement
.addAttribute("draw:style-name", "dp1");
115 tmpStyleMasterPageOpenElement
.write(mpHandler
);
117 TagCloseElement("style:master-page").write(mpHandler
);
119 TagCloseElement("office:master-styles").write(mpHandler
);
121 TagOpenElement("office:body").write(mpHandler
);
123 TagOpenElement("office:drawing").write(mpHandler
);
125 TagOpenElement
tmpDrawPageOpenElement("draw:page");
126 tmpDrawPageOpenElement
.addAttribute("draw:name", "page1");
127 tmpDrawPageOpenElement
.addAttribute("draw:style-name", "dp1");
128 tmpDrawPageOpenElement
.addAttribute("draw:master-page-name", "Default");
129 tmpDrawPageOpenElement
.write(mpHandler
);
131 for (std::vector
<DocumentElement
*>::const_iterator bodyIter
= mpBodyElements
.begin();
132 bodyIter
!= mpBodyElements
.end(); bodyIter
++)
134 (*bodyIter
)->write(mpHandler
);
137 TagCloseElement("draw:page").write(mpHandler
);
138 TagCloseElement("office:drawing").write(mpHandler
);
139 TagCloseElement("office:body").write(mpHandler
);
140 TagCloseElement("office:document").write(mpHandler
);
142 mpHandler
->endDocument();
145 void OdgExporter::setPen(const libwpg::WPGPen
& pen
)
150 void OdgExporter::setBrush(const libwpg::WPGBrush
& brush
)
155 void OdgExporter::setFillRule(FillRule rule
)
160 void OdgExporter::startLayer(unsigned int /* id */)
164 void OdgExporter::endLayer(unsigned int)
168 void OdgExporter::drawRectangle(const libwpg::WPGRect
& rect
, double rx
, double /* ry */)
171 TagOpenElement
*pDrawRectElement
= new TagOpenElement("draw:rect");
173 sValue
.sprintf("gr%i", m_styleIndex
-1);
174 pDrawRectElement
->addAttribute("draw:style-name", sValue
);
175 sValue
= doubleToString(2.54 * rect
.x1
); sValue
.append("cm");
176 pDrawRectElement
->addAttribute("svg:x", sValue
);
177 sValue
= doubleToString(2.54 * rect
.y1
); sValue
.append("cm");
178 pDrawRectElement
->addAttribute("svg:y", sValue
);
179 sValue
= doubleToString(2.54 * (rect
.x2
-rect
.x1
)); sValue
.append("cm");
180 pDrawRectElement
->addAttribute("svg:width", sValue
);
181 sValue
= doubleToString(2.54 * (rect
.y2
-rect
.y1
)); sValue
.append("cm");
182 pDrawRectElement
->addAttribute("svg:height", sValue
);
183 sValue
= doubleToString(2.54 * rx
); sValue
.append("cm");
184 // FIXME: what to do when rx != ry ?
185 pDrawRectElement
->addAttribute("draw:corner-radius", sValue
);
186 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawRectElement
));
187 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:rect")));
190 void OdgExporter::drawEllipse(const libwpg::WPGPoint
& center
, double rx
, double ry
)
193 TagOpenElement
*pDrawEllipseElement
= new TagOpenElement("draw:ellipse");
195 sValue
.sprintf("gr%i", m_styleIndex
-1);
196 pDrawEllipseElement
->addAttribute("draw:style-name", sValue
);
197 sValue
= doubleToString(2.54 * (center
.x
-rx
)); sValue
.append("cm");
198 pDrawEllipseElement
->addAttribute("svg:x", sValue
);
199 sValue
= doubleToString(2.54 * (center
.y
-ry
)); sValue
.append("cm");
200 pDrawEllipseElement
->addAttribute("svg:y", sValue
);
201 sValue
= doubleToString(2 * 2.54 * rx
); sValue
.append("cm");
202 pDrawEllipseElement
->addAttribute("svg:width", sValue
);
203 sValue
= doubleToString(2 * 2.54 * ry
); sValue
.append("cm");
204 pDrawEllipseElement
->addAttribute("svg:height", sValue
);
205 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawEllipseElement
));
206 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:ellipse")));
209 void OdgExporter::drawPolygon(const libwpg::WPGPointArray
& vertices
)
211 if(vertices
.count() < 2)
214 if(vertices
.count() == 2)
216 const libwpg::WPGPoint
& p1
= vertices
[0];
217 const libwpg::WPGPoint
& p2
= vertices
[1];
220 TagOpenElement
*pDrawLineElement
= new TagOpenElement("draw:line");
222 sValue
.sprintf("gr%i", m_styleIndex
-1);
223 pDrawLineElement
->addAttribute("draw:style-name", sValue
);
224 pDrawLineElement
->addAttribute("draw:text-style-name", "P1");
225 pDrawLineElement
->addAttribute("draw:layer", "layout");
226 sValue
= doubleToString(2.54 * p1
.x
); sValue
.append("cm");
227 pDrawLineElement
->addAttribute("svg:x1", sValue
);
228 sValue
= doubleToString(2.54 * p1
.y
); sValue
.append("cm");
229 pDrawLineElement
->addAttribute("svg:y1", sValue
);
230 sValue
= doubleToString(2.54 * p2
.x
); sValue
.append("cm");
231 pDrawLineElement
->addAttribute("svg:x2", sValue
);
232 sValue
= doubleToString(2.54 * p2
.y
); sValue
.append("cm");
233 pDrawLineElement
->addAttribute("svg:y2", sValue
);
234 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawLineElement
));
235 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:line")));
240 libwpg::WPGPath path
;
241 path
.moveTo(vertices
[0]);
242 for(unsigned long ii
= 1; ii
< vertices
.count(); ii
++)
243 path
.lineTo(vertices
[ii
]);
249 void OdgExporter::drawPath(const libwpg::WPGPath
& path
)
251 if(path
.count() == 0)
254 // try to find the bounding box
255 // this is simple convex hull technique, the bounding box might not be
256 // accurate but that should be enough for this purpose
257 libwpg::WPGPoint p
= path
.element(0).point
;
258 libwpg::WPGPoint q
= path
.element(0).point
;
259 for(unsigned k
= 0; k
< path
.count(); k
++)
261 libwpg::WPGPathElement element
= path
.element(k
);
262 p
.x
= (p
.x
> element
.point
.x
) ? element
.point
.x
: p
.x
;
263 p
.y
= (p
.y
> element
.point
.y
) ? element
.point
.y
: p
.y
;
264 q
.x
= (q
.x
< element
.point
.x
) ? element
.point
.x
: q
.x
;
265 q
.y
= (q
.y
< element
.point
.y
) ? element
.point
.y
: q
.y
;
266 if(element
.type
== libwpg::WPGPathElement::CurveToElement
)
268 p
.x
= (p
.x
> element
.extra1
.x
) ? element
.extra1
.x
: p
.x
;
269 p
.y
= (p
.y
> element
.extra1
.y
) ? element
.extra1
.y
: p
.y
;
270 q
.x
= (q
.x
< element
.extra1
.x
) ? element
.extra1
.x
: q
.x
;
271 q
.y
= (q
.y
< element
.extra1
.y
) ? element
.extra1
.y
: q
.y
;
272 p
.x
= (p
.x
> element
.extra2
.x
) ? element
.extra2
.x
: p
.x
;
273 p
.y
= (p
.y
> element
.extra2
.y
) ? element
.extra2
.y
: p
.y
;
274 q
.x
= (q
.x
< element
.extra2
.x
) ? element
.extra2
.x
: q
.x
;
275 q
.y
= (q
.y
< element
.extra2
.y
) ? element
.extra2
.y
: q
.y
;
278 double vw
= q
.x
- p
.x
;
279 double vh
= q
.y
- p
.y
;
283 TagOpenElement
*pDrawPathElement
= new TagOpenElement("draw:path");
285 sValue
.sprintf("gr%i", m_styleIndex
-1);
286 pDrawPathElement
->addAttribute("draw:style-name", sValue
);
287 pDrawPathElement
->addAttribute("draw:text-style-name", "P1");
288 pDrawPathElement
->addAttribute("draw:layer", "layout");
289 sValue
= doubleToString(2.54 * p
.x
); sValue
.append("cm");
290 pDrawPathElement
->addAttribute("svg:x", sValue
);
291 sValue
= doubleToString(2.54 * p
.y
); sValue
.append("cm");
292 pDrawPathElement
->addAttribute("svg:y", sValue
);
293 sValue
= doubleToString(2.54 * vw
); sValue
.append("cm");
294 pDrawPathElement
->addAttribute("svg:width", sValue
);
295 sValue
= doubleToString(2.54 * vh
); sValue
.append("cm");
296 pDrawPathElement
->addAttribute("svg:height", sValue
);
297 sValue
.sprintf("%i %i %i %i", 0, 0, (int)(vw
*2540), (int)(vh
*2540));
298 pDrawPathElement
->addAttribute("svg:viewBox", sValue
);
301 for(unsigned i
= 0; i
< path
.count(); i
++)
303 libwpg::WPGPathElement element
= path
.element(i
);
304 libwpg::WPGPoint point
= element
.point
;
308 // 2540 is 2.54*1000, 2.54 cm = 1 inch
309 case libwpg::WPGPathElement::MoveToElement
:
310 sElement
.sprintf("M%i %i", (int)((point
.x
-p
.x
)*2540), (int)((point
.y
-p
.y
)*2540));
313 case libwpg::WPGPathElement::LineToElement
:
314 sElement
.sprintf("L%i %i", (int)((point
.x
-p
.x
)*2540), (int)((point
.y
-p
.y
)*2540));
317 case libwpg::WPGPathElement::CurveToElement
:
318 sElement
.sprintf("C%i %i %i %i %i %i", (int)((element
.extra1
.x
-p
.x
)*2540),
319 (int)((element
.extra1
.y
-p
.y
)*2540), (int)((element
.extra2
.x
-p
.x
)*2540),
320 (int)((element
.extra2
.y
-p
.y
)*2540), (int)((point
.x
-p
.x
)*2540), (int)((point
.y
-p
.y
)*2540));
326 sValue
.append(sElement
);
330 pDrawPathElement
->addAttribute("svg:d", sValue
);
331 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawPathElement
));
332 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:path")));
335 void OdgExporter::drawBitmap(const libwpg::WPGBitmap
& bitmap
)
337 TagOpenElement
*pDrawFrameElement
= new TagOpenElement("draw:frame");
339 sValue
= doubleToString(2.54 * bitmap
.rect
.x1
); sValue
.append("cm");
340 pDrawFrameElement
->addAttribute("svg:x", sValue
);
341 sValue
= doubleToString(2.54 * bitmap
.rect
.y1
); sValue
.append("cm");
342 pDrawFrameElement
->addAttribute("svg:y", sValue
);
343 sValue
= doubleToString(2.54 * bitmap
.rect
.height()); sValue
.append("cm");
344 pDrawFrameElement
->addAttribute("svg:height", sValue
);
345 sValue
= doubleToString(2.54 * bitmap
.rect
.width()); sValue
.append("cm");
346 pDrawFrameElement
->addAttribute("svg:width", sValue
);
347 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawFrameElement
));
349 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagOpenElement("draw:image")));
351 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagOpenElement("office:binary-data")));
353 libwpg::WPGString base64Binary
;
354 bitmap
.generateBase64DIB(base64Binary
);
355 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new CharDataElement(base64Binary
.cstr())));
357 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("office:binary-data")));
359 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:image")));
361 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:frame")));
364 void OdgExporter::drawImageObject(const libwpg::WPGBinaryData
& binaryData
)
366 if (binaryData
.mimeType
.length() <= 0)
369 TagOpenElement
*pDrawFrameElement
= new TagOpenElement("draw:frame");
371 sValue
= doubleToString(2.54 * binaryData
.rect
.x1
); sValue
.append("cm");
372 pDrawFrameElement
->addAttribute("svg:x", sValue
);
373 sValue
= doubleToString(2.54 * binaryData
.rect
.y1
); sValue
.append("cm");
374 pDrawFrameElement
->addAttribute("svg:y", sValue
);
375 sValue
= doubleToString(2.54 * binaryData
.rect
.height()); sValue
.append("cm");
376 pDrawFrameElement
->addAttribute("svg:height", sValue
);
377 sValue
= doubleToString(2.54 * binaryData
.rect
.width()); sValue
.append("cm");
378 pDrawFrameElement
->addAttribute("svg:width", sValue
);
379 mpBodyElements
.push_back(static_cast<DocumentElement
*>(pDrawFrameElement
));
381 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagOpenElement("draw:image")));
383 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagOpenElement("office:binary-data")));
385 libwpg::WPGString base64Binary
= binaryData
.getBase64Data();;
386 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new CharDataElement(base64Binary
.cstr())));
388 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("office:binary-data")));
390 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:image")));
392 mpBodyElements
.push_back(static_cast<DocumentElement
*>(new TagCloseElement("draw:frame")));
395 void OdgExporter::writeStyle()
397 if(!m_pen
.solid
&& (m_pen
.dashArray
.count() >=2 ) )
399 // ODG only supports dashes with the same length of spaces inbetween
400 // here we take the first space and assume everything else the same
401 // note that dash length is written in percentage
402 double distance
= m_pen
.dashArray
.at(1);
403 TagOpenElement
tmpDrawStrokeDashElement("draw:stroke-dash");
404 tmpDrawStrokeDashElement
.addAttribute("draw:style", "rect");
406 sValue
.sprintf("Dash_%i", m_dashIndex
++);
407 tmpDrawStrokeDashElement
.addAttribute("draw:name", sValue
);
408 sValue
.sprintf("%i \%", distance
*100);
409 tmpDrawStrokeDashElement
.addAttribute("draw:distance", sValue
);
411 for(unsigned i
= 0; i
< m_pen
.dashArray
.count()/2; i
++)
413 sName
.sprintf("draw:dots%i", i
+1);
414 tmpDrawStrokeDashElement
.addAttribute(sName
.cstr(), "1");
415 sName
.sprintf("draw:dots%i-length", i
+1);
416 sValue
.sprintf("%i\%", 100*m_pen
.dashArray
.at(i
*2));
417 tmpDrawStrokeDashElement
.addAttribute(sName
.cstr(), sValue
);
419 tmpDrawStrokeDashElement
.write(mpHandler
);
420 TagCloseElement("draw:stroke-dash").write(mpHandler
);
423 if(m_brush
.style
== libwpg::WPGBrush::Gradient
)
425 TagOpenElement
tmpDrawGradientElement("draw:gradient");
426 tmpDrawGradientElement
.addAttribute("draw:style", "linear");
428 sValue
.sprintf("Gradient_%i", m_gradientIndex
++);
429 tmpDrawGradientElement
.addAttribute("draw:name", sValue
);
431 // ODG angle unit is 0.1 degree
432 double angle
= -m_brush
.gradient
.angle();
438 sValue
.sprintf("%i", angle
*10);
439 tmpDrawGradientElement
.addAttribute("draw:angle", sValue
);
441 libwpg::WPGColor startColor
= m_brush
.gradient
.stopColor(0);
442 libwpg::WPGColor stopColor
= m_brush
.gradient
.stopColor(1);
443 sValue
.sprintf("#%.2x%.2x%.2x", (startColor
.red
& 0xff), (startColor
.green
& 0xff), (startColor
.blue
& 0xff));
444 tmpDrawGradientElement
.addAttribute("draw:start-color", sValue
);
445 sValue
.sprintf("#%.2x%.2x%.2x", (stopColor
.red
& 0xff), (stopColor
.green
& 0xff), (stopColor
.blue
& 0xff));
446 tmpDrawGradientElement
.addAttribute("draw:end-color", sValue
);
447 tmpDrawGradientElement
.addAttribute("draw:start-intensity", "100%");
448 tmpDrawGradientElement
.addAttribute("draw:end-intensity", "100%");
449 tmpDrawGradientElement
.addAttribute("draw:border", "0%");
450 tmpDrawGradientElement
.write(mpHandler
);
451 TagCloseElement("draw:gradient").write(mpHandler
);
454 TagOpenElement
tmpStyleStyleElement("style:style");
456 sValue
.sprintf("gr%i", m_styleIndex
);
457 tmpStyleStyleElement
.addAttribute("style:name", sValue
);
458 tmpStyleStyleElement
.addAttribute("style:family", "graphic");
459 tmpStyleStyleElement
.addAttribute("style:parent-style-name", "standard");
460 tmpStyleStyleElement
.write(mpHandler
);
462 TagOpenElement
tmpStyleGraphicPropertiesElement("style:graphic-properties");
464 if(m_pen
.width
> 0.0)
466 sValue
= doubleToString(2.54 * m_pen
.width
); sValue
.append("cm");
467 tmpStyleGraphicPropertiesElement
.addAttribute("svg:stroke-width", sValue
);
468 sValue
.sprintf("#%.2x%.2x%.2x", (m_pen
.foreColor
.red
& 0xff),
469 (m_pen
.foreColor
.green
& 0xff), (m_pen
.foreColor
.blue
& 0xff));
470 tmpStyleGraphicPropertiesElement
.addAttribute("svg:stroke-color", sValue
);
474 tmpStyleGraphicPropertiesElement
.addAttribute("draw:stroke", "dash");
475 sValue
.sprintf("Dash_%i", m_dashIndex
-1);
476 tmpStyleGraphicPropertiesElement
.addAttribute("draw:stroke-dash", sValue
);
480 tmpStyleGraphicPropertiesElement
.addAttribute("draw:stroke", "none");
482 if(m_brush
.style
== libwpg::WPGBrush::NoBrush
)
483 tmpStyleGraphicPropertiesElement
.addAttribute("draw:fill", "none");
485 if(m_brush
.style
== libwpg::WPGBrush::Solid
)
487 tmpStyleGraphicPropertiesElement
.addAttribute("draw:fill", "solid");
488 sValue
.sprintf("#%.2x%.2x%.2x", (m_brush
.foreColor
.red
& 0xff),
489 (m_brush
.foreColor
.green
& 0xff), (m_brush
.foreColor
.blue
& 0xff));
490 tmpStyleGraphicPropertiesElement
.addAttribute("draw:fill-color", sValue
);
493 if(m_brush
.style
== libwpg::WPGBrush::Gradient
)
495 tmpStyleGraphicPropertiesElement
.addAttribute("draw:fill", "gradient");
496 sValue
.sprintf("Gradient_%i", m_gradientIndex
-1);
497 tmpStyleGraphicPropertiesElement
.addAttribute("draw:fill-gradient-name", sValue
);
500 tmpStyleGraphicPropertiesElement
.write(mpHandler
);
501 TagCloseElement("style:graphic-properties").write(mpHandler
);
503 TagCloseElement("style:style").write(mpHandler
);
507 WPXString
OdgExporter::doubleToString(const double value
)
509 return WPXString((char *)::rtl::math::doubleToString(value
, rtl_math_StringFormat_F
, 4, '.').getStr());