summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-04-14 15:13:05 +0900
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-18 13:34:31 -0400
commitd46098a213eda6fdb8237e1cd3d862bea4f187a0 (patch)
tree5decdb8b2b77162b3d484119ee829dcce0456cfc
parentbc559eecccf08b3cb7fd328f49ea81aba32a6d71 (diff)
Function to load graphic swapped out (loaded on demand)
When a document is loaded it takes a lot of time and memory to load the graphic that are in the documet, so avoid that and just store the compressed graphic into a temporary file (handeled by GfxLink) and load when we really need to show the graphic. GraphicObject cached some attributes from Graphic, but this attributes now aren't available immediately so this attributes are removed form GraphicObject and now delegate to the Graphic itself. GetSizeBytes attribute however was removed as it is only used in some tests. GfxLink initial values were moved to the constructor and are not set in the header file anymore (as it is the recommended way to do it). The SdImportTest::testDocumentLayout failed as it looks like the dump sometimes didn't include the width and height of the null bitmap (which is set to 32x32) of the FillBitmap in some situations, but then in other situations it did include this attributes. With this change the width and height are always included for the FillBitmap which looks like it is more correct. Reviewed-on: https://gerrit.libreoffice.org/53016 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit 7b355669c6ddeab2e6cec692d6afdff41c61d0fb) Change-Id: Ia1218f93b1735402b7828404f65660e2d4acf32f
-rw-r--r--include/svx/svdograf.hxx4
-rw-r--r--include/vcl/GraphicObject.hxx16
-rw-r--r--include/vcl/gfxlink.hxx10
-rw-r--r--include/vcl/graph.hxx3
-rw-r--r--include/vcl/graphicfilter.hxx8
-rw-r--r--include/vcl/salctype.hxx3
-rw-r--r--sc/qa/extras/anchor.cxx10
-rw-r--r--sc/qa/unit/subsequent_export-test.cxx2
-rw-r--r--sd/qa/unit/data/xml/fdo64586_0.xml4
-rw-r--r--sd/qa/unit/data/xml/n758621_0.xml4
-rw-r--r--sd/qa/unit/data/xml/n758621_1.xml4
-rw-r--r--sd/qa/unit/data/xml/n819614_0.xml2
-rw-r--r--sd/qa/unit/export-tests.cxx3
-rw-r--r--svtools/qa/unit/GraphicObjectTest.cxx8
-rw-r--r--svx/source/svdraw/svdograf.cxx8
-rw-r--r--svx/source/xml/xmlgrhlp.cxx15
-rw-r--r--sw/qa/extras/globalfilter/globalfilter.cxx12
-rw-r--r--vcl/inc/graphic/Manager.hxx2
-rw-r--r--vcl/inc/impgraph.hxx16
-rw-r--r--vcl/source/filter/graphicfilter.cxx399
-rw-r--r--vcl/source/gdi/gfxlink.cxx66
-rw-r--r--vcl/source/gdi/graph.cxx10
-rw-r--r--vcl/source/gdi/impgraph.cxx154
-rw-r--r--vcl/source/graphic/GraphicObject.cxx38
-rw-r--r--vcl/source/graphic/GraphicObject2.cxx6
-rw-r--r--vcl/source/graphic/Manager.cxx21
26 files changed, 701 insertions, 127 deletions
diff --git a/include/svx/svdograf.hxx b/include/svx/svdograf.hxx
index 9e39ebb64e64..c0f5ad7a334e 100644
--- a/include/svx/svdograf.hxx
+++ b/include/svx/svdograf.hxx
@@ -144,8 +144,8 @@ public:
bool IsEPS() const;
bool IsSwappedOut() const;
- const MapMode& GetGrafPrefMapMode() const;
- const Size& GetGrafPrefSize() const;
+ MapMode GetGrafPrefMapMode() const;
+ Size GetGrafPrefSize() const;
void SetGrafStreamURL( const OUString& rGraphicStreamURL );
OUString GetGrafStreamURL() const;
diff --git a/include/vcl/GraphicObject.hxx b/include/vcl/GraphicObject.hxx
index 888109343e37..1ad14e01216f 100644
--- a/include/vcl/GraphicObject.hxx
+++ b/include/vcl/GraphicObject.hxx
@@ -202,6 +202,7 @@ private:
void VCL_DLLPRIVATE ImplAssignGraphicData();
static void VCL_DLLPRIVATE ImplEnsureGraphicManager();
void VCL_DLLPRIVATE ImplAutoSwapIn();
+
bool VCL_DLLPRIVATE ImplGetCropParams(
OutputDevice* pOut,
Point& rPt,
@@ -396,14 +397,6 @@ public:
OString GetUniqueID() const;
- GraphicType GetType() const { return meType; }
- const Size& GetPrefSize() const { return maPrefSize; }
- const MapMode& GetPrefMapMode() const { return maPrefMapMode; }
- sal_uLong GetSizeBytes() const { return mnSizeBytes; }
- bool IsTransparent() const { return mbTransparent; }
- bool IsAnimated() const { return mbAnimated; }
- bool IsEPS() const { return mbEPS; }
-
bool SwapOut();
bool SwapOut( SvStream* pOStm );
bool SwapIn();
@@ -412,6 +405,13 @@ public:
bool IsInSwapOut() const { return mbIsInSwapOut; }
bool IsSwappedOut() const { return( mbAutoSwapped || maGraphic.IsSwapOut() ); }
+ GraphicType GetType() const;
+ Size GetPrefSize() const;
+ MapMode GetPrefMapMode() const;
+ bool IsTransparent() const;
+ bool IsAnimated() const;
+ bool IsEPS() const;
+
bool Draw(
OutputDevice* pOut,
const Point& rPt,
diff --git a/include/vcl/gfxlink.hxx b/include/vcl/gfxlink.hxx
index d8eef9e3ce3a..bb0fc0af7493 100644
--- a/include/vcl/gfxlink.hxx
+++ b/include/vcl/gfxlink.hxx
@@ -64,17 +64,17 @@ private:
};
- GfxLinkType meType = GfxLinkType::NONE;
- sal_uInt32 mnUserId = 0;
+ GfxLinkType meType;
+ sal_uInt32 mnUserId;
std::shared_ptr<sal_uInt8> mpSwapInData;
std::shared_ptr<SwapOutData> mpSwapOutData;
- sal_uInt32 mnSwapInDataSize = 0;
+ sal_uInt32 mnSwapInDataSize;
MapMode maPrefMapMode;
Size maPrefSize;
- bool mbPrefMapModeValid = false;
- bool mbPrefSizeValid = false;
+ bool mbPrefMapModeValid;
+ bool mbPrefSizeValid;
SAL_DLLPRIVATE std::shared_ptr<sal_uInt8> GetSwapInData() const;
public:
diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx
index 1676b883c4d6..5e6a47b09559 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -141,6 +141,9 @@ public:
bool IsAnimated() const;
bool IsEPS() const;
+ bool isAvailable() const;
+ bool makeAvailable();
+
// #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic
// if it is a MetaFile. To be able to control this conversion it is necessary to
// allow giving parameters which control AntiAliasing and LineSnapping of the
diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx
index 8b8a7cef3008..f9e727a50051 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -100,6 +100,7 @@ namespace o3tl
#define WMF_SHORTNAME "WMF"
#define EMF_SHORTNAME "EMF"
#define SVG_SHORTNAME "SVG"
+#define PDF_SHORTNAME "PDF"
// Info class for all supported file formats
@@ -283,6 +284,11 @@ public:
sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE,
WMF_EXTERNALHEADER *pExtHeader = nullptr );
+ /// Imports multiple graphics.
+ ///
+ /// The resulting graphic is added to rGraphics on success, nullptr is added on failure.
+ void ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGraphics, const std::vector< std::shared_ptr<SvStream> >& rStreams);
+
sal_uInt16 ImportGraphic( Graphic& rGraphic, const OUString& rPath,
SvStream& rStream,
sal_uInt16 nFormat,
@@ -290,6 +296,8 @@ public:
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
WMF_EXTERNALHEADER *pExtHeader = nullptr );
+ Graphic ImportUnloadedGraphic(SvStream& rIStream);
+
const FilterErrorEx& GetLastError() const { return *pErrorEx;}
void ResetLastError();
diff --git a/include/vcl/salctype.hxx b/include/vcl/salctype.hxx
index 409fc5a79993..893adb4d47e4 100644
--- a/include/vcl/salctype.hxx
+++ b/include/vcl/salctype.hxx
@@ -37,7 +37,8 @@ enum class ConvertDataFormat
TIF,
WMF,
EMF,
- SVG
+ SVG,
+ PDF
};
class SvStream;
diff --git a/sc/qa/extras/anchor.cxx b/sc/qa/extras/anchor.cxx
index 823370529e0c..cb66feafaa0f 100644
--- a/sc/qa/extras/anchor.cxx
+++ b/sc/qa/extras/anchor.cxx
@@ -77,7 +77,7 @@ void ScAnchorTest::testUndoAnchor()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
CPPUNIT_ASSERT(!rGraphicObj.IsSwappedOut());
CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
// Get the document controller
ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false);
@@ -111,14 +111,14 @@ void ScAnchorTest::testUndoAnchor()
// Check anchor type
CPPUNIT_ASSERT(oldType == ScDrawLayer::GetAnchorType(*pObject) );
CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
pUndoMgr->Redo();
// Check anchor type
CPPUNIT_ASSERT(newType == ScDrawLayer::GetAnchorType(*pObject) );
CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
ScDrawLayer::SetPageAnchored(*pObject);
// Check state
@@ -136,14 +136,14 @@ void ScAnchorTest::testUndoAnchor()
// Check anchor type
CPPUNIT_ASSERT(oldType == ScDrawLayer::GetAnchorType(*pObject) );
CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
pUndoMgr->Redo();
// Check anchor type
CPPUNIT_ASSERT(newType == ScDrawLayer::GetAnchorType(*pObject) );
CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
xComponent->dispose();
}
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 793b239d510d..3dd6528be557 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -3532,7 +3532,7 @@ void ScExportTest::testLinkedGraphicRT()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), !rGraphicObj.IsSwappedOut());
CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
xDocSh2->DoClose();
}
diff --git a/sd/qa/unit/data/xml/fdo64586_0.xml b/sd/qa/unit/data/xml/fdo64586_0.xml
index a2487832299c..4ba0afe041a5 100644
--- a/sd/qa/unit/data/xml/fdo64586_0.xml
+++ b/sd/qa/unit/data/xml/fdo64586_0.xml
@@ -4,7 +4,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
@@ -18,7 +18,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
diff --git a/sd/qa/unit/data/xml/n758621_0.xml b/sd/qa/unit/data/xml/n758621_0.xml
index 754be1d41ed1..dc3e0935cc3e 100644
--- a/sd/qa/unit/data/xml/n758621_0.xml
+++ b/sd/qa/unit/data/xml/n758621_0.xml
@@ -4,7 +4,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
@@ -18,7 +18,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
diff --git a/sd/qa/unit/data/xml/n758621_1.xml b/sd/qa/unit/data/xml/n758621_1.xml
index 0f71931585bb..0b826248fdc9 100644
--- a/sd/qa/unit/data/xml/n758621_1.xml
+++ b/sd/qa/unit/data/xml/n758621_1.xml
@@ -4,7 +4,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
@@ -18,7 +18,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
diff --git a/sd/qa/unit/data/xml/n819614_0.xml b/sd/qa/unit/data/xml/n819614_0.xml
index aff9c324344c..ee1925a3bbc2 100644
--- a/sd/qa/unit/data/xml/n819614_0.xml
+++ b/sd/qa/unit/data/xml/n819614_0.xml
@@ -4,7 +4,7 @@
<FillTransparenceGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillGradient style="LINEAR" startColor="000000" endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" endIntensity="100" stepCount="0"/>
<FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
- <FillBitmap/>
+ <FillBitmap width="32" height="32"/>
<LineDash style="RECT" dots="1" dotLen="20" dashes="1" dashLen="20" distance="20"/>
<LineStart/>
<LineEnd/>
diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx
index a1f067287de5..0bba77ba2c24 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -512,9 +512,8 @@ void SdExportTest::testLinkedGraphicRT()
CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pObject->IsLinkedGraphic() );
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
- CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), !rGraphicObj.IsSwappedOut());
CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
xDocShRef->DoClose();
}
diff --git a/svtools/qa/unit/GraphicObjectTest.cxx b/svtools/qa/unit/GraphicObjectTest.cxx
index 9599fbfeb061..e4709e23db3a 100644
--- a/svtools/qa/unit/GraphicObjectTest.cxx
+++ b/svtools/qa/unit/GraphicObjectTest.cxx
@@ -189,7 +189,7 @@ void GraphicObjectTest::testSizeBasedAutoSwap()
{
// First image should be swapped out
CPPUNIT_ASSERT(pGrafObj1->IsSwappedOut());
- CPPUNIT_ASSERT_EQUAL(sal_uLong(697230), pGrafObj1->GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(697230), pGrafObj1->GetGraphic().GetSizeBytes());
// Still swapped out: size is cached
CPPUNIT_ASSERT(pGrafObj1->IsSwappedOut());
@@ -200,7 +200,7 @@ void GraphicObjectTest::testSizeBasedAutoSwap()
// Size based swap out is triggered by swap in, so the last swapped in image should be
// in the memory despite of size limit is reached.
CPPUNIT_ASSERT(!pGrafObj2->IsSwappedOut());
- CPPUNIT_ASSERT_EQUAL(sal_uLong(1620000), pGrafObj2->GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL(sal_uLong(1620000), pGrafObj2->GetGraphic().GetSizeBytes());
}
// Swap in first image -> second image will be swapped out
@@ -220,7 +220,7 @@ void GraphicObjectTest::testSizeBasedAutoSwap()
// Use bigger cache
{
GraphicManager& rGrfMgr = pGrafObj1->GetGraphicManager();
- rGrfMgr.SetMaxCacheSize((pGrafObj1->GetSizeBytes()+pGrafObj2->GetSizeBytes())*10);
+ rGrfMgr.SetMaxCacheSize((pGrafObj1->GetGraphic().GetSizeBytes()+pGrafObj2->GetGraphic().GetSizeBytes())*10);
}
// Swap in both images -> both should be swapped in
{
@@ -279,7 +279,7 @@ void GraphicObjectTest::testTdf88935()
// Set cache size
{
GraphicManager& rGrfMgr = pGraphObj1->GetGraphicManager();
- rGrfMgr.SetMaxCacheSize((pGraphObj1->GetSizeBytes()+pGraphObj2->GetSizeBytes())*10);
+ rGrfMgr.SetMaxCacheSize((pGraphObj1->GetGraphic().GetSizeBytes()+pGraphObj2->GetGraphic().GetSizeBytes())*10);
}
// Both images fit into the cache
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 2aced9a3227f..0415cfbe3eb2 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -288,7 +288,7 @@ sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
void SdrGrafObj::onGraphicChanged()
{
- if (!pGraphic || pGraphic->IsSwappedOut()) // don't force swap-in for this
+ if (!pGraphic || !pGraphic->GetGraphic().isAvailable())
return;
const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
@@ -552,12 +552,12 @@ bool SdrGrafObj::IsSwappedOut() const
return mbIsPreview || pGraphic->IsSwappedOut();
}
-const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
+MapMode SdrGrafObj::GetGrafPrefMapMode() const
{
return pGraphic->GetPrefMapMode();
}
-const Size& SdrGrafObj::GetGrafPrefSize() const
+Size SdrGrafObj::GetGrafPrefSize() const
{
return pGraphic->GetPrefSize();
}
@@ -1338,7 +1338,7 @@ IMPL_LINK( SdrGrafObj, ImpSwapHdl, const GraphicObject*, pO, SvStream* )
if( pO->IsInSwapOut() )
{
- if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
+ if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetGraphic().GetSizeBytes() > 20480 )
{
// test if this object is visualized from someone
// ## test only if there are VOCs other than the preview renderer
diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx
index 1add678a67b1..53b4f60dbecb 100644
--- a/svx/source/xml/xmlgrhlp.cxx
+++ b/svx/source/xml/xmlgrhlp.cxx
@@ -499,15 +499,20 @@ OUString SvXMLGraphicHelper::ImplGetGraphicMimeType( const OUString& rFileName )
Graphic SvXMLGraphicHelper::ImplReadGraphic( const OUString& rPictureStorageName,
const OUString& rPictureStreamName )
{
- Graphic aGraphic;
+ Graphic aReturnGraphic;
SvxGraphicHelperStream_Impl aStream( ImplGetGraphicStream( rPictureStorageName, rPictureStreamName ) );
- if( aStream.xStream.is() )
+ if (aStream.xStream.is())
{
- std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream( aStream.xStream ));
- GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, "", *pStream );
+ GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(aStream.xStream));
+ Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(*pStream);
+ if (aGraphic)
+ aReturnGraphic = aGraphic;
+ else
+ rGraphicFilter.ImportGraphic(aReturnGraphic, "", *pStream);
}
- return aGraphic;
+ return aReturnGraphic;
}
bool SvXMLGraphicHelper::ImplWriteGraphic( const OUString& rPictureStorageName,
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index 4f91797c28ad..4fead8219aba 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -186,15 +186,11 @@ void Test::testLinkedGraphicRT()
{
SwGrfNode* pGrfNode = aNodes[nIndex]->GetGrfNode();
CPPUNIT_ASSERT(pGrfNode);
- // RT via DOCX makes linked graphic embedded?!
- if( aFilterNames[nFilter] != "Office Open XML Text" )
- {
- CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pGrfNode->IsGrfLink());
- }
+
const GraphicObject& rGraphicObj = pGrfNode->GetGrfObj(true);
- CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), !rGraphicObj.IsSwappedOut());
- CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), int(GraphicType::Bitmap), int(rGraphicObj.GetType()));
- CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), static_cast<sal_uLong>(864900), rGraphicObj.GetSizeBytes());
+ const Graphic& rGraphic = rGraphicObj.GetGraphic();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(GraphicType::Bitmap), int(rGraphic.GetType()));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(864900), rGraphic.GetSizeBytes());
bImageFound = true;
}
}
diff --git a/vcl/inc/graphic/Manager.hxx b/vcl/inc/graphic/Manager.hxx
index 2ef93c420002..aaa4c29f04e4 100644
--- a/vcl/inc/graphic/Manager.hxx
+++ b/vcl/inc/graphic/Manager.hxx
@@ -45,6 +45,8 @@ private:
DECL_LINK(SwapOutTimerHandler, Timer*, void);
+ static sal_Int64 getGraphicSizeBytes(const ImpGraphic* pImpGraphic);
+
public:
static Manager& get();
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 10d04183f2b1..2383c1a5f53d 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -27,6 +27,13 @@ struct ImpSwapInfo
{
MapMode maPrefMapMode;
Size maPrefSize;
+
+ bool mbIsAnimated;
+ bool mbIsEPS;
+ bool mbIsTransparent;
+ bool mbIsAlpha;
+
+ sal_uInt32 mnAnimationLoopCount;
};
class OutputDevice;
@@ -38,7 +45,6 @@ class ImpGraphic;
class ImpGraphic final
{
friend class Graphic;
- friend class GraphicID;
friend class vcl::graphic::Manager;
private:
@@ -63,6 +69,7 @@ private:
GraphicExternalLink maGraphicExternalLink;
std::chrono::high_resolution_clock::time_point maLastUsed;
+ bool mbPrepared;
/// Used with GfxLink and/or PdfData when they store original media
/// which might be multi-page (PDF, f.e.) and we need to re-render
@@ -81,6 +88,8 @@ public:
ImpGraphic( const GDIMetaFile& rMtf );
~ImpGraphic();
+ void ImplSetPrepared();
+
private:
ImpGraphic& operator=( const ImpGraphic& rImpGraphic );
@@ -116,6 +125,9 @@ private:
bool ImplIsAnimated() const;
bool ImplIsEPS() const;
+ bool isAvailable() const;
+ bool makeAvailable();
+
Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const;
BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const;
/// Gives direct access to the contained BitmapEx.
@@ -185,6 +197,8 @@ private:
void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData);
bool ensureAvailable () const;
+
+ bool loadPrepared();
};
#endif // INCLUDED_VCL_INC_IMPGRAPH_HXX
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 4a84f683bef7..78f92dd7b79b 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -19,8 +19,10 @@
#include <config_folders.h>
+#include <o3tl/make_unique.hxx>
#include <osl/mutex.hxx>
#include <comphelper/processfactory.hxx>
+#include <comphelper/threadpool.hxx>
#include <comphelper/string.hxx>
#include <ucbhelper/content.hxx>
#include <cppuhelper/implbase.hxx>
@@ -34,6 +36,7 @@
#include <vcl/pngwrite.hxx>
#include <vcl/svgdata.hxx>
#include <vcl/virdev.hxx>
+#include <impgraph.hxx>
#include <vcl/svapp.hxx>
#include <osl/file.hxx>
#include <vcl/graphicfilter.hxx>
@@ -1324,6 +1327,379 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat
return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
}
+/// Contains a stream and other associated data to import pixels into a
+/// Graphic.
+struct GraphicImportContext
+{
+ /// Pixel data is read from this stream.
+ std::shared_ptr<SvStream> m_pStream;
+ /// The Graphic the import filter gets.
+ std::shared_ptr<Graphic> m_pGraphic;
+ /// Write pixel data using this access.
+ std::unique_ptr<Bitmap::ScopedWriteAccess> m_pAccess;
+ /// Signals if import finished correctly.
+ ErrCode m_nStatus = GRFILTER_FILTERERROR;
+ /// Original graphic format.
+ GfxLinkType m_eLinkType = GfxLinkType::NONE;
+ /// Position of the stream before reading the data.
+ sal_uInt64 m_nStreamBegin = 0;
+ /// Flags for the import filter.
+ GraphicFilterImportFlags m_nImportFlags = GraphicFilterImportFlags::NONE;
+};
+
+/// Graphic import worker that gets executed on a thread.
+class GraphicImportTask : public comphelper::ThreadTask
+{
+ GraphicImportContext& m_rContext;
+public:
+ GraphicImportTask(const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, GraphicImportContext& rContext);
+ void doWork() override;
+ /// Shared code between threaded and non-threaded version.
+ static void doImport(GraphicImportContext& rContext);
+};
+
+GraphicImportTask::GraphicImportTask(const std::shared_ptr<comphelper::ThreadTaskTag>& pTag, GraphicImportContext& rContext)
+ : comphelper::ThreadTask(pTag),
+ m_rContext(rContext)
+{
+}
+
+void GraphicImportTask::doWork()
+{
+ GraphicImportTask::doImport(m_rContext);
+}
+
+void GraphicImportTask::doImport(GraphicImportContext& rContext)
+{
+ if (!ImportJPEG(*rContext.m_pStream, *rContext.m_pGraphic, rContext.m_nImportFlags | GraphicFilterImportFlags::UseExistingBitmap, rContext.m_pAccess.get()))
+ rContext.m_nStatus = GRFILTER_FILTERERROR;
+ else
+ rContext.m_eLinkType = GfxLinkType::NativeJpg;
+}
+
+void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGraphics, const std::vector< std::shared_ptr<SvStream> >& rStreams)
+{
+ static bool bThreads = !getenv("VCL_NO_THREAD_IMPORT");
+ std::vector<GraphicImportContext> aContexts;
+ aContexts.reserve(rStreams.size());
+ comphelper::ThreadPool& rSharedPool = comphelper::ThreadPool::getSharedOptimalPool();
+ std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
+
+ for (const auto& pStream : rStreams)
+ {
+ aContexts.emplace_back();
+ GraphicImportContext& rContext = aContexts.back();
+
+ if (pStream)
+ {
+ rContext.m_pStream = pStream;
+ rContext.m_pGraphic = std::make_shared<Graphic>();
+ rContext.m_nStatus = ERRCODE_NONE;
+
+ // Detect the format.
+ ResetLastError();
+ rContext.m_nStreamBegin = pStream->Tell();
+ sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
+ rContext.m_nStatus = ImpTestOrFindFormat(OUString(), *pStream, nFormat);
+ pStream->Seek(rContext.m_nStreamBegin);
+
+ // Import the graphic.
+ if (rContext.m_nStatus == ERRCODE_NONE && !pStream->GetError())
+ {
+ OUString aFilterName = pConfig->GetImportFilterName(nFormat);
+
+ if (aFilterName.equalsIgnoreAsciiCase(IMP_JPEG))
+ {
+ rContext.m_nImportFlags = GraphicFilterImportFlags::SetLogsizeForJpeg;
+
+ if (!ImportJPEG( *pStream, *rContext.m_pGraphic, rContext.m_nImportFlags | GraphicFilterImportFlags::OnlyCreateBitmap, nullptr))
+ rContext.m_nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ Bitmap& rBitmap = const_cast<Bitmap&>(rContext.m_pGraphic->GetBitmapExRef().GetBitmapRef());
+ rContext.m_pAccess = o3tl::make_unique<Bitmap::ScopedWriteAccess>(rBitmap);
+ pStream->Seek(rContext.m_nStreamBegin);
+ if (bThreads)
+ rSharedPool.pushTask(new GraphicImportTask(pTag, rContext));
+ else
+ GraphicImportTask::doImport(rContext);
+ }
+ }
+ else
+ rContext.m_nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ }
+
+ rSharedPool.waitUntilDone(pTag);
+
+ // Process data after import.
+ for (auto& rContext : aContexts)
+ {
+ rContext.m_pAccess.reset(nullptr);
+
+ if (rContext.m_nStatus == ERRCODE_NONE && (rContext.m_eLinkType != GfxLinkType::NONE) && !rContext.m_pGraphic->GetContext())
+ {
+ std::unique_ptr<sal_uInt8[]> pGraphicContent;
+
+ const sal_uInt64 nStreamEnd = rContext.m_pStream->Tell();
+ sal_Int32 nGraphicContentSize = nStreamEnd - rContext.m_nStreamBegin;
+
+ if (nGraphicContentSize > 0)
+ {
+ try
+ {
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+ }
+ catch (const std::bad_alloc&)
+ {
+ rContext.m_nStatus = GRFILTER_TOOBIG;
+ }
+
+ if (rContext.m_nStatus == ERRCODE_NONE)
+ {
+ rContext.m_pStream->Seek(rContext.m_nStreamBegin);
+ rContext.m_pStream->ReadBytes(pGraphicContent.get(), nGraphicContentSize);
+ }
+ }
+
+ if (rContext.m_nStatus == ERRCODE_NONE)
+ rContext.m_pGraphic->SetGfxLink(GfxLink(std::move(pGraphicContent), nGraphicContentSize, rContext.m_eLinkType));
+ }
+
+ if (rContext.m_nStatus != ERRCODE_NONE)
+ rContext.m_pGraphic = nullptr;
+
+ rGraphics.push_back(rContext.m_pGraphic);
+ }
+}
+
+Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& rIStream)
+{
+ Graphic aGraphic;
+ sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW;
+ GfxLinkType eLinkType = GfxLinkType::NONE;
+
+ ResetLastError();
+
+ const sal_uLong nStreamBegin = rIStream.Tell();
+
+ rIStream.Seek(nStreamBegin);
+
+ ErrCode nStatus = ImpTestOrFindFormat("", rIStream, nFormat);
+
+ rIStream.Seek(nStreamBegin);
+ const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamBegin);
+
+ OUString aFilterName = pConfig->GetImportFilterName(nFormat);
+ OUString aExternalFilterName = pConfig->GetExternalFilterName(nFormat, false);
+
+ std::unique_ptr<sal_uInt8[]> pGraphicContent;
+ sal_Int32 nGraphicContentSize = 0;
+
+ // read graphic
+ if (pConfig->IsImportInternalFilter(nFormat))
+ {
+ if (aFilterName.equalsIgnoreAsciiCase(IMP_GIF))
+ {
+ eLinkType = GfxLinkType::NativeGif;
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_PNG))
+ {
+ vcl::PNGReader aPNGReader(rIStream);
+
+ // check if this PNG contains a GIF chunk!
+ const std::vector<vcl::PNGReader::ChunkData>& rChunkData = aPNGReader.GetChunks();
+ for (auto const& chunk : rChunkData)
+ {
+ // Microsoft Office is storing Animated GIFs in following chunk
+ if (chunk.nType == PMGCHUNG_msOG)
+ {
+ sal_uInt32 nChunkSize = chunk.aData.size();
+
+ if (nChunkSize > 11)
+ {
+ const std::vector<sal_uInt8>& rData = chunk.aData;
+ nGraphicContentSize = nChunkSize - 11;
+ SvMemoryStream aIStrm(const_cast<sal_uInt8*>(&rData[11]), nGraphicContentSize, StreamMode::READ);
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+ sal_uInt64 aCurrentPosition = aIStrm.Tell();
+ aIStrm.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
+ aIStrm.Seek(aCurrentPosition);
+ eLinkType = GfxLinkType::NativeGif;
+ break;
+ }
+ }
+ }
+ if (eLinkType == GfxLinkType::NONE)
+ {
+ eLinkType = GfxLinkType::NativePng;
+ }
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_JPEG))
+ {
+ eLinkType = GfxLinkType::NativeJpg;
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_SVG))
+ {
+ bool bOkay(false);
+
+ if (nStreamLength > 0)
+ {
+ std::vector<sal_uInt8> aTwoBytes(2);
+ rIStream.ReadBytes(aTwoBytes.data(), 2);
+ rIStream.Seek(nStreamBegin);
+
+ if (aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B)
+ {
+ SvMemoryStream aMemStream;
+ ZCodec aCodec;
+ long nMemoryLength;
+
+ aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, false, true);
+ nMemoryLength = aCodec.Decompress(rIStream, aMemStream);
+ aCodec.EndCompression();
+
+ if (!rIStream.GetError() && nMemoryLength >= 0)
+ {
+ nGraphicContentSize = nMemoryLength;
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+
+ aMemStream.Seek(STREAM_SEEK_TO_BEGIN);
+ aMemStream.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
+
+ bOkay = true;
+ }
+ }
+ else
+ {
+ nGraphicContentSize = nStreamLength;
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+ rIStream.ReadBytes(pGraphicContent.get(), nStreamLength);
+
+ bOkay = true;
+ }
+ }
+
+ if (bOkay)
+ {
+ eLinkType = GfxLinkType::NativeSvg;
+ }
+ else
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_BMP))
+ {
+ eLinkType = GfxLinkType::NativeBmp;
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_MOV))
+ {
+ eLinkType = GfxLinkType::NativeMov;
+ }
+ else if (aFilterName.equalsIgnoreAsciiCase(IMP_WMF) ||
+ aFilterName.equalsIgnoreAsciiCase(IMP_EMF))
+ {
+ nGraphicContentSize = nStreamLength;
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+
+ rIStream.ReadBytes(pGraphicContent.get(), nStreamLength);
+
+ if (!rIStream.GetError())
+ {
+ eLinkType = GfxLinkType::NativeWmf;
+ }
+ else
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ else if (aFilterName == IMP_PDF)
+ {
+ eLinkType = GfxLinkType::NativePdf;
+ }
+ else
+ {
+ nStatus = GRFILTER_FILTERERROR;
+ }
+ }
+ else
+ {
+ ImpFilterLibCacheEntry* pFilter = nullptr;
+
+ // find first filter in filter paths
+ sal_Int32 i, nTokenCount = getTokenCount(aFilterPath, ';');
+ ImpFilterLibCache &rCache = Cache::get();
+ for( i = 0; ( i < nTokenCount ) && ( pFilter == nullptr ); i++ )
+ pFilter = rCache.GetFilter(aFilterPath.getToken(i, ';'), aFilterName, aExternalFilterName);
+ nStatus = GRFILTER_FILTERERROR;
+ if( !pFilter )
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ PFilterCall pFunc = pFilter->GetImportFunction();
+
+ if (!pFunc)
+ nStatus = GRFILTER_FILTERERROR;
+ else
+ {
+ OUString aShortName;
+ if (nFormat != GRFILTER_FORMAT_DONTKNOW)
+ aShortName = GetImportFormatShortName(nFormat).toAsciiUpperCase();
+
+ if (aShortName.startsWith(TIF_SHORTNAME))
+ eLinkType = GfxLinkType::NativeTif;
+ else if( aShortName.startsWith(MET_SHORTNAME))
+ eLinkType = GfxLinkType::NativeMet;
+ else if( aShortName.startsWith(PCT_SHORTNAME))
+ eLinkType = GfxLinkType::NativePct;
+ }
+ }
+ }
+
+ if (nStatus == ERRCODE_NONE && eLinkType != GfxLinkType::NONE)
+ {
+ if (!pGraphicContent)
+ {
+ nGraphicContentSize = nStreamLength;
+
+ if (nGraphicContentSize > 0)
+ {
+ try
+ {
+ pGraphicContent.reset(new sal_uInt8[nGraphicContentSize]);
+ }
+ catch (const std::bad_alloc&)
+ {
+ nStatus = GRFILTER_TOOBIG;
+ }
+
+ if (nStatus == ERRCODE_NONE)
+ {
+ rIStream.Seek(nStreamBegin);
+ rIStream.ReadBytes(pGraphicContent.get(), nGraphicContentSize);
+ }
+ }
+ }
+
+ if( nStatus == ERRCODE_NONE )
+ {
+ aGraphic.SetGfxLink(GfxLink(std::move(pGraphicContent), nGraphicContentSize, eLinkType));
+ aGraphic.ImplGetImpGraphic()->ImplSetPrepared();
+ }
+ }
+
+ // Set error code or try to set native buffer
+ if(nStatus != ERRCODE_NONE)
+ {
+ ImplSetError(nStatus, &rIStream);
+ rIStream.Seek(nStreamBegin);
+ }
+
+ return aGraphic;
+}
+
sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
@@ -2182,17 +2558,18 @@ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData&, rData, bool )
OString aShortName;
switch( rData.mnFormat )
{
- case( ConvertDataFormat::BMP ): aShortName = BMP_SHORTNAME; break;
- case( ConvertDataFormat::GIF ): aShortName = GIF_SHORTNAME; break;
- case( ConvertDataFormat::JPG ): aShortName = JPG_SHORTNAME; break;
- case( ConvertDataFormat::MET ): aShortName = MET_SHORTNAME; break;
- case( ConvertDataFormat::PCT ): aShortName = PCT_SHORTNAME; break;
- case( ConvertDataFormat::PNG ): aShortName = PNG_SHORTNAME; break;
- case( ConvertDataFormat::SVM ): aShortName = SVM_SHORTNAME; break;
- case( ConvertDataFormat::TIF ): aShortName = TIF_SHORTNAME; break;
- case( ConvertDataFormat::WMF ): aShortName = WMF_SHORTNAME; break;
- case( ConvertDataFormat::EMF ): aShortName = EMF_SHORTNAME; break;
- case( ConvertDataFormat::SVG ): aShortName = SVG_SHORTNAME; break;
+ case ConvertDataFormat::BMP: aShortName = BMP_SHORTNAME; break;
+ case ConvertDataFormat::GIF: aShortName = GIF_SHORTNAME; break;
+ case ConvertDataFormat::JPG: aShortName = JPG_SHORTNAME; break;
+ case ConvertDataFormat::MET: aShortName = MET_SHORTNAME; break;
+ case ConvertDataFormat::PCT: aShortName = PCT_SHORTNAME; break;
+ case ConvertDataFormat::PNG: aShortName = PNG_SHORTNAME; break;
+ case ConvertDataFormat::SVM: aShortName = SVM_SHORTNAME; break;
+ case ConvertDataFormat::TIF: aShortName = TIF_SHORTNAME; break;
+ case ConvertDataFormat::WMF: aShortName = WMF_SHORTNAME; break;
+ case ConvertDataFormat::EMF: aShortName = EMF_SHORTNAME; break;
+ case ConvertDataFormat::SVG: aShortName = SVG_SHORTNAME; break;
+ case ConvertDataFormat::PDF: aShortName = PDF_SHORTNAME; break;
default:
break;
diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx
index 8f7c3708f28a..798ef5e8a00c 100644
--- a/vcl/source/gdi/gfxlink.cxx
+++ b/vcl/source/gdi/gfxlink.cxx
@@ -27,22 +27,28 @@
#include <vcl/graph.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/cvtgrf.hxx>
-#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <vcl/graphicfilter.hxx>
#include <memory>
#include <o3tl/make_shared.hxx>
GfxLink::GfxLink()
+ : meType(GfxLinkType::NONE)
+ , mnUserId(0)
+ , mnSwapInDataSize(0)
+ , mbPrefMapModeValid(false)
+ , mbPrefSizeValid(false)
{
}
-GfxLink::GfxLink( std::unique_ptr<sal_uInt8[]> pBuf, sal_uInt32 nSize, GfxLinkType nType )
+GfxLink::GfxLink(std::unique_ptr<sal_uInt8[]> pBuf, sal_uInt32 nSize, GfxLinkType nType)
+ : meType(nType)
+ , mnUserId(0)
+ , mpSwapInData(std::shared_ptr<sal_uInt8>(pBuf.release(), pBuf.get_deleter())) // std::move(pBuf) does not compile on Jenkins MacOSX (24 May 2016)
+ , mnSwapInDataSize(nSize)
+ , mbPrefMapModeValid(false)
+ , mbPrefSizeValid(false)
{
- SAL_WARN_IF( pBuf == nullptr || !nSize, "vcl",
- "GfxLink::GfxLink(): empty/NULL buffer given" );
-
- meType = nType;
- mnSwapInDataSize = nSize;
- mpSwapInData = std::shared_ptr<sal_uInt8>(pBuf.release(), pBuf.get_deleter()); // std::move(pBuf) does not compile on Jenkins MacOSX (24 May 2016)
+ SAL_WARN_IF(mpSwapInData.get() == nullptr || mnSwapInDataSize <= 0, "vcl", "GfxLink::GfxLink(): empty/NULL buffer given");
}
bool GfxLink::operator==( const GfxLink& rGfxLink ) const
@@ -102,31 +108,33 @@ bool GfxLink::LoadNative( Graphic& rGraphic )
if( IsNative() && mnSwapInDataSize )
{
const sal_uInt8* pData = GetData();
-
- if( pData )
+ if (pData)
{
- SvMemoryStream aMemStm;
- ConvertDataFormat nCvtType;
-
- aMemStm.SetBuffer( const_cast<sal_uInt8*>(pData), mnSwapInDataSize, mnSwapInDataSize );
+ SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(pData), mnSwapInDataSize, StreamMode::READ | StreamMode::WRITE);
+ OUString aShortName;
- switch( meType )
+ switch (meType)
{
- case GfxLinkType::NativeGif: nCvtType = ConvertDataFormat::GIF; break;
- case GfxLinkType::NativeBmp: nCvtType = ConvertDataFormat::BMP; break;
- case GfxLinkType::NativeJpg: nCvtType = ConvertDataFormat::JPG; break;
- case GfxLinkType::NativePng: nCvtType = ConvertDataFormat::PNG; break;
- case GfxLinkType::NativeTif: nCvtType = ConvertDataFormat::TIF; break;
- case GfxLinkType::NativeWmf: nCvtType = ConvertDataFormat::WMF; break;
- case GfxLinkType::NativeMet: nCvtType = ConvertDataFormat::MET; break;
- case GfxLinkType::NativePct: nCvtType = ConvertDataFormat::PCT; break;
- case GfxLinkType::NativeSvg: nCvtType = ConvertDataFormat::SVG; break;
-
- default: nCvtType = ConvertDataFormat::Unknown; break;
+ case GfxLinkType::NativeGif: aShortName = GIF_SHORTNAME; break;
+ case GfxLinkType::NativeJpg: aShortName = JPG_SHORTNAME; break;
+ case GfxLinkType::NativePng: aShortName = PNG_SHORTNAME; break;
+ case GfxLinkType::NativeTif: aShortName = TIF_SHORTNAME; break;
+ case GfxLinkType::NativeWmf: aShortName = WMF_SHORTNAME; break;
+ case GfxLinkType::NativeMet: aShortName = MET_SHORTNAME; break;
+ case GfxLinkType::NativePct: aShortName = PCT_SHORTNAME; break;
+ case GfxLinkType::NativeSvg: aShortName = SVG_SHORTNAME; break;
+ case GfxLinkType::NativeBmp: aShortName = BMP_SHORTNAME; break;
+ case GfxLinkType::NativePdf: aShortName = PDF_SHORTNAME; break;
+ default: break;
+ }
+ if (!aShortName.isEmpty())
+ {
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+ sal_uInt16 nFormat = rFilter.GetImportFormatNumberForShortName(aShortName);
+ ErrCode nResult = rFilter.ImportGraphic(rGraphic, OUString(), aMemoryStream, nFormat);
+ if (nResult == ERRCODE_NONE)
+ bRet = true;
}
-
- if( nCvtType != ConvertDataFormat::Unknown && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
- bRet = true;
}
}
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index d22a29779d8b..dfb091362ec9 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -253,6 +253,16 @@ void Graphic::ImplTestRefCount()
}
}
+bool Graphic::isAvailable() const
+{
+ return mxImpGraphic->isAvailable();
+}
+
+bool Graphic::makeAvailable()
+{
+ return mxImpGraphic->makeAvailable();
+}
+
Graphic& Graphic::operator=( const Graphic& rGraphic )
{
if( &rGraphic != this )
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 64b5bab9ac75..798022e8f9f4 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -30,6 +30,7 @@
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/tempfile.hxx>
#include <vcl/outdev.hxx>
+#include <vcl/graphicfilter.hxx>
#include <vcl/virdev.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/cvtgrf.hxx>
@@ -106,6 +107,7 @@ ImpGraphic::ImpGraphic() :
mbSwapOut ( false ),
mbDummyContext ( false ),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared ( false ),
mnPageNumber(-1)
{
}
@@ -124,6 +126,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
, mpPdfData(rImpGraphic.mpPdfData)
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
+ , mbPrepared (rImpGraphic.mbPrepared)
, mnPageNumber(rImpGraphic.mnPageNumber)
{
if( rImpGraphic.mpGfxLink )
@@ -152,12 +155,25 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic)
, mpPdfData(std::move(rImpGraphic.mpPdfData))
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
+ , mbPrepared (rImpGraphic.mbPrepared)
, mnPageNumber(rImpGraphic.mnPageNumber)
{
rImpGraphic.ImplClear();
rImpGraphic.mbDummyContext = false;
}
+ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
+ meType ( GraphicType::Default ),
+ mnSizeBytes ( 0 ),
+ mbSwapOut ( false ),
+ mbDummyContext ( false ),
+ maGraphicExternalLink(rGraphicExternalLink),
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
+ mnPageNumber(-1)
+{
+}
+
ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
maEx ( rBitmap ),
meType ( !rBitmap.IsEmpty() ? GraphicType::Bitmap : GraphicType::NONE ),
@@ -165,6 +181,7 @@ ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
mbSwapOut ( false ),
mbDummyContext ( false ),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
mnPageNumber(-1)
{
}
@@ -176,6 +193,7 @@ ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
mbSwapOut ( false ),
mbDummyContext ( false ),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
mnPageNumber(-1)
{
}
@@ -187,6 +205,7 @@ ImpGraphic::ImpGraphic(const SvgDataPtr& rSvgDataPtr)
mbDummyContext ( false ),
maSvgData(rSvgDataPtr),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
mnPageNumber(-1)
{
}
@@ -199,6 +218,7 @@ ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
mbSwapOut ( false ),
mbDummyContext ( false ),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
mnPageNumber(-1)
{
}
@@ -210,6 +230,7 @@ ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
mbSwapOut ( false ),
mbDummyContext ( false ),
maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false),
mnPageNumber(-1)
{
}
@@ -249,6 +270,7 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
mbSwapOut = rImpGraphic.mbSwapOut;
mpSwapFile = rImpGraphic.mpSwapFile;
+ mbPrepared = rImpGraphic.mbPrepared;
mpGfxLink.reset();
@@ -284,6 +306,7 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
maSvgData = std::move(rImpGraphic.maSvgData);
mpPdfData = std::move(rImpGraphic.mpPdfData);
maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
+ mbPrepared = rImpGraphic.mbPrepared;
rImpGraphic.ImplClear();
rImpGraphic.mbDummyContext = false;
@@ -302,7 +325,11 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
if( this == &rImpGraphic )
bRet = true;
- else if( !ImplIsSwapOut() && ( rImpGraphic.meType == meType ) )
+ else if (mbPrepared && rImpGraphic.mbPrepared)
+ {
+ bRet = (*mpGfxLink == *rImpGraphic.mpGfxLink);
+ }
+ else if (isAvailable() && rImpGraphic.isAvailable())
{
switch( meType )
{
@@ -379,6 +406,11 @@ void ImpGraphic::ImplCreateSwapInfo()
{
maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
maSwapInfo.maPrefSize = ImplGetPrefSize();
+ maSwapInfo.mbIsAnimated = ImplIsAnimated();
+ maSwapInfo.mbIsEPS = ImplIsEPS();
+ maSwapInfo.mbIsTransparent = ImplIsTransparent();
+ maSwapInfo.mbIsAlpha = ImplIsAlpha();
+ maSwapInfo.mnAnimationLoopCount = ImplGetAnimationLoopCount();
}
}
@@ -416,10 +448,37 @@ ImpSwapFile::~ImpSwapFile()
}
}
+void ImpGraphic::ImplSetPrepared()
+{
+ mbPrepared = true;
+ mbSwapOut = true;
+ meType = GraphicType::Bitmap;
+
+ SvMemoryStream aMemoryStream(const_cast<sal_uInt8*>(mpGfxLink->GetData()), mpGfxLink->GetDataSize(), StreamMode::READ | StreamMode::WRITE);
+
+ GraphicDescriptor aDescriptor(aMemoryStream, nullptr);
+ if (aDescriptor.Detect(true))
+ {
+ maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
+ maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
+ }
+ maSwapInfo.mnAnimationLoopCount = 0;
+ maSwapInfo.mbIsAnimated = false;
+ maSwapInfo.mbIsEPS = false;
+ maSwapInfo.mbIsTransparent = false;
+ maSwapInfo.mbIsAlpha = false;
+
+ if (mpGfxLink->GetType() == GfxLinkType::NativeGif)
+ {
+ maSwapInfo.mbIsAnimated = true;
+ }
+}
+
void ImpGraphic::ImplClear()
{
mpSwapFile.reset();
mbSwapOut = false;
+ mbPrepared = false;
// cleanup
ImplClearGraphics();
@@ -445,11 +504,13 @@ bool ImpGraphic::ImplIsTransparent() const
{
bool bRet(true);
- ensureAvailable();
-
- if( meType == GraphicType::Bitmap && !maSvgData.get())
+ if (mbSwapOut)
{
- bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
+ bRet = maSwapInfo.mbIsTransparent;
+ }
+ else if (meType == GraphicType::Bitmap && !maSvgData.get())
+ {
+ bRet = mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent();
}
return bRet;
@@ -459,15 +520,17 @@ bool ImpGraphic::ImplIsAlpha() const
{
bool bRet(false);
- ensureAvailable();
-
- if(maSvgData.get())
+ if (mbSwapOut)
+ {
+ bRet = maSwapInfo.mbIsAlpha;
+ }
+ else if (maSvgData.get())
{
bRet = true;
}
- else if( meType == GraphicType::Bitmap )
+ else if (meType == GraphicType::Bitmap)
{
- bRet = ( nullptr == mpAnimation ) && maEx.IsAlpha();
+ bRet = (nullptr == mpAnimation && maEx.IsAlpha());
}
return bRet;
@@ -475,19 +538,29 @@ bool ImpGraphic::ImplIsAlpha() const
bool ImpGraphic::ImplIsAnimated() const
{
- ensureAvailable();
- return( mpAnimation != nullptr );
+ return mbSwapOut ? maSwapInfo.mbIsAnimated : mpAnimation != nullptr;
}
bool ImpGraphic::ImplIsEPS() const
{
- ensureAvailable();
+ if (mbSwapOut)
+ return maSwapInfo.mbIsEPS;
return( ( meType == GraphicType::GdiMetafile ) &&
( maMetaFile.GetActionSize() > 0 ) &&
( maMetaFile.GetAction( 0 )->GetType() == MetaActionType::EPS ) );
}
+bool ImpGraphic::isAvailable() const
+{
+ return !mbPrepared && !mbSwapOut;
+}
+
+bool ImpGraphic::makeAvailable()
+{
+ return ensureAvailable();
+}
+
Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
{
Bitmap aRetBmp;
@@ -697,8 +770,10 @@ Size ImpGraphic::ImplGetPrefSize() const
{
Size aSize;
- if( ImplIsSwapOut() )
+ if (ImplIsSwapOut())
+ {
aSize = maSwapInfo.maPrefSize;
+ }
else
{
switch( meType )
@@ -742,6 +817,8 @@ Size ImpGraphic::ImplGetPrefSize() const
void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
{
+ ensureAvailable();
+
switch( meType )
{
case GraphicType::NONE:
@@ -782,8 +859,10 @@ MapMode ImpGraphic::ImplGetPrefMapMode() const
{
MapMode aMapMode;
- if( ImplIsSwapOut() )
+ if (ImplIsSwapOut())
+ {
aMapMode = maSwapInfo.maPrefMapMode;
+ }
else
{
switch( meType )
@@ -823,6 +902,8 @@ MapMode ImpGraphic::ImplGetPrefMapMode() const
void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
{
+ ensureAvailable();
+
switch( meType )
{
case GraphicType::NONE:
@@ -863,6 +944,9 @@ sal_uLong ImpGraphic::ImplGetSizeBytes() const
{
if( 0 == mnSizeBytes )
{
+ if (mbPrepared)
+ ensureAvailable();
+
if( meType == GraphicType::Bitmap )
{
if(maSvgData.get())
@@ -977,12 +1061,16 @@ void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt
void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
{
+ ensureAvailable();
+
if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
mpAnimation->Stop( pOutDev, nExtraData );
}
void ImpGraphic::ImplSetAnimationNotifyHdl( const Link<Animation*,void>& rLink )
{
+ ensureAvailable();
+
if( mpAnimation )
mpAnimation->SetNotifyHdl( rLink );
}
@@ -991,6 +1079,8 @@ Link<Animation*,void> ImpGraphic::ImplGetAnimationNotifyHdl() const
{
Link<Animation*,void> aLink;
+ ensureAvailable();
+
if( mpAnimation )
aLink = mpAnimation->GetNotifyHdl();
@@ -999,8 +1089,10 @@ Link<Animation*,void> ImpGraphic::ImplGetAnimationNotifyHdl() const
sal_uInt32 ImpGraphic::ImplGetAnimationLoopCount() const
{
- ensureAvailable();
- return( mpAnimation ? mpAnimation->GetLoopCount() : 0 );
+ if (mbSwapOut)
+ return maSwapInfo.mnAnimationLoopCount;
+
+ return mpAnimation ? mpAnimation->GetLoopCount() : 0;
}
void ImpGraphic::ImplSetContext( const std::shared_ptr<GraphicReader>& pReader )
@@ -1011,6 +1103,8 @@ void ImpGraphic::ImplSetContext( const std::shared_ptr<GraphicReader>& pReader )
bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm )
{
+ ensureAvailable();
+
MapMode aMapMode;
Size aSize;
sal_uInt32 nId;
@@ -1318,17 +1412,37 @@ bool ImpGraphic::ImplSwapOut( SvStream* xOStm )
bool ImpGraphic::ensureAvailable() const
{
auto pThis = const_cast<ImpGraphic*>(this);
- pThis->maLastUsed = std::chrono::high_resolution_clock::now();
+
if (ImplIsSwapOut())
return pThis->ImplSwapIn();
+
+ pThis->maLastUsed = std::chrono::high_resolution_clock::now();
return true;
}
+bool ImpGraphic::loadPrepared()
+{
+ Graphic aGraphic;
+ if (mpGfxLink->LoadNative(aGraphic))
+ {
+ *this = *aGraphic.ImplGetImpGraphic();
+ return true;
+ }
+ return false;
+}
+
bool ImpGraphic::ImplSwapIn()
{
bool bRet = false;
- if( ImplIsSwapOut() )
+ if (!ImplIsSwapOut())
+ return bRet;
+
+ if (mbPrepared)
+ {
+ bRet = loadPrepared();
+ }
+ else
{
OUString aSwapURL;
@@ -1675,6 +1789,8 @@ SvStream& WriteImpGraphic( SvStream& rOStm, const ImpGraphic& rImpGraphic )
if (rOStm.GetError())
return rOStm;
+ rImpGraphic.ensureAvailable();
+
if (rImpGraphic.ImplIsSwapOut())
{
rOStm.SetError( SVSTREAM_GENERALERROR );
diff --git a/vcl/source/graphic/GraphicObject.cxx b/vcl/source/graphic/GraphicObject.cxx
index 67ef8a7b249b..444a5a26cf24 100644
--- a/vcl/source/graphic/GraphicObject.cxx
+++ b/vcl/source/graphic/GraphicObject.cxx
@@ -140,7 +140,7 @@ void GraphicObject::ImplAssignGraphicData()
mnSizeBytes = maGraphic.GetSizeBytes();
meType = maGraphic.GetType();
mbTransparent = maGraphic.IsTransparent();
- mbAlpha = maGraphic.IsAlpha();
+ // mbAlpha = maGraphic.IsAlpha();
mbAnimated = maGraphic.IsAnimated();
mbEPS = maGraphic.IsEPS();
mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
@@ -234,7 +234,37 @@ void GraphicObject::ImplAutoSwapIn()
}
}
-bool GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
+GraphicType GraphicObject::GetType() const
+{
+ return maGraphic.GetType();
+}
+
+Size GraphicObject::GetPrefSize() const
+{
+ return maGraphic.GetPrefSize();
+}
+
+MapMode GraphicObject::GetPrefMapMode() const
+{
+ return maGraphic.GetPrefMapMode();
+}
+
+bool GraphicObject::IsTransparent() const
+{
+ return maGraphic.IsTransparent();
+}
+
+bool GraphicObject::IsAnimated() const
+{
+ return maGraphic.IsAnimated();
+}
+
+bool GraphicObject::IsEPS() const
+{
+ return maGraphic.IsEPS();
+}
+
+bool GraphicObject::ImplGetCropParams( OutputDevice * pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
tools::PolyPolygon& rClipPolyPoly, bool& bRectClipRegion ) const
{
bool bRet = false;
@@ -316,7 +346,6 @@ GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
maAttr = rGraphicObj.maAttr;
maLink = rGraphicObj.maLink;
maUserData = rGraphicObj.maUserData;
- ImplAssignGraphicData();
mbAutoSwapped = false;
mpGlobalMgr->ImplRegisterObj( *this, maGraphic, nullptr, &rGraphicObj );
if( rGraphicObj.HasUserData() && rGraphicObj.IsSwappedOut() )
@@ -633,7 +662,6 @@ void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pC
maGraphic = rGraphic;
mbAutoSwapped = false;
- ImplAssignGraphicData();
maLink.clear();
mxSimpleCache.reset();
@@ -920,7 +948,7 @@ Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const /
if( ( GetType() == GraphicType::Bitmap ) && IsAnimated() )
{
Animation aAnimation( maGraphic.GetAnimation() );
- aAnimation.SetLoopCount( mnAnimationLoopCount );
+ aAnimation.SetLoopCount(maGraphic.GetAnimationLoopCount());
aGraphic = aAnimation;
}
else
diff --git a/vcl/source/graphic/GraphicObject2.cxx b/vcl/source/graphic/GraphicObject2.cxx
index 4fa85ee9d85a..87122f5af02d 100644
--- a/vcl/source/graphic/GraphicObject2.cxx
+++ b/vcl/source/graphic/GraphicObject2.cxx
@@ -165,8 +165,8 @@ void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
{
mpCache->GraphicObjectWasSwappedOut( rObj );
- assert(mnUsedSize >= rObj.GetSizeBytes());
- mnUsedSize -= rObj.GetSizeBytes();
+ assert(mnUsedSize >= rObj.GetGraphic().GetSizeBytes());
+ mnUsedSize -= rObj.GetGraphic().GetSizeBytes();
}
OString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
@@ -215,7 +215,7 @@ void GraphicManager::ImplCheckSizeOfSwappedInGraphics(const GraphicObject* pGrap
}
// do not swap out when we have less than 16KB data objects
- if(pObj->GetSizeBytes() >= (16 * 1024))
+ if(pObj->GetGraphic().GetSizeBytes() >= (16 * 1024))
{
pObj->FireSwapOutRequest();
}
diff --git a/vcl/source/graphic/Manager.cxx b/vcl/source/graphic/Manager.cxx
index be8343fa664a..7a959577313f 100644
--- a/vcl/source/graphic/Manager.cxx
+++ b/vcl/source/graphic/Manager.cxx
@@ -68,7 +68,7 @@ void Manager::reduceGraphicMemory()
if (mnUsedSize < mnTotalCacheSize * 0.7)
return;
- sal_Int64 nCurrentGraphicSize = pEachImpGraphic->ImplGetSizeBytes();
+ sal_Int64 nCurrentGraphicSize = getGraphicSizeBytes(pEachImpGraphic);
if (!pEachImpGraphic->ImplIsSwapOut() && nCurrentGraphicSize > 1000000)
{
if (!pEachImpGraphic->mpContext)
@@ -84,6 +84,13 @@ void Manager::reduceGraphicMemory()
}
}
+sal_Int64 Manager::getGraphicSizeBytes(const ImpGraphic* pImpGraphic)
+{
+ if (!pImpGraphic->isAvailable())
+ return 0;
+ return pImpGraphic->ImplGetSizeBytes();
+}
+
IMPL_LINK(Manager, SwapOutTimerHandler, Timer*, pTimer, void)
{
pTimer->Stop();
@@ -99,7 +106,7 @@ void Manager::registerGraphic(std::shared_ptr<ImpGraphic>& pImpGraphic,
reduceGraphicMemory();
// Insert and update the used size (bytes)
- mnUsedSize += pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize += getGraphicSizeBytes(pImpGraphic.get());
m_pImpGraphicList.insert(pImpGraphic.get());
// calculate size of the graphic set
@@ -108,7 +115,7 @@ void Manager::registerGraphic(std::shared_ptr<ImpGraphic>& pImpGraphic,
{
if (!pEachImpGraphic->ImplIsSwapOut())
{
- calculatedSize += pEachImpGraphic->ImplGetSizeBytes();
+ calculatedSize += getGraphicSizeBytes(pEachImpGraphic);
}
}
@@ -123,7 +130,7 @@ void Manager::registerGraphic(std::shared_ptr<ImpGraphic>& pImpGraphic,
void Manager::unregisterGraphic(ImpGraphic* pImpGraphic)
{
- mnUsedSize -= pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize -= getGraphicSizeBytes(pImpGraphic);
m_pImpGraphicList.erase(pImpGraphic);
}
@@ -178,18 +185,18 @@ std::shared_ptr<ImpGraphic> Manager::newInstance(const GDIMetaFile& rMetaFile)
void Manager::swappedIn(const ImpGraphic* pImpGraphic)
{
- mnUsedSize += pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize += getGraphicSizeBytes(pImpGraphic);
}
void Manager::swappedOut(const ImpGraphic* pImpGraphic)
{
- mnUsedSize -= pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize -= getGraphicSizeBytes(pImpGraphic);
}
void Manager::changeExisting(const ImpGraphic* pImpGraphic, sal_Int64 nOldSizeBytes)
{
mnUsedSize -= nOldSizeBytes;
- mnUsedSize += pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize += getGraphicSizeBytes(pImpGraphic);
}
}
} // end vcl::graphic