vcl/inc/TypeSerializer.hxx            |    4 +
 vcl/qa/cppunit/TypeSerializerTest.cxx |   57 ++++++++++++++++
 vcl/source/gdi/TypeSerializer.cxx     |  117 ++++++++++++++++++++++++++++++++++
 3 files changed, 178 insertions(+)

New commits:
commit c79dd92480cbc409a7061da7f3dd3abaaf9a4883
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Apr 30 10:48:44 2020 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Sun May 3 08:22:45 2020 +0200

    vcl: add Graphic serialization (writing) to TypeSerializer + tests
    
    Change-Id: I3c4845550e776c4c2c891d94db71bacea27c9a37
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93328
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/vcl/inc/TypeSerializer.hxx b/vcl/inc/TypeSerializer.hxx
index befd4edd7660..4ac7e06471ea 100644
--- a/vcl/inc/TypeSerializer.hxx
+++ b/vcl/inc/TypeSerializer.hxx
@@ -24,6 +24,7 @@
 #include <tools/GenericTypeSerializer.hxx>
 #include <vcl/gradient.hxx>
 #include <vcl/gfxlink.hxx>
+#include <vcl/graph.hxx>
 
 class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer
 {
@@ -35,6 +36,9 @@ public:
 
     void readGfxLink(GfxLink& rGfxLink);
     void writeGfxLink(const GfxLink& rGfxLink);
+
+    static void readGraphic(Graphic& rGraphic);
+    void writeGraphic(const Graphic& rGraphic);
 };
 
 #endif
diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx 
b/vcl/qa/cppunit/TypeSerializerTest.cxx
index e5d3a259f803..0c737a4c4f03 100644
--- a/vcl/qa/cppunit/TypeSerializerTest.cxx
+++ b/vcl/qa/cppunit/TypeSerializerTest.cxx
@@ -130,6 +130,43 @@ void TypeSerializerTest::testGraphic()
         
CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
                              toHexString(aHash));
     }
+
+    // Test TypeSerializer - Native Format 5
+    {
+        SvMemoryStream aMemoryStream;
+        aMemoryStream.SetVersion(SOFFICE_FILEFORMAT_50);
+        aMemoryStream.SetCompressMode(SvStreamCompressFlags::NATIVE);
+        {
+            TypeSerializer aSerializer(aMemoryStream);
+            aSerializer.writeGraphic(aGraphic);
+        }
+        aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(290), aMemoryStream.remainingSize());
+        std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+        
CPPUNIT_ASSERT_EQUAL(std::string("ee55ab6faa73b61b68bc3d5628d95f0d3c528e2a"),
+                             toHexString(aHash));
+
+        aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+        sal_uInt32 nType;
+        aMemoryStream.ReadUInt32(nType);
+        CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType);
+    }
+
+    // Test TypeSerializer - Normal
+    {
+        SvMemoryStream aMemoryStream;
+        {
+            TypeSerializer aSerializer(aMemoryStream);
+            aSerializer.writeGraphic(aGraphic);
+        }
+        aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(233), aMemoryStream.remainingSize());
+        std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+        
CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"),
+                             toHexString(aHash));
+    }
 }
 
 void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
@@ -155,6 +192,26 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink()
         aMemoryStream.ReadUInt16(nType);
         CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with 
WriteDIBBitmapEx
     }
+
+    // Test TypeSerializer
+    {
+        SvMemoryStream aMemoryStream;
+        {
+            TypeSerializer aSerializer(aMemoryStream);
+            aSerializer.writeGraphic(aGraphic);
+        }
+        aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+
+        CPPUNIT_ASSERT_EQUAL(sal_uInt64(383), aMemoryStream.remainingSize());
+        std::vector<unsigned char> aHash = calculateHash(aMemoryStream);
+        
CPPUNIT_ASSERT_EQUAL(std::string("da831418499146d51bf245fadf60b9111faa76c2"),
+                             toHexString(aHash));
+
+        aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
+        sal_uInt16 nType;
+        aMemoryStream.ReadUInt16(nType);
+        CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with 
WriteDIBBitmapEx
+    }
 }
 
 } // namespace
diff --git a/vcl/source/gdi/TypeSerializer.cxx 
b/vcl/source/gdi/TypeSerializer.cxx
index ad2f1400da85..8266c6ac9813 100644
--- a/vcl/source/gdi/TypeSerializer.cxx
+++ b/vcl/source/gdi/TypeSerializer.cxx
@@ -20,6 +20,8 @@
 #include <TypeSerializer.hxx>
 #include <tools/vcompat.hxx>
 #include <sal/log.hxx>
+#include <comphelper/fileformat.h>
+#include <vcl/gdimtf.hxx>
 
 TypeSerializer::TypeSerializer(SvStream& rStream)
     : GenericTypeSerializer(rStream)
@@ -148,4 +150,119 @@ void TypeSerializer::writeGfxLink(const GfxLink& rGfxLink)
     }
 }
 
+namespace
+{
+constexpr sal_uInt32 constSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') 
<< 16)
+                                   | (sal_uInt32('g') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') 
<< 16)
+                                   | (sal_uInt32('f') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') 
<< 16)
+                                   | (sal_uInt32('f') << 8) | sal_uInt32('0'));
+constexpr sal_uInt32 constPdfMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') 
<< 16)
+                                   | (sal_uInt32('g') << 8) | sal_uInt32('0'));
+
+#define NATIVE_FORMAT_50 COMPAT_FORMAT('N', 'A', 'T', '5')
+
+} // end anonymous namespace
+
+void TypeSerializer::readGraphic(Graphic& /*rGraphic*/) {}
+
+void TypeSerializer::writeGraphic(const Graphic& rGraphic)
+{
+    Graphic aGraphic(rGraphic);
+
+    if (!aGraphic.makeAvailable())
+        return;
+
+    auto pGfxLink = aGraphic.GetSharedGfxLink();
+
+    if (mrStream.GetVersion() >= SOFFICE_FILEFORMAT_50
+        && (mrStream.GetCompressMode() & SvStreamCompressFlags::NATIVE) && 
pGfxLink
+        && pGfxLink->IsNative())
+    {
+        // native format
+        mrStream.WriteUInt32(NATIVE_FORMAT_50);
+
+        // write compat info, destructor writes stuff into the header
+        {
+            VersionCompat aCompat(mrStream, StreamMode::WRITE, 1);
+        }
+        pGfxLink->SetPrefMapMode(aGraphic.GetPrefMapMode());
+        pGfxLink->SetPrefSize(aGraphic.GetPrefSize());
+        writeGfxLink(*pGfxLink);
+    }
+    else
+    {
+        // own format
+        const SvStreamEndian nOldFormat = mrStream.GetEndian();
+        mrStream.SetEndian(SvStreamEndian::LITTLE);
+
+        switch (aGraphic.GetType())
+        {
+            case GraphicType::NONE:
+            case GraphicType::Default:
+                break;
+
+            case GraphicType::Bitmap:
+            {
+                auto pVectorGraphicData = aGraphic.getVectorGraphicData();
+                if (pVectorGraphicData)
+                {
+                    // stream out Vector Graphic defining data (length, byte 
array and evtl. path)
+                    // this is used e.g. in swapping out graphic data and in 
transporting it over UNO API
+                    // as sequence of bytes, but AFAIK not written anywhere to 
any kind of file, so it should be
+                    // no problem to extend it; only used at runtime
+                    switch (pVectorGraphicData->getVectorGraphicDataType())
+                    {
+                        case VectorGraphicDataType::Wmf:
+                        {
+                            mrStream.WriteUInt32(constWmfMagic);
+                            break;
+                        }
+                        case VectorGraphicDataType::Emf:
+                        {
+                            mrStream.WriteUInt32(constEmfMagic);
+                            break;
+                        }
+                        case VectorGraphicDataType::Svg:
+                        {
+                            mrStream.WriteUInt32(constSvgMagic);
+                            break;
+                        }
+                        case VectorGraphicDataType::Pdf:
+                        {
+                            mrStream.WriteUInt32(constPdfMagic);
+                            break;
+                        }
+                    }
+
+                    sal_uInt32 nSize = 
pVectorGraphicData->getVectorGraphicDataArrayLength();
+                    mrStream.WriteUInt32(nSize);
+                    mrStream.WriteBytes(
+                        
pVectorGraphicData->getVectorGraphicDataArray().getConstArray(), nSize);
+                    
mrStream.WriteUniOrByteString(pVectorGraphicData->getPath(),
+                                                  mrStream.GetStreamCharSet());
+                }
+                else if (aGraphic.IsAnimated())
+                {
+                    WriteAnimation(mrStream, aGraphic.GetAnimation());
+                }
+                else
+                {
+                    WriteDIBBitmapEx(aGraphic.GetBitmapEx(), mrStream);
+                }
+            }
+            break;
+
+            default:
+            {
+                if (aGraphic.IsSupportedGraphic())
+                    WriteGDIMetaFile(mrStream, rGraphic.GetGDIMetaFile());
+            }
+            break;
+        }
+        mrStream.SetEndian(nOldFormat);
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to