summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-04-14 15:13:05 +0900
committerTomaž Vajngerl <quikee@gmail.com>2018-04-20 09:15:22 +0200
commit7b355669c6ddeab2e6cec692d6afdff41c61d0fb (patch)
tree46c55326bccfa68a2bb5fad6d637e0f4576c8d68
parent663fd3d6e1f93ec989dc289e688d5dbfe434cbca (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. Change-Id: Ia1218f93b1735402b7828404f65660e2d4acf32f Reviewed-on: https://gerrit.libreoffice.org/53016 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--include/svx/svdograf.hxx4
-rw-r--r--include/vcl/GraphicObject.hxx23
-rw-r--r--include/vcl/gfxlink.hxx10
-rw-r--r--include/vcl/graph.hxx3
-rw-r--r--include/vcl/graphicfilter.hxx3
-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.cxx4
-rw-r--r--svx/source/svdraw/svdograf.cxx6
-rw-r--r--svx/source/xml/xmlgrhlp.cxx15
-rw-r--r--sw/qa/extras/globalfilter/globalfilter.cxx5
-rw-r--r--vcl/inc/graphic/Manager.hxx2
-rw-r--r--vcl/inc/impgraph.hxx15
-rw-r--r--vcl/source/filter/graphicfilter.cxx227
-rw-r--r--vcl/source/gdi/gfxlink.cxx65
-rw-r--r--vcl/source/gdi/graph.cxx10
-rw-r--r--vcl/source/gdi/impgraph.cxx165
-rw-r--r--vcl/source/graphic/GraphicObject.cxx55
-rw-r--r--vcl/source/graphic/Manager.cxx21
24 files changed, 526 insertions, 136 deletions
diff --git a/include/svx/svdograf.hxx b/include/svx/svdograf.hxx
index f3b0b1946564..9b1a4631b376 100644
--- a/include/svx/svdograf.hxx
+++ b/include/svx/svdograf.hxx
@@ -156,8 +156,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 const & GetGrafStreamURL() const;
diff --git a/include/vcl/GraphicObject.hxx b/include/vcl/GraphicObject.hxx
index 140ea7402540..d9f60e49598d 100644
--- a/include/vcl/GraphicObject.hxx
+++ b/include/vcl/GraphicObject.hxx
@@ -172,19 +172,9 @@ class VCL_DLLPUBLIC GraphicObject
private:
Graphic maGraphic;
GraphicAttr maAttr;
- Size maPrefSize;
- MapMode maPrefMapMode;
- sal_uLong mnSizeBytes;
- GraphicType meType;
OUString maUserData;
std::unique_ptr<GrfSimpleCacheObj> mxSimpleCache;
- sal_uInt32 mnAnimationLoopCount;
- bool mbTransparent : 1;
- bool mbAnimated : 1;
- bool mbEPS : 1;
-
- void VCL_DLLPRIVATE ImplAssignGraphicData();
bool VCL_DLLPRIVATE ImplGetCropParams(
OutputDevice const * pOut,
Point& rPt,
@@ -342,13 +332,12 @@ 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; }
+ GraphicType GetType() const;
+ Size GetPrefSize() const;
+ MapMode GetPrefMapMode() const;
+ bool IsTransparent() const;
+ bool IsAnimated() const;
+ bool IsEPS() const;
bool Draw(
OutputDevice* pOut,
diff --git a/include/vcl/gfxlink.hxx b/include/vcl/gfxlink.hxx
index 2d84fd293e4f..054ab2cf2dca 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 d69b9e8538b0..8406686c6e09 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -144,6 +144,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 bc218851f412..adf308914837 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -98,6 +98,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
@@ -289,6 +290,8 @@ public:
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
WmfExternal const *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 1407b784fa9e..133b1bdae043 100644
--- a/sc/qa/extras/anchor.cxx
+++ b/sc/qa/extras/anchor.cxx
@@ -87,7 +87,7 @@ void ScAnchorTest::testUndoAnchor()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
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);
@@ -121,14 +121,14 @@ void ScAnchorTest::testUndoAnchor()
// Check anchor type
CPPUNIT_ASSERT_EQUAL(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_EQUAL(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
@@ -146,14 +146,14 @@ void ScAnchorTest::testUndoAnchor()
// Check anchor type
CPPUNIT_ASSERT_EQUAL(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_EQUAL(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 1339274f5ddd..2a7a76e244a8 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -3253,7 +3253,7 @@ void ScExportTest::testLinkedGraphicRT()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
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 368a2fafcd2b..e51b520d3130 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 fca7018e836d..f5c7c4e97d15 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -590,7 +590,7 @@ void SdExportTest::testLinkedGraphicRT()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedImportMessage.getStr(), int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedImportMessage.getStr(), sal_uLong(864900), rGraphicObj.GetSizeBytes());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedImportMessage.getStr(), sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
}
// Save and reload
@@ -615,7 +615,7 @@ void SdExportTest::testLinkedGraphicRT()
const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
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/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 018aef7e018b..48949649e8f5 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -282,7 +282,7 @@ sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
void SdrGrafObj::onGraphicChanged()
{
- if (!mpGraphicObject) // don't force swap-in for this
+ if (!mpGraphicObject || !mpGraphicObject->GetGraphic().isAvailable())
return;
const VectorGraphicDataPtr& rVectorGraphicDataPtr = mpGraphicObject->GetGraphic().getVectorGraphicData();
@@ -551,12 +551,12 @@ bool SdrGrafObj::IsSwappedOut() const
return false;
}
-const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
+MapMode SdrGrafObj::GetGrafPrefMapMode() const
{
return mpGraphicObject->GetPrefMapMode();
}
-const Size& SdrGrafObj::GetGrafPrefSize() const
+Size SdrGrafObj::GetGrafPrefSize() const
{
return mpGraphicObject->GetPrefSize();
}
diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx
index e420cc103274..971402aea6b0 100644
--- a/svx/source/xml/xmlgrhlp.cxx
+++ b/svx/source/xml/xmlgrhlp.cxx
@@ -493,15 +493,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;
}
void SvXMLGraphicHelper::Init( const uno::Reference < embed::XStorage >& rXMLStorage,
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index 66b0d72d31b3..2145eb9fde55 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -184,8 +184,9 @@ void Test::testLinkedGraphicRT()
CPPUNIT_ASSERT(pGrfNode);
const GraphicObject& rGraphicObj = pGrfNode->GetGrfObj(true);
- 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 4b4585203639..6dd88a5a4c1c 100644
--- a/vcl/inc/graphic/Manager.hxx
+++ b/vcl/inc/graphic/Manager.hxx
@@ -46,6 +46,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 814f9feed6f5..660fdfce81cd 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;
@@ -85,6 +92,7 @@ private:
GraphicExternalLink maGraphicExternalLink;
std::chrono::high_resolution_clock::time_point maLastUsed;
+ bool mbPrepared;
public:
ImpGraphic();
@@ -98,6 +106,8 @@ public:
ImpGraphic( const GDIMetaFile& rMtf );
~ImpGraphic();
+ void ImplSetPrepared();
+
private:
ImpGraphic& operator=( const ImpGraphic& rImpGraphic );
@@ -135,6 +145,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.
@@ -203,6 +216,8 @@ private:
void setPdfData(const 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 79c6e484fdc4..023c07ecb9a2 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -37,6 +37,7 @@
#include <vcl/pngwrite.hxx>
#include <vcl/vectorgraphicdata.hxx>
#include <vcl/virdev.hxx>
+#include <impgraph.hxx>
#include <vcl/svapp.hxx>
#include <osl/file.hxx>
#include <vcl/graphicfilter.hxx>
@@ -1441,6 +1442,231 @@ void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGra
}
}
+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 = ERRCODE_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 = ERRCODE_GRFILTER_FILTERERROR;
+ }
+ }
+ else if (aFilterName == IMP_PDF)
+ {
+ eLinkType = GfxLinkType::NativePdf;
+ }
+ else
+ {
+ nStatus = ERRCODE_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);
+ if( !pFilter )
+ nStatus = ERRCODE_GRFILTER_FILTERERROR;
+ else
+ {
+ PFilterCall pFunc = pFilter->GetImportFunction();
+
+ if (!pFunc)
+ nStatus = ERRCODE_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 = ERRCODE_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;
+}
+
ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
@@ -2272,6 +2498,7 @@ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData&, rData, bool )
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 c1b0cd4bd5df..885385cb51b0 100644
--- a/vcl/source/gdi/gfxlink.cxx
+++ b/vcl/source/gdi/gfxlink.cxx
@@ -24,21 +24,28 @@
#include <vcl/graph.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/cvtgrf.hxx>
+#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
@@ -98,31 +105,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 91dcad7e4ae5..9ba35ddd7366 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -257,6 +257,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 c4ef749ec6da..9cd9bbb11717 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>
@@ -103,6 +104,8 @@ Size GraphicReader::GetPreviewSize() const
GraphicID::GraphicID(ImpGraphic const & rGraphic)
{
+ rGraphic.ensureAvailable();
+
mnID1 = static_cast<sal_uLong>(rGraphic.ImplGetType()) << 28;
mnID2 = mnID3 = mnID4 = 0;
@@ -176,7 +179,8 @@ ImpGraphic::ImpGraphic() :
mnSizeBytes ( 0 ),
mbSwapOut ( false ),
mbDummyContext ( false ),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared ( false )
{
}
@@ -194,6 +198,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic)
, maPdfData(rImpGraphic.maPdfData)
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
+ , mbPrepared (rImpGraphic.mbPrepared)
{
if( rImpGraphic.mpGfxLink )
mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink );
@@ -221,6 +226,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic)
, maPdfData(std::move(rImpGraphic.maPdfData))
, maGraphicExternalLink(rImpGraphic.maGraphicExternalLink)
, maLastUsed (std::chrono::high_resolution_clock::now())
+ , mbPrepared (rImpGraphic.mbPrepared)
{
rImpGraphic.ImplClear();
rImpGraphic.mbDummyContext = false;
@@ -232,7 +238,8 @@ ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) :
mbSwapOut ( false ),
mbDummyContext ( false ),
maGraphicExternalLink(rGraphicExternalLink),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -242,7 +249,8 @@ ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
mnSizeBytes ( 0 ),
mbSwapOut ( false ),
mbDummyContext ( false ),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -252,7 +260,8 @@ ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
mnSizeBytes ( 0 ),
mbSwapOut ( false ),
mbDummyContext ( false ),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -262,7 +271,8 @@ ImpGraphic::ImpGraphic(const VectorGraphicDataPtr& rVectorGraphicDataPtr)
mbSwapOut( false ),
mbDummyContext ( false ),
maVectorGraphicData(rVectorGraphicDataPtr),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -273,7 +283,8 @@ ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
mnSizeBytes ( 0 ),
mbSwapOut ( false ),
mbDummyContext ( false ),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -283,7 +294,8 @@ ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
mnSizeBytes ( 0 ),
mbSwapOut ( false ),
mbDummyContext ( false ),
- maLastUsed (std::chrono::high_resolution_clock::now())
+ maLastUsed (std::chrono::high_resolution_clock::now()),
+ mbPrepared (false)
{
}
@@ -321,6 +333,7 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
mbSwapOut = rImpGraphic.mbSwapOut;
mpSwapFile = rImpGraphic.mpSwapFile;
+ mbPrepared = rImpGraphic.mbPrepared;
mpGfxLink.reset();
@@ -355,6 +368,7 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic)
maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData);
maPdfData = std::move(rImpGraphic.maPdfData);
maGraphicExternalLink = rImpGraphic.maGraphicExternalLink;
+ mbPrepared = rImpGraphic.mbPrepared;
rImpGraphic.ImplClear();
rImpGraphic.mbDummyContext = false;
@@ -371,7 +385,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 )
{
@@ -427,16 +445,22 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
const VectorGraphicDataPtr& ImpGraphic::getVectorGraphicData() const
{
+ ensureAvailable();
+
return maVectorGraphicData;
}
void ImpGraphic::setPdfData(const uno::Sequence<sal_Int8>& rPdfData)
{
+ ensureAvailable();
+
maPdfData = rPdfData;
}
const uno::Sequence<sal_Int8>& ImpGraphic::getPdfData() const
{
+ ensureAvailable();
+
return maPdfData;
}
@@ -446,6 +470,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();
}
}
@@ -483,10 +512,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();
@@ -512,11 +568,13 @@ bool ImpGraphic::ImplIsTransparent() const
{
bool bRet(true);
- ensureAvailable();
-
- if( meType == GraphicType::Bitmap && !maVectorGraphicData.get())
+ if (mbSwapOut)
+ {
+ bRet = maSwapInfo.mbIsTransparent;
+ }
+ else if (meType == GraphicType::Bitmap && !maVectorGraphicData.get())
{
- bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
+ bRet = mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent();
}
return bRet;
@@ -526,15 +584,17 @@ bool ImpGraphic::ImplIsAlpha() const
{
bool bRet(false);
- ensureAvailable();
-
- if(maVectorGraphicData.get())
+ if (mbSwapOut)
+ {
+ bRet = maSwapInfo.mbIsAlpha;
+ }
+ else if (maVectorGraphicData.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;
@@ -542,19 +602,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;
@@ -790,8 +860,10 @@ Size ImpGraphic::ImplGetPrefSize() const
{
Size aSize;
- if( ImplIsSwapOut() )
+ if (ImplIsSwapOut())
+ {
aSize = maSwapInfo.maPrefSize;
+ }
else
{
switch( meType )
@@ -835,6 +907,8 @@ Size ImpGraphic::ImplGetPrefSize() const
void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
{
+ ensureAvailable();
+
switch( meType )
{
case GraphicType::NONE:
@@ -875,8 +949,10 @@ MapMode ImpGraphic::ImplGetPrefMapMode() const
{
MapMode aMapMode;
- if( ImplIsSwapOut() )
+ if (ImplIsSwapOut())
+ {
aMapMode = maSwapInfo.maPrefMapMode;
+ }
else
{
switch( meType )
@@ -916,6 +992,8 @@ MapMode ImpGraphic::ImplGetPrefMapMode() const
void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
{
+ ensureAvailable();
+
switch( meType )
{
case GraphicType::NONE:
@@ -956,6 +1034,9 @@ sal_uLong ImpGraphic::ImplGetSizeBytes() const
{
if( 0 == mnSizeBytes )
{
+ if (mbPrepared)
+ ensureAvailable();
+
if( meType == GraphicType::Bitmap )
{
if(maVectorGraphicData.get())
@@ -1070,12 +1151,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 );
}
@@ -1084,6 +1169,8 @@ Link<Animation*,void> ImpGraphic::ImplGetAnimationNotifyHdl() const
{
Link<Animation*,void> aLink;
+ ensureAvailable();
+
if( mpAnimation )
aLink = mpAnimation->GetNotifyHdl();
@@ -1092,8 +1179,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 )
@@ -1104,6 +1193,8 @@ void ImpGraphic::ImplSetContext( const std::shared_ptr<GraphicReader>& pReader )
bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm )
{
+ ensureAvailable();
+
MapMode aMapMode;
Size aSize;
sal_uInt32 nId;
@@ -1405,17 +1496,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;
@@ -1763,6 +1874,8 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic)
if (rOStm.GetError())
return;
+ rImpGraphic.ensureAvailable();
+
if (rImpGraphic.ImplIsSwapOut())
{
rOStm.SetError( SVSTREAM_GENERALERROR );
diff --git a/vcl/source/graphic/GraphicObject.cxx b/vcl/source/graphic/GraphicObject.cxx
index b3f6a52f6b0b..c855c901b27c 100644
--- a/vcl/source/graphic/GraphicObject.cxx
+++ b/vcl/source/graphic/GraphicObject.cxx
@@ -303,27 +303,17 @@ struct GrfSimpleCacheObj
GraphicObject::GraphicObject()
{
- ImplAssignGraphicData();
}
GraphicObject::GraphicObject(const Graphic& rGraphic)
: maGraphic(rGraphic)
{
- ImplAssignGraphicData();
}
GraphicObject::GraphicObject(const GraphicObject& rGraphicObj)
: maGraphic(rGraphicObj.GetGraphic())
, maAttr(rGraphicObj.maAttr)
- , maPrefSize(rGraphicObj.maPrefSize)
- , maPrefMapMode(rGraphicObj.maPrefMapMode)
- , mnSizeBytes(rGraphicObj.mnSizeBytes)
- , meType(rGraphicObj.meType)
, maUserData(rGraphicObj.maUserData)
- , mnAnimationLoopCount(rGraphicObj.mnAnimationLoopCount)
- , mbTransparent(rGraphicObj.mbTransparent)
- , mbAnimated(rGraphicObj.mbAnimated)
- , mbEPS(rGraphicObj.mbEPS)
{
}
@@ -331,16 +321,34 @@ GraphicObject::~GraphicObject()
{
}
-void GraphicObject::ImplAssignGraphicData()
+GraphicType GraphicObject::GetType() const
{
- maPrefSize = maGraphic.GetPrefSize();
- maPrefMapMode = maGraphic.GetPrefMapMode();
- mnSizeBytes = maGraphic.GetSizeBytes();
- meType = maGraphic.GetType();
- mbTransparent = maGraphic.IsTransparent();
- mbAnimated = maGraphic.IsAnimated();
- mbEPS = maGraphic.IsEPS();
- mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
+ 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 const * pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
@@ -420,7 +428,6 @@ GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
maGraphic = rGraphicObj.GetGraphic();
maAttr = rGraphicObj.maAttr;
maUserData = rGraphicObj.maUserData;
- ImplAssignGraphicData();
}
return *this;
@@ -551,10 +558,9 @@ bool GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const
GetGraphic();
-
const GraphicAttr aAttr( GetAttr() );
- if( mbAnimated )
+ if (IsAnimated())
{
Point aPt( rPt );
Size aSz( rSz );
@@ -610,7 +616,6 @@ const Graphic& GraphicObject::GetGraphic() const
void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* /*pCopyObj*/)
{
maGraphic = rGraphic;
- ImplAssignGraphicData();
}
void GraphicObject::SetGraphic( const Graphic& rGraphic, const OUString& /*rLink*/ )
@@ -862,7 +867,7 @@ Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const
{
Animation aAnimation( maGraphic.GetAnimation() );
lclImplAdjust( aAnimation, aAttr, GraphicAdjustmentFlags::ALL );
- aAnimation.SetLoopCount( mnAnimationLoopCount );
+ aAnimation.SetLoopCount(maGraphic.GetAnimationLoopCount());
aGraphic = aAnimation;
}
else
@@ -884,7 +889,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/Manager.cxx b/vcl/source/graphic/Manager.cxx
index 549b9c6d6add..106677cc0db4 100644
--- a/vcl/source/graphic/Manager.cxx
+++ b/vcl/source/graphic/Manager.cxx
@@ -71,7 +71,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)
@@ -87,6 +87,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();
@@ -102,7 +109,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
@@ -111,7 +118,7 @@ void Manager::registerGraphic(std::shared_ptr<ImpGraphic>& pImpGraphic,
{
if (!pEachImpGraphic->ImplIsSwapOut())
{
- calculatedSize += pEachImpGraphic->ImplGetSizeBytes();
+ calculatedSize += getGraphicSizeBytes(pEachImpGraphic);
}
}
@@ -126,7 +133,7 @@ void Manager::registerGraphic(std::shared_ptr<ImpGraphic>& pImpGraphic,
void Manager::unregisterGraphic(ImpGraphic* pImpGraphic)
{
- mnUsedSize -= pImpGraphic->ImplGetSizeBytes();
+ mnUsedSize -= getGraphicSizeBytes(pImpGraphic);
m_pImpGraphicList.erase(pImpGraphic);
}
@@ -188,18 +195,18 @@ std::shared_ptr<ImpGraphic> Manager::newInstance(const GraphicExternalLink& rGra
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