diff options
Diffstat (limited to 'vcl/source/gdi/mtfxmldump.cxx')
-rw-r--r-- | vcl/source/gdi/mtfxmldump.cxx | 1568 |
1 files changed, 1568 insertions, 0 deletions
diff --git a/vcl/source/gdi/mtfxmldump.cxx b/vcl/source/gdi/mtfxmldump.cxx new file mode 100644 index 0000000000..e6b1adc80e --- /dev/null +++ b/vcl/source/gdi/mtfxmldump.cxx @@ -0,0 +1,1568 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <vcl/mtfxmldump.hxx> +#include <tools/XmlWriter.hxx> +#include <tools/fract.hxx> + +#include <vcl/metaact.hxx> +#include <vcl/outdev.hxx> +#include <vcl/bitmap.hxx> +#include <vcl/BitmapReadAccess.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/hash.hxx> + +#include <sstream> + +namespace +{ + +OUString collectPushFlags(vcl::PushFlags nFlags) +{ + if ((nFlags & vcl::PushFlags::ALL) == vcl::PushFlags::ALL) + return "PushAll"; + else if ((nFlags & PUSH_ALLFONT) == PUSH_ALLFONT) + return "PushAllFont"; + + std::vector<OUString> aStrings; + + if (nFlags & vcl::PushFlags::LINECOLOR) + aStrings.emplace_back("PushLineColor"); + if (nFlags & vcl::PushFlags::FILLCOLOR) + aStrings.emplace_back("PushFillColor"); + if (nFlags & vcl::PushFlags::FONT) + aStrings.emplace_back("PushFont"); + if (nFlags & vcl::PushFlags::TEXTCOLOR) + aStrings.emplace_back("PushTextColor"); + if (nFlags & vcl::PushFlags::MAPMODE) + aStrings.emplace_back("PushMapMode"); + if (nFlags & vcl::PushFlags::CLIPREGION) + aStrings.emplace_back("PushClipRegion"); + if (nFlags & vcl::PushFlags::RASTEROP) + aStrings.emplace_back("PushRasterOp"); + if (nFlags & vcl::PushFlags::TEXTFILLCOLOR) + aStrings.emplace_back("PushTextFillColor"); + if (nFlags & vcl::PushFlags::TEXTALIGN) + aStrings.emplace_back("PushTextAlign"); + if (nFlags & vcl::PushFlags::REFPOINT) + aStrings.emplace_back("PushRefPoint"); + if (nFlags & vcl::PushFlags::TEXTLINECOLOR) + aStrings.emplace_back("PushTextLineColor"); + if (nFlags & vcl::PushFlags::TEXTLAYOUTMODE) + aStrings.emplace_back("PushTextLayoutMode"); + if (nFlags & vcl::PushFlags::TEXTLANGUAGE) + aStrings.emplace_back("PushTextLanguage"); + if (nFlags & vcl::PushFlags::OVERLINECOLOR) + aStrings.emplace_back("PushOverlineColor"); + if (nFlags & vcl::PushFlags::RTLENABLED) + aStrings.emplace_back("PushRTLEnabled"); + + OUString aString; + + if (aStrings.empty()) + return aString; + + aString = aStrings[0]; + for (size_t i = 1; i < aStrings.size(); ++i) + { + aString += ", " + aStrings[i]; + } + return aString; +} + +OUString convertDrawTextFlagsToString(DrawTextFlags eDrawTextFlags) +{ + std::vector<OUString> aStrings; + if (eDrawTextFlags & DrawTextFlags::Disable) + aStrings.emplace_back("Disable"); + if (eDrawTextFlags & DrawTextFlags::Mnemonic) + aStrings.emplace_back("Mnemonic"); + if (eDrawTextFlags & DrawTextFlags::Mono) + aStrings.emplace_back("Mono"); + if (eDrawTextFlags & DrawTextFlags::Clip) + aStrings.emplace_back("Clip"); + if (eDrawTextFlags & DrawTextFlags::Left) + aStrings.emplace_back("Left"); + if (eDrawTextFlags & DrawTextFlags::Center) + aStrings.emplace_back("Center"); + if (eDrawTextFlags & DrawTextFlags::Right) + aStrings.emplace_back("Right"); + if (eDrawTextFlags & DrawTextFlags::Top) + aStrings.emplace_back("Top"); + if (eDrawTextFlags & DrawTextFlags::VCenter) + aStrings.emplace_back("VCenter"); + if (eDrawTextFlags & DrawTextFlags::Bottom) + aStrings.emplace_back("Bottom"); + if (eDrawTextFlags & DrawTextFlags::EndEllipsis) + aStrings.emplace_back("EndEllipsis"); + if (eDrawTextFlags & DrawTextFlags::PathEllipsis) + aStrings.emplace_back("PathEllipsis"); + if (eDrawTextFlags & DrawTextFlags::MultiLine) + aStrings.emplace_back("MultiLine"); + if (eDrawTextFlags & DrawTextFlags::WordBreak) + aStrings.emplace_back("WordBreak"); + if (eDrawTextFlags & DrawTextFlags::NewsEllipsis) + aStrings.emplace_back("NewsEllipsis"); + if (eDrawTextFlags & DrawTextFlags::WordBreakHyphenation) + aStrings.emplace_back("WordBreakHyphenation"); + if (eDrawTextFlags & DrawTextFlags::CenterEllipsis) + aStrings.emplace_back("CenterEllipsis"); + + OUString aString; + + if (aStrings.empty()) + return "None"; + + aString = aStrings[0]; + for (size_t i = 1; i < aStrings.size(); ++i) + { + aString += " " + aStrings[i]; + } + return aString; +}; + +OUString convertRopToString(RasterOp eRop) +{ + switch (eRop) + { + case RasterOp::OverPaint: return "overpaint"; + case RasterOp::Xor: return "xor"; + case RasterOp::N0: return "0"; + case RasterOp::N1: return "1"; + case RasterOp::Invert: return "invert"; + } + return OUString(); +} + +OUString convertTextAlignToString(TextAlign eAlign) +{ + switch (eAlign) + { + case ALIGN_BASELINE: return "baseline"; + case ALIGN_BOTTOM: return "bottom"; + case ALIGN_TOP: return "top"; + case TextAlign_FORCE_EQUAL_SIZE: return "equalsize"; + } + return OUString(); +} + +OUString convertColorToString(Color aColor) +{ + OUString aRGBString = aColor.AsRGBHexString(); + return "#" + aRGBString; +} + +OUString convertLineStyleToString(LineStyle eAlign) +{ + switch (eAlign) + { + case LineStyle::NONE: return "none"; + case LineStyle::Solid: return "solid"; + case LineStyle::Dash: return "dash"; + default: break; + } + return OUString(); +} + +OUString convertLineJoinToString(basegfx::B2DLineJoin eJoin) +{ + switch (eJoin) + { + default: + case basegfx::B2DLineJoin::NONE: return "none"; + case basegfx::B2DLineJoin::Bevel: return "bevel"; + case basegfx::B2DLineJoin::Miter: return "miter"; + case basegfx::B2DLineJoin::Round: return "round"; + } +} + +OUString convertLineCapToString(css::drawing::LineCap eCap) +{ + switch (eCap) + { + default: + case css::drawing::LineCap_BUTT: return "butt"; + case css::drawing::LineCap_ROUND: return "round"; + case css::drawing::LineCap_SQUARE: return "square"; + } +} + +OUString convertPolygonFlags(PolyFlags eFlags) +{ + switch (eFlags) + { + default: + case PolyFlags::Normal: return "normal"; + case PolyFlags::Control: return "control"; + case PolyFlags::Smooth: return "smooth"; + case PolyFlags::Symmetric: return "symmetric"; + } +} + +OUString convertFontWeightToString(FontWeight eFontWeight) +{ + switch (eFontWeight) + { + case WEIGHT_DONTKNOW: return "unknown"; + case WEIGHT_THIN: return "thin"; + case WEIGHT_ULTRALIGHT: return "ultralight"; + case WEIGHT_LIGHT: return "light"; + case WEIGHT_SEMILIGHT: return "semilight"; + case WEIGHT_NORMAL: return "normal"; + case WEIGHT_MEDIUM: return "medium"; + case WEIGHT_SEMIBOLD: return "semibold"; + case WEIGHT_BOLD: return "bold"; + case WEIGHT_ULTRABOLD: return "ultrabold"; + case WEIGHT_BLACK: return "black"; + case FontWeight_FORCE_EQUAL_SIZE: return "equalsize"; + } + return OUString(); +} + +OUString convertFontStrikeoutToString(FontStrikeout eFontStrikeout) +{ + switch (eFontStrikeout) + { + case STRIKEOUT_NONE: return "none"; + case STRIKEOUT_SINGLE: return "single"; + case STRIKEOUT_DOUBLE: return "double"; + case STRIKEOUT_DONTKNOW: return "dontknow"; + case STRIKEOUT_BOLD: return "bold"; + case STRIKEOUT_SLASH: return "slash"; + case STRIKEOUT_X: return "x"; + case FontStrikeout_FORCE_EQUAL_SIZE: return "equalsize"; + } + return OUString(); +} + +OUString convertFontLineStyleToString(FontLineStyle eFontLineStyle) +{ + switch (eFontLineStyle) + { + case LINESTYLE_NONE: return "none"; + case LINESTYLE_SINGLE: return "single"; + case LINESTYLE_DOUBLE: return "double"; + case LINESTYLE_DOTTED: return "dotted"; + case LINESTYLE_DONTKNOW: return "dontknow"; + case LINESTYLE_DASH: return "dash"; + case LINESTYLE_LONGDASH: return "longdash"; + case LINESTYLE_DASHDOT: return "dashdot"; + case LINESTYLE_DASHDOTDOT: return "dashdotdot"; + case LINESTYLE_SMALLWAVE: return "smallwave"; + case LINESTYLE_WAVE: return "wave"; + case LINESTYLE_DOUBLEWAVE: return "doublewave"; + case LINESTYLE_BOLD: return "bold"; + case LINESTYLE_BOLDDOTTED: return "bolddotted"; + case LINESTYLE_BOLDDASH: return "bolddash"; + case LINESTYLE_BOLDLONGDASH: return "boldlongdash"; + case LINESTYLE_BOLDDASHDOT: return "bolddashdot"; + case LINESTYLE_BOLDDASHDOTDOT: return "bolddashdotdot"; + case LINESTYLE_BOLDWAVE: return "boldwave"; + case FontLineStyle_FORCE_EQUAL_SIZE: return "equalsize"; + } + return OUString(); +} + +OString convertLineStyleToString(const MetaActionType nActionType) +{ + switch (nActionType) + { + case MetaActionType::NONE: return "null"_ostr; + case MetaActionType::PIXEL: return "pixel"_ostr; + case MetaActionType::POINT: return "point"_ostr; + case MetaActionType::LINE: return "line"_ostr; + case MetaActionType::RECT: return "rect"_ostr; + case MetaActionType::ROUNDRECT: return "roundrect"_ostr; + case MetaActionType::ELLIPSE: return "ellipse"_ostr; + case MetaActionType::ARC: return "arc"_ostr; + case MetaActionType::PIE: return "pie"_ostr; + case MetaActionType::CHORD: return "chord"_ostr; + case MetaActionType::POLYLINE: return "polyline"_ostr; + case MetaActionType::POLYGON: return "polygon"_ostr; + case MetaActionType::POLYPOLYGON: return "polypolygon"_ostr; + case MetaActionType::TEXT: return "text"_ostr; + case MetaActionType::TEXTARRAY: return "textarray"_ostr; + case MetaActionType::STRETCHTEXT: return "stretchtext"_ostr; + case MetaActionType::TEXTRECT: return "textrect"_ostr; + case MetaActionType::TEXTLINE: return "textline"_ostr; + case MetaActionType::BMP: return "bmp"_ostr; + case MetaActionType::BMPSCALE: return "bmpscale"_ostr; + case MetaActionType::BMPSCALEPART: return "bmpscalepart"_ostr; + case MetaActionType::BMPEX: return "bmpex"_ostr; + case MetaActionType::BMPEXSCALE: return "bmpexscale"_ostr; + case MetaActionType::BMPEXSCALEPART: return "bmpexscalepart"_ostr; + case MetaActionType::MASK: return "mask"_ostr; + case MetaActionType::MASKSCALE: return "maskscale"_ostr; + case MetaActionType::MASKSCALEPART: return "maskscalepart"_ostr; + case MetaActionType::GRADIENT: return "gradient"_ostr; + case MetaActionType::GRADIENTEX: return "gradientex"_ostr; + case MetaActionType::HATCH: return "hatch"_ostr; + case MetaActionType::WALLPAPER: return "wallpaper"_ostr; + case MetaActionType::CLIPREGION: return "clipregion"_ostr; + case MetaActionType::ISECTRECTCLIPREGION: return "sectrectclipregion"_ostr; + case MetaActionType::ISECTREGIONCLIPREGION: return "sectregionclipregion"_ostr; + case MetaActionType::MOVECLIPREGION: return "moveclipregion"_ostr; + case MetaActionType::LINECOLOR: return "linecolor"_ostr; + case MetaActionType::FILLCOLOR: return "fillcolor"_ostr; + case MetaActionType::TEXTCOLOR: return "textcolor"_ostr; + case MetaActionType::TEXTFILLCOLOR: return "textfillcolor"_ostr; + case MetaActionType::TEXTLINECOLOR: return "textlinecolor"_ostr; + case MetaActionType::OVERLINECOLOR: return "overlinecolor"_ostr; + case MetaActionType::TEXTALIGN: return "textalign"_ostr; + case MetaActionType::MAPMODE: return "mapmode"_ostr; + case MetaActionType::FONT: return "font"_ostr; + case MetaActionType::PUSH: return "push"_ostr; + case MetaActionType::POP: return "pop"_ostr; + case MetaActionType::RASTEROP: return "rasterop"_ostr; + case MetaActionType::Transparent: return "transparent"_ostr; + case MetaActionType::FLOATTRANSPARENT: return "floattransparent"_ostr; + case MetaActionType::EPS: return "eps"_ostr; + case MetaActionType::REFPOINT: return "refpoint"_ostr; + case MetaActionType::COMMENT: return "comment"_ostr; + case MetaActionType::LAYOUTMODE: return "layoutmode"_ostr; + case MetaActionType::TEXTLANGUAGE: return "textlanguage"_ostr; + } + return ""_ostr; +} + +OUString convertBitmapExTransparentType(BitmapEx const & rBitmapEx) +{ + if (rBitmapEx.IsAlpha()) + return "bitmap"; + else + return "none"; +} + +OUString convertMapUnitToString(MapUnit eUnit) +{ + switch (eUnit) + { + default: + case MapUnit::LASTENUMDUMMY: return "LASTENUMDUMMY"; + case MapUnit::Map1000thInch: return "Map1000thInch"; + case MapUnit::Map100thInch: return "Map100thInch"; + case MapUnit::Map100thMM: return "Map100thMM"; + case MapUnit::Map10thInch: return "Map10thInch"; + case MapUnit::Map10thMM: return "Map10thMM"; + case MapUnit::MapAppFont: return "MapAppFont"; + case MapUnit::MapCM: return "MapCM"; + case MapUnit::MapInch: return "MapInch"; + case MapUnit::MapMM: return "MapMM"; + case MapUnit::MapPixel: return "MapPixel"; + case MapUnit::MapPoint: return "MapPoint"; + case MapUnit::MapRelative: return "MapRelative"; + case MapUnit::MapSysFont: return "MapSysFont"; + case MapUnit::MapTwip: return "MapTwip"; + } +} + +OUString convertFractionToString(const Fraction& aFraction) +{ + std::stringstream ss; + + ss << aFraction; + + return OUString::createFromAscii(ss.str()); +} + +OUString convertGradientStyleToOUString(css::awt::GradientStyle eStyle) +{ + switch (eStyle) + { + case css::awt::GradientStyle_LINEAR: return "Linear"; + case css::awt::GradientStyle_AXIAL: return "Axial"; + case css::awt::GradientStyle_RADIAL: return "Radial"; + case css::awt::GradientStyle_ELLIPTICAL: return "Elliptical"; + case css::awt::GradientStyle_SQUARE: return "Square"; + case css::awt::GradientStyle_RECT: return "Rect"; + case css::awt::GradientStyle::GradientStyle_MAKE_FIXED_SIZE: return "ForceEqualSize"; + } + return OUString(); +} + +OUString convertHatchStyle(HatchStyle eStyle) +{ + switch (eStyle) + { + case HatchStyle::Single: return "Single"; + case HatchStyle::Double: return "Double"; + case HatchStyle::Triple: return "Triple"; + case HatchStyle::FORCE_EQUAL_SIZE: return "ForceEqualSize"; + } + return OUString(); +} + +OUString convertLanguageTypeToString(LanguageType rLanguageType) +{ + std::stringstream ss; + ss << std::hex << std::setfill ('0') << std::setw(4) << rLanguageType.get(); + return "#" + OUString::createFromAscii(ss.str()); +} + +OUString convertWallpaperStyleToString(WallpaperStyle eWallpaperStyle) +{ + switch (eWallpaperStyle) + { + case WallpaperStyle::NONE: return "NONE"; + case WallpaperStyle::Tile: return "Tile"; + case WallpaperStyle::Center: return "Center"; + case WallpaperStyle::Scale: return "Scale"; + case WallpaperStyle::TopLeft: return "TopLeft"; + case WallpaperStyle::Top: return "Top"; + case WallpaperStyle::TopRight: return "TopRight"; + case WallpaperStyle::Left: return "Left"; + case WallpaperStyle::Right: return "Right"; + case WallpaperStyle::BottomLeft: return "BottomLeft"; + case WallpaperStyle::Bottom: return "Bottom"; + case WallpaperStyle::BottomRight: return "BottomRight"; + case WallpaperStyle::ApplicationGradient: return "ApplicationGradient"; + } + return OUString(); +} + +OUString convertPixelFormatToString(vcl::PixelFormat ePixelFormat) +{ + switch (ePixelFormat) + { + case vcl::PixelFormat::INVALID: return "INVALID"; + case vcl::PixelFormat::N8_BPP: return "8BPP"; + case vcl::PixelFormat::N24_BPP: return "24BPP"; + case vcl::PixelFormat::N32_BPP: return "32BPP"; + } + return OUString(); +} + +OUString convertComplexTestLayoutFlags(vcl::text::ComplexTextLayoutFlags nFlags) +{ + if (nFlags == vcl::text::ComplexTextLayoutFlags::Default) + return "Default"; + + std::vector<OUString> aStrings; + + if (nFlags & vcl::text::ComplexTextLayoutFlags::BiDiRtl) + aStrings.emplace_back("BiDiRtl"); + if (nFlags & vcl::text::ComplexTextLayoutFlags::BiDiStrong) + aStrings.emplace_back("BiDiStrong"); + if (nFlags & vcl::text::ComplexTextLayoutFlags::TextOriginLeft) + aStrings.emplace_back("TextOriginLeft"); + if (nFlags & vcl::text::ComplexTextLayoutFlags::TextOriginRight) + aStrings.emplace_back("TextOriginRight"); + + OUString aString; + + if (aStrings.empty()) + return aString; + + aString = aStrings[0]; + for (size_t i = 1; i < aStrings.size(); ++i) + { + aString += ", " + aStrings[i]; + } + return aString; +} + +OUString convertGfxLinkTypeToString(GfxLinkType eGfxLinkType) +{ + switch(eGfxLinkType) + { + case GfxLinkType::EpsBuffer: return "EpsBuffer"; + case GfxLinkType::NativeBmp: return "NativeBmp"; + case GfxLinkType::NativeGif: return "NativeGif"; + case GfxLinkType::NativeJpg: return "NativeJpg"; + case GfxLinkType::NativeMet: return "NativeMet"; + case GfxLinkType::NativeMov: return "NativeMov"; + case GfxLinkType::NativePct: return "NativePct"; + case GfxLinkType::NativePdf: return "NativePdf"; + case GfxLinkType::NativePng: return "NativePng"; + case GfxLinkType::NativeSvg: return "NativeSvg"; + case GfxLinkType::NativeTif: return "NativeTif"; + case GfxLinkType::NativeWmf: return "NativeWmf"; + case GfxLinkType::NativeWebp: return "NativeWebp"; + case GfxLinkType::NONE: return "None"; + } + return OUString(); +} + +OUString hex32(sal_uInt32 nNumber) +{ + std::stringstream ss; + ss << std::hex << std::setfill('0') << std::setw(8) << nNumber; + return OUString::createFromAscii(ss.str()); +} + +OUString toHexString(const sal_uInt8* nData, sal_uInt32 nDataSize){ + + std::stringstream aStrm; + for (sal_uInt32 i = 0; i < nDataSize; i++) + { + aStrm << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(nData[i]); + } + + return OUString::createFromAscii(aStrm.str()); +} + +void writePoint(tools::XmlWriter& rWriter, Point const& rPoint) +{ + rWriter.attribute("x", rPoint.X()); + rWriter.attribute("y", rPoint.Y()); +} + +void writeStartPoint(tools::XmlWriter& rWriter, Point const& rPoint) +{ + rWriter.attribute("startx", rPoint.X()); + rWriter.attribute("starty", rPoint.Y()); +} + +void writeEndPoint(tools::XmlWriter& rWriter, Point const& rPoint) +{ + rWriter.attribute("endx", rPoint.X()); + rWriter.attribute("endy", rPoint.Y()); +} + +void writeSize(tools::XmlWriter& rWriter, Size const& rSize) +{ + rWriter.attribute("width", rSize.Width()); + rWriter.attribute("height", rSize.Height()); +} + +void writeRectangle(tools::XmlWriter& rWriter, tools::Rectangle const& rRectangle) +{ + rWriter.attribute("left", rRectangle.Left()); + rWriter.attribute("top", rRectangle.Top()); + if (rRectangle.IsWidthEmpty()) + rWriter.attribute("right", "empty"_ostr); + else + rWriter.attribute("right", rRectangle.Right()); + if (rRectangle.IsHeightEmpty()) + rWriter.attribute("bottom", "empty"_ostr); + else + rWriter.attribute("bottom", rRectangle.Bottom()); +} + +void writeMapMode(tools::XmlWriter& rWriter, MapMode const& rMapMode) +{ + rWriter.attribute("mapunit", convertMapUnitToString( rMapMode.GetMapUnit() )); + writePoint(rWriter, rMapMode.GetOrigin()); + rWriter.attribute("scalex", convertFractionToString(rMapMode.GetScaleX())); + rWriter.attribute("scaley", convertFractionToString(rMapMode.GetScaleY())); +} + +void writeLineInfo(tools::XmlWriter& rWriter, LineInfo const& rLineInfo) +{ + rWriter.attribute("style", convertLineStyleToString(rLineInfo.GetStyle())); + rWriter.attribute("width", rLineInfo.GetWidth()); + rWriter.attribute("dashlen", rLineInfo.GetDashLen()); + rWriter.attribute("dashcount", rLineInfo.GetDashCount()); + rWriter.attribute("dotlen", rLineInfo.GetDotLen()); + rWriter.attribute("dotcount", rLineInfo.GetDotCount()); + rWriter.attribute("distance", rLineInfo.GetDistance()); + rWriter.attribute("join", convertLineJoinToString(rLineInfo.GetLineJoin())); + rWriter.attribute("cap", convertLineCapToString(rLineInfo.GetLineCap())); +} + +void writeGradient(tools::XmlWriter& rWriter, Gradient const& rGradient) +{ + rWriter.attribute("style", convertGradientStyleToOUString(rGradient.GetStyle())); + rWriter.attribute("startcolor", convertColorToString(rGradient.GetStartColor())); + rWriter.attribute("endcolor", convertColorToString(rGradient.GetEndColor())); + rWriter.attribute("angle", rGradient.GetAngle().get()); + rWriter.attribute("border", rGradient.GetBorder()); + rWriter.attribute("offsetx", rGradient.GetOfsX()); + rWriter.attribute("offsety", rGradient.GetOfsY()); + rWriter.attribute("startintensity", rGradient.GetStartIntensity()); + rWriter.attribute("endintensity", rGradient.GetEndIntensity()); + rWriter.attribute("steps", rGradient.GetSteps()); +} + +OString toHexString(const std::vector<unsigned char>& a) +{ + std::stringstream aStrm; + for (auto& i : a) + { + aStrm << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(i); + } + + return OString(aStrm.str()); +} + +void writeBitmapContentChecksum(tools::XmlWriter& rWriter, Bitmap const& rBitmap) +{ + Bitmap aBitmap(rBitmap); + + comphelper::Hash aHashEngine(comphelper::HashType::SHA1); + BitmapScopedReadAccess pReadAccess(aBitmap); + assert(pReadAccess); + + for (tools::Long y = 0 ; y < pReadAccess->Height() ; ++y) + { + for (tools::Long x = 0 ; x < pReadAccess->Width() ; ++x) + { + BitmapColor aColor = pReadAccess->GetColor(y, x); + sal_uInt8 r = aColor.GetRed(); + sal_uInt8 g = aColor.GetGreen(); + sal_uInt8 b = aColor.GetBlue(); + sal_uInt8 a = aColor.GetAlpha(); + aHashEngine.update(&r, 1); + aHashEngine.update(&g, 1); + aHashEngine.update(&b, 1); + aHashEngine.update(&a, 1); + } + } + std::vector<unsigned char> aVector = aHashEngine.finalize(); + rWriter.attribute("contentchecksum", toHexString(aVector)); +} + +void writeBitmap(tools::XmlWriter& rWriter, Bitmap const& rBitmap) +{ + writeBitmapContentChecksum(rWriter, rBitmap); + rWriter.attribute("bitmapwidth", rBitmap.GetSizePixel().Width()); + rWriter.attribute("bitmapheight", rBitmap.GetSizePixel().Height()); + rWriter.attribute("pixelformat", convertPixelFormatToString(rBitmap.getPixelFormat())); + rWriter.attribute("crc", hex32(rBitmap.GetChecksum())); +} + +} // anonymous namespace + +MetafileXmlDump::MetafileXmlDump() +{ + maFilter.fill(false); +} + +void MetafileXmlDump::filterActionType(const MetaActionType nActionType, bool bShouldFilter) +{ + maFilter[nActionType] = bShouldFilter; +} + +void MetafileXmlDump::filterAllActionTypes() +{ + maFilter.fill(true); +} + +void MetafileXmlDump::dump(const GDIMetaFile& rMetaFile, SvStream& rStream) +{ + tools::XmlWriter aWriter(&rStream); + aWriter.startDocument(); + aWriter.startElement("metafile"); + + writeXml(rMetaFile, aWriter); + + aWriter.endElement(); + aWriter.endDocument(); +} + +void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, tools::XmlWriter& rWriter) +{ + MapMode aMtfMapMode = rMetaFile.GetPrefMapMode(); + rWriter.attribute("mapunit", convertMapUnitToString(aMtfMapMode.GetMapUnit())); + writePoint(rWriter, aMtfMapMode.GetOrigin()); + rWriter.attribute("scalex", convertFractionToString(aMtfMapMode.GetScaleX())); + rWriter.attribute("scaley", convertFractionToString(aMtfMapMode.GetScaleY())); + + Size aMtfSize = rMetaFile.GetPrefSize(); + writeSize(rWriter, aMtfSize); + + for(size_t nAction = 0; nAction < rMetaFile.GetActionSize(); ++nAction) + { + MetaAction* pAction = rMetaFile.GetAction(nAction); + const MetaActionType nActionType = pAction->GetType(); + if (maFilter[nActionType]) + continue; + + OString sCurrentElementTag = convertLineStyleToString(nActionType); + + switch (nActionType) + { + case MetaActionType::NONE: + { + rWriter.startElement(sCurrentElementTag); + rWriter.endElement(); + } + break; + + case MetaActionType::PIXEL: + { + auto* pMetaAction = static_cast<MetaPixelAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMetaAction->GetPoint()); + rWriter.attribute("color", convertColorToString(pMetaAction->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::POINT: + { + auto* pMetaAction = static_cast<MetaPointAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMetaAction->GetPoint()); + rWriter.endElement(); + } + break; + + case MetaActionType::LINE: + { + MetaLineAction* pMetaLineAction = static_cast<MetaLineAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeStartPoint(rWriter, pMetaLineAction->GetStartPoint()); + writeEndPoint(rWriter, pMetaLineAction->GetEndPoint()); + + writeLineInfo(rWriter, pMetaLineAction->GetLineInfo()); + rWriter.endElement(); + } + break; + + case MetaActionType::RECT: + { + MetaRectAction* pMetaAction = static_cast<MetaRectAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + rWriter.endElement(); + } + break; + + case MetaActionType::ROUNDRECT: + { + auto pMetaAction = static_cast<MetaRoundRectAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + rWriter.attribute("horizontalround", pMetaAction->GetHorzRound()); + rWriter.attribute("verticalround", pMetaAction->GetVertRound()); + rWriter.endElement(); + } + break; + + case MetaActionType::ELLIPSE: + { + auto pMetaAction = static_cast<MetaEllipseAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + rWriter.endElement(); + } + break; + + case MetaActionType::ARC: + { + auto pMetaAction = static_cast<MetaArcAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + writeStartPoint(rWriter, pMetaAction->GetStartPoint()); + writeEndPoint(rWriter, pMetaAction->GetEndPoint()); + rWriter.endElement(); + } + break; + + case MetaActionType::PIE: + { + auto pMetaAction = static_cast<MetaPieAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + writeStartPoint(rWriter, pMetaAction->GetStartPoint()); + writeEndPoint(rWriter, pMetaAction->GetEndPoint()); + rWriter.endElement(); + } + break; + + case MetaActionType::CHORD: + { + auto pMetaAction = static_cast<MetaChordAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMetaAction->GetRect()); + writeStartPoint(rWriter, pMetaAction->GetStartPoint()); + writeEndPoint(rWriter, pMetaAction->GetEndPoint()); + rWriter.endElement(); + } + break; + + case MetaActionType::POLYLINE: + { + MetaPolyLineAction* pMetaPolyLineAction = static_cast<MetaPolyLineAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + writeLineInfo(rWriter, pMetaPolyLineAction->GetLineInfo()); + + tools::Polygon aPolygon = pMetaPolyLineAction->GetPolygon(); + bool bFlags = aPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++) + { + rWriter.startElement("point"); + writePoint(rWriter, aPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i))); + rWriter.endElement(); + } + + rWriter.endElement(); + } + break; + + case MetaActionType::POLYGON: + { + MetaPolygonAction* pMetaPolygonAction = static_cast<MetaPolygonAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + tools::Polygon aPolygon = pMetaPolygonAction->GetPolygon(); + bool bFlags = aPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++) + { + rWriter.startElement("point"); + writePoint(rWriter, aPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i))); + rWriter.endElement(); + } + + rWriter.endElement(); + } + break; + + case MetaActionType::POLYPOLYGON: + { + MetaPolyPolygonAction *const pMetaPolyPolygonAction = static_cast<MetaPolyPolygonAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + tools::PolyPolygon const& rPolyPolygon(pMetaPolyPolygonAction->GetPolyPolygon()); + + for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j) + { + rWriter.startElement("polygon"); + tools::Polygon const& rPolygon = rPolyPolygon[j]; + bool bFlags = rPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i) + { + rWriter.startElement("point"); + writePoint(rWriter, rPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i))); + rWriter.endElement(); + } + rWriter.endElement(); + } + rWriter.endElement(); + } + break; + + case MetaActionType::TEXT: + { + auto* pMeta = static_cast<MetaTextAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + rWriter.attribute("index", pMeta->GetIndex()); + rWriter.attribute("length", pMeta->GetLen()); + rWriter.startElement("textcontent"); + rWriter.content(pMeta->GetText()); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTARRAY: + { + MetaTextArrayAction* pMetaTextArrayAction = static_cast<MetaTextArrayAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + sal_Int32 aIndex = pMetaTextArrayAction->GetIndex(); + sal_Int32 aLength = pMetaTextArrayAction->GetLen(); + + writePoint(rWriter, pMetaTextArrayAction->GetPoint()); + rWriter.attribute("index", aIndex); + rWriter.attribute("length", aLength); + + if (!pMetaTextArrayAction->GetDXArray().empty()) + { + auto & rArray = pMetaTextArrayAction->GetDXArray(); + rWriter.startElement("dxarray"); + if (aIndex < o3tl::narrowing<sal_Int32>(rArray.size())) + rWriter.attribute("first", rArray[aIndex]); + if (aIndex + aLength - 1 < o3tl::narrowing<sal_Int32>(rArray.size())) + rWriter.attribute("last", rArray[aIndex + aLength - 1]); + OUStringBuffer sDxLengthString(std::max((aLength - aIndex) * 4, sal_Int32(0))); + for (sal_Int32 i = 0; i < aLength - aIndex; ++i) + { + sDxLengthString.append(OUString::number(rArray[aIndex + i]) + " "); + } + rWriter.content(sDxLengthString); + rWriter.endElement(); + } + + rWriter.startElement("text"); + + const OUString& rStr = pMetaTextArrayAction->GetText(); + // fix bad XML dump by removing forbidden 0x01 + // FIXME: expand footnote anchor point 0x01 instead of this + if ( rStr.indexOf(0x01) > -1 ) + rWriter.content(rStr.replaceAll("\001", "")); + else + rWriter.content(rStr); + + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::STRETCHTEXT: + { + auto* pMeta = static_cast<MetaStretchTextAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + writePoint(rWriter, pMeta->GetPoint()); + rWriter.attribute("index", pMeta->GetIndex()); + rWriter.attribute("length", pMeta->GetLen()); + rWriter.attribute("width", pMeta->GetWidth()); + + rWriter.startElement("textcontent"); + rWriter.content(pMeta->GetText()); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTRECT: + { + auto* pMeta = static_cast<MetaTextRectAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writeRectangle(rWriter, pMeta->GetRect()); + rWriter.startElement("textcontent"); + rWriter.content(pMeta->GetText()); + rWriter.endElement(); + + rWriter.startElement("style"); + rWriter.content(convertDrawTextFlagsToString(pMeta->GetStyle())); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::BMP: + { + auto pMeta = static_cast<MetaBmpAction*>(pAction); + Bitmap aBitmap = pMeta->GetBitmap(); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::BMPSCALE: + { + auto pMeta = static_cast<MetaBmpScaleAction*>(pAction); + Bitmap aBitmap = pMeta->GetBitmap(); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + writeSize(rWriter, pMeta->GetSize()); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::BMPSCALEPART: + { + auto pMeta = static_cast<MetaBmpScalePartAction*>(pAction); + Bitmap aBitmap = pMeta->GetBitmap(); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("destx", pMeta->GetDestPoint().X()); + rWriter.attribute("desty", pMeta->GetDestPoint().Y()); + rWriter.attribute("destwidth", pMeta->GetDestSize().Width()); + rWriter.attribute("destheight", pMeta->GetDestSize().Height()); + rWriter.attribute("srcx", pMeta->GetSrcPoint().X()); + rWriter.attribute("srcy", pMeta->GetSrcPoint().Y()); + rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width()); + rWriter.attribute("srcheight", pMeta->GetSrcSize().Height()); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::BMPEX: + { + auto pMeta = static_cast<MetaBmpExAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + Bitmap aBitmap = pMeta->GetBitmapEx().GetBitmap(); + rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx())); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::BMPEXSCALE: + { + auto pMeta = static_cast<MetaBmpExScaleAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + writeSize(rWriter, pMeta->GetSize()); + Bitmap aBitmap = pMeta->GetBitmapEx().GetBitmap(); + rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx())); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::BMPEXSCALEPART: + { + auto pMeta = static_cast<MetaBmpExScalePartAction*>(pAction); + Bitmap aBitmap = pMeta->GetBitmapEx().GetBitmap(); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("destx", pMeta->GetDestPoint().X()); + rWriter.attribute("desty", pMeta->GetDestPoint().Y()); + rWriter.attribute("destwidth", pMeta->GetDestSize().Width()); + rWriter.attribute("destheight", pMeta->GetDestSize().Height()); + rWriter.attribute("srcx", pMeta->GetSrcPoint().X()); + rWriter.attribute("srcy", pMeta->GetSrcPoint().Y()); + rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width()); + rWriter.attribute("srcheight", pMeta->GetSrcSize().Height()); + rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx())); + writeBitmap(rWriter, aBitmap); + rWriter.endElement(); + } + break; + + case MetaActionType::MASK: + { + auto pMeta = static_cast<MetaMaskAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum())); + rWriter.attribute("color", convertColorToString(pMeta->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::MASKSCALE: + { + auto pMeta = static_cast<MetaMaskScaleAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + writeSize(rWriter, pMeta->GetSize()); + rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum())); + rWriter.attribute("color", convertColorToString(pMeta->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::MASKSCALEPART: + { + auto pMeta = static_cast<MetaMaskScalePartAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("destx", pMeta->GetDestPoint().X()); + rWriter.attribute("desty", pMeta->GetDestPoint().Y()); + rWriter.attribute("destwidth", pMeta->GetDestSize().Width()); + rWriter.attribute("destheight", pMeta->GetDestSize().Height()); + rWriter.attribute("srcx", pMeta->GetSrcPoint().X()); + rWriter.attribute("srcy", pMeta->GetSrcPoint().Y()); + rWriter.attribute("srcwidth", pMeta->GetSrcSize().Width()); + rWriter.attribute("srcheight", pMeta->GetSrcSize().Height()); + rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum())); + rWriter.attribute("color", convertColorToString(pMeta->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::GRADIENT: + { + const MetaGradientAction* pMeta = static_cast<MetaGradientAction*>(pAction); + + rWriter.startElement(sCurrentElementTag); + writeGradient(rWriter, pMeta->GetGradient()); + + rWriter.startElement("rectangle"); + writeRectangle(rWriter, pMeta->GetRect()); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::HATCH: + { + auto* const pMetaHatchAction = static_cast<MetaHatchAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + tools::PolyPolygon const& rPolyPolygon(pMetaHatchAction->GetPolyPolygon()); + + for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j) + { + rWriter.startElement("polygon"); + tools::Polygon const& rPolygon = rPolyPolygon[j]; + bool bFlags = rPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i) + { + rWriter.startElement("point"); + writePoint(rWriter, rPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i))); + rWriter.endElement(); + } + rWriter.endElement(); + } + + rWriter.startElement("hatch"); + const auto& rHatch = pMetaHatchAction->GetHatch(); + rWriter.attribute("style", convertHatchStyle(rHatch.GetStyle())); + rWriter.attribute("color", convertColorToString(rHatch.GetColor())); + rWriter.attribute("distance", sal_Int32(rHatch.GetDistance())); + rWriter.attribute("angle", sal_Int32(rHatch.GetAngle().get())); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::WALLPAPER: + { + const auto* pMetaAction = static_cast<const MetaWallpaperAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + writeRectangle(rWriter, pMetaAction->GetRect()); + + rWriter.startElement("wallpaper"); + const auto& rWallpaper = pMetaAction->GetWallpaper(); + + rWriter.attribute("color", convertColorToString(rWallpaper.GetColor())); + + WallpaperStyle eStyle = rWallpaper.GetStyle(); + rWriter.attribute("style", convertWallpaperStyleToString(eStyle)); + + if (rWallpaper.IsBitmap()) + { + rWriter.startElement("bitmap"); + BitmapEx const & rBitmapEx = rWallpaper.GetBitmap(); + rWriter.attribute("crc", hex32(rBitmapEx.GetChecksum())); + rWriter.attribute("transparenttype", convertBitmapExTransparentType(rBitmapEx)); + rWriter.attribute("pixelformat", convertPixelFormatToString(rBitmapEx.GetBitmap().getPixelFormat())); + rWriter.attribute("width", hex32(rBitmapEx.GetSizePixel().Width())); + rWriter.attribute("height", hex32(rBitmapEx.GetSizePixel().Height())); + rWriter.endElement(); + } + + if (rWallpaper.IsGradient()) + { + rWriter.startElement("gradient"); + Gradient aGradient = rWallpaper.GetGradient(); + writeGradient(rWriter, aGradient); + rWriter.endElement(); + } + + if (rWallpaper.IsRect()) + { + tools::Rectangle aRect = rWallpaper.GetRect(); + rWriter.startElement("rectangle"); + writeRectangle(rWriter, aRect); + rWriter.endElement(); + } + + rWriter.attribute("fixed", rWallpaper.IsFixed() ? "true" : "false"); + rWriter.attribute("scrollable", rWallpaper.IsScrollable() ? "true" : "false"); + + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::CLIPREGION: + { + const auto* pMetaClipRegionAction = static_cast<const MetaClipRegionAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + tools::Rectangle aRectangle = pMetaClipRegionAction->GetRegion().GetBoundRect(); + writeRectangle(rWriter, aRectangle); + + vcl::Region aRegion = pMetaClipRegionAction->GetRegion(); + + if (aRegion.HasPolyPolygonOrB2DPolyPolygon()) + { + tools::PolyPolygon aPolyPolygon = aRegion.GetAsPolyPolygon(); + + for (sal_uInt16 j = 0; j < aPolyPolygon.Count(); ++j) + { + rWriter.startElement("polygon"); + tools::Polygon const& rPolygon = aPolyPolygon[j]; + bool bFlags = rPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i) + { + rWriter.startElement("point"); + writePoint(rWriter, rPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i))); + rWriter.endElement(); + } + rWriter.endElement(); + } + } + + rWriter.endElement(); + } + break; + + case MetaActionType::ISECTRECTCLIPREGION: + { + MetaISectRectClipRegionAction* pMetaISectRectClipRegionAction = static_cast<MetaISectRectClipRegionAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + tools::Rectangle aRectangle = pMetaISectRectClipRegionAction->GetRect(); + writeRectangle(rWriter, aRectangle); + rWriter.endElement(); + } + break; + + case MetaActionType::ISECTREGIONCLIPREGION: + { + MetaISectRegionClipRegionAction* pMetaISectRegionClipRegionAction = static_cast<MetaISectRegionClipRegionAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + // FIXME for now we dump only the bounding box; this is + // enough for the tests we have, but may need extending to + // dumping the real polypolygon in the future + tools::Rectangle aRectangle = pMetaISectRegionClipRegionAction->GetRegion().GetBoundRect(); + writeRectangle(rWriter, aRectangle); + rWriter.endElement(); + } + break; + + case MetaActionType::MOVECLIPREGION: + { + const auto* pMetaMoveClipRegionAction = static_cast<MetaMoveClipRegionAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("horzmove", pMetaMoveClipRegionAction->GetHorzMove()); + rWriter.attribute("vertmove", pMetaMoveClipRegionAction->GetVertMove()); + rWriter.endElement(); + } + break; + + case MetaActionType::LINECOLOR: + { + MetaLineColorAction* pMetaLineColorAction = static_cast<MetaLineColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("color", convertColorToString(pMetaLineColorAction->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::FILLCOLOR: + { + MetaFillColorAction* pMetaFillColorAction = static_cast<MetaFillColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("color", convertColorToString(pMetaFillColorAction->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTCOLOR: + { + MetaTextColorAction* pMetaTextColorAction = static_cast<MetaTextColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("color", convertColorToString(pMetaTextColorAction->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTFILLCOLOR: + { + MetaTextFillColorAction* pMetaTextFillColorAction = static_cast<MetaTextFillColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("color", convertColorToString(pMetaTextFillColorAction->GetColor())); + + if (pMetaTextFillColorAction->IsSetting()) + rWriter.attribute("setting", u"true"); + + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTALIGN: + { + MetaTextAlignAction* pMetaTextAlignAction = static_cast<MetaTextAlignAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + OUString sAlign = convertTextAlignToString(pMetaTextAlignAction->GetTextAlign()); + if (!sAlign.isEmpty()) + rWriter.attribute("align", sAlign); + rWriter.endElement(); + } + break; + + case MetaActionType::MAPMODE: + { + const MetaMapModeAction* pMeta = static_cast<MetaMapModeAction*>(pAction); + MapMode aMapMode = pMeta->GetMapMode(); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("mapunit", convertMapUnitToString( aMapMode.GetMapUnit() )); + writePoint(rWriter, aMapMode.GetOrigin()); + rWriter.attribute("scalex", convertFractionToString(aMapMode.GetScaleX())); + rWriter.attribute("scaley", convertFractionToString(aMapMode.GetScaleY())); + rWriter.endElement(); + } + break; + + case MetaActionType::FONT: + { + MetaFontAction* pMetaFontAction = static_cast<MetaFontAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + vcl::Font aFont = pMetaFontAction->GetFont(); + + rWriter.attribute("color", convertColorToString(aFont.GetColor())); + rWriter.attribute("fillcolor", convertColorToString(aFont.GetFillColor())); + rWriter.attribute("name", aFont.GetFamilyName()); + rWriter.attribute("stylename", aFont.GetStyleName()); + rWriter.attribute("width", aFont.GetFontSize().Width()); + rWriter.attribute("height", aFont.GetFontSize().Height()); + rWriter.attribute("orientation", aFont.GetOrientation().get()); + rWriter.attribute("weight", convertFontWeightToString(aFont.GetWeight())); + rWriter.attribute("vertical", aFont.IsVertical() ? "true" : "false"); + + rWriter.endElement(); + } + break; + + case MetaActionType::PUSH: + { + MetaPushAction* pMetaPushAction = static_cast<MetaPushAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("flags", collectPushFlags(pMetaPushAction->GetFlags())); + } + break; + + case MetaActionType::POP: + { + rWriter.endElement(); + } + break; + + case MetaActionType::RASTEROP: + { + MetaRasterOpAction* pMetaRasterOpAction = static_cast<MetaRasterOpAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + if (pMetaRasterOpAction->GetRasterOp() != RasterOp::OverPaint) + { + rWriter.attribute("operation", convertRopToString(pMetaRasterOpAction->GetRasterOp())); + } + rWriter.endElement(); + } + break; + + case MetaActionType::Transparent: + { + const MetaTransparentAction* pMeta = static_cast<MetaTransparentAction*>(pAction); + + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("transparence", pMeta->GetTransparence()); + + tools::PolyPolygon const& rPolyPolygon(pMeta->GetPolyPolygon()); + + for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j) + { + rWriter.startElement("polygon"); + tools::Polygon const& rPolygon = rPolyPolygon[j]; + bool bFlags = rPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i) + { + rWriter.startElement("point"); + writePoint(rWriter, rPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i))); + rWriter.endElement(); + } + rWriter.endElement(); + } + + rWriter.endElement(); + } + break; + + case MetaActionType::EPS: + { + MetaEPSAction* pMetaEPSAction = static_cast<MetaEPSAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + writePoint(rWriter, pMetaEPSAction->GetPoint()); + writeSize(rWriter, pMetaEPSAction->GetSize()); + + rWriter.startElement("gfxlink"); + writeSize(rWriter, pMetaEPSAction->GetLink().GetPrefSize()); + rWriter.attribute("type", convertGfxLinkTypeToString(pMetaEPSAction->GetLink().GetType())); + rWriter.attribute("userid", pMetaEPSAction->GetLink().GetUserId()); + rWriter.attribute("datasize", pMetaEPSAction->GetLink().GetDataSize()); + rWriter.attribute("data", toHexString(pMetaEPSAction->GetLink().GetData(), pMetaEPSAction->GetLink().GetDataSize())); + rWriter.attribute("native", pMetaEPSAction->GetLink().IsNative() ? "true" : "false"); + rWriter.attribute("emf", pMetaEPSAction->GetLink().IsEMF() ? "true" : "false"); + rWriter.attribute("validmapmode", pMetaEPSAction->GetLink().IsPrefMapModeValid() ? "true" : "false"); + rWriter.startElement("prefmapmode"); + writeMapMode(rWriter, pMetaEPSAction->GetLink().GetPrefMapMode()); + rWriter.endElement(); + rWriter.endElement(); + + rWriter.startElement("metafile"); + writeXml(pMetaEPSAction->GetSubstitute(), rWriter); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::REFPOINT: + { + auto* pMeta = static_cast<MetaRefPointAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetRefPoint()); + rWriter.attribute("set", pMeta->IsSetting() ? "true" : "false"); + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTLINECOLOR: + { + auto* pMeta = static_cast<MetaTextLineColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("color", convertColorToString(pMeta->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTLINE: + { + auto* pMeta = static_cast<MetaTextLineAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetStartPoint()); + rWriter.attribute("width", pMeta->GetWidth()); + rWriter.attribute("strikeout", convertFontStrikeoutToString(pMeta->GetStrikeout())); + rWriter.attribute("underline", convertFontLineStyleToString(pMeta->GetUnderline())); + rWriter.attribute("overline", convertFontLineStyleToString(pMeta->GetOverline())); + rWriter.endElement(); + } + break; + + case MetaActionType::FLOATTRANSPARENT: + { + const auto* pMeta = static_cast<MetaFloatTransparentAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + writePoint(rWriter, pMeta->GetPoint()); + writeSize(rWriter, pMeta->GetSize()); + rWriter.attribute("transparent", pMeta->IsTransparent() ? "true" : "false"); + + rWriter.startElement("gradient"); + writeGradient(rWriter, pMeta->GetGradient()); + rWriter.endElement(); + + rWriter.startElement("metafile"); + writeXml(pMeta->GetGDIMetaFile(), rWriter); + rWriter.endElement(); + + rWriter.endElement(); + } + break; + + case MetaActionType::GRADIENTEX: + { + const MetaGradientExAction* pMetaGradientExAction = static_cast<MetaGradientExAction*>(pAction); + + rWriter.startElement(sCurrentElementTag); + writeGradient(rWriter, pMetaGradientExAction->GetGradient()); + + tools::PolyPolygon const& rPolyPolygon(pMetaGradientExAction->GetPolyPolygon()); + for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j) + { + rWriter.startElement("polygon"); + tools::Polygon const& rPolygon = rPolyPolygon[j]; + bool bFlags = rPolygon.HasFlags(); + for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i) + { + rWriter.startElement("point"); + writePoint(rWriter, rPolygon[i]); + if (bFlags) + rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i))); + rWriter.endElement(); + } + rWriter.endElement(); + } + + rWriter.endElement(); + } + break; + + case MetaActionType::LAYOUTMODE: + { + const MetaLayoutModeAction* pMetaLayoutModeAction = static_cast<MetaLayoutModeAction*>(pAction); + + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("textlayout", convertComplexTestLayoutFlags(pMetaLayoutModeAction->GetLayoutMode())); + + rWriter.endElement(); + } + break; + + case MetaActionType::TEXTLANGUAGE: + { + const MetaTextLanguageAction* pMetaTextLanguageAction = static_cast<MetaTextLanguageAction*>(pAction); + + rWriter.startElement(sCurrentElementTag); + + rWriter.attribute("language", convertLanguageTypeToString(pMetaTextLanguageAction->GetTextLanguage())); + + rWriter.endElement(); + } + break; + + case MetaActionType::OVERLINECOLOR: + { + const auto* pMetaAction = static_cast<MetaOverlineColorAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("color", convertColorToString(pMetaAction->GetColor())); + rWriter.endElement(); + } + break; + + case MetaActionType::COMMENT: + { + MetaCommentAction* pMetaCommentAction = static_cast<MetaCommentAction*>(pAction); + rWriter.startElement(sCurrentElementTag); + + if (pMetaCommentAction->GetDataSize() > 0) + { + rWriter.attribute("datasize", pMetaCommentAction->GetDataSize()); + rWriter.attribute("data", toHexString(pMetaCommentAction->GetData(), pMetaCommentAction->GetDataSize())); + } + rWriter.attribute("value", pMetaCommentAction->GetValue()); + + if (!pMetaCommentAction->GetComment().isEmpty()) + { + rWriter.startElement("comment"); + rWriter.content(pMetaCommentAction->GetComment()); + rWriter.endElement(); + } + rWriter.endElement(); + } + break; + + default: + { + rWriter.startElement(sCurrentElementTag); + rWriter.attribute("note", "not implemented in xml dump"_ostr); + rWriter.endElement(); + } + break; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |