[Libreoffice-commits] core.git: include/test test/source vcl/CppunitTest_vcl_svm_test.mk vcl/Module_vcl.mk vcl/qa

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Sat Jan 14 23:02:02 UTC 2017


 include/test/xmltesttools.hxx   |    4 
 test/source/mtfxmldump.cxx      |  329 +++++++++++++-
 test/source/xmltesttools.cxx    |    9 
 vcl/CppunitTest_vcl_svm_test.mk |   55 ++
 vcl/Module_vcl.mk               |    1 
 vcl/qa/cppunit/svm/svmtest.cxx  |  904 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 1279 insertions(+), 23 deletions(-)

New commits:
commit 61af2bae8d3cdf0e7acfa9e49224ca5afcdd38dc
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Mon Jan 9 23:46:25 2017 +0100

    vcl: add SVM metafile reading and writing test and extend xml dump
    
    Change-Id: I88ffb795a9c33ea62d05d599757a287335c7d680
    Reviewed-on: https://gerrit.libreoffice.org/32914
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/test/xmltesttools.hxx b/include/test/xmltesttools.hxx
index a4cf8cc..80f95b3 100644
--- a/include/test/xmltesttools.hxx
+++ b/include/test/xmltesttools.hxx
@@ -25,6 +25,8 @@
 
 #include <cppunit/TestAssert.h>
 
+#include <vector>
+
 class OOO_DLLPUBLIC_TEST XmlTestTools
 {
 public:
@@ -62,6 +64,8 @@ protected:
     void          assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath,
                               const OString& rAttribute = OString(),
                               const OUString& rExpectedValue = OUString());
+    void          assertXPathAttrs(xmlDocPtr pXmlDoc, const OString& rXPath,
+                                   std::vector<std::pair<OString, OUString>> aPairVector);
     /**
      * Assert that rXPath exists, and returns exactly nNumberOfNodes nodes.
      * Useful for checking that we do _not_ export some node (nNumberOfNodes == 0).
diff --git a/test/source/mtfxmldump.cxx b/test/source/mtfxmldump.cxx
index e2225e8..ee2bd7a 100644
--- a/test/source/mtfxmldump.cxx
+++ b/test/source/mtfxmldump.cxx
@@ -56,25 +56,28 @@ OUString flagToString(PushFlags nFlag)
 
 OUString collectPushFlags(PushFlags nFlags)
 {
-    if ((nFlags & PushFlags::ALL) == nFlags)
+    if ((nFlags & PushFlags::ALL) == PushFlags::ALL)
         return OUString("PushAll");
-    else if ((nFlags & PUSH_ALLFONT) == nFlags)
+    else if ((nFlags & PUSH_ALLFONT) == PUSH_ALLFONT)
         return OUString("PushAllFont");
-    else if ((nFlags & PUSH_ALLTEXT) == nFlags)
+    else if ((nFlags & PUSH_ALLTEXT) == PUSH_ALLTEXT)
         return OUString("PushAllText");
 
     OUString sFlags;
 
     for (sal_uInt16 nFlag = 1; nFlag > 0; nFlag <<= 1)
     {
-        OUString sFlag = flagToString(static_cast<PushFlags>(nFlag));
-        if (!sFlag.isEmpty())
+        if ((nFlag & sal_uInt16(nFlags)) == nFlag)
         {
-            if (!sFlags.isEmpty())
+            OUString sFlag = flagToString(static_cast<PushFlags>(nFlag));
+            if (!sFlag.isEmpty())
             {
-                sFlags += ",";
+                if (!sFlags.isEmpty())
+                {
+                    sFlags += ", ";
+                }
+                sFlags += flagToString(static_cast<PushFlags>(nFlag));
             }
-            sFlags += flagToString(static_cast<PushFlags>(nFlag));
         }
     }
 
@@ -147,6 +150,18 @@ OUString convertLineCapToString(css::drawing::LineCap eCap)
     }
 }
 
+OUString convertPolygonFlags(PolyFlags eFlags)
+{
+    switch (eFlags)
+    {
+        default:
+        case PolyFlags::Normal:   return OUString("normal");
+        case PolyFlags::Control:  return OUString("control");
+        case PolyFlags::Smooth:   return OUString("smooth");
+        case PolyFlags::Symmetric:   return OUString("symmetric");
+    }
+}
+
 OUString convertFontWeigthToString(FontWeight eFontWeight)
 {
     enum FontWeight { WEIGHT_DONTKNOW, WEIGHT_THIN, WEIGHT_ULTRALIGHT,
@@ -233,6 +248,25 @@ OString convertLineStyleToString(const MetaActionType nActionType)
     return "";
 }
 
+OUString convertBitmapExTransparentType(TransparentType eType)
+{
+    switch (eType)
+    {
+        default:
+        case TransparentType::NONE:   return OUString("none");
+        case TransparentType::Bitmap: return OUString("bitmap");
+        case TransparentType::Color:  return OUString("color");
+    }
+}
+
+
+OUString hex32(sal_uInt32 nNumber)
+{
+    std::stringstream ss;
+    ss << std::hex << std::setfill ('0') << std::setw(8) << nNumber;
+    return OUString::createFromAscii(ss.str().c_str());
+}
+
 } // anonymous namespace
 
 MetafileXmlDump::MetafileXmlDump()
@@ -291,6 +325,119 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
 
         switch (nActionType)
         {
+            case MetaActionType::PIXEL:
+            {
+                auto* pMetaAction = static_cast<MetaPixelAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMetaAction->GetPoint().X());
+                rWriter.attribute("y", pMetaAction->GetPoint().Y());
+                rWriter.attribute("color", convertColorToString(pMetaAction->GetColor()));
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::POINT:
+            {
+                auto* pMetaAction = static_cast<MetaPointAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMetaAction->GetPoint().X());
+                rWriter.attribute("y", pMetaAction->GetPoint().Y());
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::RECT:
+            {
+                MetaRectAction* pMetaAction = static_cast<MetaRectAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::ROUNDRECT:
+            {
+                auto pMetaAction = static_cast<MetaRoundRectAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+                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);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::ARC:
+            {
+                auto pMetaAction = static_cast<MetaArcAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+
+                rWriter.attribute("startx", pMetaAction->GetStartPoint().X());
+                rWriter.attribute("starty", pMetaAction->GetStartPoint().Y());
+                rWriter.attribute("endx", pMetaAction->GetEndPoint().X());
+                rWriter.attribute("endy", pMetaAction->GetEndPoint().Y());
+
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::PIE:
+            {
+                auto pMetaAction = static_cast<MetaPieAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+
+                rWriter.attribute("startx", pMetaAction->GetStartPoint().X());
+                rWriter.attribute("starty", pMetaAction->GetStartPoint().Y());
+                rWriter.attribute("endx", pMetaAction->GetEndPoint().X());
+                rWriter.attribute("endy", pMetaAction->GetEndPoint().Y());
+
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::CHORD:
+            {
+                auto pMetaAction = static_cast<MetaChordAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("left", pMetaAction->GetRect().Left());
+                rWriter.attribute("top", pMetaAction->GetRect().Top());
+                rWriter.attribute("right", pMetaAction->GetRect().Right());
+                rWriter.attribute("bottom", pMetaAction->GetRect().Bottom());
+
+                rWriter.attribute("startx", pMetaAction->GetStartPoint().X());
+                rWriter.attribute("starty", pMetaAction->GetStartPoint().Y());
+                rWriter.attribute("endx", pMetaAction->GetEndPoint().X());
+                rWriter.attribute("endy", pMetaAction->GetEndPoint().Y());
+
+                rWriter.endElement();
+            }
+            break;
+
             case MetaActionType::LINE:
             {
                 MetaLineAction* pMetaLineAction = static_cast<MetaLineAction*>(pAction);
@@ -408,6 +555,24 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
             }
             break;
 
+            case MetaActionType::TEXT:
+            {
+                auto* pMeta = static_cast<MetaTextAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                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);
@@ -425,7 +590,7 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
                 {
                     rWriter.startElement("dxarray");
                     OUString sDxLengthString;
-                    for (sal_Int32 i = 0; i < aLength; ++i)
+                    for (sal_Int32 i = 0; i < aLength - aIndex; ++i)
                     {
                         sDxLengthString += OUString::number(pMetaTextArrayAction->GetDXArray()[aIndex + i]);
                         sDxLengthString += " ";
@@ -442,6 +607,25 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
             }
             break;
 
+            case MetaActionType::STRETCHTEXT:
+            {
+                auto* pMeta = static_cast<MetaStretchTextAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                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::LINECOLOR:
             {
                 MetaLineColorAction* pMetaLineColorAction = static_cast<MetaLineColorAction*>(pAction);
@@ -518,22 +702,29 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
                 MetaPolyLineAction* pMetaPolyLineAction = static_cast<MetaPolyLineAction*>(pAction);
                 rWriter.startElement(sCurrentElementTag);
 
+                LineInfo aLineInfo = pMetaPolyLineAction->GetLineInfo();
+                rWriter.attribute("style", convertLineStyleToString(aLineInfo.GetStyle()));
+                rWriter.attribute("width", aLineInfo.GetWidth());
+                rWriter.attribute("dashlen", aLineInfo.GetDashLen());
+                rWriter.attribute("dashcount", aLineInfo.GetDashCount());
+                rWriter.attribute("dotlen", aLineInfo.GetDotLen());
+                rWriter.attribute("dotcount", aLineInfo.GetDotCount());
+                rWriter.attribute("distance", aLineInfo.GetDistance());
+                rWriter.attribute("join", convertLineJoinToString(aLineInfo.GetLineJoin()));
+                rWriter.attribute("cap", convertLineCapToString(aLineInfo.GetLineCap()));
+
                 tools::Polygon aPolygon = pMetaPolyLineAction->GetPolygon();
+                bool bFlags = aPolygon.HasFlags();
                 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
                 {
                     rWriter.startElement("point");
                     rWriter.attribute("x", aPolygon[i].X());
                     rWriter.attribute("y", aPolygon[i].Y());
+                    if (bFlags)
+                        rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i)));
                     rWriter.endElement();
                 }
 
-                LineInfo aLineInfo = pMetaPolyLineAction->GetLineInfo();
-                rWriter.attribute("style", convertLineStyleToString(aLineInfo.GetStyle()));
-                rWriter.attribute("width", aLineInfo.GetWidth());
-                rWriter.attribute("dashlen", aLineInfo.GetDashLen());
-                rWriter.attribute("dotlen", aLineInfo.GetDotLen());
-                rWriter.attribute("distance", aLineInfo.GetDistance());
-
                 rWriter.endElement();
             }
             break;
@@ -544,11 +735,14 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
                 rWriter.startElement(sCurrentElementTag);
 
                 tools::Polygon aPolygon = pMetaPolygonAction->GetPolygon();
+                bool bFlags = aPolygon.HasFlags();
                 for (sal_uInt16 i = 0; i < aPolygon.GetSize(); i++)
                 {
                     rWriter.startElement("point");
                     rWriter.attribute("x", aPolygon[i].X());
                     rWriter.attribute("y", aPolygon[i].Y());
+                    if (bFlags)
+                        rWriter.attribute("flags", convertPolygonFlags(aPolygon.GetFlags(i)));
                     rWriter.endElement();
                 }
 
@@ -558,19 +752,23 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
 
             case MetaActionType::POLYPOLYGON:
             {
-                MetaPolyPolygonAction *const pMPPAction(
-                        static_cast<MetaPolyPolygonAction*>(pAction));
+                MetaPolyPolygonAction *const pMetaPolyPolygonAction = static_cast<MetaPolyPolygonAction*>(pAction);
                 rWriter.startElement(sCurrentElementTag);
 
-                tools::PolyPolygon const& rPoly(pMPPAction->GetPolyPolygon());
-                for (sal_uInt16 j = 0; j < rPoly.Count(); ++j)
+                tools::PolyPolygon const& rPolyPolygon(pMetaPolyPolygonAction->GetPolyPolygon());
+
+                for (sal_uInt16 j = 0; j < rPolyPolygon.Count(); ++j)
                 {
                     rWriter.startElement("polygon");
-                    for (sal_uInt16 i = 0; i < rPoly[j].GetSize(); i++)
+                    tools::Polygon const& rPolygon = rPolyPolygon[j];
+                    bool bFlags = rPolygon.HasFlags();
+                    for (sal_uInt16 i = 0; i < rPolygon.GetSize(); ++i)
                     {
                         rWriter.startElement("point");
-                        rWriter.attribute("x", rPoly[j][i].X());
-                        rWriter.attribute("y", rPoly[j][i].Y());
+                        rWriter.attribute("x", rPolygon[i].X());
+                        rWriter.attribute("y", rPolygon[i].Y());
+                        if (bFlags)
+                            rWriter.attribute("flags", convertPolygonFlags(rPolygon.GetFlags(i)));
                         rWriter.endElement();
                     }
                     rWriter.endElement();
@@ -600,6 +798,91 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, XmlWriter& rWriter)
             }
             break;
 
+            case MetaActionType::BMP:
+            {
+                auto pMeta = static_cast<MetaBmpAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::BMPSCALE:
+            {
+                auto pMeta = static_cast<MetaBmpScaleAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                rWriter.attribute("width", pMeta->GetSize().Width());
+                rWriter.attribute("height", pMeta->GetSize().Height());
+                rWriter.attribute("crc", hex32(pMeta->GetBitmap().GetChecksum()));
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::BMPSCALEPART:
+            {
+                auto pMeta = static_cast<MetaBmpScalePartAction*>(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.endElement();
+            }
+            break;
+
+            case MetaActionType::BMPEX:
+            {
+                auto pMeta = static_cast<MetaBmpExAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                rWriter.attribute("crc", hex32(pMeta->GetBitmapEx().GetBitmap().GetChecksum()));
+                rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::BMPEXSCALE:
+            {
+                auto pMeta = static_cast<MetaBmpExScaleAction*>(pAction);
+                rWriter.startElement(sCurrentElementTag);
+                rWriter.attribute("x", pMeta->GetPoint().X());
+                rWriter.attribute("y", pMeta->GetPoint().Y());
+                rWriter.attribute("width", pMeta->GetSize().Width());
+                rWriter.attribute("height", pMeta->GetSize().Height());
+                rWriter.attribute("crc", hex32(pMeta->GetBitmapEx().GetBitmap().GetChecksum()));
+                rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
+                rWriter.endElement();
+            }
+            break;
+
+            case MetaActionType::BMPEXSCALEPART:
+            {
+                auto pMeta = static_cast<MetaBmpExScalePartAction*>(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->GetBitmapEx().GetBitmap().GetChecksum()));
+                rWriter.attribute("transparenttype", convertBitmapExTransparentType(pMeta->GetBitmapEx().GetTransparentType()));
+                rWriter.endElement();
+            }
+            break;
+
             default:
             {
                 rWriter.element(sCurrentElementTag);
diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx
index 55e1949..04e90f3 100644
--- a/test/source/xmltesttools.cxx
+++ b/test/source/xmltesttools.cxx
@@ -99,6 +99,15 @@ void XmlTestTools::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const O
                                  rExpectedValue, aValue);
 }
 
+
+void XmlTestTools::assertXPathAttrs(xmlDocPtr pXmlDoc, const OString& rXPath, std::vector<std::pair<OString, OUString>> aPairVector)
+{
+    for (auto& rPair : aPairVector)
+    {
+        assertXPath(pXmlDoc, rXPath, rPair.first, rPair.second);
+    }
+}
+
 void XmlTestTools::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, int nNumberOfNodes)
 {
     xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
diff --git a/vcl/CppunitTest_vcl_svm_test.mk b/vcl/CppunitTest_vcl_svm_test.mk
new file mode 100644
index 0000000..499ae5b
--- /dev/null
+++ b/vcl/CppunitTest_vcl_svm_test.mk
@@ -0,0 +1,55 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_svm_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_svm_test, \
+    vcl/qa/cppunit/svm/svmtest \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,vcl_svm_test,\
+	boost_headers \
+    libxml2 \
+))
+
+
+$(eval $(call gb_CppunitTest_set_include,vcl_svm_test,\
+    $$(INCLUDE) \
+    -I$(SRCDIR)/vcl/inc \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,vcl_svm_test, \
+	comphelper \
+	cppu \
+	cppuhelper \
+	sal \
+    svt \
+	test \
+	tl \
+	unotest \
+	vcl \
+	utl \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,vcl_svm_test))
+
+$(eval $(call gb_CppunitTest_use_ure,vcl_svm_test))
+$(eval $(call gb_CppunitTest_use_vcl,vcl_svm_test))
+
+$(eval $(call gb_CppunitTest_use_components,vcl_svm_test,\
+    configmgr/source/configmgr \
+    i18npool/util/i18npool \
+    ucb/source/core/ucb1 \
+    unotools/util/utl \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,vcl_svm_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 2c46a97..f0298d8 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -134,6 +134,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
 	CppunitTest_vcl_app_test \
 	$(if $(MERGELIBS),,CppunitTest_vcl_wmf_test) \
 	CppunitTest_vcl_jpeg_read_write_test \
+	CppunitTest_vcl_svm_test \
 ))
 
 
diff --git a/vcl/qa/cppunit/svm/svmtest.cxx b/vcl/qa/cppunit/svm/svmtest.cxx
new file mode 100644
index 0000000..64e6477
--- /dev/null
+++ b/vcl/qa/cppunit/svm/svmtest.cxx
@@ -0,0 +1,904 @@
+/* -*- 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 <test/bootstrapfixture.hxx>
+#include <test/xmltesttools.hxx>
+#include <test/mtfxmldump.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/bitmapaccess.hxx>
+
+using namespace css;
+
+class SvmTest : public test::BootstrapFixture, public XmlTestTools
+{
+    OUString maDataUrl;
+
+    /*OUString getFullUrl(const OUString& sFileName)
+    {
+        return m_directories.getURLFromSrc(maDataUrl) + sFileName;
+    }*/
+
+    xmlDocPtr dumpMeta(const GDIMetaFile& rMetaFile, const OUString& rFileUrl = OUString());
+
+    void checkVirtualDevice(xmlDocPtr pDoc);
+    void checkErase(xmlDocPtr pDoc);
+
+    void checkPixel(const GDIMetaFile& rMetaFile);
+    void testPixel();
+
+    void checkLine(const GDIMetaFile& rMetaFile);
+    void testLine();
+
+    void checkRect(const GDIMetaFile& rMetaFile);
+    void testRect();
+
+    void checkRoundRect(const GDIMetaFile& rMetaFile);
+    void testRoundRect();
+
+    void checkEllipse(const GDIMetaFile& rMetaFile);
+    void testEllipse();
+
+    void checkArc(const GDIMetaFile& rMetaFile);
+    void testArc();
+
+    void checkPie(const GDIMetaFile& rMetaFile);
+    void testPie();
+
+    void checkChord(const GDIMetaFile& rMetaFile);
+    void testChord();
+
+    void checkPolyLine(const GDIMetaFile& rMetaFile);
+    void testPolyLine();
+
+    void checkPolygon(const GDIMetaFile& rMetaFile);
+    void testPolygon();
+
+    void checkPolyPolygon(const GDIMetaFile& rMetaFile);
+    void testPolyPolygon();
+
+    void checkBitmaps(const GDIMetaFile& rMetaFile);
+    void testBitmaps();
+
+    void checkBitmapExs(const GDIMetaFile& rMetaFile);
+    void testBitmapExs();
+
+    void checkPushPop(const GDIMetaFile& rMetaFile);
+    void testPushPop();
+
+    void checkText(const GDIMetaFile& rMetaFile);
+    void testText();
+
+    void checkTextArray(const GDIMetaFile& rMetaFile);
+    void testTextArray();
+
+    void checkStrechText(const GDIMetaFile& rMetaFile);
+    void testStrechText();
+
+    void checkTextColor(const GDIMetaFile& rMetaFile);
+    void testTextColor();
+
+    void checkTextFillColor(const GDIMetaFile& rMetaFile);
+    void testTextFillColor();
+
+    void checkTextLineColor(const GDIMetaFile& rMetaFile);
+    void testTextLineColor();
+
+public:
+    SvmTest() :
+        BootstrapFixture(true, false),
+        maDataUrl("/vcl/qa/cppunit/svm/data/")
+    {}
+
+    CPPUNIT_TEST_SUITE(SvmTest);
+    CPPUNIT_TEST(testPixel);
+    CPPUNIT_TEST(testLine);
+    CPPUNIT_TEST(testRect);
+    CPPUNIT_TEST(testRoundRect);
+    CPPUNIT_TEST(testEllipse);
+    CPPUNIT_TEST(testArc);
+    CPPUNIT_TEST(testPie);
+    CPPUNIT_TEST(testChord);
+    CPPUNIT_TEST(testPolyLine);
+    CPPUNIT_TEST(testPolygon);
+    CPPUNIT_TEST(testPolyPolygon);
+    CPPUNIT_TEST(testBitmaps);
+    CPPUNIT_TEST(testBitmapExs);
+    CPPUNIT_TEST(testPushPop);
+    CPPUNIT_TEST(testText);
+    CPPUNIT_TEST(testTextArray);
+    CPPUNIT_TEST(testStrechText);
+    CPPUNIT_TEST(testTextColor);
+    CPPUNIT_TEST(testTextFillColor);
+    CPPUNIT_TEST(testTextLineColor);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void setupBaseVirtualDevice(VirtualDevice& rDevice, GDIMetaFile& rMeta)
+{
+    rDevice.SetConnectMetaFile(&rMeta);
+    Size aVDSize(10, 10);
+    rDevice.SetOutputSizePixel(aVDSize);
+    rDevice.SetBackground(Wallpaper(COL_LIGHTRED));
+    rDevice.Erase();
+}
+
+GDIMetaFile readMetafile(const OUString& rUrl)
+{
+    SvFileStream aFileStream(rUrl, StreamMode::READ);
+    GDIMetaFile aResultMetafile;
+    aFileStream.Seek(STREAM_SEEK_TO_BEGIN);
+    aResultMetafile.Read(aFileStream);
+    return aResultMetafile;
+}
+
+void writeMetaFile(GDIMetaFile& rInputMetafile, const OUString& rUrl)
+{
+    SvFileStream aFileStream(rUrl, StreamMode::WRITE);
+    aFileStream.Seek(STREAM_SEEK_TO_BEGIN);
+    rInputMetafile.Write(aFileStream);
+    aFileStream.Close();
+}
+
+xmlDocPtr SvmTest::dumpMeta(const GDIMetaFile& rMetaFile, const OUString& rFileUrl)
+{
+    MetafileXmlDump dumper;
+    xmlDocPtr pDoc = dumper.dumpAndParse(rMetaFile, rFileUrl);
+    CPPUNIT_ASSERT (pDoc);
+
+    checkVirtualDevice(pDoc);
+    checkErase(pDoc);
+
+    return pDoc;
+}
+
+void SvmTest::checkVirtualDevice(xmlDocPtr pDoc)
+{
+    assertXPath(pDoc, "/metafile/linecolor[1]", "color", "#000000");
+    assertXPath(pDoc, "/metafile/fillcolor[1]", "color", "#ffffff");
+
+    assertXPathAttrs(pDoc, "/metafile/rect[1]", {
+        {"left", "0"},  {"top", "0"},
+        {"right", "9"}, {"bottom", "9"}
+    });
+
+    assertXPath(pDoc, "/metafile/linecolor[2]", "color", "#000000");
+    assertXPath(pDoc, "/metafile/fillcolor[2]", "color", "#ffffff");
+}
+
+void SvmTest::checkErase(xmlDocPtr pDoc)
+{
+    assertXPath(pDoc, "/metafile/linecolor[3]", "color", "#000000");
+    assertXPath(pDoc, "/metafile/fillcolor[3]", "color", "#ff0000");
+
+    assertXPathAttrs(pDoc, "/metafile/rect[2]", {
+        {"left", "0"},  {"top", "0"},
+        {"right", "9"}, {"bottom", "9"}
+    });
+}
+
+void SvmTest::checkPixel(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/pixel[1]", {
+        {"x", "8"}, {"y", "1"}, {"color", "#008000"},
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/pixel[2]", {
+        {"x", "1"}, {"y", "8"}, {"color", "#000080"},
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/point[1]", {
+        {"x", "4"}, {"y", "4"}
+    });
+}
+
+void SvmTest::testPixel()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->DrawPixel(Point(8, 1), COL_GREEN);
+    pVirtualDev->DrawPixel(Point(1, 8), COL_BLUE);
+    pVirtualDev->DrawPixel(Point(4, 4));
+
+    writeMetaFile(aGDIMetaFile, "pixel.svm");
+    checkPixel(readMetafile("pixel.svm"));
+}
+
+void SvmTest::checkLine(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/line[1]", {
+        {"startx", "1"}, {"starty", "1"},
+        {"endx", "8"},   {"endy", "8"},
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/line[1]", {
+        {"style", "solid"}, {"width", "0"},
+        {"dashlen", "0"},   {"dashcount", "0"},
+        {"dotlen", "0"},    {"dotcount", "0"},
+        {"distance", "0"},
+        {"join", "round"},  {"cap", "butt"}
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/line[2]", {
+        {"startx", "1"}, {"starty", "8"},
+        {"endx", "8"},   {"endy", "1"},
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/line[2]", {
+        {"style", "dash"},  {"width", "7"},
+        {"dashlen", "5"},   {"dashcount", "4"},
+        {"dotlen", "3"},    {"dotcount", "2"},
+        {"distance", "1"},
+        {"join", "miter"},  {"cap", "round"}
+    });
+}
+
+void SvmTest::testLine()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->DrawLine(Point(1, 1), Point(8, 8));
+    LineInfo aLineInfo(LineStyle::Dash, 7);
+    aLineInfo.SetDashLen(5);
+    aLineInfo.SetDashCount(4);
+    aLineInfo.SetDotLen(3);
+    aLineInfo.SetDotCount(2);
+    aLineInfo.SetDistance(1);
+    aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Miter);
+    aLineInfo.SetLineCap(css::drawing::LineCap_ROUND);
+    pVirtualDev->DrawLine(Point(1, 8), Point(8, 1), aLineInfo);
+
+    writeMetaFile(aGDIMetaFile, "line.svm");
+    checkLine(readMetafile("line.svm"));
+}
+
+void SvmTest::checkRect(const GDIMetaFile& rMetaFile)
+{
+
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/rect[3]", {
+        {"left", "1"}, {"top", "2"},
+        {"right", "4"},   {"bottom", "5"},
+    });
+}
+
+void SvmTest::testRect()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawRect(Rectangle(Point(1, 2), Size(4, 4)));
+
+    writeMetaFile(aGDIMetaFile, "rect.svm");
+    checkRect(readMetafile("rect.svm"));
+}
+
+void SvmTest::checkRoundRect(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/roundrect[1]", {
+        {"left", "1"}, {"top", "2"},
+        {"right", "4"},   {"bottom", "5"},
+        {"horizontalround", "1"}, {"verticalround", "2"}
+    });
+}
+
+void SvmTest::testRoundRect()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawRect(Rectangle(Point(1, 2), Size(4, 4)), 1, 2);
+
+    writeMetaFile(aGDIMetaFile, "roundrect.svm");
+    checkRoundRect(readMetafile("roundrect.svm"));
+}
+
+void SvmTest::checkEllipse(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/ellipse[1]", {
+        {"left", "1"}, {"top", "2"},
+        {"right", "4"},   {"bottom", "5"},
+    });
+}
+
+void SvmTest::testEllipse()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawEllipse(Rectangle(Point(1, 2), Size(4, 4)));
+
+    writeMetaFile(aGDIMetaFile, "ellipse.svm");
+    checkEllipse(readMetafile("ellipse.svm"));
+}
+
+void SvmTest::checkArc(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/arc[1]", {
+        {"left",  "1"}, {"top",    "2"},
+        {"right", "4"}, {"bottom", "5"},
+
+        {"startx", "10"}, {"starty", "11"},
+        {"endx",   "12"}, {"endy",   "13"},
+    });
+}
+
+void SvmTest::testArc()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawArc(Rectangle(Point(1, 2), Size(4, 4)), Point(10, 11), Point(12, 13));
+
+    writeMetaFile(aGDIMetaFile, "arc.svm");
+    checkArc(readMetafile("arc.svm"));
+}
+
+void SvmTest::checkPie(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/pie[1]", {
+        {"left",  "11"}, {"top",    "12"},
+        {"right", "14"}, {"bottom", "15"},
+
+        {"startx", "20"}, {"starty", "21"},
+        {"endx",   "22"}, {"endy",   "23"},
+    });
+}
+
+void SvmTest::testPie()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawPie(Rectangle(Point(11, 12), Size(4, 4)), Point(20, 21), Point(22, 23));
+
+    writeMetaFile(aGDIMetaFile, "pie.svm");
+    checkPie(readMetafile("pie.svm"));
+}
+
+void SvmTest::checkChord(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPath(pDoc, "/metafile/linecolor[5]", "color", "#123456");
+    assertXPath(pDoc, "/metafile/fillcolor[5]", "color", "#654321");
+
+    assertXPathAttrs(pDoc, "/metafile/chord[1]", {
+        {"left",  "21"}, {"top",    "22"},
+        {"right", "24"}, {"bottom", "25"},
+
+        {"startx", "30"}, {"starty", "31"},
+        {"endx",   "32"}, {"endy",   "33"},
+    });
+}
+
+void SvmTest::testChord()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(Color(0x123456));
+    pVirtualDev->SetFillColor(Color(0x654321));
+
+    pVirtualDev->DrawChord(Rectangle(Point(21, 22), Size(4, 4)), Point(30, 31), Point(32, 33));
+
+    writeMetaFile(aGDIMetaFile, "chord.svm");
+    checkChord(readMetafile("chord.svm"));
+}
+
+void SvmTest::checkPolyLine(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/polyline[1]", {
+        {"style", "solid"}, {"width", "0"},
+        {"dashlen", "0"},   {"dashcount", "0"},
+        {"dotlen", "0"},    {"dotcount", "0"},
+        {"distance", "0"},
+        {"join", "round"},  {"cap", "butt"}
+    });
+
+    assertXPathAttrs(pDoc, "/metafile/polyline[1]/point[1]", {{"x", "1"}, {"y", "8"}});
+    assertXPathAttrs(pDoc, "/metafile/polyline[1]/point[2]", {{"x", "2"}, {"y", "7"}});
+    assertXPathAttrs(pDoc, "/metafile/polyline[1]/point[3]", {{"x", "3"}, {"y", "6"}});
+
+    assertXPathAttrs(pDoc, "/metafile/polyline[2]", {
+        {"style", "dash"},  {"width", "7"},
+        {"dashlen", "5"},   {"dashcount", "4"},
+        {"dotlen", "3"},    {"dotcount", "2"},
+        {"distance", "1"},
+        {"join", "miter"},  {"cap", "round"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/polyline[2]/point[1]", {{"x", "8"}, {"y", "1"}, {"flags", "normal"}});
+    assertXPathAttrs(pDoc, "/metafile/polyline[2]/point[2]", {{"x", "7"}, {"y", "2"}, {"flags", "control"}});
+    assertXPathAttrs(pDoc, "/metafile/polyline[2]/point[3]", {{"x", "6"}, {"y", "3"}, {"flags", "smooth"}});
+    assertXPathAttrs(pDoc, "/metafile/polyline[2]/point[4]", {{"x", "5"}, {"y", "4"}, {"flags", "symmetric"}});
+}
+
+void SvmTest::testPolyLine()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    tools::Polygon aPolygon(3);
+    aPolygon.SetPoint(Point(1, 8), 0);
+    aPolygon.SetPoint(Point(2, 7), 1);
+    aPolygon.SetPoint(Point(3, 6), 2);
+
+    pVirtualDev->DrawPolyLine(aPolygon);
+
+    tools::Polygon aPolygonWithControl(4);
+    aPolygonWithControl.SetPoint(Point(8, 1), 0);
+    aPolygonWithControl.SetPoint(Point(7, 2), 1);
+    aPolygonWithControl.SetPoint(Point(6, 3), 2);
+    aPolygonWithControl.SetPoint(Point(5, 4), 3);
+
+    aPolygonWithControl.SetFlags(0, PolyFlags::Normal);
+    aPolygonWithControl.SetFlags(1, PolyFlags::Control);
+    aPolygonWithControl.SetFlags(2, PolyFlags::Smooth);
+    aPolygonWithControl.SetFlags(3, PolyFlags::Symmetric);
+
+    LineInfo aLineInfo(LineStyle::Dash, 7);
+    aLineInfo.SetDashLen(5);
+    aLineInfo.SetDashCount(4);
+    aLineInfo.SetDotLen(3);
+    aLineInfo.SetDotCount(2);
+    aLineInfo.SetDistance(1);
+    aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Miter);
+    aLineInfo.SetLineCap(css::drawing::LineCap_ROUND);
+
+    pVirtualDev->DrawPolyLine(aPolygonWithControl, aLineInfo);
+
+    writeMetaFile(aGDIMetaFile, "polyline.svm");
+    checkPolyLine(readMetafile("polyline.svm"));
+}
+
+void SvmTest::checkPolygon(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/polygon[1]/point[1]", {{"x", "1"}, {"y", "8"}});
+    assertXPathAttrs(pDoc, "/metafile/polygon[1]/point[2]", {{"x", "2"}, {"y", "7"}});
+    assertXPathAttrs(pDoc, "/metafile/polygon[1]/point[3]", {{"x", "3"}, {"y", "6"}});
+
+    assertXPathAttrs(pDoc, "/metafile/polygon[2]/point[1]", {{"x", "8"}, {"y", "1"}, {"flags", "normal"}});
+    assertXPathAttrs(pDoc, "/metafile/polygon[2]/point[2]", {{"x", "7"}, {"y", "2"}, {"flags", "control"}});
+    assertXPathAttrs(pDoc, "/metafile/polygon[2]/point[3]", {{"x", "6"}, {"y", "3"}, {"flags", "smooth"}});
+    assertXPathAttrs(pDoc, "/metafile/polygon[2]/point[4]", {{"x", "5"}, {"y", "4"}, {"flags", "symmetric"}});
+}
+
+void SvmTest::testPolygon()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    tools::Polygon aPolygon(3);
+    aPolygon.SetPoint(Point(1, 8), 0);
+    aPolygon.SetPoint(Point(2, 7), 1);
+    aPolygon.SetPoint(Point(3, 6), 2);
+
+    pVirtualDev->DrawPolygon(aPolygon);
+
+    tools::Polygon aPolygonWithControl(4);
+    aPolygonWithControl.SetPoint(Point(8, 1), 0);
+    aPolygonWithControl.SetPoint(Point(7, 2), 1);
+    aPolygonWithControl.SetPoint(Point(6, 3), 2);
+    aPolygonWithControl.SetPoint(Point(5, 4), 3);
+
+    aPolygonWithControl.SetFlags(0, PolyFlags::Normal);
+    aPolygonWithControl.SetFlags(1, PolyFlags::Control);
+    aPolygonWithControl.SetFlags(2, PolyFlags::Smooth);
+    aPolygonWithControl.SetFlags(3, PolyFlags::Symmetric);
+
+    pVirtualDev->DrawPolygon(aPolygonWithControl);
+
+    writeMetaFile(aGDIMetaFile, "polygon.svm");
+    checkPolygon(readMetafile("polygon.svm"));
+}
+
+void SvmTest::checkPolyPolygon(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[1]/point[1]", {{"x", "1"}, {"y", "8"}});
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[1]/point[2]", {{"x", "2"}, {"y", "7"}});
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[1]/point[3]", {{"x", "3"}, {"y", "6"}});
+
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[2]/point[1]", {{"x", "8"}, {"y", "1"}, {"flags", "normal"}});
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[2]/point[2]", {{"x", "7"}, {"y", "2"}, {"flags", "control"}});
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[2]/point[3]", {{"x", "6"}, {"y", "3"}, {"flags", "smooth"}});
+    assertXPathAttrs(pDoc, "/metafile/polypolygon[1]/polygon[2]/point[4]", {{"x", "5"}, {"y", "4"}, {"flags", "symmetric"}});
+}
+
+void SvmTest::testPolyPolygon()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    tools::Polygon aPolygon(3);
+    aPolygon.SetPoint(Point(1, 8), 0);
+    aPolygon.SetPoint(Point(2, 7), 1);
+    aPolygon.SetPoint(Point(3, 6), 2);
+
+    tools::Polygon aPolygonWithControl(4);
+    aPolygonWithControl.SetPoint(Point(8, 1), 0);
+    aPolygonWithControl.SetPoint(Point(7, 2), 1);
+    aPolygonWithControl.SetPoint(Point(6, 3), 2);
+    aPolygonWithControl.SetPoint(Point(5, 4), 3);
+
+    aPolygonWithControl.SetFlags(0, PolyFlags::Normal);
+    aPolygonWithControl.SetFlags(1, PolyFlags::Control);
+    aPolygonWithControl.SetFlags(2, PolyFlags::Smooth);
+    aPolygonWithControl.SetFlags(3, PolyFlags::Symmetric);
+
+    tools::PolyPolygon aPolyPolygon(2);
+    aPolyPolygon.Insert(aPolygon);
+    aPolyPolygon.Insert(aPolygonWithControl);
+
+    pVirtualDev->DrawPolyPolygon(aPolyPolygon);
+
+    writeMetaFile(aGDIMetaFile, "polypolygon.svm");
+    checkPolyPolygon(readMetafile("polypolygon.svm"));
+}
+
+void SvmTest::checkBitmaps(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+#ifdef LINUX
+    assertXPathAttrs(pDoc, "/metafile/bmp[1]", {{"x", "1"}, {"y", "2"}, {"crc", "7932585a"}});
+    assertXPathAttrs(pDoc, "/metafile/bmpscale[1]", {
+        {"x", "1"}, {"y", "2"}, {"width", "3"}, {"height", "4"}, {"crc", "08bfca1f"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpscalepart[1]", {
+        {"destx", "1"}, {"desty", "2"}, {"destwidth", "3"}, {"destheight", "4"},
+        {"srcx", "2"},  {"srcy", "1"},  {"srcwidth", "4"},  {"srcheight", "3"},
+        {"crc", "abd45514"}
+    });
+#else
+    assertXPathAttrs(pDoc, "/metafile/bmp[1]", {{"x", "1"}, {"y", "2"}, {"crc", "b8dee5da"}});
+    assertXPathAttrs(pDoc, "/metafile/bmpscale[1]", {
+        {"x", "1"}, {"y", "2"}, {"width", "3"}, {"height", "4"}, {"crc", "281fc589"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpscalepart[1]", {
+        {"destx", "1"}, {"desty", "2"}, {"destwidth", "3"}, {"destheight", "4"},
+        {"srcx", "2"},  {"srcy", "1"},  {"srcwidth", "4"},  {"srcheight", "3"},
+        {"crc", "5e01ddcc"}
+    });
+#endif
+}
+
+void SvmTest::testBitmaps()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    Bitmap aBitmap1(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap1);
+        pAccess->Erase(COL_RED);
+    }
+    Bitmap aBitmap2(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap2);
+        pAccess->Erase(COL_GREEN);
+    }
+    Bitmap aBitmap3(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap3);
+        pAccess->Erase(COL_BLUE);
+    }
+    pVirtualDev->DrawBitmap(Point(1, 2), aBitmap1);
+    pVirtualDev->DrawBitmap(Point(1, 2), Size(3, 4), aBitmap2);
+    pVirtualDev->DrawBitmap(Point(1, 2), Size(3, 4), Point(2, 1), Size(4, 3), aBitmap3);
+
+    writeMetaFile(aGDIMetaFile, "bitmaps.svm");
+    checkBitmaps(readMetafile("bitmaps.svm"));
+}
+
+void SvmTest::checkBitmapExs(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+#ifdef LINUX
+    assertXPathAttrs(pDoc, "/metafile/bmpex[1]", {
+        {"x", "1"}, {"y", "2"}, {"crc", "7932585a"}, {"transparenttype", "bitmap"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpexscale[1]", {
+        {"x", "1"}, {"y", "2"}, {"width", "3"}, {"height", "4"},
+        {"crc", "08bfca1f"}, {"transparenttype", "bitmap"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpexscalepart[1]", {
+        {"destx", "1"}, {"desty", "2"}, {"destwidth", "3"}, {"destheight", "4"},
+        {"srcx", "2"},  {"srcy", "1"},  {"srcwidth", "4"},  {"srcheight", "3"},
+        {"crc", "abd45514"}, {"transparenttype", "bitmap"}
+    });
+#else
+    assertXPathAttrs(pDoc, "/metafile/bmpex[1]", {
+        {"x", "1"}, {"y", "2"}, {"crc", "b8dee5da"}, {"transparenttype", "bitmap"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpexscale[1]", {
+        {"x", "1"}, {"y", "2"}, {"width", "3"}, {"height", "4"},
+        {"crc", "281fc589"}, {"transparenttype", "bitmap"}
+    });
+    assertXPathAttrs(pDoc, "/metafile/bmpexscalepart[1]", {
+        {"destx", "1"}, {"desty", "2"}, {"destwidth", "3"}, {"destheight", "4"},
+        {"srcx", "2"},  {"srcy", "1"},  {"srcwidth", "4"},  {"srcheight", "3"},
+        {"crc", "5e01ddcc"}, {"transparenttype", "bitmap"}
+    });
+#endif
+}
+
+void SvmTest::testBitmapExs()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    Bitmap aBitmap1(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap1);
+        pAccess->Erase(COL_RED);
+    }
+    BitmapEx aBitmapEx1(aBitmap1, COL_YELLOW);
+
+    Bitmap aBitmap2(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap2);
+        pAccess->Erase(COL_GREEN);
+    }
+    BitmapEx aBitmapEx2(aBitmap2, COL_YELLOW);
+
+    Bitmap aBitmap3(Size(4,4), 24);
+    {
+        Bitmap::ScopedWriteAccess pAccess(aBitmap3);
+        pAccess->Erase(COL_BLUE);
+    }
+    BitmapEx aBitmapEx3(aBitmap3, COL_YELLOW);
+
+    pVirtualDev->DrawBitmapEx(Point(1, 2), aBitmapEx1);
+    pVirtualDev->DrawBitmapEx(Point(1, 2), Size(3, 4), aBitmapEx2);
+    pVirtualDev->DrawBitmapEx(Point(1, 2), Size(3, 4), Point(2, 1), Size(4, 3), aBitmapEx3);
+
+    writeMetaFile(aGDIMetaFile, "bitmapexs.svm");
+    checkBitmapExs(readMetafile("bitmapexs.svm"));
+}
+
+void SvmTest::checkPushPop(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/push[1]", {{"flags", "PushAll"}});
+    assertXPathAttrs(pDoc, "/metafile/push[1]/linecolor[1]", {{"color", "#800000"}});
+    assertXPathAttrs(pDoc, "/metafile/push[1]/line[1]", {
+        {"startx", "4"}, {"starty", "4"},
+        {"endx", "6"},   {"endy", "6"},
+    });
+    assertXPathAttrs(pDoc, "/metafile/push[1]/push[1]", {{"flags", "PushLineColor, PushFillColor"}});
+    assertXPathAttrs(pDoc, "/metafile/push[1]/push[1]/line[1]", {
+        {"startx", "5"}, {"starty", "5"},
+        {"endx", "7"},   {"endy", "7"},
+    });
+}
+
+void SvmTest::testPushPop()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetLineColor(COL_YELLOW);
+    pVirtualDev->Push();
+    pVirtualDev->SetLineColor(COL_RED);
+    pVirtualDev->DrawLine(Point(4,4), Point(6,6));
+    pVirtualDev->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
+    pVirtualDev->SetLineColor(COL_LIGHTRED);
+    pVirtualDev->DrawLine(Point(5,5), Point(7,7));
+    pVirtualDev->Pop();
+    pVirtualDev->Pop();
+    pVirtualDev->DrawLine(Point(1,1), Point(8,8));
+
+    writeMetaFile(aGDIMetaFile, "pushpop.svm");
+    checkPushPop(readMetafile("pushpop.svm"));
+}
+
+void SvmTest::checkText(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/text[1]", {
+        {"x", "4"}, {"y", "6"}, {"index", "1"}, {"length", "2"},
+    });
+
+    assertXPathContent(pDoc, "/metafile/text[1]/textcontent", "xABC");
+}
+
+void SvmTest::testText()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->DrawText(Point(4,6), "xABC", 1, 2);
+
+    writeMetaFile(aGDIMetaFile, "text.svm");
+    checkText(readMetafile("text.svm"));
+}
+
+void SvmTest::checkTextArray(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/textarray[1]", {
+        {"x", "4"}, {"y", "6"}, {"index", "1"}, {"length", "4"},
+    });
+    assertXPathContent(pDoc, "/metafile/textarray[1]/dxarray", "15 20 25 ");
+    assertXPathContent(pDoc, "/metafile/textarray[1]/text", "123456");
+}
+
+void SvmTest::testTextArray()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+    long aDX[] = { 10, 15, 20, 25, 30, 35 };
+    pVirtualDev->DrawTextArray(Point(4,6), "123456", aDX, 1, 4);
+
+    writeMetaFile(aGDIMetaFile, "textarray.svm");
+    checkTextArray(readMetafile("textarray.svm"));
+}
+
+void SvmTest::checkStrechText(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile, "svmtest_output.xml");
+
+    assertXPathAttrs(pDoc, "/metafile/stretchtext[1]", {
+        {"x", "4"}, {"y", "6"}, {"index", "1"}, {"length", "4"}, {"width", "10"}
+    });
+
+    assertXPathContent(pDoc, "/metafile/stretchtext[1]/textcontent", "123456");
+}
+
+void SvmTest::testStrechText()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+    pVirtualDev->DrawStretchText(Point(4,6), 10, "123456", 1, 4);
+
+    writeMetaFile(aGDIMetaFile, "strecthtext.svm");
+    checkStrechText(readMetafile("strecthtext.svm"));
+}
+
+void SvmTest::checkTextColor(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/textcolor[1]", {
+        {"color", "#123456"},
+    });
+}
+
+void SvmTest::testTextColor()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetTextColor(Color(0x123456));
+
+    writeMetaFile(aGDIMetaFile, "textcolor.svm");
+    checkTextColor(readMetafile("textcolor.svm"));
+}
+
+void SvmTest::checkTextFillColor(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/textfillcolor[1]", {
+        {"color", "#234567"},
+    });
+}
+
+void SvmTest::testTextFillColor()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetTextFillColor(Color(0x234567));
+
+    writeMetaFile(aGDIMetaFile, "textfillecolor.svm");
+    checkTextFillColor(readMetafile("textfillecolor.svm"));
+}
+
+void SvmTest::checkTextLineColor(const GDIMetaFile& rMetaFile)
+{
+    xmlDocPtr pDoc = dumpMeta(rMetaFile);
+
+    assertXPathAttrs(pDoc, "/metafile/textlinecolor[1]", {
+        {"color", "#345678"},
+    });
+}
+
+void SvmTest::testTextLineColor()
+{
+    GDIMetaFile aGDIMetaFile;
+    ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+    setupBaseVirtualDevice(*pVirtualDev.get(), aGDIMetaFile);
+
+    pVirtualDev->SetTextLineColor(Color(0x345678));
+
+    writeMetaFile(aGDIMetaFile, "textlinecolor.svm");
+    checkTextLineColor(readMetafile("textlinecolor.svm"));
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SvmTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list