Branch libreoffice-5-0-4
[LibreOffice.git] / test / source / mtfxmldump.cxx
blob3df33b9568201e1202f070e47e182a6b9a7d0836
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <test/mtfxmldump.hxx>
11 #include <test/xmltesttools.hxx>
12 #include <test/xmlwriter.hxx>
14 #include <vcl/metaact.hxx>
15 #include <rtl/string.hxx>
16 #include <rtl/strbuf.hxx>
18 #include <boost/scoped_ptr.hpp>
20 namespace
23 OUString flagToString(PushFlags nFlag)
25 if (nFlag & PushFlags::LINECOLOR)
26 return OUString("PushLineColor");
27 else if (nFlag & PushFlags::FILLCOLOR)
28 return OUString("PushFillColor");
29 else if (nFlag & PushFlags::FONT)
30 return OUString("PushFont");
31 else if (nFlag & PushFlags::TEXTCOLOR)
32 return OUString("PushTextColor");
33 else if (nFlag & PushFlags::MAPMODE)
34 return OUString("PushMapMode");
35 else if (nFlag & PushFlags::CLIPREGION)
36 return OUString("PushClipRegion");
37 else if (nFlag & PushFlags::RASTEROP)
38 return OUString("PushRasterOp");
39 else if (nFlag & PushFlags::TEXTFILLCOLOR)
40 return OUString("PushTextFillColor");
41 else if (nFlag & PushFlags::TEXTALIGN)
42 return OUString("PushTextAlign");
43 else if (nFlag & PushFlags::REFPOINT)
44 return OUString("PushRefPoint");
45 else if (nFlag & PushFlags::TEXTLINECOLOR)
46 return OUString("PushTextLineColor");
47 else if (nFlag & PushFlags::TEXTLAYOUTMODE)
48 return OUString("PushTextLayoutMode");
49 else if (nFlag & PushFlags::TEXTLANGUAGE)
50 return OUString("PushTextLanguage");
51 else if (nFlag & PushFlags::OVERLINECOLOR)
52 return OUString("PushOverlineColor");
54 return OUString();
57 OUString collectPushFlags(PushFlags nFlags)
59 if ((nFlags & PushFlags::ALL) == nFlags)
60 return OUString("PushAll");
61 else if ((nFlags & PUSH_ALLFONT) == nFlags)
62 return OUString("PushAllFont");
63 else if ((nFlags & PUSH_ALLTEXT) == nFlags)
64 return OUString("PushAllText");
66 OUString sFlags;
68 for (sal_uInt16 nFlag = 1; nFlag > 0; nFlag <<= 1)
70 OUString sFlag = flagToString(static_cast<PushFlags>(nFlag));
71 if (!sFlag.isEmpty())
73 if (!sFlags.isEmpty())
75 sFlags += ",";
77 sFlags += flagToString(static_cast<PushFlags>(nFlag));
81 return sFlags;
84 OUString convertRopToString(RasterOp eRop)
86 switch (eRop)
88 case ROP_OVERPAINT: return OUString("overpaint");
89 case ROP_XOR: return OUString("xor");
90 case ROP_0: return OUString("0");
91 case ROP_1: return OUString("1");
92 case ROP_INVERT: return OUString("invert");
94 return OUString();
97 OUString convertTextAlignToString(TextAlign eAlign)
99 switch (eAlign)
101 case ALIGN_BASELINE: return OUString("baseline");
102 case ALIGN_BOTTOM: return OUString("bottom");
103 case ALIGN_TOP: return OUString("top");
104 case TextAlign_FORCE_EQUAL_SIZE: return OUString("equalsize");
106 return OUString();
109 OUString convertColorToString(Color aColor)
111 OUString aRGBString = aColor.AsRGBHexString();
112 return "#" + aRGBString;
115 OUString convertLineStyleToString(LineStyle eAlign)
117 switch (eAlign)
119 case LINE_NONE: return OUString("none");
120 case LINE_SOLID: return OUString("solid");
121 case LINE_DASH: return OUString("dash");
122 case LineStyle_FORCE_EQUAL_SIZE: return OUString("equalsize");
124 return OUString();
127 OUString convertFontWeigthToString(FontWeight eFontWeight)
129 enum FontWeight { WEIGHT_DONTKNOW, WEIGHT_THIN, WEIGHT_ULTRALIGHT,
130 WEIGHT_LIGHT, WEIGHT_SEMILIGHT, WEIGHT_NORMAL,
131 WEIGHT_MEDIUM, WEIGHT_SEMIBOLD, WEIGHT_BOLD,
132 WEIGHT_ULTRABOLD, WEIGHT_BLACK, FontWeight_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
133 switch (eFontWeight)
135 case WEIGHT_DONTKNOW: return OUString("unknown");
136 case WEIGHT_THIN: return OUString("thin");
137 case WEIGHT_ULTRALIGHT: return OUString("ultralight");
138 case WEIGHT_LIGHT: return OUString("light");
139 case WEIGHT_SEMILIGHT: return OUString("semilight");
140 case WEIGHT_NORMAL: return OUString("normal");
141 case WEIGHT_MEDIUM: return OUString("medium");
142 case WEIGHT_SEMIBOLD: return OUString("semibold");
143 case WEIGHT_BOLD: return OUString("bold");
144 case WEIGHT_ULTRABOLD: return OUString("ultrabold");
145 case WEIGHT_BLACK: return OUString("black");
146 case FontWeight_FORCE_EQUAL_SIZE: return OUString("equalsize");
148 return OUString();
151 OString convertLineStyleToString(const MetaActionType nActionType)
153 switch (nActionType)
155 case MetaActionType::NONE: return "null";
156 case MetaActionType::PIXEL: return "pixel";
157 case MetaActionType::POINT: return "point";
158 case MetaActionType::LINE: return "line";
159 case MetaActionType::RECT: return "rect";
160 case MetaActionType::ROUNDRECT: return "roundrect";
161 case MetaActionType::ELLIPSE: return "ellipse";
162 case MetaActionType::ARC: return "arc";
163 case MetaActionType::PIE: return "pie";
164 case MetaActionType::CHORD: return "chord";
165 case MetaActionType::POLYLINE: return "polyline";
166 case MetaActionType::POLYGON: return "polygon";
167 case MetaActionType::POLYPOLYGON: return "polypolygon";
168 case MetaActionType::TEXT: return "text";
169 case MetaActionType::TEXTARRAY: return "textarray";
170 case MetaActionType::STRETCHTEXT: return "stretchtext";
171 case MetaActionType::TEXTRECT: return "textrect";
172 case MetaActionType::TEXTLINE: return "textline";
173 case MetaActionType::BMP: return "bmp";
174 case MetaActionType::BMPSCALE: return "bmpscale";
175 case MetaActionType::BMPSCALEPART: return "bmpscalepart";
176 case MetaActionType::BMPEX: return "bmpex";
177 case MetaActionType::BMPEXSCALE: return "bmpexscale";
178 case MetaActionType::BMPEXSCALEPART: return "bmpexscalepart";
179 case MetaActionType::MASK: return "mask";
180 case MetaActionType::MASKSCALE: return "maskscale";
181 case MetaActionType::MASKSCALEPART: return "maskscalepart";
182 case MetaActionType::GRADIENT: return "gradient";
183 case MetaActionType::GRADIENTEX: return "gradientex";
184 case MetaActionType::HATCH: return "hatch";
185 case MetaActionType::WALLPAPER: return "wallpaper";
186 case MetaActionType::CLIPREGION: return "clipregion";
187 case MetaActionType::ISECTRECTCLIPREGION: return "sectrectclipregion";
188 case MetaActionType::ISECTREGIONCLIPREGION: return "sectregionclipregion";
189 case MetaActionType::MOVECLIPREGION: return "moveclipregion";
190 case MetaActionType::LINECOLOR: return "linecolor";
191 case MetaActionType::FILLCOLOR: return "fillcolor";
192 case MetaActionType::TEXTCOLOR: return "textcolor";
193 case MetaActionType::TEXTFILLCOLOR: return "textfillcolor";
194 case MetaActionType::TEXTLINECOLOR: return "textlinecolor";
195 case MetaActionType::OVERLINECOLOR: return "overlinecolor";
196 case MetaActionType::TEXTALIGN: return "textalign";
197 case MetaActionType::MAPMODE: return "mapmode";
198 case MetaActionType::FONT: return "font";
199 case MetaActionType::PUSH: return "push";
200 case MetaActionType::POP: return "pop";
201 case MetaActionType::RASTEROP: return "rasterop";
202 case MetaActionType::Transparent: return "transparent";
203 case MetaActionType::FLOATTRANSPARENT: return "floattransparent";
204 case MetaActionType::EPS: return "eps";
205 case MetaActionType::REFPOINT: return "refpoint";
206 case MetaActionType::COMMENT: return "comment";
207 case MetaActionType::LAYOUTMODE: return "layoutmode";
208 case MetaActionType::TEXTLANGUAGE: return "textlanguage";
210 return "";
213 } // anonymous namespace
215 MetafileXmlDump::MetafileXmlDump()
217 maFilter.fill(false);
220 MetafileXmlDump::~MetafileXmlDump()
223 void MetafileXmlDump::filterActionType(const MetaActionType nActionType, bool bShouldFilter)
225 maFilter[nActionType] = bShouldFilter;
228 void MetafileXmlDump::filterAllActionTypes()
230 maFilter.fill(true);
233 xmlDocPtr MetafileXmlDump::dumpAndParse(const GDIMetaFile& rMetaFile, const OUString& rTempStreamName)
235 boost::scoped_ptr<SvStream> pStream;
237 if (rTempStreamName.isEmpty())
238 pStream.reset(new SvMemoryStream());
239 else
240 pStream.reset(new SvFileStream(rTempStreamName, STREAM_STD_READWRITE | StreamMode::TRUNC));
242 XmlWriter aWriter(pStream.get());
243 aWriter.startDocument();
244 aWriter.startElement("metafile");
246 writeXml(rMetaFile, aWriter);
248 aWriter.endElement();
249 aWriter.endDocument();
251 pStream->Seek(STREAM_SEEK_TO_BEGIN);
253 xmlDocPtr pDoc = XmlTestTools::parseXmlStream(pStream.get());
255 return pDoc;
258 void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
260 for(size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction)
262 MetaAction* pAction = rMetaFile.GetAction(nAction);
263 const MetaActionType nActionType = pAction->GetType();
264 if (maFilter[nActionType])
265 continue;
267 OString sCurrentElementTag = convertLineStyleToString(nActionType);
269 switch (nActionType)
271 case MetaActionType::LINE:
273 MetaLineAction* pMetaLineAction = static_cast<MetaLineAction*>(pAction);
274 rWriter.startElement(sCurrentElementTag);
276 rWriter.attribute("startx", pMetaLineAction->GetStartPoint().X());
277 rWriter.attribute("starty", pMetaLineAction->GetStartPoint().Y());
278 rWriter.attribute("endx", pMetaLineAction->GetEndPoint().X());
279 rWriter.attribute("endy", pMetaLineAction->GetEndPoint().Y());
281 LineInfo aLineInfo = pMetaLineAction->GetLineInfo();
282 rWriter.attribute("style", convertLineStyleToString(aLineInfo.GetStyle()));
283 rWriter.attribute("width", aLineInfo.GetWidth());
284 rWriter.attribute("dashlen", aLineInfo.GetDashLen());
285 rWriter.attribute("dotlen", aLineInfo.GetDotLen());
286 rWriter.attribute("distance", aLineInfo.GetDistance());
288 rWriter.endElement();
290 break;
292 case MetaActionType::PUSH:
294 MetaPushAction* pMetaPushAction = static_cast<MetaPushAction*>(pAction);
295 rWriter.startElement(sCurrentElementTag);
297 rWriter.attribute("flags", collectPushFlags(pMetaPushAction->GetFlags()));
299 break;
301 case MetaActionType::POP:
303 rWriter.endElement();
305 break;
307 case MetaActionType::RASTEROP:
309 MetaRasterOpAction* pMetaRasterOpAction = static_cast<MetaRasterOpAction*>(pAction);
310 rWriter.startElement(sCurrentElementTag);
312 if (pMetaRasterOpAction->GetRasterOp() != ROP_OVERPAINT)
314 rWriter.attribute("operation", convertRopToString(pMetaRasterOpAction->GetRasterOp()));
316 rWriter.endElement();
318 break;
320 case MetaActionType::TEXTLINECOLOR:
322 MetaTextLineColorAction* pMetaTextLineColorAction = static_cast<MetaTextLineColorAction*>(pAction);
323 rWriter.startElement(sCurrentElementTag);
325 rWriter.attribute("color", convertColorToString(pMetaTextLineColorAction->GetColor()));
326 rWriter.endElement();
328 break;
330 case MetaActionType::TEXTFILLCOLOR:
332 MetaTextFillColorAction* pMetaTextFillColorAction = static_cast<MetaTextFillColorAction*>(pAction);
333 rWriter.startElement(sCurrentElementTag);
335 rWriter.attribute("color", convertColorToString(pMetaTextFillColorAction->GetColor()));
337 if (pMetaTextFillColorAction->IsSetting())
338 rWriter.attribute("setting", OUString("true"));
340 rWriter.endElement();
342 break;
344 case MetaActionType::FONT:
346 MetaFontAction* pMetaFontAction = static_cast<MetaFontAction*>(pAction);
347 rWriter.startElement(sCurrentElementTag);
349 vcl::Font aFont = pMetaFontAction->GetFont();
351 rWriter.attribute("color", convertColorToString(aFont.GetColor()));
352 rWriter.attribute("fillcolor", convertColorToString(aFont.GetFillColor()));
353 rWriter.attribute("name", aFont.GetName());
354 rWriter.attribute("stylename", aFont.GetStyleName());
355 rWriter.attribute("width", aFont.GetSize().Width());
356 rWriter.attribute("height", aFont.GetSize().Height());
357 rWriter.attribute("orientation", aFont.GetOrientation());
358 rWriter.attribute("weight", convertFontWeigthToString(aFont.GetWeight()));
360 rWriter.endElement();
362 break;
364 case MetaActionType::TEXTALIGN:
366 MetaTextAlignAction* pMetaTextAlignAction = static_cast<MetaTextAlignAction*>(pAction);
367 rWriter.startElement(sCurrentElementTag);
368 OUString sAlign = convertTextAlignToString(pMetaTextAlignAction->GetTextAlign());
369 if (!sAlign.isEmpty())
370 rWriter.attribute("align", sAlign);
371 rWriter.endElement();
373 break;
375 case MetaActionType::TEXTCOLOR:
377 MetaTextColorAction* pMetaTextColorAction = static_cast<MetaTextColorAction*>(pAction);
378 rWriter.startElement(sCurrentElementTag);
380 rWriter.attribute("color", convertColorToString(pMetaTextColorAction->GetColor()));
381 rWriter.endElement();
383 break;
385 case MetaActionType::TEXTARRAY:
387 MetaTextArrayAction* pMetaTextArrayAction = static_cast<MetaTextArrayAction*>(pAction);
388 rWriter.startElement(sCurrentElementTag);
390 sal_Int32 aIndex = pMetaTextArrayAction->GetIndex();
391 sal_Int32 aLength = pMetaTextArrayAction->GetLen();
393 rWriter.attribute("x", pMetaTextArrayAction->GetPoint().X());
394 rWriter.attribute("y", pMetaTextArrayAction->GetPoint().Y());
395 rWriter.attribute("index", aIndex);
396 rWriter.attribute("length", aLength);
398 rWriter.startElement("dxarray");
399 OUString sDxLengthString;
400 for (sal_Int32 i = 0; i < aLength; ++i)
402 sDxLengthString += OUString::number(pMetaTextArrayAction->GetDXArray()[aIndex+i]);
403 sDxLengthString += " ";
405 rWriter.content(sDxLengthString);
406 rWriter.endElement();
408 rWriter.startElement("text");
409 rWriter.content(pMetaTextArrayAction->GetText());
410 rWriter.endElement();
412 rWriter.endElement();
414 break;
416 case MetaActionType::LINECOLOR:
418 MetaLineColorAction* pMetaLineColorAction = static_cast<MetaLineColorAction*>(pAction);
419 rWriter.startElement(sCurrentElementTag);
421 rWriter.attribute("color", convertColorToString(pMetaLineColorAction->GetColor()));
422 rWriter.endElement();
424 break;
426 case MetaActionType::FILLCOLOR:
428 MetaFillColorAction* pMetaFillColorAction = static_cast<MetaFillColorAction*>(pAction);
429 rWriter.startElement(sCurrentElementTag);
431 rWriter.attribute("color", convertColorToString(pMetaFillColorAction->GetColor()));
432 rWriter.endElement();
434 break;
436 case MetaActionType::CLIPREGION:
438 const MetaClipRegionAction* pA = static_cast< const MetaClipRegionAction* >(pAction);
439 rWriter.startElement(sCurrentElementTag);
441 // FIXME for now we dump only the bounding box; this is
442 // enough for the tests we have, but may need extending to
443 // dumping the real polypolygon in the future
444 Rectangle aRectangle = pA->GetRegion().GetBoundRect();
445 rWriter.attribute("top", aRectangle.Top());
446 rWriter.attribute("left", aRectangle.Left());
447 rWriter.attribute("bottom", aRectangle.Bottom());
448 rWriter.attribute("right", aRectangle.Right());
450 rWriter.endElement();
452 break;
454 case MetaActionType::ISECTRECTCLIPREGION:
456 MetaISectRectClipRegionAction* pMetaISectRectClipRegionAction = static_cast<MetaISectRectClipRegionAction*>(pAction);
457 rWriter.startElement(sCurrentElementTag);
459 Rectangle aRectangle = pMetaISectRectClipRegionAction->GetRect();
460 rWriter.attribute("top", aRectangle.Top());
461 rWriter.attribute("left", aRectangle.Left());
462 rWriter.attribute("bottom", aRectangle.Bottom());
463 rWriter.attribute("right", aRectangle.Right());
465 rWriter.endElement();
467 break;
469 case MetaActionType::POLYLINE:
471 MetaPolyLineAction* pMetaPolyLineAction = static_cast<MetaPolyLineAction*>(pAction);
472 rWriter.startElement(sCurrentElementTag);
474 Polygon aPolygon = pMetaPolyLineAction->GetPolygon();
475 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
477 rWriter.startElement("point");
478 rWriter.attribute("x", aPolygon[i].X());
479 rWriter.attribute("y", aPolygon[i].Y());
480 rWriter.endElement();
483 LineInfo aLineInfo = pMetaPolyLineAction->GetLineInfo();
484 rWriter.attribute("style", convertLineStyleToString(aLineInfo.GetStyle()));
485 rWriter.attribute("width", aLineInfo.GetWidth());
486 rWriter.attribute("dashlen", aLineInfo.GetDashLen());
487 rWriter.attribute("dotlen", aLineInfo.GetDotLen());
488 rWriter.attribute("distance", aLineInfo.GetDistance());
490 rWriter.endElement();
492 break;
494 case MetaActionType::POLYGON:
496 MetaPolygonAction* pMetaPolygonAction = static_cast<MetaPolygonAction*>(pAction);
497 rWriter.startElement(sCurrentElementTag);
499 Polygon aPolygon = pMetaPolygonAction->GetPolygon();
500 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
502 rWriter.startElement("point");
503 rWriter.attribute("x", aPolygon[i].X());
504 rWriter.attribute("y", aPolygon[i].Y());
505 rWriter.endElement();
508 rWriter.endElement();
510 break;
512 case MetaActionType::COMMENT:
514 MetaCommentAction* pMetaCommentAction = static_cast<MetaCommentAction*>(pAction);
515 rWriter.startElement(sCurrentElementTag);
517 if (pMetaCommentAction->GetDataSize() > 0)
519 rWriter.attribute("datasize", pMetaCommentAction->GetDataSize());
521 if (!pMetaCommentAction->GetComment().isEmpty())
523 rWriter.startElement("comment");
524 rWriter.content(pMetaCommentAction->GetComment());
525 rWriter.endElement();
528 rWriter.endElement();
530 break;
532 default:
534 rWriter.element(sCurrentElementTag);
536 break;
541 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */