1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <vcl/mtfxmldump.hxx>
11 #include <tools/XmlWriter.hxx>
12 #include <tools/fract.hxx>
13 
14 #include <vcl/metaact.hxx>
15 #include <vcl/outdev.hxx>
16 #include <rtl/string.hxx>
17 
18 #include <sstream>
19 
20 namespace
21 {
22 
collectPushFlags(PushFlags nFlags)23 OUString collectPushFlags(PushFlags nFlags)
24 {
25     if ((nFlags & PushFlags::ALL) == PushFlags::ALL)
26         return "PushAll";
27     else if ((nFlags & PUSH_ALLFONT) == PUSH_ALLFONT)
28         return "PushAllFont";
29     else if ((nFlags & PUSH_ALLTEXT) == PUSH_ALLTEXT)
30         return "PushAllText";
31 
32     std::vector<OUString> aStrings;
33 
34     if (nFlags & PushFlags::LINECOLOR)
35         aStrings.emplace_back("PushLineColor");
36     if (nFlags & PushFlags::FILLCOLOR)
37         aStrings.emplace_back("PushFillColor");
38     if (nFlags & PushFlags::FONT)
39         aStrings.emplace_back("PushFont");
40     if (nFlags & PushFlags::TEXTCOLOR)
41         aStrings.emplace_back("PushTextColor");
42     if (nFlags & PushFlags::MAPMODE)
43         aStrings.emplace_back("PushMapMode");
44     if (nFlags & PushFlags::CLIPREGION)
45         aStrings.emplace_back("PushClipRegion");
46     if (nFlags & PushFlags::RASTEROP)
47         aStrings.emplace_back("PushRasterOp");
48     if (nFlags & PushFlags::TEXTFILLCOLOR)
49         aStrings.emplace_back("PushTextFillColor");
50     if (nFlags & PushFlags::TEXTALIGN)
51         aStrings.emplace_back("PushTextAlign");
52     if (nFlags & PushFlags::REFPOINT)
53         aStrings.emplace_back("PushRefPoint");
54     if (nFlags & PushFlags::TEXTLINECOLOR)
55         aStrings.emplace_back("PushTextLineColor");
56     if (nFlags & PushFlags::TEXTLAYOUTMODE)
57         aStrings.emplace_back("PushTextLayoutMode");
58     if (nFlags & PushFlags::TEXTLANGUAGE)
59         aStrings.emplace_back("PushTextLanguage");
60     if (nFlags & PushFlags::OVERLINECOLOR)
61         aStrings.emplace_back("PushOverlineColor");
62 
63     OUString aString;
64 
65     if (aStrings.empty())
66         return aString;
67 
68     aString = aStrings[0];
69     for (size_t i = 1; i < aStrings.size(); ++i)
70     {
71         aString += ", " + aStrings[i];
72     }
73     return aString;
74 }
75 
convertDrawTextFlagsToString(DrawTextFlags eDrawTextFlags)76 OUString convertDrawTextFlagsToString(DrawTextFlags eDrawTextFlags)
77 {
78     std::vector<OUString> aStrings;
79     if (eDrawTextFlags & DrawTextFlags::Disable)
80         aStrings.emplace_back("Disable");
81     if (eDrawTextFlags & DrawTextFlags::Mnemonic)
82         aStrings.emplace_back("Mnemonic");
83     if (eDrawTextFlags & DrawTextFlags::Mono)
84         aStrings.emplace_back("Mono");
85     if (eDrawTextFlags & DrawTextFlags::Clip)
86         aStrings.emplace_back("Clip");
87     if (eDrawTextFlags & DrawTextFlags::Left)
88         aStrings.emplace_back("Left");
89     if (eDrawTextFlags & DrawTextFlags::Center)
90         aStrings.emplace_back("Center");
91     if (eDrawTextFlags & DrawTextFlags::Right)
92         aStrings.emplace_back("Right");
93     if (eDrawTextFlags & DrawTextFlags::Top)
94         aStrings.emplace_back("Top");
95     if (eDrawTextFlags & DrawTextFlags::VCenter)
96         aStrings.emplace_back("VCenter");
97     if (eDrawTextFlags & DrawTextFlags::Bottom)
98         aStrings.emplace_back("Bottom");
99     if (eDrawTextFlags & DrawTextFlags::EndEllipsis)
100         aStrings.emplace_back("EndEllipsis");
101     if (eDrawTextFlags & DrawTextFlags::PathEllipsis)
102         aStrings.emplace_back("PathEllipsis");
103     if (eDrawTextFlags & DrawTextFlags::MultiLine)
104         aStrings.emplace_back("MultiLine");
105     if (eDrawTextFlags & DrawTextFlags::WordBreak)
106         aStrings.emplace_back("WordBreak");
107     if (eDrawTextFlags & DrawTextFlags::NewsEllipsis)
108         aStrings.emplace_back("NewsEllipsis");
109     if (eDrawTextFlags & DrawTextFlags::WordBreakHyphenation)
110         aStrings.emplace_back("WordBreakHyphenation");
111     if (eDrawTextFlags & DrawTextFlags::CenterEllipsis)
112         aStrings.emplace_back("CenterEllipsis");
113     if (eDrawTextFlags & DrawTextFlags::HideMnemonic)
114         aStrings.emplace_back("HideMnemonic");
115 
116     OUString aString;
117 
118     if (aStrings.empty())
119         return "None";
120 
121     aString = aStrings[0];
122     for (size_t i = 1; i < aStrings.size(); ++i)
123     {
124         aString += " " + aStrings[i];
125     }
126     return aString;
127 };
128 
convertRopToString(RasterOp eRop)129 OUString convertRopToString(RasterOp eRop)
130 {
131     switch (eRop)
132     {
133         case RasterOp::OverPaint: return "overpaint";
134         case RasterOp::Xor:       return "xor";
135         case RasterOp::N0:        return "0";
136         case RasterOp::N1:        return "1";
137         case RasterOp::Invert:    return "invert";
138     }
139     return OUString();
140 }
141 
convertTextAlignToString(TextAlign eAlign)142 OUString convertTextAlignToString(TextAlign eAlign)
143 {
144     switch (eAlign)
145     {
146         case ALIGN_BASELINE:             return "baseline";
147         case ALIGN_BOTTOM:               return "bottom";
148         case ALIGN_TOP:                  return "top";
149         case TextAlign_FORCE_EQUAL_SIZE: return "equalsize";
150     }
151     return OUString();
152 }
153 
convertColorToString(Color aColor)154 OUString convertColorToString(Color aColor)
155 {
156     OUString aRGBString = aColor.AsRGBHexString();
157     return "#" + aRGBString;
158 }
159 
convertLineStyleToString(LineStyle eAlign)160 OUString convertLineStyleToString(LineStyle eAlign)
161 {
162     switch (eAlign)
163     {
164         case LineStyle::NONE:    return "none";
165         case LineStyle::Solid:   return "solid";
166         case LineStyle::Dash:    return "dash";
167         default: break;
168     }
169     return OUString();
170 }
171 
convertLineJoinToString(basegfx::B2DLineJoin eJoin)172 OUString convertLineJoinToString(basegfx::B2DLineJoin eJoin)
173 {
174     switch (eJoin)
175     {
176         default:
177         case basegfx::B2DLineJoin::NONE:    return "none";
178         case basegfx::B2DLineJoin::Bevel:   return "bevel";
179         case basegfx::B2DLineJoin::Miter:   return "miter";
180         case basegfx::B2DLineJoin::Round:   return "round";
181     }
182 }
183 
convertLineCapToString(css::drawing::LineCap eCap)184 OUString convertLineCapToString(css::drawing::LineCap eCap)
185 {
186     switch (eCap)
187     {
188         default:
189         case css::drawing::LineCap_BUTT:   return "butt";
190         case css::drawing::LineCap_ROUND:  return "round";
191         case css::drawing::LineCap_SQUARE: return "square";
192     }
193 }
194 
convertPolygonFlags(PolyFlags eFlags)195 OUString convertPolygonFlags(PolyFlags eFlags)
196 {
197     switch (eFlags)
198     {
199         default:
200         case PolyFlags::Normal:    return "normal";
201         case PolyFlags::Control:   return "control";
202         case PolyFlags::Smooth:    return "smooth";
203         case PolyFlags::Symmetric: return "symmetric";
204     }
205 }
206 
convertFontWeigthToString(FontWeight eFontWeight)207 OUString convertFontWeigthToString(FontWeight eFontWeight)
208 {
209     switch (eFontWeight)
210     {
211         case WEIGHT_DONTKNOW:   return "unknown";
212         case WEIGHT_THIN:       return "thin";
213         case WEIGHT_ULTRALIGHT: return "ultralight";
214         case WEIGHT_LIGHT:      return "light";
215         case WEIGHT_SEMILIGHT:  return "semilight";
216         case WEIGHT_NORMAL:     return "normal";
217         case WEIGHT_MEDIUM:     return "medium";
218         case WEIGHT_SEMIBOLD:   return "semibold";
219         case WEIGHT_BOLD:       return "bold";
220         case WEIGHT_ULTRABOLD:  return "ultrabold";
221         case WEIGHT_BLACK:      return "black";
222         case FontWeight_FORCE_EQUAL_SIZE: return "equalsize";
223     }
224     return OUString();
225 }
226 
convertFontStrikeoutToString(FontStrikeout eFontStrikeout)227 OUString convertFontStrikeoutToString(FontStrikeout eFontStrikeout)
228 {
229     switch (eFontStrikeout)
230     {
231         case STRIKEOUT_NONE:     return "none";
232         case STRIKEOUT_SINGLE:   return "single";
233         case STRIKEOUT_DOUBLE:   return "double";
234         case STRIKEOUT_DONTKNOW: return "dontknow";
235         case STRIKEOUT_BOLD:     return "bold";
236         case STRIKEOUT_SLASH:    return "slash";
237         case STRIKEOUT_X:        return "x";
238         case FontStrikeout_FORCE_EQUAL_SIZE: return "equalsize";
239     }
240     return OUString();
241 }
242 
convertFontLineStyleToString(FontLineStyle eFontLineStyle)243 OUString convertFontLineStyleToString(FontLineStyle eFontLineStyle)
244 {
245     switch (eFontLineStyle)
246     {
247         case LINESTYLE_NONE:            return "none";
248         case LINESTYLE_SINGLE:          return "single";
249         case LINESTYLE_DOUBLE:          return "double";
250         case LINESTYLE_DOTTED:          return "dotted";
251         case LINESTYLE_DONTKNOW:        return "dontknow";
252         case LINESTYLE_DASH:            return "dash";
253         case LINESTYLE_LONGDASH:        return "longdash";
254         case LINESTYLE_DASHDOT:         return "dashdot";
255         case LINESTYLE_DASHDOTDOT:      return "dashdotdot";
256         case LINESTYLE_SMALLWAVE:       return "smallwave";
257         case LINESTYLE_WAVE:            return "wave";
258         case LINESTYLE_DOUBLEWAVE:      return "doublewave";
259         case LINESTYLE_BOLD:            return "bold";
260         case LINESTYLE_BOLDDOTTED:      return "bolddotted";
261         case LINESTYLE_BOLDDASH:        return "bolddash";
262         case LINESTYLE_BOLDLONGDASH:    return "boldlongdash";
263         case LINESTYLE_BOLDDASHDOT:     return "bolddashdot";
264         case LINESTYLE_BOLDDASHDOTDOT:  return "bolddashdotdot";
265         case LINESTYLE_BOLDWAVE:        return "boldwave";
266         case FontLineStyle_FORCE_EQUAL_SIZE: return "equalsize";
267     }
268     return OUString();
269 }
270 
convertLineStyleToString(const MetaActionType nActionType)271 OString convertLineStyleToString(const MetaActionType nActionType)
272 {
273     switch (nActionType)
274     {
275         case MetaActionType::NONE:                  return "null";
276         case MetaActionType::PIXEL:                 return "pixel";
277         case MetaActionType::POINT:                 return "point";
278         case MetaActionType::LINE:                  return "line";
279         case MetaActionType::RECT:                  return "rect";
280         case MetaActionType::ROUNDRECT:             return "roundrect";
281         case MetaActionType::ELLIPSE:               return "ellipse";
282         case MetaActionType::ARC:                   return "arc";
283         case MetaActionType::PIE:                   return "pie";
284         case MetaActionType::CHORD:                 return "chord";
285         case MetaActionType::POLYLINE:              return "polyline";
286         case MetaActionType::POLYGON:               return "polygon";
287         case MetaActionType::POLYPOLYGON:           return "polypolygon";
288         case MetaActionType::TEXT:                  return "text";
289         case MetaActionType::TEXTARRAY:             return "textarray";
290         case MetaActionType::STRETCHTEXT:           return "stretchtext";
291         case MetaActionType::TEXTRECT:              return "textrect";
292         case MetaActionType::TEXTLINE:              return "textline";
293         case MetaActionType::BMP:                   return "bmp";
294         case MetaActionType::BMPSCALE:              return "bmpscale";
295         case MetaActionType::BMPSCALEPART:          return "bmpscalepart";
296         case MetaActionType::BMPEX:                 return "bmpex";
297         case MetaActionType::BMPEXSCALE:            return "bmpexscale";
298         case MetaActionType::BMPEXSCALEPART:        return "bmpexscalepart";
299         case MetaActionType::MASK:                  return "mask";
300         case MetaActionType::MASKSCALE:             return "maskscale";
301         case MetaActionType::MASKSCALEPART:         return "maskscalepart";
302         case MetaActionType::GRADIENT:              return "gradient";
303         case MetaActionType::GRADIENTEX:            return "gradientex";
304         case MetaActionType::HATCH:                 return "hatch";
305         case MetaActionType::WALLPAPER:             return "wallpaper";
306         case MetaActionType::CLIPREGION:            return "clipregion";
307         case MetaActionType::ISECTRECTCLIPREGION:   return "sectrectclipregion";
308         case MetaActionType::ISECTREGIONCLIPREGION: return "sectregionclipregion";
309         case MetaActionType::MOVECLIPREGION:        return "moveclipregion";
310         case MetaActionType::LINECOLOR:             return "linecolor";
311         case MetaActionType::FILLCOLOR:             return "fillcolor";
312         case MetaActionType::TEXTCOLOR:             return "textcolor";
313         case MetaActionType::TEXTFILLCOLOR:         return "textfillcolor";
314         case MetaActionType::TEXTLINECOLOR:         return "textlinecolor";
315         case MetaActionType::OVERLINECOLOR:         return "overlinecolor";
316         case MetaActionType::TEXTALIGN:             return "textalign";
317         case MetaActionType::MAPMODE:               return "mapmode";
318         case MetaActionType::FONT:                  return "font";
319         case MetaActionType::PUSH:                  return "push";
320         case MetaActionType::POP:                   return "pop";
321         case MetaActionType::RASTEROP:              return "rasterop";
322         case MetaActionType::Transparent:           return "transparent";
323         case MetaActionType::FLOATTRANSPARENT:      return "floattransparent";
324         case MetaActionType::EPS:                   return "eps";
325         case MetaActionType::REFPOINT:              return "refpoint";
326         case MetaActionType::COMMENT:               return "comment";
327         case MetaActionType::LAYOUTMODE:            return "layoutmode";
328         case MetaActionType::TEXTLANGUAGE:          return "textlanguage";
329     }
330     return "";
331 }
332 
convertBitmapExTransparentType(TransparentType eType)333 OUString convertBitmapExTransparentType(TransparentType eType)
334 {
335     switch (eType)
336     {
337         default:
338         case TransparentType::NONE:   return "none";
339         case TransparentType::Bitmap: return "bitmap";
340         case TransparentType::Color:  return "color";
341     }
342 }
343 
convertMapUnitToString(MapUnit eUnit)344 OUString convertMapUnitToString(MapUnit eUnit)
345 {
346     switch (eUnit)
347     {
348         default:
349         case MapUnit::LASTENUMDUMMY:    return "LASTENUMDUMMY";
350         case MapUnit::Map1000thInch:    return "Map1000thInch";
351         case MapUnit::Map100thInch:     return "Map100thInch";
352         case MapUnit::Map100thMM:       return "Map100thMM";
353         case MapUnit::Map10thInch:      return "Map10thInch";
354         case MapUnit::Map10thMM:        return "Map10thMM";
355         case MapUnit::MapAppFont:       return "MapAppFont";
356         case MapUnit::MapCM:            return "MapCM";
357         case MapUnit::MapInch:          return "MapInch";
358         case MapUnit::MapMM:            return "MapMM";
359         case MapUnit::MapPixel:         return "MapPixel";
360         case MapUnit::MapPoint:         return "MapPoint";
361         case MapUnit::MapRelative:      return "MapRelative";
362         case MapUnit::MapSysFont:       return "MapSysFont";
363         case MapUnit::MapTwip:          return "MapTwip";
364     }
365 }
366 
convertFractionToString(const Fraction & aFraction)367 OUString convertFractionToString(const Fraction& aFraction)
368 {
369     std::stringstream ss;
370 
371     ss << aFraction;
372 
373     return OUString::createFromAscii(ss.str().c_str());
374 }
375 
convertGradientStyle(GradientStyle eStyle)376 OUString convertGradientStyle(GradientStyle eStyle)
377 {
378     switch (eStyle)
379     {
380         case GradientStyle::Linear:     return "Linear";
381         case GradientStyle::Axial:      return "Axial";
382         case GradientStyle::Radial:     return "Radial";
383         case GradientStyle::Elliptical: return "Elliptical";
384         case GradientStyle::Square:     return "Square";
385         case GradientStyle::Rect:       return "Rect";
386         case GradientStyle::FORCE_EQUAL_SIZE: return "ForceEqualSize";
387     }
388     return OUString();
389 }
390 
convertHatchStyle(HatchStyle eStyle)391 OUString convertHatchStyle(HatchStyle eStyle)
392 {
393     switch (eStyle)
394     {
395         case HatchStyle::Single: return "Single";
396         case HatchStyle::Double: return "Double";
397         case HatchStyle::Triple: return "Triple";
398         case HatchStyle::FORCE_EQUAL_SIZE: return "ForceEqualSize";
399     }
400     return OUString();
401 }
402 
convertWallpaperStyleToString(WallpaperStyle eWallpaperStyle)403 OUString convertWallpaperStyleToString(WallpaperStyle eWallpaperStyle)
404 {
405     switch (eWallpaperStyle)
406     {
407         case WallpaperStyle::NONE: return "NONE";
408         case WallpaperStyle::Tile: return "Tile";
409         case WallpaperStyle::Center: return "Center";
410         case WallpaperStyle::Scale: return "Scale";
411         case WallpaperStyle::TopLeft: return "TopLeft";
412         case WallpaperStyle::Top: return "Top";
413         case WallpaperStyle::TopRight: return "TopRight";
414         case WallpaperStyle::Left: return "Left";
415         case WallpaperStyle::Right: return "Right";
416         case WallpaperStyle::BottomLeft: return "BottomLeft";
417         case WallpaperStyle::Bottom: return "Bottom";
418         case WallpaperStyle::BottomRight: return "BottomRight";
419         case WallpaperStyle::ApplicationGradient: return "ApplicationGradient";
420     }
421     return OUString();
422 }
423 
hex32(sal_uInt32 nNumber)424 OUString hex32(sal_uInt32 nNumber)
425 {
426     std::stringstream ss;
427     ss << std::hex << std::setfill('0') << std::setw(8) << nNumber;
428     return OUString::createFromAscii(ss.str().c_str());
429 }
430 
writePoint(tools::XmlWriter & rWriter,Point const & rPoint)431 void writePoint(tools::XmlWriter& rWriter, Point const& rPoint)
432 {
433     rWriter.attribute("x", rPoint.X());
434     rWriter.attribute("y", rPoint.Y());
435 }
436 
writeStartPoint(tools::XmlWriter & rWriter,Point const & rPoint)437 void writeStartPoint(tools::XmlWriter& rWriter, Point const& rPoint)
438 {
439     rWriter.attribute("startx", rPoint.X());
440     rWriter.attribute("starty", rPoint.Y());
441 }
442 
writeEndPoint(tools::XmlWriter & rWriter,Point const & rPoint)443 void writeEndPoint(tools::XmlWriter& rWriter, Point const& rPoint)
444 {
445     rWriter.attribute("endx", rPoint.X());
446     rWriter.attribute("endy", rPoint.Y());
447 }
448 
writeSize(tools::XmlWriter & rWriter,Size const & rSize)449 void writeSize(tools::XmlWriter& rWriter, Size const& rSize)
450 {
451     rWriter.attribute("width", rSize.Width());
452     rWriter.attribute("height", rSize.Height());
453 }
454 
writeRectangle(tools::XmlWriter & rWriter,tools::Rectangle const & rRectangle)455 void writeRectangle(tools::XmlWriter& rWriter, tools::Rectangle const& rRectangle)
456 {
457     rWriter.attribute("left", rRectangle.Left());
458     rWriter.attribute("top", rRectangle.Top());
459     if (rRectangle.IsWidthEmpty())
460         rWriter.attribute("right", OString("empty"));
461     else
462         rWriter.attribute("right", rRectangle.Right());
463     if (rRectangle.IsHeightEmpty())
464         rWriter.attribute("bottom", OString("empty"));
465     else
466         rWriter.attribute("bottom", rRectangle.Bottom());
467 }
468 
writeLineInfo(tools::XmlWriter & rWriter,LineInfo const & rLineInfo)469 void writeLineInfo(tools::XmlWriter& rWriter, LineInfo const& rLineInfo)
470 {
471     rWriter.attribute("style", convertLineStyleToString(rLineInfo.GetStyle()));
472     rWriter.attribute("width", rLineInfo.GetWidth());
473     rWriter.attribute("dashlen", rLineInfo.GetDashLen());
474     rWriter.attribute("dashcount", rLineInfo.GetDashCount());
475     rWriter.attribute("dotlen", rLineInfo.GetDotLen());
476     rWriter.attribute("dotcount", rLineInfo.GetDotCount());
477     rWriter.attribute("distance", rLineInfo.GetDistance());
478     rWriter.attribute("join", convertLineJoinToString(rLineInfo.GetLineJoin()));
479     rWriter.attribute("cap", convertLineCapToString(rLineInfo.GetLineCap()));
480 }
481 
writeGradient(tools::XmlWriter & rWriter,Gradient const & rGradient)482 void writeGradient(tools::XmlWriter& rWriter, Gradient const& rGradient)
483 {
484     rWriter.attribute("style", convertGradientStyle(rGradient.GetStyle()));
485     rWriter.attribute("startcolor", convertColorToString(rGradient.GetStartColor()));
486     rWriter.attribute("endcolor", convertColorToString(rGradient.GetEndColor()));
487     rWriter.attribute("angle", rGradient.GetAngle());
488     rWriter.attribute("border", rGradient.GetBorder());
489     rWriter.attribute("offsetx", rGradient.GetOfsX());
490     rWriter.attribute("offsety", rGradient.GetOfsY());
491     rWriter.attribute("startintensity", rGradient.GetStartIntensity());
492     rWriter.attribute("endintensity", rGradient.GetEndIntensity());
493     rWriter.attribute("steps", rGradient.GetSteps());
494 }
495 
496 } // anonymous namespace
497 
MetafileXmlDump()498 MetafileXmlDump::MetafileXmlDump()
499 {
500     maFilter.fill(false);
501 }
502 
~MetafileXmlDump()503 MetafileXmlDump::~MetafileXmlDump()
504 {}
505 
filterActionType(const MetaActionType nActionType,bool bShouldFilter)506 void MetafileXmlDump::filterActionType(const MetaActionType nActionType, bool bShouldFilter)
507 {
508     maFilter[nActionType] = bShouldFilter;
509 }
510 
filterAllActionTypes()511 void MetafileXmlDump::filterAllActionTypes()
512 {
513     maFilter.fill(true);
514 }
515 
dump(const GDIMetaFile & rMetaFile,SvStream & rStream)516 void MetafileXmlDump::dump(const GDIMetaFile& rMetaFile, SvStream& rStream)
517 {
518     tools::XmlWriter aWriter(&rStream);
519     aWriter.startDocument();
520     aWriter.startElement("metafile");
521 
522     writeXml(rMetaFile, aWriter);
523 
524     aWriter.endElement();
525     aWriter.endDocument();
526 }
527 
writeXml(const GDIMetaFile & rMetaFile,tools::XmlWriter & rWriter)528 void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, tools::XmlWriter& rWriter)
529 {
530     for(size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction)
531     {
532         MetaAction* pAction = rMetaFile.GetAction(nAction);
533         const MetaActionType nActionType = pAction->GetType();
534         if (maFilter[nActionType])
535             continue;
536 
537         OString sCurrentElementTag = convertLineStyleToString(nActionType);
538 
539         switch (nActionType)
540         {
541             case MetaActionType::NONE:
542             {
543                 rWriter.startElement(sCurrentElementTag);
544                 rWriter.endElement();
545             }
546             break;
547 
548             case MetaActionType::PIXEL:
549             {
550                 auto* pMetaAction = static_cast<MetaPixelAction*>(pAction);
551                 rWriter.startElement(sCurrentElementTag);
552                 writePoint(rWriter, pMetaAction->GetPoint());
553                 rWriter.attribute("color", convertColorToString(pMetaAction->GetColor()));
554                 rWriter.endElement();
555             }
556             break;
557 
558             case MetaActionType::POINT:
559             {
560                 auto* pMetaAction = static_cast<MetaPointAction*>(pAction);
561                 rWriter.startElement(sCurrentElementTag);
562                 writePoint(rWriter, pMetaAction->GetPoint());
563                 rWriter.endElement();
564             }
565             break;
566 
567             case MetaActionType::LINE:
568             {
569                 MetaLineAction* pMetaLineAction = static_cast<MetaLineAction*>(pAction);
570                 rWriter.startElement(sCurrentElementTag);
571                 writeStartPoint(rWriter, pMetaLineAction->GetStartPoint());
572                 writeEndPoint(rWriter, pMetaLineAction->GetEndPoint());
573 
574                 writeLineInfo(rWriter, pMetaLineAction->GetLineInfo());
575                 rWriter.endElement();
576             }
577             break;
578 
579             case MetaActionType::RECT:
580             {
581                 MetaRectAction* pMetaAction = static_cast<MetaRectAction*>(pAction);
582                 rWriter.startElement(sCurrentElementTag);
583                 writeRectangle(rWriter, pMetaAction->GetRect());
584                 rWriter.endElement();
585             }
586             break;
587 
588             case MetaActionType::ROUNDRECT:
589             {
590                 auto pMetaAction = static_cast<MetaRoundRectAction*>(pAction);
591                 rWriter.startElement(sCurrentElementTag);
592                 writeRectangle(rWriter, pMetaAction->GetRect());
593                 rWriter.attribute("horizontalround", pMetaAction->GetHorzRound());
594                 rWriter.attribute("verticalround", pMetaAction->GetVertRound());
595                 rWriter.endElement();
596             }
597             break;
598 
599             case MetaActionType::ELLIPSE:
600             {
601                 auto pMetaAction = static_cast<MetaEllipseAction*>(pAction);
602                 rWriter.startElement(sCurrentElementTag);
603                 writeRectangle(rWriter, pMetaAction->GetRect());
604                 rWriter.endElement();
605             }
606             break;
607 
608             case MetaActionType::ARC:
609             {
610                 auto pMetaAction = static_cast<MetaArcAction*>(pAction);
611                 rWriter.startElement(sCurrentElementTag);
612                 writeRectangle(rWriter, pMetaAction->GetRect());
613                 writeStartPoint(rWriter, pMetaAction->GetStartPoint());
614                 writeEndPoint(rWriter, pMetaAction->GetEndPoint());
615                 rWriter.endElement();
616             }
617             break;
618 
619             case MetaActionType::PIE:
620             {
621                 auto pMetaAction = static_cast<MetaPieAction*>(pAction);
622                 rWriter.startElement(sCurrentElementTag);
623                 writeRectangle(rWriter, pMetaAction->GetRect());
624                 writeStartPoint(rWriter, pMetaAction->GetStartPoint());
625                 writeEndPoint(rWriter, pMetaAction->GetEndPoint());
626                 rWriter.endElement();
627             }
628             break;
629 
630             case MetaActionType::CHORD:
631             {
632                 auto pMetaAction = static_cast<MetaChordAction*>(pAction);
633                 rWriter.startElement(sCurrentElementTag);
634                 writeRectangle(rWriter, pMetaAction->GetRect());
635                 writeStartPoint(rWriter, pMetaAction->GetStartPoint());
636                 writeEndPoint(rWriter, pMetaAction->GetEndPoint());
637                 rWriter.endElement();
638             }
639             break;
640 
641             case MetaActionType::POLYLINE:
642             {
643                 MetaPolyLineAction* pMetaPolyLineAction = static_cast<MetaPolyLineAction*>(pAction);
644                 rWriter.startElement(sCurrentElementTag);
645 
646                 writeLineInfo(rWriter, pMetaPolyLineAction->GetLineInfo());
647 
648                 tools::Polygon aPolygon = pMetaPolyLineAction->GetPolygon();
649                 bool bFlags = aPolygon.HasFlags();
650                 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
651                 {
652                     rWriter.startElement("point");
653                     writePoint(rWriter, aPolygon[i]);
654                     if (bFlags)
655                         rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i)));
656                     rWriter.endElement();
657                 }
658 
659                 rWriter.endElement();
660             }
661             break;
662 
663             case MetaActionType::POLYGON:
664             {
665                 MetaPolygonAction* pMetaPolygonAction = static_cast<MetaPolygonAction*>(pAction);
666                 rWriter.startElement(sCurrentElementTag);
667 
668                 tools::Polygon aPolygon = pMetaPolygonAction->GetPolygon();
669                 bool bFlags = aPolygon.HasFlags();
670                 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
671                 {
672                     rWriter.startElement("point");
673                     writePoint(rWriter, aPolygon[i]);
674                     if (bFlags)
675                         rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i)));
676                     rWriter.endElement();
677                 }
678 
679                 rWriter.endElement();
680             }
681             break;
682 
683             case MetaActionType::POLYPOLYGON:
684             {
685                 MetaPolyPolygonAction *const pMetaPolyPolygonAction = static_cast<MetaPolyPolygonAction*>(pAction);
686                 rWriter.startElement(sCurrentElementTag);
687 
688                 tools::PolyPolygon const& rPolyPolygon(pMetaPolyPolygonAction->GetPolyPolygon());
689 
690                 for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j)
691                 {
692                     rWriter.startElement("polygon");
693                     tools::Polygon const& rPolygon = rPolyPolygon[j];
694                     bool bFlags = rPolygon.HasFlags();
695                     for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i)
696                     {
697                         rWriter.startElement("point");
698                         writePoint(rWriter, rPolygon[i]);
699                         if (bFlags)
700                             rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i)));
701                         rWriter.endElement();
702                     }
703                     rWriter.endElement();
704                 }
705 
706                 rWriter.endElement();
707             }
708             break;
709 
710             case MetaActionType::TEXT:
711             {
712                 auto* pMeta = static_cast<MetaTextAction*>(pAction);
713                 rWriter.startElement(sCurrentElementTag);
714                 writePoint(rWriter, pMeta->GetPoint());
715                 rWriter.attribute("index", pMeta->GetIndex());
716                 rWriter.attribute("length", pMeta->GetLen());
717                 rWriter.startElement("textcontent");
718                 rWriter.content(pMeta->GetText());
719                 rWriter.endElement();
720 
721                 rWriter.endElement();
722             }
723             break;
724 
725             case MetaActionType::TEXTARRAY:
726             {
727                 MetaTextArrayAction* pMetaTextArrayAction = static_cast<MetaTextArrayAction*>(pAction);
728                 rWriter.startElement(sCurrentElementTag);
729 
730                 sal_Int32 aIndex = pMetaTextArrayAction->GetIndex();
731                 sal_Int32 aLength = pMetaTextArrayAction->GetLen();
732 
733                 writePoint(rWriter, pMetaTextArrayAction->GetPoint());
734                 rWriter.attribute("index", aIndex);
735                 rWriter.attribute("length", aLength);
736 
737                 if (pMetaTextArrayAction->GetDXArray())
738                 {
739                     rWriter.startElement("dxarray");
740                     OUStringBuffer sDxLengthString;
741                     for (sal_Int32 i = 0; i < aLength - aIndex; ++i)
742                     {
743                         sDxLengthString.append(OUString::number(pMetaTextArrayAction->GetDXArray()[aIndex + i]));
744                         sDxLengthString.append(" ");
745                     }
746                     rWriter.content(sDxLengthString.makeStringAndClear());
747                     rWriter.endElement();
748                 }
749 
750                 rWriter.startElement("text");
751                 rWriter.content(pMetaTextArrayAction->GetText());
752                 rWriter.endElement();
753 
754                 rWriter.endElement();
755             }
756             break;
757 
758             case MetaActionType::STRETCHTEXT:
759             {
760                 auto* pMeta = static_cast<MetaStretchTextAction*>(pAction);
761                 rWriter.startElement(sCurrentElementTag);
762 
763                 writePoint(rWriter, pMeta->GetPoint());
764                 rWriter.attribute("index", pMeta->GetIndex());
765                 rWriter.attribute("length", pMeta->GetLen());
766                 rWriter.attribute("width", pMeta->GetWidth());
767 
768                 rWriter.startElement("textcontent");
769                 rWriter.content(pMeta->GetText());
770                 rWriter.endElement();
771 
772                 rWriter.endElement();
773             }
774             break;
775 
776             case MetaActionType::TEXTRECT:
777             {
778                 auto* pMeta = static_cast<MetaTextRectAction*>(pAction);
779                 rWriter.startElement(sCurrentElementTag);
780                 writeRectangle(rWriter, pMeta->GetRect());
781                 rWriter.startElement("textcontent");
782                 rWriter.content(pMeta->GetText());
783                 rWriter.endElement();
784 
785                 rWriter.startElement("style");
786                 rWriter.content(convertDrawTextFlagsToString(pMeta->GetStyle()));
787                 rWriter.endElement();
788 
789                 rWriter.endElement();
790             }
791             break;
792 
793             case MetaActionType::BMP:
794             {
795                 auto pMeta = static_cast<MetaBmpAction*>(pAction);
796                 rWriter.startElement(sCurrentElementTag);
797                 writePoint(rWriter, pMeta->GetPoint());
798                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
799                 rWriter.endElement();
800             }
801             break;
802 
803             case MetaActionType::BMPSCALE:
804             {
805                 auto pMeta = static_cast<MetaBmpScaleAction*>(pAction);
806                 rWriter.startElement(sCurrentElementTag);
807                 writePoint(rWriter, pMeta->GetPoint());
808                 writeSize(rWriter, pMeta->GetSize());
809                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
810                 rWriter.endElement();
811             }
812             break;
813 
814             case MetaActionType::BMPSCALEPART:
815             {
816                 auto pMeta = static_cast<MetaBmpScalePartAction*>(pAction);
817                 rWriter.startElement(sCurrentElementTag);
818                 rWriter.attribute("destx", pMeta->GetDestPoint().X());
819                 rWriter.attribute("desty", pMeta->GetDestPoint().Y());
820                 rWriter.attribute("destwidth", pMeta->GetDestSize().Width());
821                 rWriter.attribute("destheight", pMeta->GetDestSize().Height());
822                 rWriter.attribute("srcx", pMeta->GetSrcPoint().X());
823                 rWriter.attribute("srcy", pMeta->GetSrcPoint().Y());
824                 rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width());
825                 rWriter.attribute("srcheight", pMeta->GetSrcSize().Height());
826                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
827                 rWriter.endElement();
828             }
829             break;
830 
831             case MetaActionType::BMPEX:
832             {
833                 auto pMeta = static_cast<MetaBmpExAction*>(pAction);
834                 rWriter.startElement(sCurrentElementTag);
835                 writePoint(rWriter, pMeta->GetPoint());
836                 rWriter.attribute("crc", hex32(pMeta->GetBitmapEx().GetBitmap().GetChecksum()));
837                 rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
838                 rWriter.endElement();
839             }
840             break;
841 
842             case MetaActionType::BMPEXSCALE:
843             {
844                 auto pMeta = static_cast<MetaBmpExScaleAction*>(pAction);
845                 rWriter.startElement(sCurrentElementTag);
846                 writePoint(rWriter, pMeta->GetPoint());
847                 writeSize(rWriter, pMeta->GetSize());
848                 rWriter.attribute("crc", hex32(pMeta->GetBitmapEx().GetBitmap().GetChecksum()));
849                 rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
850                 rWriter.endElement();
851             }
852             break;
853 
854             case MetaActionType::BMPEXSCALEPART:
855             {
856                 auto pMeta = static_cast<MetaBmpExScalePartAction*>(pAction);
857                 rWriter.startElement(sCurrentElementTag);
858                 rWriter.attribute("destx", pMeta->GetDestPoint().X());
859                 rWriter.attribute("desty", pMeta->GetDestPoint().Y());
860                 rWriter.attribute("destwidth", pMeta->GetDestSize().Width());
861                 rWriter.attribute("destheight", pMeta->GetDestSize().Height());
862                 rWriter.attribute("srcx", pMeta->GetSrcPoint().X());
863                 rWriter.attribute("srcy", pMeta->GetSrcPoint().Y());
864                 rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width());
865                 rWriter.attribute("srcheight", pMeta->GetSrcSize().Height());
866                 rWriter.attribute("crc", hex32(pMeta->GetBitmapEx().GetBitmap().GetChecksum()));
867                 rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
868                 rWriter.endElement();
869             }
870             break;
871 
872             case MetaActionType::MASK:
873             {
874                 auto pMeta = static_cast<MetaMaskAction*>(pAction);
875                 rWriter.startElement(sCurrentElementTag);
876                 writePoint(rWriter, pMeta->GetPoint());
877                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
878                 rWriter.attribute("color", convertColorToString(pMeta->GetColor()));
879                 rWriter.endElement();
880             }
881             break;
882 
883             case MetaActionType::MASKSCALE:
884             {
885                 auto pMeta = static_cast<MetaMaskScaleAction*>(pAction);
886                 rWriter.startElement(sCurrentElementTag);
887                 writePoint(rWriter, pMeta->GetPoint());
888                 writeSize(rWriter, pMeta->GetSize());
889                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
890                 rWriter.attribute("color", convertColorToString(pMeta->GetColor()));
891                 rWriter.endElement();
892             }
893             break;
894 
895             case MetaActionType::MASKSCALEPART:
896             {
897                 auto pMeta = static_cast<MetaMaskScalePartAction*>(pAction);
898                 rWriter.startElement(sCurrentElementTag);
899                 rWriter.attribute("destx", pMeta->GetDestPoint().X());
900                 rWriter.attribute("desty", pMeta->GetDestPoint().Y());
901                 rWriter.attribute("destwidth", pMeta->GetDestSize().Width());
902                 rWriter.attribute("destheight", pMeta->GetDestSize().Height());
903                 rWriter.attribute("srcx", pMeta->GetSrcPoint().X());
904                 rWriter.attribute("srcy", pMeta->GetSrcPoint().Y());
905                 rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width());
906                 rWriter.attribute("srcheight", pMeta->GetSrcSize().Height());
907                 rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
908                 rWriter.attribute("color", convertColorToString(pMeta->GetColor()));
909                 rWriter.endElement();
910             }
911             break;
912 
913             case MetaActionType::GRADIENT:
914             {
915                 const MetaGradientAction* pMeta = static_cast<MetaGradientAction*>(pAction);
916 
917                 rWriter.startElement(sCurrentElementTag);
918                 writeGradient(rWriter, pMeta->GetGradient());
919 
920                 rWriter.startElement("rectangle");
921                 writeRectangle(rWriter, pMeta->GetRect());
922                 rWriter.endElement();
923 
924                 rWriter.endElement();
925             }
926             break;
927 
928             case MetaActionType::HATCH:
929             {
930                 auto* const pMetaHatchAction = static_cast<MetaHatchAction*>(pAction);
931                 rWriter.startElement(sCurrentElementTag);
932 
933                 tools::PolyPolygon const& rPolyPolygon(pMetaHatchAction->GetPolyPolygon());
934 
935                 for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j)
936                 {
937                     rWriter.startElement("polygon");
938                     tools::Polygon const& rPolygon = rPolyPolygon[j];
939                     bool bFlags = rPolygon.HasFlags();
940                     for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i)
941                     {
942                         rWriter.startElement("point");
943                         writePoint(rWriter, rPolygon[i]);
944                         if (bFlags)
945                             rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i)));
946                         rWriter.endElement();
947                     }
948                     rWriter.endElement();
949                 }
950 
951                 rWriter.startElement("hatch");
952                 const auto& rHatch = pMetaHatchAction->GetHatch();
953                 rWriter.attribute("style", convertHatchStyle(rHatch.GetStyle()));
954                 rWriter.attribute("color", convertColorToString(rHatch.GetColor()));
955                 rWriter.attribute("distance", sal_Int32(rHatch.GetDistance()));
956                 rWriter.attribute("angle", sal_Int32(rHatch.GetAngle()));
957                 rWriter.endElement();
958 
959                 rWriter.endElement();
960             }
961             break;
962 
963             case MetaActionType::WALLPAPER:
964             {
965                 const auto* pMetaAction = static_cast<const MetaWallpaperAction*>(pAction);
966                 rWriter.startElement(sCurrentElementTag);
967 
968                 writeRectangle(rWriter, pMetaAction->GetRect());
969 
970                 rWriter.startElement("wallpaper");
971                 const auto& rWallpaper = pMetaAction->GetWallpaper();
972 
973                 rWriter.attribute("color", convertColorToString(rWallpaper.GetColor()));
974 
975                 WallpaperStyle eStyle = rWallpaper.GetStyle();
976                 rWriter.attribute("style", convertWallpaperStyleToString(eStyle));
977 
978                 if (rWallpaper.IsBitmap())
979                 {
980                     rWriter.startElement("bitmap");
981                     BitmapEx const & rBitmapEx = rWallpaper.GetBitmap();
982                     rWriter.attribute("crc", hex32(rBitmapEx.GetChecksum()));
983                     rWriter.attribute("transparenttype", convertBitmapExTransparentType(rBitmapEx.GetTransparentType()));
984                     rWriter.attribute("bitcount", hex32(rBitmapEx.GetBitmap().GetBitCount()));
985                     rWriter.attribute("width", hex32(rBitmapEx.GetSizePixel().Width()));
986                     rWriter.attribute("height", hex32(rBitmapEx.GetSizePixel().Height()));
987                     rWriter.endElement();
988                 }
989 
990                 if (rWallpaper.IsGradient())
991                 {
992                     rWriter.startElement("gradient");
993                     Gradient aGradient = rWallpaper.GetGradient();
994                     writeGradient(rWriter, aGradient);
995                     rWriter.endElement();
996                 }
997 
998                 if (rWallpaper.IsRect())
999                 {
1000                     tools::Rectangle aRect = rWallpaper.GetRect();
1001                     rWriter.startElement("rectangle");
1002                     writeRectangle(rWriter, aRect);
1003                     rWriter.endElement();
1004                 }
1005 
1006                 rWriter.attribute("fixed", rWallpaper.IsFixed() ? "true" : "false");
1007                 rWriter.attribute("scrollable", rWallpaper.IsScrollable() ? "true" : "false");
1008 
1009                 rWriter.endElement();
1010 
1011                 rWriter.endElement();
1012             }
1013             break;
1014 
1015             case MetaActionType::CLIPREGION:
1016             {
1017                 const auto* pMetaClipRegionAction = static_cast<const MetaClipRegionAction*>(pAction);
1018                 rWriter.startElement(sCurrentElementTag);
1019 
1020                 // FIXME for now we dump only the bounding box; this is
1021                 // enough for the tests we have, but may need extending to
1022                 // dumping the real polypolygon in the future
1023                 tools::Rectangle aRectangle = pMetaClipRegionAction->GetRegion().GetBoundRect();
1024                 writeRectangle(rWriter, aRectangle);
1025                 rWriter.endElement();
1026             }
1027             break;
1028 
1029             case MetaActionType::ISECTRECTCLIPREGION:
1030             {
1031                 MetaISectRectClipRegionAction* pMetaISectRectClipRegionAction = static_cast<MetaISectRectClipRegionAction*>(pAction);
1032                 rWriter.startElement(sCurrentElementTag);
1033 
1034                 tools::Rectangle aRectangle = pMetaISectRectClipRegionAction->GetRect();
1035                 writeRectangle(rWriter, aRectangle);
1036                 rWriter.endElement();
1037             }
1038             break;
1039 
1040             case MetaActionType::ISECTREGIONCLIPREGION:
1041             {
1042                 MetaISectRegionClipRegionAction* pMetaISectRegionClipRegionAction = static_cast<MetaISectRegionClipRegionAction*>(pAction);
1043                 rWriter.startElement(sCurrentElementTag);
1044 
1045                 // FIXME for now we dump only the bounding box; this is
1046                 // enough for the tests we have, but may need extending to
1047                 // dumping the real polypolygon in the future
1048                 tools::Rectangle aRectangle = pMetaISectRegionClipRegionAction->GetRegion().GetBoundRect();
1049                 writeRectangle(rWriter, aRectangle);
1050                 rWriter.endElement();
1051             }
1052             break;
1053 
1054             // case MetaActionType::MOVECLIPREGION:
1055 
1056             case MetaActionType::LINECOLOR:
1057             {
1058                 MetaLineColorAction* pMetaLineColorAction = static_cast<MetaLineColorAction*>(pAction);
1059                 rWriter.startElement(sCurrentElementTag);
1060 
1061                 rWriter.attribute("color", convertColorToString(pMetaLineColorAction->GetColor()));
1062                 rWriter.endElement();
1063             }
1064             break;
1065 
1066             case MetaActionType::FILLCOLOR:
1067             {
1068                 MetaFillColorAction* pMetaFillColorAction = static_cast<MetaFillColorAction*>(pAction);
1069                 rWriter.startElement(sCurrentElementTag);
1070 
1071                 rWriter.attribute("color", convertColorToString(pMetaFillColorAction->GetColor()));
1072                 rWriter.endElement();
1073             }
1074             break;
1075 
1076             case MetaActionType::TEXTCOLOR:
1077             {
1078                 MetaTextColorAction* pMetaTextColorAction = static_cast<MetaTextColorAction*>(pAction);
1079                 rWriter.startElement(sCurrentElementTag);
1080 
1081                 rWriter.attribute("color", convertColorToString(pMetaTextColorAction->GetColor()));
1082                 rWriter.endElement();
1083             }
1084             break;
1085 
1086             case MetaActionType::TEXTFILLCOLOR:
1087             {
1088                 MetaTextFillColorAction* pMetaTextFillColorAction = static_cast<MetaTextFillColorAction*>(pAction);
1089                 rWriter.startElement(sCurrentElementTag);
1090 
1091                 rWriter.attribute("color", convertColorToString(pMetaTextFillColorAction->GetColor()));
1092 
1093                 if (pMetaTextFillColorAction->IsSetting())
1094                     rWriter.attribute("setting", OUString("true"));
1095 
1096                 rWriter.endElement();
1097             }
1098             break;
1099 
1100             case MetaActionType::TEXTALIGN:
1101             {
1102                 MetaTextAlignAction* pMetaTextAlignAction = static_cast<MetaTextAlignAction*>(pAction);
1103                 rWriter.startElement(sCurrentElementTag);
1104                 OUString sAlign = convertTextAlignToString(pMetaTextAlignAction->GetTextAlign());
1105                 if (!sAlign.isEmpty())
1106                     rWriter.attribute("align", sAlign);
1107                 rWriter.endElement();
1108             }
1109             break;
1110 
1111             case MetaActionType::MAPMODE:
1112             {
1113                 const MetaMapModeAction* pMeta = static_cast<MetaMapModeAction*>(pAction);
1114                 MapMode aMapMode = pMeta->GetMapMode();
1115                 rWriter.startElement(sCurrentElementTag);
1116                 rWriter.attribute("mapunit", convertMapUnitToString( aMapMode.GetMapUnit() ));
1117                 writePoint(rWriter, aMapMode.GetOrigin());
1118                 rWriter.attribute("scalex", convertFractionToString(aMapMode.GetScaleX()));
1119                 rWriter.attribute("scaley", convertFractionToString(aMapMode.GetScaleY()));
1120                 rWriter.endElement();
1121             }
1122             break;
1123 
1124             case MetaActionType::FONT:
1125             {
1126                 MetaFontAction* pMetaFontAction = static_cast<MetaFontAction*>(pAction);
1127                 rWriter.startElement(sCurrentElementTag);
1128 
1129                 vcl::Font aFont = pMetaFontAction->GetFont();
1130 
1131                 rWriter.attribute("color", convertColorToString(aFont.GetColor()));
1132                 rWriter.attribute("fillcolor", convertColorToString(aFont.GetFillColor()));
1133                 rWriter.attribute("name", aFont.GetFamilyName());
1134                 rWriter.attribute("stylename", aFont.GetStyleName());
1135                 rWriter.attribute("width", aFont.GetFontSize().Width());
1136                 rWriter.attribute("height", aFont.GetFontSize().Height());
1137                 rWriter.attribute("orientation", aFont.GetOrientation());
1138                 rWriter.attribute("weight", convertFontWeigthToString(aFont.GetWeight()));
1139                 rWriter.attribute("vertical", aFont.IsVertical() ? "true" : "false");
1140 
1141                 rWriter.endElement();
1142             }
1143             break;
1144 
1145             case MetaActionType::PUSH:
1146             {
1147                 MetaPushAction* pMetaPushAction = static_cast<MetaPushAction*>(pAction);
1148                 rWriter.startElement(sCurrentElementTag);
1149 
1150                 rWriter.attribute("flags", collectPushFlags(pMetaPushAction->GetFlags()));
1151             }
1152             break;
1153 
1154             case MetaActionType::POP:
1155             {
1156                 rWriter.endElement();
1157             }
1158             break;
1159 
1160             case MetaActionType::RASTEROP:
1161             {
1162                 MetaRasterOpAction* pMetaRasterOpAction = static_cast<MetaRasterOpAction*>(pAction);
1163                 rWriter.startElement(sCurrentElementTag);
1164 
1165                 if (pMetaRasterOpAction->GetRasterOp() != RasterOp::OverPaint)
1166                 {
1167                     rWriter.attribute("operation", convertRopToString(pMetaRasterOpAction->GetRasterOp()));
1168                 }
1169                 rWriter.endElement();
1170             }
1171             break;
1172 
1173             case MetaActionType::Transparent:
1174             {
1175                 const MetaTransparentAction* pMeta = static_cast<MetaTransparentAction*>(pAction);
1176 
1177                 rWriter.startElement(sCurrentElementTag);
1178                 rWriter.attribute("transparence", pMeta->GetTransparence());
1179 
1180                 tools::PolyPolygon const& rPolyPolygon(pMeta->GetPolyPolygon());
1181 
1182                 for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j)
1183                 {
1184                     rWriter.startElement("polygon");
1185                     tools::Polygon const& rPolygon = rPolyPolygon[j];
1186                     bool bFlags = rPolygon.HasFlags();
1187                     for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i)
1188                     {
1189                         rWriter.startElement("point");
1190                         writePoint(rWriter, rPolygon[i]);
1191                         if (bFlags)
1192                             rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i)));
1193                         rWriter.endElement();
1194                     }
1195                     rWriter.endElement();
1196                 }
1197 
1198                 rWriter.endElement();
1199             }
1200             break;
1201 
1202             //case MetaActionType::EPS:
1203             //case MetaActionType::REFPOINT:
1204 
1205             case MetaActionType::TEXTLINECOLOR:
1206             {
1207                 MetaTextLineColorAction* pMetaTextLineColorAction = static_cast<MetaTextLineColorAction*>(pAction);
1208                 rWriter.startElement(sCurrentElementTag);
1209 
1210                 rWriter.attribute("color", convertColorToString(pMetaTextLineColorAction->GetColor()));
1211                 rWriter.endElement();
1212             }
1213             break;
1214 
1215             case MetaActionType::TEXTLINE:
1216             {
1217                 auto* pMeta = static_cast<MetaTextLineAction*>(pAction);
1218                 rWriter.startElement(sCurrentElementTag);
1219                 writePoint(rWriter, pMeta->GetStartPoint());
1220                 rWriter.attribute("width", pMeta->GetWidth());
1221                 rWriter.attribute("strikeout", convertFontStrikeoutToString(pMeta->GetStrikeout()));
1222                 rWriter.attribute("underline", convertFontLineStyleToString(pMeta->GetUnderline()));
1223                 rWriter.attribute("overline", convertFontLineStyleToString(pMeta->GetOverline()));
1224                 rWriter.endElement();
1225             }
1226             break;
1227 
1228             //case MetaActionType::FLOATTRANSPARENT:
1229             //case MetaActionType::GRADIENTEX:
1230             //case MetaActionType::LAYOUTMODE:
1231             //case MetaActionType::TEXTLANGUAGE:
1232 
1233             case MetaActionType::OVERLINECOLOR:
1234             {
1235                 const auto* pMetaAction = static_cast<MetaOverlineColorAction*>(pAction);
1236                 rWriter.startElement(sCurrentElementTag);
1237                 rWriter.attribute("color", convertColorToString(pMetaAction->GetColor()));
1238                 rWriter.endElement();
1239             }
1240             break;
1241 
1242             case MetaActionType::COMMENT:
1243             {
1244                 MetaCommentAction* pMetaCommentAction = static_cast<MetaCommentAction*>(pAction);
1245                 rWriter.startElement(sCurrentElementTag);
1246 
1247                 if (pMetaCommentAction->GetDataSize() > 0)
1248                 {
1249                     rWriter.attribute("datasize", pMetaCommentAction->GetDataSize());
1250                 }
1251                 if (!pMetaCommentAction->GetComment().isEmpty())
1252                 {
1253                     rWriter.startElement("comment");
1254                     rWriter.content(pMetaCommentAction->GetComment());
1255                     rWriter.endElement();
1256                 }
1257 
1258                 rWriter.endElement();
1259             }
1260             break;
1261 
1262             default:
1263             {
1264                 rWriter.startElement(sCurrentElementTag);
1265                 rWriter.attribute("note", OString("not implemented in xml dump"));
1266                 rWriter.endElement();
1267             }
1268             break;
1269         }
1270     }
1271 }
1272 
1273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1274