when converting WMF to WMF, simply do a direct copy

Actually, if we have the graphics data, just copy the graphics data,
that'll keep both the EMF+ and non-EMF+ content.

Change-Id: Ia14df0ba2a94d4310ee745b49de1d2190e425f05
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117063
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index 608c5f4..e9af574 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -28,6 +28,7 @@
#include <unotools/tempfile.hxx>
#include <vcl/cvtgrf.hxx>
#include <vcl/metaact.hxx>
#include <vcl/wmf.hxx>

#include <impgraph.hxx>
#include <graphic/GraphicFormatDetector.hxx>
@@ -53,6 +54,7 @@ private:
    void testUnloadedGraphicSizeUnit();

    void testWMFRoundtrip();
    void testWMFWithEmfPlusRoundtrip();
    void testEmfToWmfConversion();

    void testSwappingGraphic_PNG_WithGfxLink();
@@ -89,6 +91,7 @@ private:
    CPPUNIT_TEST(testUnloadedGraphicAlpha);
    CPPUNIT_TEST(testUnloadedGraphicSizeUnit);
    CPPUNIT_TEST(testWMFRoundtrip);
    CPPUNIT_TEST(testWMFWithEmfPlusRoundtrip);
    CPPUNIT_TEST(testEmfToWmfConversion);

    CPPUNIT_TEST(testSwappingGraphic_PNG_WithGfxLink);
@@ -411,6 +414,82 @@ void GraphicTest::testWMFRoundtrip()
    CPPUNIT_ASSERT_EQUAL(nExpectedSize, nActualSize);
}

int getEmfPlusActionsCount(const Graphic& graphic)
{
    const GDIMetaFile& metafile = graphic.GetGDIMetaFile();
    int emfPlusCount = 0;
    for (size_t i = 0; i < metafile.GetActionSize(); ++i)
    {
        MetaAction* action = metafile.GetAction(i);
        if (action->GetType() == MetaActionType::COMMENT)
        {
            const MetaCommentAction* commentAction = static_cast<const MetaCommentAction*>(action);
            if (commentAction->GetComment() == "EMF_PLUS")
                ++emfPlusCount;
        }
    }
    return emfPlusCount;
}

int getPolygonActionsCount(const Graphic& graphic)
{
    const GDIMetaFile& metafile = graphic.GetGDIMetaFile();
    int polygonCount = 0;
    for (size_t i = 0; i < metafile.GetActionSize(); ++i)
    {
        MetaAction* action = metafile.GetAction(i);
        if (action->GetType() == MetaActionType::POLYGON)
            ++polygonCount;
    }
    return polygonCount;
}

void GraphicTest::testWMFWithEmfPlusRoundtrip()
{
    // Load a WMF file.
    test::Directories aDirectories;
    OUString aURL = aDirectories.getURLFromSrc(u"vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf");
    SvFileStream aStream(aURL, StreamMode::READ);
    sal_uInt64 nExpectedSize = aStream.TellEnd();
    GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
    Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);

    CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aGraphic));
    CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aGraphic));

    for (bool useConvertMetafile : { false, true })
    {
        // Save as WMF.
        utl::TempFile aTempFile;
        aTempFile.EnableKillingFile();
        SvStream& rOutStream = *aTempFile.GetStream(StreamMode::READWRITE);
        if (useConvertMetafile)
            ConvertGraphicToWMF(aGraphic, rOutStream, nullptr);
        else
        {
            sal_uInt16 nFormat = rGraphicFilter.GetExportFormatNumberForShortName(u"WMF");
            rGraphicFilter.ExportGraphic(aGraphic, OUString(), rOutStream, nFormat);
        }
        CPPUNIT_ASSERT_EQUAL(nExpectedSize, rOutStream.TellEnd());

        rOutStream.Seek(0);
        Graphic aNewGraphic = rGraphicFilter.ImportUnloadedGraphic(rOutStream);
        // Check that reading the WMF back preserves the EMF+ actions in it.
        CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aNewGraphic));
        // EmfReader::ReadEnhWMF() drops non-EMF+ drawing actions if EMF+ is found.
        CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aNewGraphic));

        // With EMF+ disabled there should be no EMF+ actions.
        auto& rDataContainer = aNewGraphic.GetGfxLink().getDataContainer();
        auto aVectorGraphicData
            = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Wmf);
        aVectorGraphicData->setEnableEMFPlus(false);
        Graphic aNoEmfPlusGraphic(aVectorGraphicData);
        CPPUNIT_ASSERT_EQUAL(0, getEmfPlusActionsCount(aNoEmfPlusGraphic));
        CPPUNIT_ASSERT_GREATER(0, getPolygonActionsCount(aNoEmfPlusGraphic));
    }
}

void GraphicTest::testEmfToWmfConversion()
{
    // Load EMF data.
diff --git a/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf
new file mode 100644
index 0000000..1e7f75b
--- /dev/null
+++ b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf
Binary files differ
diff --git a/vcl/source/filter/wmf/wmf.cxx b/vcl/source/filter/wmf/wmf.cxx
index ee1ce77..bf91502 100644
--- a/vcl/source/filter/wmf/wmf.cxx
+++ b/vcl/source/filter/wmf/wmf.cxx
@@ -90,13 +90,14 @@ bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream,
    GfxLink aLink = rGraphic.GetGfxLink();
    if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize())
    {
        // This may be an EMF+ file or WMF file with EMF+ embedded. In EmfReader::ReadEnhWMF()
        // we normally drop non-EMF commands when reading EMF+, so converting that to WMF
        // is better done by re-parsing with EMF+ disabled.
        if(!aLink.IsEMF()) // If WMF, just write directly.
            return rTargetStream.WriteBytes(aLink.GetData(), aLink.GetDataSize()) == aLink.GetDataSize();

        // This may be an EMF+ file. In EmfReader::ReadEnhWMF() we normally drop non-EMF commands
        // when reading EMF+, so converting that to WMF is better done by re-parsing with EMF+ disabled.
        auto & rDataContainer = aLink.getDataContainer();
        auto aVectorGraphicData
            = std::make_shared<VectorGraphicData>(rDataContainer,
                aLink.IsEMF() ? VectorGraphicDataType::Emf : VectorGraphicDataType::Wmf);
            = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Emf);
        aVectorGraphicData->setEnableEMFPlus(false);
        Graphic aGraphic(aVectorGraphicData);
        bool bRet = ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem,