graphic: Rework swapping algorithm to take GfxLink into account
This reworks the Graphic swap algorithm to not swap to a file when GfxLink is available and leaves the compressed data in memory. With such a sheme, at swap-out we just remember the need specific properties of the Graphic, and delete the graphic content (Bitmap, Animation, VectorGraphic, Metafile). At swap-in use the GfxLink data to decompress and recreate the graphic content, then set the properties back as they were before (if needed). If a GfxLink is not available it swaps out to a file and back, but uses a simpler data format that is specific for swapping only. In the future this case can be removed, when we switch to automatic creation of GfxLink if that one is not present. For reworking of swapping it was also necessary to extensively add and extend the tests that check various swapping scenarios. Change-Id: I135a224f74aa48e6006f48dd2be74b8026614728 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107287 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
committed by
Tomaž Vajngerl
parent
3dabbb6a5e
commit
def31e135e
@@ -32,6 +32,11 @@ constexpr sal_uInt32 createMagic(char char1, char char2, char char3, char char4)
|
|||||||
| (static_cast<sal_uInt32>(char3) << 8) | (static_cast<sal_uInt32>(char4) << 0);
|
| (static_cast<sal_uInt32>(char3) << 8) | (static_cast<sal_uInt32>(char4) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
|
|
||||||
class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer
|
class VCL_DLLPUBLIC TypeSerializer : public tools::GenericTypeSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -47,6 +47,13 @@ class ImpSwapFile;
|
|||||||
class GraphicConversionParameters;
|
class GraphicConversionParameters;
|
||||||
class ImpGraphic;
|
class ImpGraphic;
|
||||||
|
|
||||||
|
enum class GraphicContentType : sal_Int32
|
||||||
|
{
|
||||||
|
Bitmap,
|
||||||
|
Animation,
|
||||||
|
Vector
|
||||||
|
};
|
||||||
|
|
||||||
class VCL_DLLPUBLIC ImpGraphic final
|
class VCL_DLLPUBLIC ImpGraphic final
|
||||||
{
|
{
|
||||||
friend class Graphic;
|
friend class Graphic;
|
||||||
@@ -115,7 +122,9 @@ private:
|
|||||||
return mpGraphicID->getIDString();
|
return mpGraphicID->getIDString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSwapInfo();
|
void createSwapInfo();
|
||||||
|
void restoreFromSwapInfo();
|
||||||
|
|
||||||
void ImplClearGraphics();
|
void ImplClearGraphics();
|
||||||
void ImplClear();
|
void ImplClear();
|
||||||
|
|
||||||
@@ -170,7 +179,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
// swapping methods
|
// swapping methods
|
||||||
bool swapInFromStream(SvStream& rStream);
|
bool swapInFromStream(SvStream& rStream);
|
||||||
void swapInGraphic(SvStream& rStream);
|
bool swapInGraphic(SvStream& rStream);
|
||||||
|
|
||||||
bool swapInContent(SvStream& rStream);
|
bool swapInContent(SvStream& rStream);
|
||||||
bool swapOutContent(SvStream& rStream);
|
bool swapOutContent(SvStream& rStream);
|
||||||
@@ -205,6 +214,7 @@ private:
|
|||||||
sal_Int32 getPageNumber() const;
|
sal_Int32 getPageNumber() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void resetChecksum() { mnChecksum = 0; }
|
||||||
bool swapIn();
|
bool swapIn();
|
||||||
bool swapOut();
|
bool swapOut();
|
||||||
bool isSwappedOut() const { return mbSwapOut; }
|
bool isSwappedOut() const { return mbSwapOut; }
|
||||||
|
@@ -50,23 +50,50 @@ private:
|
|||||||
void testUnloadedGraphicWmf();
|
void testUnloadedGraphicWmf();
|
||||||
void testUnloadedGraphicAlpha();
|
void testUnloadedGraphicAlpha();
|
||||||
void testUnloadedGraphicSizeUnit();
|
void testUnloadedGraphicSizeUnit();
|
||||||
void testSwapping();
|
|
||||||
void testSwappingVectorGraphic();
|
|
||||||
void testSwappingPageNumber();
|
|
||||||
void testWMFRoundtrip();
|
void testWMFRoundtrip();
|
||||||
void testEmfToWmfConversion();
|
void testEmfToWmfConversion();
|
||||||
|
|
||||||
|
void testSwappingGraphic_PNG_WithGfxLink();
|
||||||
|
void testSwappingGraphic_PNG_WithoutGfxLink();
|
||||||
|
void testSwappingGraphicProperties_PNG_WithGfxLink();
|
||||||
|
void testSwappingGraphicProperties_PNG_WithoutGfxLink();
|
||||||
|
|
||||||
|
void testSwappingVectorGraphic_SVG_WithGfxLink();
|
||||||
|
void testSwappingVectorGraphic_SVG_WithoutGfxLink();
|
||||||
|
void testSwappingGraphicProperties_SVG_WithGfxLink();
|
||||||
|
void testSwappingGraphicProperties_SVG_WithoutGfxLink();
|
||||||
|
|
||||||
|
void testSwappingVectorGraphic_PDF_WithGfxLink();
|
||||||
|
void testSwappingVectorGraphic_PDF_WithoutGfxLink();
|
||||||
|
|
||||||
|
void testSwappingAnimationGraphic_GIF_WithGfxLink();
|
||||||
|
void testSwappingAnimationGraphic_GIF_WithoutGfxLink();
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(GraphicTest);
|
CPPUNIT_TEST_SUITE(GraphicTest);
|
||||||
CPPUNIT_TEST(testUnloadedGraphic);
|
CPPUNIT_TEST(testUnloadedGraphic);
|
||||||
CPPUNIT_TEST(testUnloadedGraphicLoading);
|
CPPUNIT_TEST(testUnloadedGraphicLoading);
|
||||||
CPPUNIT_TEST(testUnloadedGraphicWmf);
|
CPPUNIT_TEST(testUnloadedGraphicWmf);
|
||||||
CPPUNIT_TEST(testUnloadedGraphicAlpha);
|
CPPUNIT_TEST(testUnloadedGraphicAlpha);
|
||||||
CPPUNIT_TEST(testUnloadedGraphicSizeUnit);
|
CPPUNIT_TEST(testUnloadedGraphicSizeUnit);
|
||||||
CPPUNIT_TEST(testSwapping);
|
|
||||||
CPPUNIT_TEST(testSwappingVectorGraphic);
|
|
||||||
CPPUNIT_TEST(testSwappingPageNumber);
|
|
||||||
CPPUNIT_TEST(testWMFRoundtrip);
|
CPPUNIT_TEST(testWMFRoundtrip);
|
||||||
CPPUNIT_TEST(testEmfToWmfConversion);
|
CPPUNIT_TEST(testEmfToWmfConversion);
|
||||||
|
|
||||||
|
CPPUNIT_TEST(testSwappingGraphic_PNG_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingGraphic_PNG_WithoutGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingGraphicProperties_PNG_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingGraphicProperties_PNG_WithoutGfxLink);
|
||||||
|
|
||||||
|
CPPUNIT_TEST(testSwappingVectorGraphic_SVG_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingVectorGraphic_SVG_WithoutGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingGraphicProperties_SVG_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingGraphicProperties_SVG_WithoutGfxLink);
|
||||||
|
|
||||||
|
CPPUNIT_TEST(testSwappingVectorGraphic_PDF_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingVectorGraphic_PDF_WithoutGfxLink);
|
||||||
|
|
||||||
|
CPPUNIT_TEST(testSwappingAnimationGraphic_GIF_WithGfxLink);
|
||||||
|
CPPUNIT_TEST(testSwappingAnimationGraphic_GIF_WithoutGfxLink);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -306,6 +333,33 @@ void GraphicTest::testUnloadedGraphicSizeUnit()
|
|||||||
CPPUNIT_ASSERT_EQUAL(Size(400, 363), aGraphic.GetPrefSize());
|
CPPUNIT_ASSERT_EQUAL(Size(400, 363), aGraphic.GetPrefSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testWMFRoundtrip()
|
||||||
|
{
|
||||||
|
// Load a WMF file.
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc("vcl/qa/cppunit/data/roundtrip.wmf");
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
sal_uInt64 nExpectedSize = aStream.TellEnd();
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
|
||||||
|
// Save as WMF.
|
||||||
|
utl::TempFile aTempFile;
|
||||||
|
aTempFile.EnableKillingFile();
|
||||||
|
sal_uInt16 nFormat = rGraphicFilter.GetExportFormatNumberForShortName(u"WMF");
|
||||||
|
SvStream& rOutStream = *aTempFile.GetStream(StreamMode::READWRITE);
|
||||||
|
rGraphicFilter.ExportGraphic(aGraphic, OUString(), rOutStream, nFormat);
|
||||||
|
|
||||||
|
// Check if we preserved the WMF data perfectly.
|
||||||
|
sal_uInt64 nActualSize = rOutStream.TellEnd();
|
||||||
|
|
||||||
|
// Without the accompanying fix in place, this test would have failed with:
|
||||||
|
// - Expected: 6475
|
||||||
|
// - Actual : 2826
|
||||||
|
// i.e. we lost some of the WMF data on roundtrip.
|
||||||
|
CPPUNIT_ASSERT_EQUAL(nExpectedSize, nActualSize);
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicTest::testEmfToWmfConversion()
|
void GraphicTest::testEmfToWmfConversion()
|
||||||
{
|
{
|
||||||
// Load EMF data.
|
// Load EMF data.
|
||||||
@@ -363,7 +417,7 @@ void GraphicTest::testEmfToWmfConversion()
|
|||||||
CPPUNIT_ASSERT_LESSEQUAL(4, nCommentCount);
|
CPPUNIT_ASSERT_LESSEQUAL(4, nCommentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicTest::testSwapping()
|
void GraphicTest::testSwappingGraphic_PNG_WithGfxLink()
|
||||||
{
|
{
|
||||||
// Prepare Graphic from a PNG image first
|
// Prepare Graphic from a PNG image first
|
||||||
Graphic aGraphic = makeUnloadedGraphic(u"png");
|
Graphic aGraphic = makeUnloadedGraphic(u"png");
|
||||||
@@ -377,10 +431,64 @@ void GraphicTest::testSwapping()
|
|||||||
|
|
||||||
BitmapChecksum aChecksumBeforeSwapping = aGraphic.GetChecksum();
|
BitmapChecksum aChecksumBeforeSwapping = aGraphic.GetChecksum();
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsGfxLink());
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uInt32(319), aGraphic.GetGfxLink().GetDataSize());
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(319), aGraphic.GetGfxLink().GetDataSize());
|
||||||
|
|
||||||
// We loaded the Graphic and made it available
|
// We loaded the Graphic and made it available
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
// Get the declared byte size of the graphic
|
||||||
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
|
|
||||||
|
// Check the swap file (shouldn't exist)
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// Swapping out
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Byte size doesn't change when we swapped out
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
|
||||||
|
// Check the swap file (still shouldn't exist)
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// Let's swap in
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(aChecksumBeforeSwapping, aGraphic.GetChecksum());
|
||||||
|
|
||||||
|
// Check the bitmap
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(120), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetSizePixel().Height());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingGraphic_PNG_WithoutGfxLink()
|
||||||
|
{
|
||||||
|
// Prepare Graphic from a PNG image first
|
||||||
|
|
||||||
|
// Make sure to construct the Graphic from BitmapEx, so that we
|
||||||
|
// don't have the GfxLink present.
|
||||||
|
Graphic aGraphic(makeUnloadedGraphic(u"png").GetBitmapEx());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(120), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
BitmapChecksum aChecksumBeforeSwapping = aGraphic.GetChecksum();
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsGfxLink());
|
||||||
|
|
||||||
|
// We loaded the Graphic and made it available
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
// Get the declared byte size of the graphic
|
// Get the declared byte size of the graphic
|
||||||
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
||||||
@@ -403,19 +511,21 @@ void GraphicTest::testSwapping()
|
|||||||
CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
|
CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
|
||||||
|
|
||||||
// Check size of the stream
|
// Check size of the stream
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uInt64(449), xStream->remainingSize());
|
CPPUNIT_ASSERT_EQUAL(sal_uInt64(36079), xStream->remainingSize());
|
||||||
|
|
||||||
std::vector<unsigned char> aHash = calculateHash(xStream);
|
std::vector<unsigned char> aHash = calculateHash(xStream);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("878281e583487b29ae09078e8040c01791c7649a"),
|
CPPUNIT_ASSERT_EQUAL(std::string("9347511e3b80dfdfaadf91a3bdef55a8ae85552b"),
|
||||||
toHexString(aHash));
|
toHexString(aHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's swap in
|
// SWAP IN
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// reset the checksum to make sure we don't get the cached value
|
||||||
|
aGraphic.ImplGetImpGraphic()->resetChecksum();
|
||||||
CPPUNIT_ASSERT_EQUAL(aChecksumBeforeSwapping, aGraphic.GetChecksum());
|
CPPUNIT_ASSERT_EQUAL(aChecksumBeforeSwapping, aGraphic.GetChecksum());
|
||||||
|
|
||||||
// File shouldn't be available anymore
|
// File shouldn't be available anymore
|
||||||
@@ -424,28 +534,192 @@ void GraphicTest::testSwapping()
|
|||||||
// Check the bitmap
|
// Check the bitmap
|
||||||
CPPUNIT_ASSERT_EQUAL(tools::Long(120), aGraphic.GetSizePixel().Width());
|
CPPUNIT_ASSERT_EQUAL(tools::Long(120), aGraphic.GetSizePixel().Width());
|
||||||
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetSizePixel().Height());
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetSizePixel().Height());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic));
|
|
||||||
CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic));
|
CPPUNIT_ASSERT_EQUAL(true, checkBitmap(aGraphic));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicTest::testSwappingVectorGraphic()
|
void GraphicTest::testSwappingGraphicProperties_PNG_WithGfxLink()
|
||||||
|
{
|
||||||
|
// Prepare Graphic from a PNG image
|
||||||
|
Graphic aGraphic = makeUnloadedGraphic(u"png");
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Origin URL
|
||||||
|
aGraphic.setOriginURL("Origin URL");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
//Set PrefMapMode
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::Map100thMM, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
aGraphic.SetPrefMapMode(MapMode(MapUnit::MapTwip));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
|
||||||
|
// Set the PrefSize
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(6000), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5000), aGraphic.GetPrefSize().Height());
|
||||||
|
aGraphic.SetPrefSize(Size(200, 100));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP OUT
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingGraphicProperties_PNG_WithoutGfxLink()
|
||||||
|
{
|
||||||
|
// Prepare Graphic from a PNG image
|
||||||
|
Graphic aGraphic(makeUnloadedGraphic(u"png").GetBitmapEx());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Origin URL
|
||||||
|
aGraphic.setOriginURL("Origin URL");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
//Set PrefMapMode
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::Map100thMM, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
aGraphic.SetPrefMapMode(MapMode(MapUnit::MapTwip));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
|
||||||
|
// Set the PrefSize
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(6000), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5000), aGraphic.GetPrefSize().Height());
|
||||||
|
aGraphic.SetPrefSize(Size(200, 100));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP OUT
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(MapUnit::MapTwip, aGraphic.GetPrefMapMode().GetMapUnit());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingVectorGraphic_SVG_WithGfxLink()
|
||||||
{
|
{
|
||||||
test::Directories aDirectories;
|
test::Directories aDirectories;
|
||||||
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
|
||||||
SvFileStream aStream(aURL, StreamMode::READ);
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
// Loaded into "prepared" state
|
||||||
|
|
||||||
|
// Check that the state is as expected
|
||||||
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
// Load the vector graphic
|
// Load the vector graphic
|
||||||
|
auto pVectorData = aGraphic.getVectorGraphicData();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(pVectorData));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), pVectorData->getVectorGraphicDataArrayLength());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsGfxLink());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), aGraphic.GetGfxLink().GetDataSize());
|
||||||
|
|
||||||
|
// Remember checksum so we can compare after swapping back in again
|
||||||
|
BitmapChecksum aBitmapChecksumBeforeSwapping = aGraphic.GetBitmapEx().GetChecksum();
|
||||||
|
|
||||||
|
// Check we are not swapped out yet
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Get the declared byte size of the graphic
|
||||||
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize);
|
||||||
|
|
||||||
|
// Make sure we don't have a file
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// SWAP OUT the Graphic and make sure it's not available currently
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// We use GfxLink so no swap file in this case
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// Byte size doesn't change when we swapped out
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Compare that the checksum of the bitmap is still the same
|
||||||
|
CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, aGraphic.GetBitmapEx().GetChecksum());
|
||||||
|
|
||||||
|
// Byte size shouldn't change
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingVectorGraphic_SVG_WithoutGfxLink()
|
||||||
|
{
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
|
||||||
|
Graphic aInputGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223),
|
||||||
|
aInputGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
||||||
|
|
||||||
|
// Create graphic
|
||||||
|
Graphic aGraphic(aInputGraphic.getVectorGraphicData());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223),
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223),
|
||||||
aGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
aGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), aGraphic.GetGfxLink().GetDataSize());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsGfxLink());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
|
||||||
|
|
||||||
BitmapChecksum aBitmapChecksumBeforeSwapping = aGraphic.GetBitmapEx().GetChecksum();
|
BitmapChecksum aBitmapChecksumBeforeSwapping = aGraphic.GetBitmapEx().GetChecksum();
|
||||||
|
|
||||||
@@ -454,6 +728,7 @@ void GraphicTest::testSwappingVectorGraphic()
|
|||||||
// Get the declared byte size of the graphic
|
// Get the declared byte size of the graphic
|
||||||
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize);
|
CPPUNIT_ASSERT_EQUAL(sal_uLong(223), rByteSize);
|
||||||
|
|
||||||
OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
||||||
CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
|
CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
|
||||||
|
|
||||||
@@ -468,17 +743,19 @@ void GraphicTest::testSwappingVectorGraphic()
|
|||||||
|
|
||||||
// Let's check the swap file
|
// Let's check the swap file
|
||||||
rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, rSwapFileURL.isEmpty());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
CPPUNIT_ASSERT_EQUAL(true, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
||||||
|
|
||||||
{ // Check the swap file content
|
{
|
||||||
|
// Check the swap file content
|
||||||
std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
|
std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
|
||||||
CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
|
CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
|
||||||
|
|
||||||
// Check size of the stream
|
// Check size of the stream
|
||||||
CPPUNIT_ASSERT_EQUAL(sal_uInt64(353), xStream->remainingSize());
|
CPPUNIT_ASSERT_EQUAL(sal_uInt64(249), xStream->remainingSize());
|
||||||
|
|
||||||
std::vector<unsigned char> aHash = calculateHash(xStream);
|
std::vector<unsigned char> aHash = calculateHash(xStream);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("6ae83fc9c06ca253ada0b156d6e4700a4a028c34"),
|
CPPUNIT_ASSERT_EQUAL(std::string("322da9ea0683f03ce35cf8a71e59b686b9be28e8"),
|
||||||
toHexString(aHash));
|
toHexString(aHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,15 +763,146 @@ void GraphicTest::testSwappingVectorGraphic()
|
|||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Check the Graphic
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
||||||
|
|
||||||
|
sal_uInt32 nVectorByteSize = aGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223), nVectorByteSize);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsGfxLink());
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, aGraphic.GetBitmapEx().GetChecksum());
|
CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, aGraphic.GetBitmapEx().GetChecksum());
|
||||||
|
|
||||||
// File shouldn't be available anymore
|
// File shouldn't be available anymore
|
||||||
CPPUNIT_ASSERT_EQUAL(false, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
CPPUNIT_ASSERT_EQUAL(false, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicTest::testSwappingPageNumber()
|
void GraphicTest::testSwappingGraphicProperties_SVG_WithGfxLink()
|
||||||
|
{
|
||||||
|
// We check that Graphic properties like MapMode, PrefSize are properly
|
||||||
|
// restored through a swap cycle
|
||||||
|
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
// Loaded into "prepared" state
|
||||||
|
|
||||||
|
// Load the vector graphic
|
||||||
|
auto pVectorData = aGraphic.getVectorGraphicData();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(pVectorData));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Origin URL
|
||||||
|
aGraphic.setOriginURL("Origin URL");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
// Check size in pixels
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
// Set and check the PrefSize
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Height());
|
||||||
|
aGraphic.SetPrefSize(Size(200, 100));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP OUT the Graphic and make sure it's not available currently
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Check properties
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingGraphicProperties_SVG_WithoutGfxLink()
|
||||||
|
{
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "SimpleExample.svg";
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
|
||||||
|
Graphic aInputGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(223),
|
||||||
|
aInputGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
||||||
|
|
||||||
|
// Create graphic
|
||||||
|
Graphic aGraphic(aInputGraphic.getVectorGraphicData());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsGfxLink());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Origin URL
|
||||||
|
aGraphic.setOriginURL("Origin URL");
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
// Check size in pixels
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
// Set and check the PrefSize
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(1349), aGraphic.GetPrefSize().Height());
|
||||||
|
aGraphic.SetPrefSize(Size(200, 100));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
|
||||||
|
// SWAP OUT the Graphic and make sure it's not available currently
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(OUString("Origin URL"), aGraphic.getOriginURL());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(200), aGraphic.GetPrefSize().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(100), aGraphic.GetPrefSize().Height());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(51), aGraphic.GetSizePixel().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingVectorGraphic_PDF_WithGfxLink()
|
||||||
{
|
{
|
||||||
test::Directories aDirectories;
|
test::Directories aDirectories;
|
||||||
OUString aURL = aDirectories.getURLFromSrc(PDFEXPORT_DATA_DIRECTORY) + "SimpleMultiPagePDF.pdf";
|
OUString aURL = aDirectories.getURLFromSrc(PDFEXPORT_DATA_DIRECTORY) + "SimpleMultiPagePDF.pdf";
|
||||||
@@ -507,6 +915,7 @@ void GraphicTest::testSwappingPageNumber()
|
|||||||
|
|
||||||
// Load the vector graphic
|
// Load the vector graphic
|
||||||
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
||||||
|
|
||||||
// Set the page index
|
// Set the page index
|
||||||
aGraphic.getVectorGraphicData()->setPageIndex(1);
|
aGraphic.getVectorGraphicData()->setPageIndex(1);
|
||||||
|
|
||||||
@@ -519,12 +928,12 @@ void GraphicTest::testSwappingPageNumber()
|
|||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
// Swapping out
|
// SWAP OUT
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
// Let's swap in
|
// SWAP IN
|
||||||
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
@@ -533,31 +942,176 @@ void GraphicTest::testSwappingPageNumber()
|
|||||||
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getVectorGraphicData()->getPageIndex());
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getVectorGraphicData()->getPageIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicTest::testWMFRoundtrip()
|
void GraphicTest::testSwappingVectorGraphic_PDF_WithoutGfxLink()
|
||||||
{
|
{
|
||||||
// Load a WMF file.
|
|
||||||
test::Directories aDirectories;
|
test::Directories aDirectories;
|
||||||
OUString aURL = aDirectories.getURLFromSrc("vcl/qa/cppunit/data/roundtrip.wmf");
|
OUString aURL = aDirectories.getURLFromSrc(PDFEXPORT_DATA_DIRECTORY) + "SimpleMultiPagePDF.pdf";
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
Graphic aInputGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
|
||||||
|
// Create graphic
|
||||||
|
Graphic aGraphic(aInputGraphic.getVectorGraphicData());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(aGraphic.getVectorGraphicData()));
|
||||||
|
|
||||||
|
// Set the page index
|
||||||
|
aGraphic.getVectorGraphicData()->setPageIndex(1);
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf,
|
||||||
|
aGraphic.getVectorGraphicData()->getVectorGraphicDataType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(17693),
|
||||||
|
aGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getVectorGraphicData()->getPageIndex());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// SWAP OUT
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getVectorGraphicData()->getPageIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingAnimationGraphic_GIF_WithGfxLink()
|
||||||
|
{
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "123_Numbers.gif";
|
||||||
SvFileStream aStream(aURL, StreamMode::READ);
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
sal_uInt64 nExpectedSize = aStream.TellEnd();
|
|
||||||
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
// Loaded into "prepared" state
|
||||||
|
|
||||||
// Save as WMF.
|
// Check that the state is as expected
|
||||||
utl::TempFile aTempFile;
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
aTempFile.EnableKillingFile();
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
sal_uInt16 nFormat = rGraphicFilter.GetExportFormatNumberForShortName(u"WMF");
|
|
||||||
SvStream& rOutStream = *aTempFile.GetStream(StreamMode::READWRITE);
|
|
||||||
rGraphicFilter.ExportGraphic(aGraphic, OUString(), rOutStream, nFormat);
|
|
||||||
|
|
||||||
// Check if we preserved the WMF data perfectly.
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
sal_uInt64 nActualSize = rOutStream.TellEnd();
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
|
||||||
// Without the accompanying fix in place, this test would have failed with:
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsGfxLink());
|
||||||
// - Expected: 6475
|
|
||||||
// - Actual : 2826
|
CPPUNIT_ASSERT_EQUAL(tools::Long(124), aGraphic.GetSizePixel().Width());
|
||||||
// i.e. we lost some of the WMF data on roundtrip.
|
CPPUNIT_ASSERT_EQUAL(tools::Long(146), aGraphic.GetSizePixel().Height());
|
||||||
CPPUNIT_ASSERT_EQUAL(nExpectedSize, nActualSize);
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt32(1515), aGraphic.GetGfxLink().GetDataSize());
|
||||||
|
|
||||||
|
// Remember checksum so we can compare after swapping back in again
|
||||||
|
BitmapChecksum aBitmapChecksumBeforeSwapping = aGraphic.GetBitmapEx().GetChecksum();
|
||||||
|
|
||||||
|
// Check we are not swapped out yet
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Get the declared byte size of the graphic
|
||||||
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uLong(50373), rByteSize);
|
||||||
|
|
||||||
|
// Make sure we don't have a file
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// SWAP OUT the Graphic and make sure it's not available currently
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// We use GfxLink so no swap file in this case
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->getSwapFileURL().isEmpty());
|
||||||
|
|
||||||
|
// Byte size doesn't change when we swapped out
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Compare that the checksum of the bitmap is still the same
|
||||||
|
CPPUNIT_ASSERT_EQUAL(aBitmapChecksumBeforeSwapping, aGraphic.GetBitmapEx().GetChecksum());
|
||||||
|
|
||||||
|
// Byte size shouldn't change
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicTest::testSwappingAnimationGraphic_GIF_WithoutGfxLink()
|
||||||
|
{
|
||||||
|
test::Directories aDirectories;
|
||||||
|
OUString aURL = aDirectories.getURLFromSrc(DATA_DIRECTORY) + "123_Numbers.gif";
|
||||||
|
SvFileStream aStream(aURL, StreamMode::READ);
|
||||||
|
GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
|
||||||
|
Graphic aInputGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
|
||||||
|
Graphic aGraphic(aInputGraphic.GetAnimation());
|
||||||
|
|
||||||
|
// Check animation graphic
|
||||||
|
CPPUNIT_ASSERT_EQUAL(GraphicType::Bitmap, aGraphic.GetType());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsAnimated());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(124), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(146), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsGfxLink());
|
||||||
|
|
||||||
|
// We loaded the Graphic and made it available
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// Get the declared byte size of the graphic
|
||||||
|
sal_uLong rByteSize = aGraphic.GetSizeBytes();
|
||||||
|
OUString rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, rSwapFileURL.isEmpty());
|
||||||
|
|
||||||
|
// SWAP OUT
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->swapOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
|
||||||
|
// Byte size doesn't change when we swapped out
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
|
|
||||||
|
// Let's check the swap file
|
||||||
|
rSwapFileURL = aGraphic.ImplGetImpGraphic()->getSwapFileURL();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check the swap file content
|
||||||
|
std::unique_ptr<SvStream> xStream = createStream(rSwapFileURL);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, bool(xStream));
|
||||||
|
|
||||||
|
// Check size of the stream
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sal_uInt64(15183), xStream->remainingSize());
|
||||||
|
|
||||||
|
std::vector<unsigned char> aHash = calculateHash(xStream);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("deb13fdf0ffa0b58ce92fff0a6ca9e98c5d26ed9"),
|
||||||
|
toHexString(aHash));
|
||||||
|
}
|
||||||
|
|
||||||
|
// SWAP IN
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.makeAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, aGraphic.ImplGetImpGraphic()->isSwappedOut());
|
||||||
|
|
||||||
|
// File shouldn't be available anymore
|
||||||
|
CPPUNIT_ASSERT_EQUAL(false, comphelper::DirectoryHelper::fileExists(rSwapFileURL));
|
||||||
|
|
||||||
|
// Check the bitmap
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(124), aGraphic.GetSizePixel().Width());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(tools::Long(146), aGraphic.GetSizePixel().Height());
|
||||||
|
|
||||||
|
// Byte size is still the same
|
||||||
|
CPPUNIT_ASSERT_EQUAL(rByteSize, aGraphic.GetSizeBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -160,11 +160,6 @@ namespace
|
|||||||
{
|
{
|
||||||
#define NATIVE_FORMAT_50 COMPAT_FORMAT('N', 'A', 'T', '5')
|
#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
|
} // end anonymous namespace
|
||||||
|
|
||||||
void TypeSerializer::readGraphic(Graphic& rGraphic)
|
void TypeSerializer::readGraphic(Graphic& rGraphic)
|
||||||
|
@@ -50,23 +50,9 @@
|
|||||||
#define GRAPHIC_MTFTOBMP_MAXEXT 2048
|
#define GRAPHIC_MTFTOBMP_MAXEXT 2048
|
||||||
#define GRAPHIC_STREAMBUFSIZE 8192UL
|
#define GRAPHIC_STREAMBUFSIZE 8192UL
|
||||||
|
|
||||||
#define SYS_WINMETAFILE 0x00000003L
|
#define SWAP_FORMAT_ID COMPAT_FORMAT( 'S', 'W', 'A', 'P' )
|
||||||
#define SYS_WNTMETAFILE 0x00000004L
|
|
||||||
#define SYS_OS2METAFILE 0x00000005L
|
|
||||||
#define SYS_MACMETAFILE 0x00000006L
|
|
||||||
|
|
||||||
#define GRAPHIC_FORMAT_50 COMPAT_FORMAT( 'G', 'R', 'F', '5' )
|
|
||||||
#define NATIVE_FORMAT_50 COMPAT_FORMAT( 'N', 'A', 'T', '5' )
|
#define NATIVE_FORMAT_50 COMPAT_FORMAT( 'N', 'A', 'T', '5' )
|
||||||
|
|
||||||
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'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace com::sun::star;
|
using namespace com::sun::star;
|
||||||
|
|
||||||
class ImpSwapFile : public vcl::SwapFile
|
class ImpSwapFile : public vcl::SwapFile
|
||||||
@@ -348,6 +334,7 @@ void ImpGraphic::createSwapInfo()
|
|||||||
if (isSwappedOut())
|
if (isSwappedOut())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
maSwapInfo.maSizePixel = ImplGetSizePixel();
|
||||||
maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
|
maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
|
||||||
maSwapInfo.maPrefSize = ImplGetPrefSize();
|
maSwapInfo.maPrefSize = ImplGetPrefSize();
|
||||||
maSwapInfo.mbIsAnimated = ImplIsAnimated();
|
maSwapInfo.mbIsAnimated = ImplIsAnimated();
|
||||||
@@ -363,7 +350,6 @@ void ImpGraphic::ImplClearGraphics()
|
|||||||
maBitmapEx.Clear();
|
maBitmapEx.Clear();
|
||||||
maMetaFile.Clear();
|
maMetaFile.Clear();
|
||||||
mpAnimation.reset();
|
mpAnimation.reset();
|
||||||
mpGfxLink.reset();
|
|
||||||
maVectorGraphicData.reset();
|
maVectorGraphicData.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,107 +1107,32 @@ bool ImpGraphic::swapInContent(SvStream& rStream)
|
|||||||
{
|
{
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
|
|
||||||
ensureAvailable();
|
|
||||||
|
|
||||||
MapMode aMapMode;
|
|
||||||
Size aSize;
|
|
||||||
sal_uInt32 nId;
|
sal_uInt32 nId;
|
||||||
sal_Int32 nType;
|
sal_Int32 nType;
|
||||||
sal_Int32 nPageIndex = -1;
|
sal_Int32 nLength;
|
||||||
const SvStreamEndian nOldFormat = rStream.GetEndian();
|
|
||||||
|
|
||||||
rStream.SetEndian(SvStreamEndian::LITTLE);
|
|
||||||
rStream.ReadUInt32(nId);
|
rStream.ReadUInt32(nId);
|
||||||
|
|
||||||
// check version
|
// check version
|
||||||
if (GRAPHIC_FORMAT_50 != nId)
|
if (SWAP_FORMAT_ID != nId)
|
||||||
|
{
|
||||||
|
SAL_WARN("vcl", "Incompatible swap file!");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
// read new style header
|
|
||||||
VersionCompat aCompat(rStream, StreamMode::READ);
|
|
||||||
|
|
||||||
rStream.ReadInt32(nType);
|
rStream.ReadInt32(nType);
|
||||||
sal_Int32 nLen;
|
rStream.ReadInt32(nLength);
|
||||||
rStream.ReadInt32(nLen);
|
|
||||||
TypeSerializer aSerializer(rStream);
|
|
||||||
aSerializer.readSize(aSize);
|
|
||||||
ReadMapMode(rStream, aMapMode);
|
|
||||||
|
|
||||||
if (aCompat.GetVersion() >= 2)
|
|
||||||
{
|
|
||||||
rStream.ReadInt32(nPageIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
meType = static_cast<GraphicType>(nType);
|
meType = static_cast<GraphicType>(nType);
|
||||||
|
|
||||||
if( meType != GraphicType::NONE )
|
if (meType == GraphicType::NONE || meType == GraphicType::Default)
|
||||||
{
|
{
|
||||||
if( meType == GraphicType::Bitmap )
|
return true;
|
||||||
{
|
|
||||||
if(maVectorGraphicData && maBitmapEx.IsEmpty())
|
|
||||||
{
|
|
||||||
// use maBitmapEx as local buffer for rendered svg
|
|
||||||
maBitmapEx = getVectorGraphicReplacement();
|
|
||||||
}
|
|
||||||
|
|
||||||
maBitmapEx.SetSizePixel(aSize);
|
|
||||||
|
|
||||||
if( aMapMode != MapMode() )
|
|
||||||
{
|
|
||||||
maBitmapEx.SetPrefMapMode( aMapMode );
|
|
||||||
maBitmapEx.SetPrefSize( aSize );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maMetaFile.SetPrefMapMode( aMapMode );
|
|
||||||
maMetaFile.SetPrefSize( aSize );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( meType == GraphicType::Bitmap || meType == GraphicType::GdiMetafile )
|
|
||||||
{
|
|
||||||
swapInGraphic(rStream);
|
|
||||||
bRet = rStream.GetError() == ERRCODE_NONE;
|
|
||||||
}
|
|
||||||
else if( sal::static_int_cast<sal_uLong>(meType) >= SYS_WINMETAFILE
|
|
||||||
&& sal::static_int_cast<sal_uLong>(meType) <= SYS_MACMETAFILE )
|
|
||||||
{
|
|
||||||
Graphic aSysGraphic;
|
|
||||||
ConvertDataFormat nCvtType;
|
|
||||||
|
|
||||||
switch( sal::static_int_cast<sal_uLong>(meType) )
|
|
||||||
{
|
|
||||||
case SYS_WINMETAFILE:
|
|
||||||
case SYS_WNTMETAFILE: nCvtType = ConvertDataFormat::WMF; break;
|
|
||||||
case SYS_OS2METAFILE: nCvtType = ConvertDataFormat::MET; break;
|
|
||||||
case SYS_MACMETAFILE: nCvtType = ConvertDataFormat::PCT; break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
nCvtType = ConvertDataFormat::Unknown;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( nType && GraphicConverter::Import(rStream, aSysGraphic, nCvtType) == ERRCODE_NONE )
|
|
||||||
{
|
|
||||||
*this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
|
|
||||||
bRet = rStream.GetError() == ERRCODE_NONE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
meType = GraphicType::Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bRet)
|
|
||||||
{
|
|
||||||
ImplSetPrefMapMode( aMapMode );
|
|
||||||
ImplSetPrefSize( aSize );
|
|
||||||
if (maVectorGraphicData)
|
|
||||||
maVectorGraphicData->setPageIndex(nPageIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bRet = true;
|
{
|
||||||
|
bRet = swapInGraphic(rStream);
|
||||||
rStream.SetEndian(nOldFormat);
|
}
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
@@ -1239,149 +1150,111 @@ bool ImpGraphic::swapOutGraphic(SvStream& rStream)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rStream.GetVersion() >= SOFFICE_FILEFORMAT_50 &&
|
switch (meType)
|
||||||
rStream.GetCompressMode() & SvStreamCompressFlags::NATIVE &&
|
|
||||||
mpGfxLink && mpGfxLink->IsNative())
|
|
||||||
{
|
{
|
||||||
// native format
|
case GraphicType::GdiMetafile:
|
||||||
rStream.WriteUInt32(NATIVE_FORMAT_50);
|
|
||||||
|
|
||||||
// write compat info, destructor writes stuff into the header
|
|
||||||
{
|
{
|
||||||
VersionCompat aCompat(rStream, StreamMode::WRITE, 1);
|
WriteGDIMetaFile(rStream, maMetaFile);
|
||||||
}
|
}
|
||||||
mpGfxLink->SetPrefMapMode(ImplGetPrefMapMode());
|
break;
|
||||||
mpGfxLink->SetPrefSize(ImplGetPrefSize());
|
|
||||||
TypeSerializer aSerializer(rStream);
|
|
||||||
aSerializer.writeGfxLink(*mpGfxLink);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ImplGetType())
|
|
||||||
{
|
|
||||||
case GraphicType::NONE:
|
|
||||||
case GraphicType::Default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GraphicType::Bitmap:
|
case GraphicType::Bitmap:
|
||||||
|
{
|
||||||
|
if (maVectorGraphicData)
|
||||||
{
|
{
|
||||||
if (getVectorGraphicData())
|
rStream.WriteInt32(sal_Int32(GraphicContentType::Vector));
|
||||||
|
// 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 (maVectorGraphicData->getVectorGraphicDataType())
|
||||||
{
|
{
|
||||||
// stream out Vector Graphic defining data (length, byte array and evtl. path)
|
case VectorGraphicDataType::Wmf:
|
||||||
// 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 (getVectorGraphicData()->getVectorGraphicDataType())
|
|
||||||
{
|
{
|
||||||
case VectorGraphicDataType::Wmf:
|
rStream.WriteUInt32(constWmfMagic);
|
||||||
{
|
break;
|
||||||
rStream.WriteUInt32(constWmfMagic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VectorGraphicDataType::Emf:
|
|
||||||
{
|
|
||||||
rStream.WriteUInt32(constEmfMagic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VectorGraphicDataType::Svg:
|
|
||||||
{
|
|
||||||
rStream.WriteUInt32(constSvgMagic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VectorGraphicDataType::Pdf:
|
|
||||||
{
|
|
||||||
rStream.WriteUInt32(constPdfMagic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
case VectorGraphicDataType::Emf:
|
||||||
|
{
|
||||||
|
rStream.WriteUInt32(constEmfMagic);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VectorGraphicDataType::Svg:
|
||||||
|
{
|
||||||
|
rStream.WriteUInt32(constSvgMagic);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VectorGraphicDataType::Pdf:
|
||||||
|
{
|
||||||
|
rStream.WriteUInt32(constPdfMagic);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rStream.WriteUInt32(getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
rStream.WriteUInt32(maVectorGraphicData->getVectorGraphicDataArrayLength());
|
||||||
rStream.WriteBytes(
|
|
||||||
getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
|
rStream.WriteBytes(
|
||||||
getVectorGraphicData()->getVectorGraphicDataArrayLength());
|
maVectorGraphicData->getVectorGraphicDataArray().getConstArray(),
|
||||||
rStream.WriteUniOrByteString(getVectorGraphicData()->getPath(), rStream.GetStreamCharSet());
|
maVectorGraphicData->getVectorGraphicDataArrayLength());
|
||||||
}
|
|
||||||
else if (ImplIsAnimated())
|
rStream.WriteUniOrByteString(maVectorGraphicData->getPath(), rStream.GetStreamCharSet());
|
||||||
{
|
|
||||||
WriteAnimation(rStream, *mpAnimation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteDIBBitmapEx(maBitmapEx, rStream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
else if (ImplIsAnimated())
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
{
|
||||||
if (ImplIsSupportedGraphic())
|
rStream.WriteInt32(sal_Int32(GraphicContentType::Animation));
|
||||||
WriteGDIMetaFile(rStream, maMetaFile);
|
WriteAnimation(rStream, *mpAnimation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rStream.WriteInt32(sal_Int32(GraphicContentType::Bitmap));
|
||||||
|
WriteDIBBitmapEx(maBitmapEx, rStream);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GraphicType::NONE:
|
||||||
|
case GraphicType::Default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImpGraphic::swapOutContent(SvStream& rOStm)
|
bool ImpGraphic::swapOutContent(SvStream& rStream)
|
||||||
{
|
{
|
||||||
ensureAvailable();
|
ensureAvailable();
|
||||||
|
|
||||||
|
bool bRet = false;
|
||||||
|
|
||||||
if (meType == GraphicType::NONE || meType == GraphicType::Default || isSwappedOut())
|
if (meType == GraphicType::NONE || meType == GraphicType::Default || isSwappedOut())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const SvStreamEndian nOldFormat = rOStm.GetEndian();
|
|
||||||
|
|
||||||
const MapMode aMapMode = ImplGetPrefMapMode();
|
|
||||||
const Size aSize = ImplGetPrefSize();
|
|
||||||
sal_uLong nDataFieldPos;
|
sal_uLong nDataFieldPos;
|
||||||
|
|
||||||
rOStm.SetEndian(SvStreamEndian::LITTLE);
|
// Write te SWAP ID
|
||||||
|
rStream.WriteUInt32(SWAP_FORMAT_ID);
|
||||||
|
|
||||||
// write ID for new format (5.0)
|
rStream.WriteInt32(static_cast<sal_Int32>(meType));
|
||||||
rOStm.WriteUInt32(GRAPHIC_FORMAT_50);
|
|
||||||
|
|
||||||
// write new style header
|
// data size is updated later
|
||||||
{
|
nDataFieldPos = rStream.Tell();
|
||||||
VersionCompat aCompat(rOStm, StreamMode::WRITE, 2);
|
rStream.WriteInt32(0);
|
||||||
|
|
||||||
rOStm.WriteInt32(static_cast<sal_Int32>(meType));
|
|
||||||
|
|
||||||
// data size is updated later
|
|
||||||
nDataFieldPos = rOStm.Tell();
|
|
||||||
rOStm.WriteInt32(0);
|
|
||||||
|
|
||||||
TypeSerializer aSerializer(rOStm);
|
|
||||||
aSerializer.writeSize(aSize);
|
|
||||||
|
|
||||||
WriteMapMode(rOStm, aMapMode);
|
|
||||||
|
|
||||||
// Version 2
|
|
||||||
rOStm.WriteInt32(getPageNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bRet = false;
|
|
||||||
|
|
||||||
// write data block
|
// write data block
|
||||||
if (!rOStm.GetError())
|
const sal_uLong nDataStart = rStream.Tell();
|
||||||
|
|
||||||
|
swapOutGraphic(rStream);
|
||||||
|
|
||||||
|
if (!rStream.GetError())
|
||||||
{
|
{
|
||||||
const sal_uLong nDataStart = rOStm.Tell();
|
// Write the written length th the header
|
||||||
|
const sal_uLong nCurrentPosition = rStream.Tell();
|
||||||
if (ImplIsSupportedGraphic())
|
rStream.Seek(nDataFieldPos);
|
||||||
swapOutGraphic(rOStm);
|
rStream.WriteInt32(nCurrentPosition - nDataStart);
|
||||||
|
rStream.Seek(nCurrentPosition);
|
||||||
if( !rOStm.GetError() )
|
bRet = true;
|
||||||
{
|
|
||||||
const sal_uLong nStmPos2 = rOStm.Tell();
|
|
||||||
rOStm.Seek( nDataFieldPos );
|
|
||||||
rOStm.WriteInt32( nStmPos2 - nDataStart );
|
|
||||||
rOStm.Seek( nStmPos2 );
|
|
||||||
bRet = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rOStm.SetEndian(nOldFormat);
|
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1390,46 +1263,67 @@ bool ImpGraphic::swapOut()
|
|||||||
if (isSwappedOut())
|
if (isSwappedOut())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Create a temp filename for the swap file
|
|
||||||
utl::TempFile aTempFile;
|
|
||||||
const INetURLObject aTempFileURL(aTempFile.GetURL());
|
|
||||||
|
|
||||||
// Create a swap file
|
|
||||||
auto pSwapFile = o3tl::make_shared<ImpSwapFile>(aTempFileURL, getOriginURL());
|
|
||||||
|
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
// Open a stream to write the swap file to
|
// We have GfxLink so we have the source available
|
||||||
|
if (mpGfxLink && mpGfxLink->IsNative())
|
||||||
{
|
{
|
||||||
std::unique_ptr<SvStream> xOutputStream = pSwapFile->openOutputStream();
|
|
||||||
|
|
||||||
if (!xOutputStream)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Write to stream
|
|
||||||
xOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
|
|
||||||
xOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
|
|
||||||
xOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
|
|
||||||
|
|
||||||
if (!xOutputStream->GetError() && swapOutContent(*xOutputStream))
|
|
||||||
{
|
|
||||||
xOutputStream->Flush();
|
|
||||||
bResult = !xOutputStream->GetError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if writing was successful
|
|
||||||
if (bResult)
|
|
||||||
{
|
|
||||||
// We have swapped out, so can clean memory and prepare swap info
|
|
||||||
createSwapInfo();
|
createSwapInfo();
|
||||||
|
|
||||||
ImplClearGraphics();
|
ImplClearGraphics();
|
||||||
|
|
||||||
mpSwapFile = std::move(pSwapFile);
|
// reset the swap file
|
||||||
|
mpSwapFile.reset();
|
||||||
|
|
||||||
|
// mark as swapped out
|
||||||
mbSwapOut = true;
|
mbSwapOut = true;
|
||||||
|
|
||||||
// Signal to manager that we have swapped out
|
// Signal to manager that we have swapped out
|
||||||
vcl::graphic::Manager::get().swappedOut(this);
|
vcl::graphic::Manager::get().swappedOut(this);
|
||||||
|
|
||||||
|
bResult = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a temp filename for the swap file
|
||||||
|
utl::TempFile aTempFile;
|
||||||
|
const INetURLObject aTempFileURL(aTempFile.GetURL());
|
||||||
|
|
||||||
|
// Create a swap file
|
||||||
|
auto pSwapFile = o3tl::make_shared<ImpSwapFile>(aTempFileURL, getOriginURL());
|
||||||
|
|
||||||
|
// Open a stream to write the swap file to
|
||||||
|
{
|
||||||
|
std::unique_ptr<SvStream> xOutputStream = pSwapFile->openOutputStream();
|
||||||
|
|
||||||
|
if (!xOutputStream)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Write to stream
|
||||||
|
xOutputStream->SetVersion(SOFFICE_FILEFORMAT_50);
|
||||||
|
xOutputStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
|
||||||
|
xOutputStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
|
||||||
|
|
||||||
|
if (!xOutputStream->GetError() && swapOutContent(*xOutputStream))
|
||||||
|
{
|
||||||
|
xOutputStream->Flush();
|
||||||
|
bResult = !xOutputStream->GetError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if writing was successful
|
||||||
|
if (bResult)
|
||||||
|
{
|
||||||
|
// We have swapped out, so can clean memory and prepare swap info
|
||||||
|
createSwapInfo();
|
||||||
|
ImplClearGraphics();
|
||||||
|
|
||||||
|
mpSwapFile = std::move(pSwapFile);
|
||||||
|
mbSwapOut = true;
|
||||||
|
|
||||||
|
// Signal to manager that we have swapped out
|
||||||
|
vcl::graphic::Manager::get().swappedOut(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bResult;
|
return bResult;
|
||||||
@@ -1439,11 +1333,13 @@ bool ImpGraphic::ensureAvailable() const
|
|||||||
{
|
{
|
||||||
auto pThis = const_cast<ImpGraphic*>(this);
|
auto pThis = const_cast<ImpGraphic*>(this);
|
||||||
|
|
||||||
|
bool bResult = true;
|
||||||
|
|
||||||
if (isSwappedOut())
|
if (isSwappedOut())
|
||||||
return pThis->swapIn();
|
bResult = pThis->swapIn();
|
||||||
|
|
||||||
pThis->maLastUsed = std::chrono::high_resolution_clock::now();
|
pThis->maLastUsed = std::chrono::high_resolution_clock::now();
|
||||||
return true;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImpGraphic::loadPrepared()
|
bool ImpGraphic::loadPrepared()
|
||||||
@@ -1470,30 +1366,95 @@ void ImpGraphic::updateFromLoadedGraphic(ImpGraphic* graphic)
|
|||||||
maGraphicExternalLink = aLink;
|
maGraphicExternalLink = aLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImpGraphic::restoreFromSwapInfo()
|
||||||
|
{
|
||||||
|
// Reset the parameters
|
||||||
|
if (!maBitmapEx.IsEmpty())
|
||||||
|
{
|
||||||
|
maBitmapEx.SetPrefMapMode(maSwapInfo.maPrefMapMode);
|
||||||
|
maBitmapEx.SetPrefSize(maSwapInfo.maPrefSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meType == GraphicType::GdiMetafile)
|
||||||
|
{
|
||||||
|
maMetaFile.SetPrefMapMode(maSwapInfo.maPrefMapMode);
|
||||||
|
maMetaFile.SetPrefSize(maSwapInfo.maPrefSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImplIsAnimated())
|
||||||
|
{
|
||||||
|
auto & rAnimationBitmap = const_cast<BitmapEx&>(mpAnimation->GetBitmapEx());
|
||||||
|
rAnimationBitmap.SetPrefMapMode(maSwapInfo.maPrefMapMode);
|
||||||
|
rAnimationBitmap.SetPrefSize(maSwapInfo.maPrefSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maVectorGraphicData)
|
||||||
|
{
|
||||||
|
maExPrefSize = maSwapInfo.maPrefSize;
|
||||||
|
maVectorGraphicData->setPageIndex(maSwapInfo.mnPageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ImpGraphic::swapIn()
|
bool ImpGraphic::swapIn()
|
||||||
{
|
{
|
||||||
bool bRet = false;
|
|
||||||
|
|
||||||
if (!isSwappedOut())
|
if (!isSwappedOut())
|
||||||
return bRet;
|
return false;
|
||||||
|
|
||||||
|
bool bReturn = false;
|
||||||
|
|
||||||
if (mbPrepared)
|
if (mbPrepared)
|
||||||
{
|
{
|
||||||
bRet = loadPrepared();
|
bReturn = loadPrepared();
|
||||||
|
}
|
||||||
|
else if (mpGfxLink && mpGfxLink->IsNative())
|
||||||
|
{
|
||||||
|
Graphic aGraphic;
|
||||||
|
if (!mpGfxLink->LoadNative(aGraphic))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto & rImpGraphic = *aGraphic.ImplGetImpGraphic();
|
||||||
|
|
||||||
|
if (meType != rImpGraphic.meType)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Move over only graphic content
|
||||||
|
mpAnimation.reset();
|
||||||
|
if (rImpGraphic.mpAnimation)
|
||||||
|
{
|
||||||
|
mpAnimation = std::make_unique<Animation>(*rImpGraphic.mpAnimation);
|
||||||
|
maBitmapEx = mpAnimation->GetBitmapEx();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maBitmapEx = rImpGraphic.maBitmapEx;
|
||||||
|
}
|
||||||
|
|
||||||
|
maMetaFile = rImpGraphic.maMetaFile;
|
||||||
|
maVectorGraphicData = rImpGraphic.maVectorGraphicData;
|
||||||
|
|
||||||
|
// Set to 0, to force recalculation
|
||||||
|
mnSizeBytes = 0;
|
||||||
|
mnChecksum = 0;
|
||||||
|
|
||||||
|
restoreFromSwapInfo();
|
||||||
|
|
||||||
|
maLastUsed = std::chrono::high_resolution_clock::now();
|
||||||
|
mbSwapOut = false;
|
||||||
|
bReturn = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OUString aSwapURL;
|
OUString aSwapURL;
|
||||||
|
|
||||||
if( mpSwapFile )
|
if (mpSwapFile)
|
||||||
aSwapURL = mpSwapFile->getSwapURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
aSwapURL = mpSwapFile->getSwapURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
|
||||||
|
|
||||||
if( !aSwapURL.isEmpty() )
|
if (!aSwapURL.isEmpty())
|
||||||
{
|
{
|
||||||
std::unique_ptr<SvStream> xStream;
|
std::unique_ptr<SvStream> xStream;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
xStream = ::utl::UcbStreamHelper::CreateStream( aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE );
|
xStream = ::utl::UcbStreamHelper::CreateStream(aSwapURL, StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
|
||||||
}
|
}
|
||||||
catch( const css::uno::Exception& )
|
catch( const css::uno::Exception& )
|
||||||
{
|
{
|
||||||
@@ -1501,51 +1462,43 @@ bool ImpGraphic::swapIn()
|
|||||||
|
|
||||||
if (xStream)
|
if (xStream)
|
||||||
{
|
{
|
||||||
xStream->SetVersion( SOFFICE_FILEFORMAT_50 );
|
xStream->SetVersion(SOFFICE_FILEFORMAT_50);
|
||||||
xStream->SetCompressMode( SvStreamCompressFlags::NATIVE );
|
xStream->SetCompressMode(SvStreamCompressFlags::NATIVE);
|
||||||
|
xStream->SetBufferSize(GRAPHIC_STREAMBUFSIZE);
|
||||||
|
|
||||||
|
bReturn = swapInFromStream(*xStream);
|
||||||
|
|
||||||
bRet = swapInFromStream(*xStream);
|
|
||||||
xStream.reset();
|
xStream.reset();
|
||||||
|
|
||||||
|
restoreFromSwapInfo();
|
||||||
|
|
||||||
if (mpSwapFile)
|
if (mpSwapFile)
|
||||||
setOriginURL(mpSwapFile->getOriginURL());
|
setOriginURL(mpSwapFile->getOriginURL());
|
||||||
|
|
||||||
mpSwapFile.reset();
|
mpSwapFile.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bRet)
|
if (bReturn)
|
||||||
vcl::graphic::Manager::get().swappedIn(this);
|
vcl::graphic::Manager::get().swappedIn(this);
|
||||||
|
|
||||||
return bRet;
|
return bReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImpGraphic::swapInFromStream(SvStream& rStream)
|
bool ImpGraphic::swapInFromStream(SvStream& rStream)
|
||||||
{
|
{
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
|
|
||||||
rStream.SetBufferSize(GRAPHIC_STREAMBUFSIZE);
|
|
||||||
|
|
||||||
if (rStream.GetError())
|
if (rStream.GetError())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//keep the swap file alive, because its quite possibly the backing storage
|
ImplClearGraphics();
|
||||||
//for xIStm
|
mnSizeBytes = 0;
|
||||||
std::shared_ptr<ImpSwapFile> xSwapFile(std::move(mpSwapFile));
|
mnChecksum = 0;
|
||||||
assert(!mpSwapFile);
|
|
||||||
|
|
||||||
std::shared_ptr<GraphicReader> xContext(std::move(mpContext));
|
|
||||||
assert(!mpContext);
|
|
||||||
|
|
||||||
bool bDummyContext = mbDummyContext;
|
|
||||||
mbDummyContext = false;
|
|
||||||
|
|
||||||
bRet = swapInContent(rStream);
|
bRet = swapInContent(rStream);
|
||||||
|
|
||||||
//restore ownership of the swap file and context
|
|
||||||
mpSwapFile = std::move(xSwapFile);
|
|
||||||
mpContext = std::move(xContext);
|
|
||||||
mbDummyContext = bDummyContext;
|
|
||||||
|
|
||||||
if (!bRet)
|
if (!bRet)
|
||||||
{
|
{
|
||||||
//throw away swapfile, etc.
|
//throw away swapfile, etc.
|
||||||
@@ -1557,165 +1510,116 @@ bool ImpGraphic::swapInFromStream(SvStream& rStream)
|
|||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImpGraphic::swapInGraphic(SvStream& rStream)
|
bool ImpGraphic::swapInGraphic(SvStream& rStream)
|
||||||
{
|
{
|
||||||
|
bool bReturn = false;
|
||||||
|
|
||||||
if (rStream.GetError())
|
if (rStream.GetError())
|
||||||
return;
|
return bReturn;
|
||||||
|
|
||||||
const sal_uLong nStmPos1 = rStream.Tell();
|
if (meType == GraphicType::Bitmap)
|
||||||
sal_uInt32 nID;
|
|
||||||
|
|
||||||
ImplClear();
|
|
||||||
|
|
||||||
// read Id
|
|
||||||
rStream.ReadUInt32(nID);
|
|
||||||
|
|
||||||
// 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 (!rStream.good())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (NATIVE_FORMAT_50 == nID)
|
|
||||||
{
|
{
|
||||||
Graphic aGraphic;
|
sal_Int32 nContentType = -1;
|
||||||
GfxLink aLink;
|
rStream.ReadInt32(nContentType);
|
||||||
|
if (nContentType < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// read compat info, destructor writes stuff into the header
|
auto eContentType = static_cast<GraphicContentType>(nContentType);
|
||||||
|
|
||||||
|
switch (eContentType)
|
||||||
{
|
{
|
||||||
VersionCompat aCompat(rStream, StreamMode::READ);
|
case GraphicContentType::Bitmap:
|
||||||
}
|
|
||||||
|
|
||||||
TypeSerializer aSerializer(rStream);
|
|
||||||
aSerializer.readGfxLink(aLink);
|
|
||||||
|
|
||||||
// set dummy link to avoid creation of additional link after filtering;
|
|
||||||
// we set a default link to avoid unnecessary swapping of native data
|
|
||||||
aGraphic.SetGfxLink(std::make_shared<GfxLink>());
|
|
||||||
|
|
||||||
if (!rStream.GetError() && aLink.LoadNative(aGraphic))
|
|
||||||
{
|
|
||||||
// set link only, if no other link was set
|
|
||||||
const bool bSetLink = !mpGfxLink;
|
|
||||||
|
|
||||||
// assign graphic
|
|
||||||
*this = *aGraphic.ImplGetImpGraphic();
|
|
||||||
|
|
||||||
if (aLink.IsPrefMapModeValid())
|
|
||||||
ImplSetPrefMapMode(aLink.GetPrefMapMode());
|
|
||||||
|
|
||||||
if (aLink.IsPrefSizeValid())
|
|
||||||
ImplSetPrefSize(aLink.GetPrefSize());
|
|
||||||
|
|
||||||
if (bSetLink)
|
|
||||||
ImplSetLink(std::make_shared<GfxLink>(aLink));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rStream.Seek(nStmPos1);
|
|
||||||
rStream.SetError(ERRCODE_IO_WRONGFORMAT);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BitmapEx aBmpEx;
|
|
||||||
const SvStreamEndian nOldFormat = rStream.GetEndian();
|
|
||||||
|
|
||||||
rStream.SeekRel(-4);
|
|
||||||
rStream.SetEndian(SvStreamEndian::LITTLE);
|
|
||||||
ReadDIBBitmapEx(aBmpEx, rStream);
|
|
||||||
|
|
||||||
if (!rStream.GetError())
|
|
||||||
{
|
|
||||||
sal_uInt32 nMagic1(0);
|
|
||||||
sal_uInt32 nMagic2(0);
|
|
||||||
sal_uLong nActPos = rStream.Tell();
|
|
||||||
|
|
||||||
rStream.ReadUInt32(nMagic1);
|
|
||||||
rStream.ReadUInt32(nMagic2);
|
|
||||||
rStream.Seek(nActPos);
|
|
||||||
|
|
||||||
*this = ImpGraphic(aBmpEx);
|
|
||||||
|
|
||||||
if (!rStream.GetError() && (0x5344414e == nMagic1) && (0x494d4931 == nMagic2))
|
|
||||||
{
|
|
||||||
mpAnimation = std::make_unique<Animation>();
|
|
||||||
ReadAnimation(rStream, *mpAnimation);
|
|
||||||
|
|
||||||
// #108077# manually set loaded BmpEx to Animation
|
|
||||||
// (which skips loading its BmpEx if already done)
|
|
||||||
mpAnimation->SetBitmapEx(aBmpEx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rStream.ResetError();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GDIMetaFile aMetaFile;
|
|
||||||
|
|
||||||
rStream.Seek(nStmPos1);
|
|
||||||
rStream.ResetError();
|
|
||||||
ReadGDIMetaFile(rStream, aMetaFile);
|
|
||||||
|
|
||||||
if (!rStream.GetError())
|
|
||||||
{
|
|
||||||
*this = aMetaFile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ErrCode nOrigError = rStream.GetErrorCode();
|
|
||||||
// try to stream in Svg defining data (length, byte array and evtl. path)
|
|
||||||
// See below (operator<<) for more information
|
|
||||||
sal_uInt32 nMagic;
|
|
||||||
rStream.Seek(nStmPos1);
|
|
||||||
rStream.ResetError();
|
|
||||||
rStream.ReadUInt32( nMagic );
|
|
||||||
|
|
||||||
if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic || constPdfMagic == nMagic)
|
|
||||||
{
|
{
|
||||||
sal_uInt32 nVectorGraphicDataArrayLength(0);
|
BitmapEx aBitmapEx;
|
||||||
rStream.ReadUInt32(nVectorGraphicDataArrayLength);
|
ReadDIBBitmapEx(aBitmapEx, rStream);
|
||||||
|
if (!rStream.GetError())
|
||||||
if (nVectorGraphicDataArrayLength)
|
|
||||||
{
|
{
|
||||||
VectorGraphicDataArray aNewData(nVectorGraphicDataArrayLength);
|
maBitmapEx = aBitmapEx;
|
||||||
|
bReturn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
rStream.ReadBytes(aNewData.getArray(), nVectorGraphicDataArrayLength);
|
case GraphicContentType::Animation:
|
||||||
OUString aPath = rStream.ReadUniOrByteString(rStream.GetStreamCharSet());
|
{
|
||||||
|
auto pAnimation = std::make_unique<Animation>();
|
||||||
|
ReadAnimation(rStream, *pAnimation);
|
||||||
|
if (!rStream.GetError())
|
||||||
|
{
|
||||||
|
mpAnimation = std::move(pAnimation);
|
||||||
|
maBitmapEx = mpAnimation->GetBitmapEx();
|
||||||
|
bReturn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (!rStream.GetError())
|
case GraphicContentType::Vector:
|
||||||
|
{
|
||||||
|
// try to stream in Svg defining data (length, byte array and evtl. path)
|
||||||
|
// See below (operator<<) for more information
|
||||||
|
sal_uInt32 nMagic;
|
||||||
|
rStream.ReadUInt32(nMagic);
|
||||||
|
|
||||||
|
if (constSvgMagic == nMagic || constWmfMagic == nMagic || constEmfMagic == nMagic || constPdfMagic == nMagic)
|
||||||
|
{
|
||||||
|
sal_uInt32 nVectorGraphicDataArrayLength(0);
|
||||||
|
rStream.ReadUInt32(nVectorGraphicDataArrayLength);
|
||||||
|
|
||||||
|
if (nVectorGraphicDataArrayLength)
|
||||||
{
|
{
|
||||||
VectorGraphicDataType aDataType(VectorGraphicDataType::Svg);
|
VectorGraphicDataArray aNewData(nVectorGraphicDataArrayLength);
|
||||||
|
|
||||||
if (constWmfMagic == nMagic)
|
rStream.ReadBytes(aNewData.getArray(), nVectorGraphicDataArrayLength);
|
||||||
|
|
||||||
|
OUString aPath = rStream.ReadUniOrByteString(rStream.GetStreamCharSet());
|
||||||
|
|
||||||
|
if (rStream.GetError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VectorGraphicDataType aDataType;
|
||||||
|
|
||||||
|
switch (nMagic)
|
||||||
{
|
{
|
||||||
aDataType = VectorGraphicDataType::Wmf;
|
case constSvgMagic:
|
||||||
}
|
aDataType = VectorGraphicDataType::Svg;
|
||||||
else if (constEmfMagic == nMagic)
|
break;
|
||||||
{
|
case constWmfMagic:
|
||||||
aDataType = VectorGraphicDataType::Emf;
|
aDataType = VectorGraphicDataType::Wmf;
|
||||||
}
|
break;
|
||||||
else if (constPdfMagic == nMagic)
|
case constEmfMagic:
|
||||||
{
|
aDataType = VectorGraphicDataType::Emf;
|
||||||
aDataType = VectorGraphicDataType::Pdf;
|
break;
|
||||||
|
case constPdfMagic:
|
||||||
|
aDataType = VectorGraphicDataType::Pdf;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aNewData, aPath, aDataType);
|
auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aNewData, aPath, aDataType);
|
||||||
*this = ImpGraphic(aVectorGraphicDataPtr);
|
|
||||||
|
if (!rStream.GetError())
|
||||||
|
{
|
||||||
|
maVectorGraphicData = aVectorGraphicDataPtr;
|
||||||
|
bReturn = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
rStream.SetError(nOrigError);
|
|
||||||
}
|
|
||||||
|
|
||||||
rStream.Seek(nStmPos1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (meType == GraphicType::GdiMetafile)
|
||||||
rStream.SetEndian(nOldFormat);
|
{
|
||||||
|
GDIMetaFile aMetaFile;
|
||||||
|
ReadGDIMetaFile(rStream, aMetaFile);
|
||||||
|
if (!rStream.GetError())
|
||||||
|
{
|
||||||
|
maMetaFile = aMetaFile;
|
||||||
|
bReturn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImpGraphic::ImplSetLink(const std::shared_ptr<GfxLink>& rGfxLink)
|
void ImpGraphic::ImplSetLink(const std::shared_ptr<GfxLink>& rGfxLink)
|
||||||
|
Reference in New Issue
Block a user