summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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