include/tools/UnitConversion.hxx | 25 ++++ include/tools/mapunit.hxx | 11 -- svx/source/svdraw/svdpdf.cxx | 4 svx/source/svdraw/svdpdf.hxx | 2 vcl/inc/TypeSerializer.hxx | 6 + vcl/qa/cppunit/TypeSerializerTest.cxx | 68 ++++++++++++- vcl/source/gdi/TypeSerializer.cxx | 172 ++++++++++++++++++++++++++++++++-- 7 files changed, 262 insertions(+), 26 deletions(-)
New commits: commit 8c99b4407decae2374caddd2e561917e7d447ce9 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri May 1 19:24:01 2020 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri May 1 19:24:01 2020 +0200 vcl: add Graphic reading to TypeSerializer + tests Change-Id: I73aafc4f9a6f964a31d116610df6cf15dc51770c diff --git a/vcl/inc/TypeSerializer.hxx b/vcl/inc/TypeSerializer.hxx index 136af57a399a..060876593aa5 100644 --- a/vcl/inc/TypeSerializer.hxx +++ b/vcl/inc/TypeSerializer.hxx @@ -26,6 +26,12 @@ #include <vcl/gfxlink.hxx> #include <vcl/graph.hxx> +constexpr sal_uInt32 createMagic(char char1, char char2, char char3, char char4) +{ + return (static_cast<sal_uInt32>(char1) << 24) | (static_cast<sal_uInt32>(char2) << 16) + | (static_cast<sal_uInt32>(char3) << 8) | (static_cast<sal_uInt32>(char4) << 0); +} + class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer { public: diff --git a/vcl/qa/cppunit/TypeSerializerTest.cxx b/vcl/qa/cppunit/TypeSerializerTest.cxx index 0c737a4c4f03..43fd00ee0065 100644 --- a/vcl/qa/cppunit/TypeSerializerTest.cxx +++ b/vcl/qa/cppunit/TypeSerializerTest.cxx @@ -51,12 +51,12 @@ std::string toHexString(const std::vector<unsigned char>& a) class TypeSerializerTest : public CppUnit::TestFixture { void testGradient(); - void testGraphic(); + void testGraphic_Vector_NoGfxLink(); void testGraphic_Bitmap_NoGfxLink(); CPPUNIT_TEST_SUITE(TypeSerializerTest); CPPUNIT_TEST(testGradient); - CPPUNIT_TEST(testGraphic); + CPPUNIT_TEST(testGraphic_Vector_NoGfxLink); CPPUNIT_TEST(testGraphic_Bitmap_NoGfxLink); CPPUNIT_TEST_SUITE_END(); }; @@ -91,7 +91,7 @@ void TypeSerializerTest::testGradient() CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aReadGradient.GetSteps()); } -void TypeSerializerTest::testGraphic() +void TypeSerializerTest::testGraphic_Vector_NoGfxLink() { test::Directories aDirectories; OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg"; @@ -99,6 +99,7 @@ void TypeSerializerTest::testGraphic() GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream); aGraphic.makeAvailable(); + BitmapChecksum aChecksum = aGraphic.getVectorGraphicData()->GetChecksum(); // Test WriteGraphic - Native Format 5 { @@ -117,6 +118,13 @@ void TypeSerializerTest::testGraphic() sal_uInt32 nType; aMemoryStream.ReadUInt32(nType); CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType); + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + ReadGraphic(aMemoryStream, aNewGraphic); + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum()); } // Test WriteGraphic - Normal @@ -129,6 +137,18 @@ void TypeSerializerTest::testGraphic() std::vector<unsigned char> aHash = calculateHash(aMemoryStream); CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"), toHexString(aHash)); + + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + sal_uInt32 nType; + aMemoryStream.ReadUInt32(nType); + CPPUNIT_ASSERT_EQUAL(createMagic('s', 'v', 'g', '0'), nType); + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + ReadGraphic(aMemoryStream, aNewGraphic); + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum()); } // Test TypeSerializer - Native Format 5 @@ -151,6 +171,16 @@ void TypeSerializerTest::testGraphic() sal_uInt32 nType; aMemoryStream.ReadUInt32(nType); CPPUNIT_ASSERT_EQUAL(COMPAT_FORMAT('N', 'A', 'T', '5'), nType); + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + { + TypeSerializer aSerializer(aMemoryStream); + aSerializer.readGraphic(aNewGraphic); + } + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum()); } // Test TypeSerializer - Normal @@ -166,6 +196,21 @@ void TypeSerializerTest::testGraphic() std::vector<unsigned char> aHash = calculateHash(aMemoryStream); CPPUNIT_ASSERT_EQUAL(std::string("c2bed2099ce617f1cc035701de5186f0d43e3064"), toHexString(aHash)); + + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + sal_uInt32 nType; + aMemoryStream.ReadUInt32(nType); + CPPUNIT_ASSERT_EQUAL(createMagic('s', 'v', 'g', '0'), nType); + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + { + TypeSerializer aSerializer(aMemoryStream); + aSerializer.readGraphic(aNewGraphic); + } + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aChecksum, aNewGraphic.getVectorGraphicData()->GetChecksum()); } } @@ -191,6 +236,13 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink() sal_uInt16 nType; aMemoryStream.ReadUInt16(nType); CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + ReadGraphic(aMemoryStream, aNewGraphic); + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aBitmapEx.GetChecksum(), aNewGraphic.GetBitmapExRef().GetChecksum()); } // Test TypeSerializer @@ -211,6 +263,16 @@ void TypeSerializerTest::testGraphic_Bitmap_NoGfxLink() sal_uInt16 nType; aMemoryStream.ReadUInt16(nType); CPPUNIT_ASSERT_EQUAL(sal_uInt16(0x4D42), nType); // Magic written with WriteDIBBitmapEx + + // Read it back + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + Graphic aNewGraphic; + { + TypeSerializer aSerializer(aMemoryStream); + aSerializer.readGraphic(aNewGraphic); + } + CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aNewGraphic.GetType()); + CPPUNIT_ASSERT_EQUAL(aBitmapEx.GetChecksum(), aNewGraphic.GetBitmapExRef().GetChecksum()); } } diff --git a/vcl/source/gdi/TypeSerializer.cxx b/vcl/source/gdi/TypeSerializer.cxx index 8266c6ac9813..0f1fd0ee43b9 100644 --- a/vcl/source/gdi/TypeSerializer.cxx +++ b/vcl/source/gdi/TypeSerializer.cxx @@ -22,6 +22,7 @@ #include <sal/log.hxx> #include <comphelper/fileformat.h> #include <vcl/gdimtf.hxx> +#include <vcl/dibtools.hxx> TypeSerializer::TypeSerializer(SvStream& rStream) : GenericTypeSerializer(rStream) @@ -152,20 +153,171 @@ 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') +constexpr sal_uInt32 constSvgMagic = createMagic('s', 'v', 'g', '0'); +constexpr sal_uInt32 constWmfMagic = createMagic('w', 'm', 'f', '0'); +constexpr sal_uInt32 constEmfMagic = createMagic('e', 'm', 'f', '0'); +constexpr sal_uInt32 constPdfMagic = createMagic('p', 'd', 'f', '0'); + } // end anonymous namespace -void TypeSerializer::readGraphic(Graphic& /*rGraphic*/) {} +void TypeSerializer::readGraphic(Graphic& rGraphic) +{ + if (mrStream.GetError()) + return; + + const sal_uLong nInitialStreamPosition = mrStream.Tell(); + sal_uInt32 nType; + + // read Id + mrStream.ReadUInt32(nType); + + // if there is no more data, avoid further expensive + // reading which will create VDevs and other stuff, just to + // read nothing. CAUTION: Eof is only true AFTER reading another + // byte, a speciality of SvMemoryStream (!) + if (!mrStream.good()) + return; + + if (NATIVE_FORMAT_50 == nType) + { + Graphic aGraphic; + GfxLink aLink; + + // read compat info, destructor writes stuff into the header + { + VersionCompat aCompat(mrStream, StreamMode::READ); + } + + readGfxLink(aLink); + + if (!mrStream.GetError() && aLink.LoadNative(aGraphic)) + { + if (aLink.IsPrefMapModeValid()) + aGraphic.SetPrefMapMode(aLink.GetPrefMapMode()); + + if (aLink.IsPrefSizeValid()) + aGraphic.SetPrefSize(aLink.GetPrefSize()); + } + else + { + mrStream.Seek(nInitialStreamPosition); + mrStream.SetError(ERRCODE_IO_WRONGFORMAT); + } + rGraphic = aGraphic; + } + else + { + BitmapEx aBitmapEx; + const SvStreamEndian nOldFormat = mrStream.GetEndian(); + + mrStream.SeekRel(-4); + mrStream.SetEndian(SvStreamEndian::LITTLE); + ReadDIBBitmapEx(aBitmapEx, mrStream); + + if (!mrStream.GetError()) + { + sal_uInt32 nMagic1 = 0; + sal_uInt32 nMagic2 = 0; + sal_uInt64 nBeginPoisition = mrStream.Tell(); + + mrStream.ReadUInt32(nMagic1); + mrStream.ReadUInt32(nMagic2); + mrStream.Seek(nBeginPoisition); + + if (!mrStream.GetError()) + { + if (nMagic1 == 0x5344414e && nMagic2 == 0x494d4931) + { + Animation aAnimation; + ReadAnimation(mrStream, aAnimation); + + // #108077# manually set loaded BmpEx to Animation + // (which skips loading its BmpEx if already done) + aAnimation.SetBitmapEx(aBitmapEx); + rGraphic = Graphic(aAnimation); + } + else + { + rGraphic = Graphic(aBitmapEx); + } + } + else + { + mrStream.ResetError(); + } + } + else + { + Graphic aGraphic; + GDIMetaFile aMetaFile; + + mrStream.Seek(nInitialStreamPosition); + mrStream.ResetError(); + ReadGDIMetaFile(mrStream, aMetaFile); + + if (!mrStream.GetError()) + { + rGraphic = Graphic(aMetaFile); + } + else + { + ErrCode nOriginalError = mrStream.GetErrorCode(); + // try to stream in Svg defining data (length, byte array and evtl. path) + // See below (operator<<) for more information + sal_uInt32 nMagic; + mrStream.Seek(nInitialStreamPosition); + mrStream.ResetError(); + mrStream.ReadUInt32(nMagic); + + if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic + || constPdfMagic == nMagic) + { + sal_uInt32 nLength = 0; + mrStream.ReadUInt32(nLength); + + if (nLength) + { + VectorGraphicDataArray aData(nLength); + + mrStream.ReadBytes(aData.getArray(), nLength); + OUString aPath = mrStream.ReadUniOrByteString(mrStream.GetStreamCharSet()); + + if (!mrStream.GetError()) + { + VectorGraphicDataType aDataType(VectorGraphicDataType::Svg); + + switch (nMagic) + { + case constWmfMagic: + aDataType = VectorGraphicDataType::Wmf; + break; + case constEmfMagic: + aDataType = VectorGraphicDataType::Emf; + break; + case constPdfMagic: + aDataType = VectorGraphicDataType::Pdf; + break; + } + + auto aVectorGraphicDataPtr + = std::make_shared<VectorGraphicData>(aData, aPath, aDataType); + rGraphic = Graphic(aVectorGraphicDataPtr); + } + } + } + else + { + mrStream.SetError(nOriginalError); + } + + mrStream.Seek(nInitialStreamPosition); + } + } + mrStream.SetEndian(nOldFormat); + } +} void TypeSerializer::writeGraphic(const Graphic& rGraphic) { commit 81f4604e9a655a858887e8f5f143f78aa3afe1b7 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri May 1 17:30:22 2020 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri May 1 19:23:28 2020 +0200 SdrPdfImport: rename ImportText to InsertTextObject There are two ImportText methods, so rename one to something else to avoid confusion. Change-Id: I1ccc491fca47b2d72ba1f7bd5a75d325819ec041 diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 296d2b53f31b..7e4a3e6a5345 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -879,10 +879,10 @@ void ImpSdrPdfImport::ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTex mbFntDirty = true; } - ImportText(aRect.TopLeft(), aRect.GetSize(), sText); + InsertTextObject(aRect.TopLeft(), aRect.GetSize(), sText); } -void ImpSdrPdfImport::ImportText(const Point& rPos, const Size& rSize, const OUString& rStr) +void ImpSdrPdfImport::InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr) { // calc text box size, add 5% to make it fit safely diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index db5eabe3445d..d9d35fe0c80c 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -110,7 +110,7 @@ class ImpSdrPdfImport final void ImportImage(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); void ImportPath(FPDF_PAGEOBJECT pPageObject, int nPageObjectIndex); void ImportText(FPDF_PAGEOBJECT pPageObject, FPDF_TEXTPAGE pTextPage, int nPageObjectIndex); - void ImportText(const Point& rPos, const Size& rSize, const OUString& rStr); + void InsertTextObject(const Point& rPos, const Size& rSize, const OUString& rStr); void SetupPageScale(const double dPageWidth, const double dPageHeight); void SetAttributes(SdrObject* pObj, bool bForceTextAttr = false); commit 44b3fea7e3b0cdbe849f18038882b91f9111d59e Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri May 1 17:20:26 2020 +0200 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri May 1 17:20:26 2020 +0200 move unit conversions to UnitConversion, add convertPointToMm100 Change-Id: I3e5a4632e9809562885c1e0ec5c5262acec145d0 diff --git a/include/tools/UnitConversion.hxx b/include/tools/UnitConversion.hxx new file mode 100644 index 000000000000..8ad489dee590 --- /dev/null +++ b/include/tools/UnitConversion.hxx @@ -0,0 +1,25 @@ +/* -*- 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/. + * + */ + +#pragma once + +constexpr sal_Int64 convertTwipToMm100(sal_Int64 n) +{ + return (n >= 0) ? (n * 127 + 36) / 72 : (n * 127 - 36) / 72; +} + +constexpr sal_Int64 convertPointToMm100(sal_Int64 n) { return convertTwipToMm100(n * 20); } + +constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n) +{ + return (n >= 0) ? (n * 72 + 63) / 127 : (n * 72 - 63) / 127; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/mapunit.hxx b/include/tools/mapunit.hxx index 2209f4d35261..6112bc7ef461 100644 --- a/include/tools/mapunit.hxx +++ b/include/tools/mapunit.hxx @@ -21,6 +21,7 @@ #define INCLUDED_TOOLS_MAPUNIT_HXX #include <sal/types.h> +#include <tools/UnitConversion.hxx> enum class MapUnit { @@ -34,16 +35,6 @@ enum class MapUnit LASTENUMDUMMY // used as an error return }; -constexpr sal_Int64 convertTwipToMm100(sal_Int64 n) -{ - return (n >= 0)? (n*127+36)/72: (n*127-36)/72; -} - -constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n) -{ - return (n >= 0)? (n*72+63)/127: (n*72-63)/127; -} - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits