summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-03-31 17:27:01 +0900
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-19 23:08:22 -0400
commit7be2fd11d068bdea630caad2607e6166b12b9288 (patch)
tree19e8f3f0d37c7f8d43a54cca8f336ae6eb36fc50
parent515abeeadd732ef1f7721eef544997668f75238d (diff)
vcl: detach usage and remove GraphicManager and GraphicCache
Also remove some GraphicObjectTest because they call into GraphicManager which now doesn't exist anymore. Reviewed-on: https://gerrit.libreoffice.org/52243 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit ea3d755ac949c1b6dada5c341e018f8c23f5d395) Change-Id: Ia434736d8611df629af3e897c878a7fb8bbe4706
-rw-r--r--include/vcl/GraphicObject.hxx159
-rw-r--r--include/vcl/graph.hxx2
-rw-r--r--svtools/qa/unit/GraphicObjectTest.cxx157
-rw-r--r--sw/source/core/doc/notxtfrm.cxx23
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/impgraph.hxx35
-rw-r--r--vcl/source/gdi/graph.cxx8
-rw-r--r--vcl/source/gdi/impgraph.cxx71
-rw-r--r--vcl/source/graphic/GraphicObject.cxx440
-rw-r--r--vcl/source/graphic/GraphicObject2.cxx1596
-rw-r--r--vcl/source/graphic/grfcache.cxx1289
-rw-r--r--vcl/source/graphic/grfcache.hxx138
12 files changed, 425 insertions, 3494 deletions
diff --git a/include/vcl/GraphicObject.hxx b/include/vcl/GraphicObject.hxx
index 1ad14e01216f..822f37abb72b 100644
--- a/include/vcl/GraphicObject.hxx
+++ b/include/vcl/GraphicObject.hxx
@@ -168,13 +168,9 @@ public:
class VCL_DLLPUBLIC GraphicObject
{
- friend class GraphicManager;
friend class SdrGrafObj;
private:
-
- static GraphicManager* mpGlobalMgr;
-
Graphic maGraphic;
GraphicAttr maAttr;
Size maPrefSize;
@@ -197,7 +193,6 @@ private:
bool mbEPS : 1;
bool mbIsInSwapIn : 1;
bool mbIsInSwapOut : 1;
- bool mbAlpha : 1;
void VCL_DLLPRIVATE ImplAssignGraphicData();
static void VCL_DLLPRIVATE ImplEnsureGraphicManager();
@@ -305,10 +300,6 @@ private:
) const;
DECL_LINK( ImplAutoSwapOutHdl, Timer*, void );
-
- // Handle evtl. needed AfterDataChanges, needs to be called when new
- // graphic data is swapped in/added to the GraphicManager
- void VCL_DLLPRIVATE ImplAfterDataChange();
protected:
SvStream* GetSwapStream() const;
@@ -317,8 +308,8 @@ protected:
public:
GraphicObject();
GraphicObject( const Graphic& rGraphic );
+ GraphicObject(const OString& rUniqueID);
GraphicObject( const GraphicObject& rCacheObj );
- explicit GraphicObject( const OString& rUniqueID );
~GraphicObject();
GraphicObject& operator=( const GraphicObject& rCacheObj );
@@ -331,21 +322,6 @@ public:
void FireSwapInRequest();
void FireSwapOutRequest();
- GraphicManager& GetGraphicManager() const
- {
- (void)this; // avoid loplugin:staticmethods because first GraphicManager ctor creates
- // mpGlobalMgr and the last GraphicManager dtor destroys it
- return *mpGlobalMgr;
- }
-
- bool IsCached(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicAttr* pAttr,
- GraphicManagerDrawFlags nFlags = GraphicManagerDrawFlags::STANDARD
- ) const;
-
const Graphic& GetGraphic() const;
void SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj = nullptr);
void SetGraphic( const Graphic& rGraphic, const OUString& rLink );
@@ -467,6 +443,8 @@ public:
void StopAnimation( OutputDevice* pOut = nullptr, long nExtraData = 0 );
+ static bool isGraphicObjectUniqueIdURL(OUString const & rURL);
+
static GraphicObject CreateGraphicObjectFromURL( const OUString &rURL );
// will inspect an object ( e.g. a control ) for any 'ImageURL'
// properties and return these in a vector. Note: this implementation
@@ -489,128 +467,23 @@ public:
sal_uLong GetDataChangeTimeStamp() const { return mnDataChangeTimeStamp; }
};
-class VCL_DLLPUBLIC GraphicManager
+namespace vcl
+{
+namespace graphic
{
- friend class GraphicObject;
- friend class GraphicDisplayCacheEntry;
-private:
+// Will search an object ( e.g. a control ) for any 'ImageURL' or 'Graphic'
+// properties and return graphics from the properties in a vector. ImageURL
+// will be loaded from the URL.
+//
+// Note: this implementation will cater for XNameContainer objects and deep inspect any containers
+// if they exist
- std::unordered_set< GraphicObject* > maObjList;
- sal_uLong mnUsedSize; // currently used memory footprint of all swapped in graphics
- GraphicCache* mpCache;
-
- GraphicManager( const GraphicManager& ) {}
- GraphicManager& operator=( const GraphicManager& ) { return *this; }
-
- bool VCL_DLLPRIVATE ImplDraw(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- GraphicObject& rObj,
- const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags,
- bool& rCached
- );
-
- static bool VCL_DLLPRIVATE ImplCreateOutput(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const BitmapEx& rBmpEx,
- const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags,
- BitmapEx* pBmpEx = nullptr
- );
- static bool VCL_DLLPRIVATE ImplCreateOutput(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GDIMetaFile& rMtf,
- const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags,
- GDIMetaFile& rOutMtf,
- BitmapEx& rOutBmpEx
- );
-
- static void VCL_DLLPRIVATE ImplAdjust(
- BitmapEx& rBmpEx,
- const GraphicAttr& rAttr,
- GraphicAdjustmentFlags nAdjustmentFlags
- );
- static void VCL_DLLPRIVATE ImplAdjust(
- GDIMetaFile& rMtf,
- const GraphicAttr& rAttr,
- GraphicAdjustmentFlags nAdjustmentFlags
- );
- static void VCL_DLLPRIVATE ImplAdjust(
- Animation& rAnimation,
- const GraphicAttr& rAttr,
- GraphicAdjustmentFlags nAdjustmentFlags
- );
-
- static void VCL_DLLPRIVATE ImplDraw(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GDIMetaFile& rMtf,
- const GraphicAttr& rAttr
- );
-
- // Only used by GraphicObject's Ctor's and Dtor's
- void VCL_DLLPRIVATE ImplRegisterObj(
- const GraphicObject& rObj,
- Graphic& rSubstitute,
- const OString* pID,
- const GraphicObject* pCopyObj
- );
- void VCL_DLLPRIVATE ImplUnregisterObj( const GraphicObject& rObj );
- bool VCL_DLLPRIVATE ImplHasObjects() const { return !maObjList.empty(); }
-
- // Only used in swap case by GraphicObject
- void VCL_DLLPRIVATE ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj );
- void VCL_DLLPRIVATE ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj );
-
- OString VCL_DLLPRIVATE ImplGetUniqueID( const GraphicObject& rObj ) const;
-
- // This method allows to check memory footprint for all currently swapped in GraphicObjects on this GraphicManager
- // which are based on Bitmaps. This is needed on 32Bit systems and only does something on those systems. The problem
- // to solve is that normally the SwapOut is timer-driven, but even with short timer settings there are situations
- // where this does not trigger - or in other words: A maximum limitation for GraphicManagers was not in place before.
- // For 32Bit systems this leads to situations where graphics will be missing. This method will actively swap out
- // the longest swapped in graphics until a maximum memory boundary (derived from user settings in tools/options/memory)
- // is no longer exceeded
- void VCL_DLLPRIVATE ImplCheckSizeOfSwappedInGraphics(const GraphicObject* pGraphicToIgnore);
-public:
+VCL_DLLPUBLIC void SearchForGraphics(css::uno::Reference<css::uno::XInterface> const & rxInterface,
+ std::vector<css::uno::Reference<css::graphic::XGraphic>> & raGraphicList);
- GraphicManager( sal_uLong nCacheSize, sal_uLong nMaxObjCacheSize );
- ~GraphicManager();
-
- void SetMaxCacheSize( sal_uLong nNewCacheSize );
- sal_uLong GetMaxCacheSize() const;
-
- void SetMaxObjCacheSize( sal_uLong nNewMaxObjSize );
-
- void SetCacheTimeout( sal_uLong nTimeoutSeconds );
-
- bool IsInCache(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr
- ) const;
-
- bool DrawObj(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- GraphicObject& rObj,
- const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags,
- bool& rCached
- );
-};
+}
+} // end namespace vcl::graphic
#endif // INCLUDED_VCL_GRAPHICOBJECT_HXX
diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx
index 5e6a47b09559..8bc96ddfab73 100644
--- a/include/vcl/graph.hxx
+++ b/include/vcl/graph.hxx
@@ -198,6 +198,8 @@ public:
OUString getOriginURL() const;
void setOriginURL(OUString const & rOriginURL);
+ OString getUniqueID() const;
+
public:
std::shared_ptr<GraphicReader>& GetContext();
diff --git a/svtools/qa/unit/GraphicObjectTest.cxx b/svtools/qa/unit/GraphicObjectTest.cxx
index e4709e23db3a..7d646dacd085 100644
--- a/svtools/qa/unit/GraphicObjectTest.cxx
+++ b/svtools/qa/unit/GraphicObjectTest.cxx
@@ -38,9 +38,7 @@ class GraphicObjectTest: public test::BootstrapFixture, public unotest::MacrosTe
public:
void testSwap();
- void testSizeBasedAutoSwap();
void testTdf88836();
- void testTdf88935();
void testPdf();
@@ -57,9 +55,7 @@ private:
private:
CPPUNIT_TEST_SUITE(GraphicObjectTest);
CPPUNIT_TEST(testSwap);
- CPPUNIT_TEST(testSizeBasedAutoSwap);
CPPUNIT_TEST(testTdf88836);
- CPPUNIT_TEST(testTdf88935);
CPPUNIT_TEST(testPdf);
CPPUNIT_TEST_SUITE_END();
};
@@ -147,92 +143,6 @@ void GraphicObjectTest::testSwap()
}
}
-void GraphicObjectTest::testSizeBasedAutoSwap()
-{
- // Set cache size to a very small value to check what happens
- {
- std::shared_ptr< comphelper::ConfigurationChanges > aBatch(comphelper::ConfigurationChanges::create());
- officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), aBatch);
- aBatch->commit();
- }
-
- uno::Reference< lang::XComponent > xComponent =
- loadFromDesktop(m_directories.getURLFromSrc("svtools/qa/unit/data/document_with_two_images.odt"), "com.sun.star.text.TextDocument");
-
- SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(xComponent.get());
- CPPUNIT_ASSERT(pTxtDoc);
- SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
- CPPUNIT_ASSERT(pDoc);
- SwNodes& aNodes = pDoc->GetNodes();
-
- // Find images
- const GraphicObject* pGrafObj1 = nullptr;
- const GraphicObject* pGrafObj2 = nullptr;
- for( sal_uLong nIndex = 0; nIndex < aNodes.Count(); ++nIndex)
- {
- if( aNodes[nIndex]->IsGrfNode() )
- {
- SwGrfNode* pGrfNode = aNodes[nIndex]->GetGrfNode();
- CPPUNIT_ASSERT(pGrfNode);
- if( !pGrafObj1 )
- {
- pGrafObj1 = &pGrfNode->GetGrfObj();
- }
- else
- {
- pGrafObj2 = &pGrfNode->GetGrfObj();
- }
- }
- }
- CPPUNIT_ASSERT_MESSAGE("Missing image", pGrafObj1 != nullptr && pGrafObj2 != nullptr);
-
- {
- // First image should be swapped out
- CPPUNIT_ASSERT(pGrafObj1->IsSwappedOut());
- CPPUNIT_ASSERT_EQUAL(sal_uLong(697230), pGrafObj1->GetGraphic().GetSizeBytes());
-
- // Still swapped out: size is cached
- CPPUNIT_ASSERT(pGrafObj1->IsSwappedOut());
- }
-
- {
- // Second image should be in the memory
- // Size based swap out is triggered by swap in, so the last swapped in image should be
- // in the memory despite of size limit is reached.
- CPPUNIT_ASSERT(!pGrafObj2->IsSwappedOut());
- CPPUNIT_ASSERT_EQUAL(sal_uLong(1620000), pGrafObj2->GetGraphic().GetSizeBytes());
- }
-
- // Swap in first image -> second image will be swapped out
- {
- pGrafObj1->GetGraphic(); // GetGraphic calls swap in on a const object
- CPPUNIT_ASSERT(!pGrafObj1->IsSwappedOut());
- CPPUNIT_ASSERT(pGrafObj2->IsSwappedOut());
- }
-
- // Swap in second image -> first image will be swapped out
- {
- pGrafObj2->GetGraphic(); // GetGraphic calls swap in on a const object
- CPPUNIT_ASSERT(!pGrafObj2->IsSwappedOut());
- CPPUNIT_ASSERT(pGrafObj1->IsSwappedOut());
- }
-
- // Use bigger cache
- {
- GraphicManager& rGrfMgr = pGrafObj1->GetGraphicManager();
- rGrfMgr.SetMaxCacheSize((pGrafObj1->GetGraphic().GetSizeBytes()+pGrafObj2->GetGraphic().GetSizeBytes())*10);
- }
- // Swap in both images -> both should be swapped in
- {
- pGrafObj1->GetGraphic();
- pGrafObj2->GetGraphic();
- CPPUNIT_ASSERT(!pGrafObj1->IsSwappedOut());
- CPPUNIT_ASSERT(!pGrafObj2->IsSwappedOut());
- }
-
- xComponent->dispose();
-}
-
void GraphicObjectTest::testTdf88836()
{
// Construction with empty bitmap -> type should be GraphicType::NONE
@@ -242,73 +152,6 @@ void GraphicObjectTest::testTdf88836()
CPPUNIT_ASSERT_EQUAL(int(GraphicType::NONE), int(aGraphic.GetType()));
}
-void GraphicObjectTest::testTdf88935()
-{
- // Cache size was not updated by deletion of graphic objects
-
- // Load a file with two images
- uno::Reference< lang::XComponent > xComponent =
- loadFromDesktop(m_directories.getURLFromSrc("svtools/qa/unit/data/document_with_two_images.odt"), "com.sun.star.text.TextDocument");
- SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(xComponent.get());
- CPPUNIT_ASSERT(pTxtDoc);
- SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
- CPPUNIT_ASSERT(pDoc);
- SwNodes& aNodes = pDoc->GetNodes();
-
- // Find images
- const GraphicObject* pGraphObj1 = nullptr;
- const GraphicObject* pGraphObj2 = nullptr;
- for( sal_uLong nIndex = 0; nIndex < aNodes.Count(); ++nIndex)
- {
- if( aNodes[nIndex]->IsGrfNode() )
- {
- SwGrfNode* pGrfNode = aNodes[nIndex]->GetGrfNode();
- CPPUNIT_ASSERT(pGrfNode);
- if( !pGraphObj1 )
- {
- pGraphObj1 = &pGrfNode->GetGrfObj();
- }
- else
- {
- pGraphObj2 = &pGrfNode->GetGrfObj();
- }
- }
- }
- CPPUNIT_ASSERT_MESSAGE("Missing image", pGraphObj1 != nullptr && pGraphObj2 != nullptr);
-
- // Set cache size
- {
- GraphicManager& rGrfMgr = pGraphObj1->GetGraphicManager();
- rGrfMgr.SetMaxCacheSize((pGraphObj1->GetGraphic().GetSizeBytes()+pGraphObj2->GetGraphic().GetSizeBytes())*10);
- }
-
- // Both images fit into the cache
- {
- pGraphObj1->GetGraphic();
- pGraphObj2->GetGraphic();
- CPPUNIT_ASSERT(!pGraphObj1->IsSwappedOut());
- CPPUNIT_ASSERT(!pGraphObj2->IsSwappedOut());
- }
-
- // Create and remove some copy of the first image
- for( int i = 0; i < 50; ++i )
- {
- GraphicObject aGraphObj3(*pGraphObj1);
- CPPUNIT_ASSERT(aGraphObj3.SwapOut());
- CPPUNIT_ASSERT(aGraphObj3.SwapIn());
- }
-
- // Both images fit into the cache
- {
- pGraphObj1->GetGraphic();
- pGraphObj2->GetGraphic();
- CPPUNIT_ASSERT(!pGraphObj1->IsSwappedOut());
- CPPUNIT_ASSERT(!pGraphObj2->IsSwappedOut());
- }
-
- xComponent->dispose();
-}
-
void GraphicObjectTest::testPdf()
{
#if HAVE_FEATURE_PDFIUM
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 1159fbdf3663..556727e5d504 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -583,29 +583,8 @@ void SwNoTextFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
case RES_GRF_REREAD_AND_INCACHE:
if( SwNodeType::Grf == GetNode()->GetNodeType() )
{
+ // TODO: Remove - due to GraphicObject refactoring
bComplete = false;
- SwGrfNode* pNd = static_cast<SwGrfNode*>( GetNode());
-
- SwViewShell* pVSh = pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
- if( pVSh )
- {
- GraphicAttr aAttr;
- if( pNd->GetGrfObj().IsCached( pVSh->GetOut(), Point(),
- Prt().SSize(), &pNd->GetGraphicAttr( aAttr, this ) ))
- {
- for(SwViewShell& rShell : pVSh->GetRingContainer())
- {
- SET_CURR_SHELL( &rShell );
- if( rShell.GetWin() )
- {
- if( rShell.IsPreview() )
- ::RepaintPagePreview( &rShell, Frame().SVRect() );
- else
- rShell.GetWin()->Invalidate( Frame().SVRect() );
- }
- }
- }
- }
}
break;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 6dfa6445a4ad..11e7fe32a1be 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -306,7 +306,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/graphic/GraphicLoader \
vcl/source/graphic/GraphicObject \
vcl/source/graphic/GraphicObject2 \
- vcl/source/graphic/grfcache \
vcl/source/graphic/grfattr \
vcl/source/graphic/Manager \
vcl/source/graphic/UnoGraphic \
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx
index 2383c1a5f53d..e36181321341 100644
--- a/vcl/inc/impgraph.hxx
+++ b/vcl/inc/impgraph.hxx
@@ -42,9 +42,35 @@ struct ImpSwapFile;
class GraphicConversionParameters;
class ImpGraphic;
+class GraphicID
+{
+private:
+ sal_uInt32 mnID1;
+ sal_uInt32 mnID2;
+ sal_uInt32 mnID3;
+ BitmapChecksum mnID4;
+
+public:
+ GraphicID(ImpGraphic& rGraphic);
+
+ bool operator==(const GraphicID& rID) const
+ {
+ return rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
+ rID.mnID3 == mnID3 && rID.mnID4 == mnID4;
+ }
+
+ bool IsEmpty() const
+ {
+ return 0 == mnID4;
+ }
+
+ OString getIDString() const;
+};
+
class ImpGraphic final
{
friend class Graphic;
+ friend class GraphicID;
friend class vcl::graphic::Manager;
private:
@@ -61,6 +87,8 @@ private:
bool mbSwapOut;
bool mbDummyContext;
SvgDataPtr maSvgData;
+ std::unique_ptr<GraphicID> mpGraphicID;
+
/// The PDF stream from which this Graphic is rendered,
/// as converted (version downgraded) from the original,
@@ -112,6 +140,13 @@ private:
return mpPdfData && mpPdfData->hasElements();
}
+ OString getUniqueID()
+ {
+ if (!mpGraphicID)
+ mpGraphicID.reset(new GraphicID(*this));
+ return mpGraphicID->getIDString();
+ }
+
void ImplCreateSwapInfo();
void ImplClearGraphics();
void ImplClear();
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index dfb091362ec9..ef10b004cf39 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -643,6 +643,14 @@ void Graphic::setOriginURL(OUString const & rOriginURL)
}
}
+OString Graphic::getUniqueID() const
+{
+ OString aUniqueString;
+ if (mxImpGraphic)
+ aUniqueString = mxImpGraphic->getUniqueID();
+ return aUniqueString;
+}
+
namespace {
struct Id: public rtl::Static<cppu::OImplementationId, Id> {};
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 004c315a8ea7..be5f442269a2 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -41,6 +41,7 @@
#include <vcl/dibtools.hxx>
#include <memory>
#include <o3tl/make_unique.hxx>
+#include <rtl/strbuf.hxx>
#include <vcl/pdfread.hxx>
@@ -101,6 +102,76 @@ Size GraphicReader::GetPreviewSize() const
return aSize;
}
+GraphicID::GraphicID(ImpGraphic & rGraphic)
+{
+ mnID1 = static_cast<sal_uLong>(rGraphic.ImplGetType()) << 28;
+ mnID2 = mnID3 = mnID4 = 0;
+
+ if (rGraphic.ImplGetType() == GraphicType::Bitmap)
+ {
+ if (rGraphic.getSvgData().get())
+ {
+ const SvgDataPtr& rSvgDataPtr = rGraphic.getSvgData();
+ const basegfx::B2DRange& rRange = rSvgDataPtr->getRange();
+
+ mnID1 |= rSvgDataPtr->getSvgDataArrayLength();
+ mnID2 = basegfx::fround(rRange.getWidth());
+ mnID3 = basegfx::fround(rRange.getHeight());
+ mnID4 = vcl_get_checksum(0, rSvgDataPtr->getSvgDataArray().getConstArray(), rSvgDataPtr->getSvgDataArrayLength());
+ }
+ else if (rGraphic.ImplIsAnimated())
+ {
+ const Animation aAnimation(rGraphic.ImplGetAnimation());
+
+ mnID1 |= ( aAnimation.Count() & 0x0fffffff );
+ mnID2 = aAnimation.GetDisplaySizePixel().Width();
+ mnID3 = aAnimation.GetDisplaySizePixel().Height();
+ mnID4 = rGraphic.ImplGetChecksum();
+ }
+ else
+ {
+ const BitmapEx aBmpEx(rGraphic.ImplGetBitmapEx(GraphicConversionParameters()));
+
+ mnID1 |= ( ( ( static_cast<sal_uLong>(aBmpEx.GetTransparentType()) << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
+ mnID2 = aBmpEx.GetSizePixel().Width();
+ mnID3 = aBmpEx.GetSizePixel().Height();
+ mnID4 = rGraphic.ImplGetChecksum();
+ }
+ }
+ else if (rGraphic.ImplGetType() == GraphicType::GdiMetafile)
+ {
+ const GDIMetaFile& rMtf = rGraphic.ImplGetGDIMetaFile();
+
+ mnID1 |= ( rMtf.GetActionSize() & 0x0fffffff );
+ mnID2 = rMtf.GetPrefSize().Width();
+ mnID3 = rMtf.GetPrefSize().Height();
+ mnID4 = rGraphic.ImplGetChecksum();
+ }
+}
+
+OString GraphicID::getIDString() const
+{
+ static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ OStringBuffer aHexStr;
+ sal_Int32 nShift, nIndex = 0;
+ aHexStr.setLength(24 + (2 * BITMAP_CHECKSUM_SIZE));
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ aHexStr[nIndex++] = aHexData[ ( mnID1 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ aHexStr[nIndex++] = aHexData[ ( mnID2 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
+
+ for( nShift = 28; nShift >= 0; nShift -= 4 )
+ aHexStr[nIndex++] = aHexData[ ( mnID3 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
+
+ for( nShift = ( 8 * BITMAP_CHECKSUM_SIZE ) - 4; nShift >= 0; nShift -= 4 )
+ aHexStr[nIndex++] = aHexData[ ( mnID4 >> static_cast<sal_uInt32>(nShift) ) & 0xf ];
+
+ return aHexStr.makeStringAndClear();
+}
+
ImpGraphic::ImpGraphic() :
meType ( GraphicType::NONE ),
mnSizeBytes ( 0UL ),
diff --git a/vcl/source/graphic/GraphicObject.cxx b/vcl/source/graphic/GraphicObject.cxx
index 444a5a26cf24..8e2df2a7f440 100644
--- a/vcl/source/graphic/GraphicObject.cxx
+++ b/vcl/source/graphic/GraphicObject.cxx
@@ -34,11 +34,15 @@
#include <vcl/metaact.hxx>
#include <vcl/virdev.hxx>
#include <vcl/GraphicObject.hxx>
+#include <vcl/GraphicLoader.hxx>
+#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <memory>
+
+using namespace css;
using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::UNO_QUERY;
@@ -46,7 +50,248 @@ using com::sun::star::uno::Sequence;
using com::sun::star::container::XNameContainer;
using com::sun::star::beans::XPropertySet;
-GraphicManager* GraphicObject::mpGlobalMgr = nullptr;
+#define WATERMARK_LUM_OFFSET 50
+#define WATERMARK_CON_OFFSET -70
+
+namespace vcl
+{
+namespace graphic
+{
+
+void SearchForGraphics(uno::Reference<uno::XInterface> const & xInterface,
+ std::vector<uno::Reference<css::graphic::XGraphic>> & raGraphicList)
+{
+ uno::Reference<beans::XPropertySet> xPropertySet(xInterface, UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ if (xPropertySet->getPropertySetInfo()->hasPropertyByName("ImageURL"))
+ {
+ OUString sURL;
+ xPropertySet->getPropertyValue("ImageURL") >>= sURL;
+ if (!sURL.isEmpty() && !GraphicObject::isGraphicObjectUniqueIdURL(sURL))
+ {
+ Graphic aGraphic = vcl::graphic::loadFromURL(sURL);
+ if (aGraphic)
+ {
+ raGraphicList.push_back(aGraphic.GetXGraphic());
+ }
+ }
+ } else if (xPropertySet->getPropertySetInfo()->hasPropertyByName("Graphic"))
+ {
+ uno::Reference<css::graphic::XGraphic> xGraphic;
+ xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
+ if (xGraphic.is())
+ {
+ raGraphicList.push_back(xGraphic);
+ }
+ }
+ }
+ Reference<XNameContainer> xContainer(xInterface, UNO_QUERY);
+ if (xContainer.is())
+ {
+ for (OUString const & rName : xContainer->getElementNames())
+ {
+ uno::Reference<XInterface> xInnerInterface;
+ xContainer->getByName(rName) >>= xInnerInterface;
+ SearchForGraphics(xInnerInterface, raGraphicList);
+ }
+ }
+}
+
+}} // end namespace vcl::graphic
+
+namespace
+{
+
+bool lclDrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
+ GraphicObject const & rObj, const GraphicAttr& rAttr)
+{
+ Point aPt( rPt );
+ Size aSz( rSz );
+ bool bRet = false;
+
+ if( ( rObj.GetType() == GraphicType::Bitmap ) || ( rObj.GetType() == GraphicType::GdiMetafile ) )
+ {
+ // simple output of transformed graphic
+ const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
+
+ if( aGraphic.IsSupportedGraphic() )
+ {
+ const sal_uInt16 nRot10 = rAttr.GetRotation() % 3600;
+
+ if( nRot10 )
+ {
+ tools::Polygon aPoly( Rectangle( aPt, aSz ) );
+
+ aPoly.Rotate( aPt, nRot10 );
+ const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
+ aPt = aRotBoundRect.TopLeft();
+ aSz = aRotBoundRect.GetSize();
+ }
+
+ aGraphic.Draw( pOut, aPt, aSz );
+ }
+
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void lclImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case GRAPHICDRAWMODE_MONO:
+ rBmpEx.Convert( BmpConversion::N1BitThreshold );
+ break;
+
+ case GRAPHICDRAWMODE_GREYS:
+ rBmpEx.Convert( BmpConversion::N8BitGreys );
+ break;
+
+ case GRAPHICDRAWMODE_WATERMARK:
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
+ {
+ rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
+ {
+ rBmpEx.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
+ {
+ rBmpEx.Rotate( aAttr.GetRotation(), COL_TRANSPARENT );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ rBmpEx.AdjustTransparency(aAttr.GetTransparency());
+ }
+}
+
+void lclImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case GRAPHICDRAWMODE_MONO:
+ rMtf.Convert( MtfConversion::N1BitThreshold );
+ break;
+
+ case GRAPHICDRAWMODE_GREYS:
+ rMtf.Convert( MtfConversion::N8BitGreys );
+ break;
+
+ case GRAPHICDRAWMODE_WATERMARK:
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
+ {
+ rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
+ {
+ rMtf.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
+ {
+ rMtf.Rotate( aAttr.GetRotation() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ OSL_FAIL( "Missing implementation: Mtf-Transparency" );
+ }
+}
+
+void lclImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
+{
+ GraphicAttr aAttr( rAttr );
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
+ {
+ switch( aAttr.GetDrawMode() )
+ {
+ case GRAPHICDRAWMODE_MONO:
+ rAnimation.Convert( BmpConversion::N1BitThreshold );
+ break;
+
+ case GRAPHICDRAWMODE_GREYS:
+ rAnimation.Convert( BmpConversion::N8BitGreys );
+ break;
+
+ case GRAPHICDRAWMODE_WATERMARK:
+ {
+ aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
+ aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
+ {
+ rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
+ aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
+ aAttr.GetGamma(), aAttr.IsInvert() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
+ {
+ rAnimation.Mirror( aAttr.GetMirrorFlags() );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
+ {
+ OSL_FAIL( "Missing implementation: Animation-Rotation" );
+ }
+
+ if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
+ {
+ OSL_FAIL( "Missing implementation: Animation-Transparency" );
+ }
+}
+
+} // end anonymous namespace
struct GrfSimpleCacheObj
{
@@ -57,19 +302,6 @@ struct GrfSimpleCacheObj
maGraphic( rGraphic ), maAttr( rAttr ) {}
};
-// unique increasing ID for being able to detect the GraphicObject with the
-// oldest last data changes
-static sal_uLong aIncrementingTimeOfLastDataChange = 1;
-
-void GraphicObject::ImplAfterDataChange()
-{
- // set unique timestamp ID of last data change
- mnDataChangeTimeStamp = aIncrementingTimeOfLastDataChange++;
-
- // check memory footprint of all GraphicObjects managed and evtl. take action
- mpGlobalMgr->ImplCheckSizeOfSwappedInGraphics(this);
-}
-
GraphicObject::GraphicObject()
: mbAutoSwapped(false)
, mbIsInSwapIn(false)
@@ -77,7 +309,6 @@ GraphicObject::GraphicObject()
{
ImplEnsureGraphicManager();
ImplAssignGraphicData();
- mpGlobalMgr->ImplRegisterObj(*this, maGraphic, nullptr, nullptr);
}
GraphicObject::GraphicObject(const Graphic& rGraphic)
@@ -88,7 +319,6 @@ GraphicObject::GraphicObject(const Graphic& rGraphic)
{
ImplEnsureGraphicManager();
ImplAssignGraphicData();
- mpGlobalMgr->ImplRegisterObj(*this, maGraphic, nullptr, nullptr);
}
GraphicObject::GraphicObject(const GraphicObject& rGraphicObj)
@@ -101,7 +331,6 @@ GraphicObject::GraphicObject(const GraphicObject& rGraphicObj)
, mbIsInSwapOut(false)
{
ImplAssignGraphicData();
- mpGlobalMgr->ImplRegisterObj(*this, maGraphic, nullptr, &rGraphicObj);
if( rGraphicObj.HasUserData() && rGraphicObj.IsSwappedOut() )
SetSwapState();
}
@@ -116,21 +345,12 @@ GraphicObject::GraphicObject(const OString& rUniqueID)
// assign default properties
ImplAssignGraphicData();
- mpGlobalMgr->ImplRegisterObj(*this, maGraphic, &rUniqueID, nullptr);
-
// update properties
ImplAssignGraphicData();
}
GraphicObject::~GraphicObject()
{
- mpGlobalMgr->ImplUnregisterObj( *this );
-
- if (!mpGlobalMgr->ImplHasObjects())
- {
- delete mpGlobalMgr;
- mpGlobalMgr = nullptr;
- }
}
void GraphicObject::ImplAssignGraphicData()
@@ -144,94 +364,66 @@ void GraphicObject::ImplAssignGraphicData()
mbAnimated = maGraphic.IsAnimated();
mbEPS = maGraphic.IsEPS();
mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
-
- // Handle evtl. needed AfterDataChanges
- ImplAfterDataChange();
}
void GraphicObject::ImplEnsureGraphicManager()
{
- if (!mpGlobalMgr)
- {
- if (!utl::ConfigManager::IsAvoidConfig())
- {
- mpGlobalMgr = new GraphicManager(
- (officecfg::Office::Common::Cache::GraphicManager::
- TotalCacheSize::get()),
- (officecfg::Office::Common::Cache::GraphicManager::
- ObjectCacheSize::get()));
- mpGlobalMgr->SetCacheTimeout(
- officecfg::Office::Common::Cache::GraphicManager::
- ObjectReleaseTime::get());
- }
- else
- {
- mpGlobalMgr = new GraphicManager(
- 20000,
- 20000);
- mpGlobalMgr->SetCacheTimeout(
- 20000);
- }
- }
}
void GraphicObject::ImplAutoSwapIn()
{
- if( IsSwappedOut() )
+ if( !IsSwappedOut() )
+ return;
+
{
+ mbIsInSwapIn = true;
+
+ if( maGraphic.SwapIn() )
+ mbAutoSwapped = false;
+ else
{
- mbIsInSwapIn = true;
+ SvStream* pStream = GetSwapStream();
- if( maGraphic.SwapIn() )
- mbAutoSwapped = false;
- else
+ if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
{
- SvStream* pStream = GetSwapStream();
-
- if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
+ if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
{
- if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
+ if( HasLink() )
{
- if( HasLink() )
+ OUString aURLStr;
+
+ if( osl::FileBase::getFileURLFromSystemPath( GetLink(), aURLStr ) == osl::FileBase::E_None )
{
- OUString aURLStr;
+ std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aURLStr, StreamMode::READ ));
- if( osl::FileBase::getFileURLFromSystemPath( GetLink(), aURLStr ) == osl::FileBase::E_None )
+ if( pIStm )
{
- std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aURLStr, StreamMode::READ ));
-
- if( pIStm )
- {
- ReadGraphic( *pIStm, maGraphic );
- mbAutoSwapped = ( maGraphic.GetType() != GraphicType::NONE );
- }
+ ReadGraphic( *pIStm, maGraphic );
+ mbAutoSwapped = ( maGraphic.GetType() != GraphicType::NONE );
}
}
}
- else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
- mbAutoSwapped = !maGraphic.SwapIn();
- else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
- mbAutoSwapped = maGraphic.IsSwapOut();
- else
- {
- mbAutoSwapped = !maGraphic.SwapIn( pStream );
- delete pStream;
- }
}
+ else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
+ mbAutoSwapped = !maGraphic.SwapIn();
+ else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
+ mbAutoSwapped = maGraphic.IsSwapOut();
else
{
- DBG_ASSERT( ( GraphicType::NONE == meType ) || ( GraphicType::Default == meType ),
- "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
+ mbAutoSwapped = !maGraphic.SwapIn( pStream );
+ delete pStream;
}
}
-
- mbIsInSwapIn = false;
-
- if (!mbAutoSwapped)
- mpGlobalMgr->ImplGraphicObjectWasSwappedIn( *this );
+ else
+ {
+ DBG_ASSERT( ( GraphicType::NONE == meType ) || ( GraphicType::Default == meType ),
+ "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
+ }
}
- ImplAssignGraphicData();
+
+ mbIsInSwapIn = false;
}
+ ImplAssignGraphicData();
}
GraphicType GraphicObject::GetType() const
@@ -337,8 +529,6 @@ GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
{
if( &rGraphicObj != this )
{
- mpGlobalMgr->ImplUnregisterObj( *this );
-
maSwapStreamHdl = Link<const GraphicObject*, SvStream*>();
mxSimpleCache.reset();
@@ -347,7 +537,6 @@ GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
maLink = rGraphicObj.maLink;
maUserData = rGraphicObj.maUserData;
mbAutoSwapped = false;
- mpGlobalMgr->ImplRegisterObj( *this, maGraphic, nullptr, &rGraphicObj );
if( rGraphicObj.HasUserData() && rGraphicObj.IsSwappedOut() )
SetSwapState();
}
@@ -367,7 +556,7 @@ OString GraphicObject::GetUniqueID() const
if ( !IsInSwapIn() && IsEPS() )
const_cast<GraphicObject*>(this)->FireSwapInRequest();
- return mpGlobalMgr->ImplGetUniqueID(*this);
+ return GetGraphic().getUniqueID();
}
SvStream* GraphicObject::GetSwapStream() const
@@ -452,29 +641,6 @@ void GraphicObject::FireSwapOutRequest()
ImplAutoSwapOutHdl( nullptr );
}
-bool GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicAttr* pAttr, GraphicManagerDrawFlags nFlags ) const
-{
- bool bRet;
-
- if( nFlags & GraphicManagerDrawFlags::CACHED )
- {
- Point aPt( rPt );
- Size aSz( rSz );
- if ( pAttr && pAttr->IsCropped() )
- {
- tools::PolyPolygon aClipPolyPoly;
- bool bRectClip;
- ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip );
- }
- bRet = mpGlobalMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
- }
- else
- bRet = false;
-
- return bRet;
-}
-
bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
const GraphicAttr* pAttr, GraphicManagerDrawFlags nFlags )
{
@@ -483,7 +649,6 @@ bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
Size aSz( rSz );
const DrawModeFlags nOldDrawMode = pOut->GetDrawMode();
bool bCropped = aAttr.IsCropped();
- bool bCached = false;
bool bRet;
// #i29534# Provide output rects for PDF writer
@@ -532,23 +697,13 @@ bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
}
}
- bRet = mpGlobalMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached );
+ bRet = lclDrawObj(pOut, aPt, aSz, *this, aAttr);
if( bCropped )
pOut->Pop();
pOut->SetDrawMode( nOldDrawMode );
- // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins
- // (code above needs to call GetGraphic twice)
- if( bCached )
- {
- if (mxSwapOutTimer)
- mxSwapOutTimer->Start();
- else
- FireSwapOutRequest();
- }
-
return bRet;
}
@@ -653,10 +808,8 @@ const Graphic& GraphicObject::GetGraphic() const
return maGraphic;
}
-void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
+void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* /*pCopyObj*/ )
{
- mpGlobalMgr->ImplUnregisterObj( *this );
-
if (mxSwapOutTimer)
mxSwapOutTimer->Stop();
@@ -665,12 +818,8 @@ void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pC
maLink.clear();
mxSimpleCache.reset();
- mpGlobalMgr->ImplRegisterObj( *this, maGraphic, nullptr, pCopyObj);
-
if (mxSwapOutTimer)
mxSwapOutTimer->Start();
-
-
}
void GraphicObject::SetGraphic( const Graphic& rGraphic, const OUString& rLink )
@@ -909,7 +1058,7 @@ Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMo
return aTransGraphic;
}
-Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl
+Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const
{
GetGraphic();
@@ -925,21 +1074,21 @@ Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const /
if( IsAnimated() )
{
Animation aAnimation( maGraphic.GetAnimation() );
- GraphicManager::ImplAdjust( aAnimation, aAttr, GraphicAdjustmentFlags::ALL );
+ lclImplAdjust( aAnimation, aAttr, GraphicAdjustmentFlags::ALL );
aAnimation.SetLoopCount( mnAnimationLoopCount );
aGraphic = aAnimation;
}
else
{
BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
- GraphicManager::ImplAdjust( aBmpEx, aAttr, GraphicAdjustmentFlags::ALL );
+ lclImplAdjust( aBmpEx, aAttr, GraphicAdjustmentFlags::ALL );
aGraphic = aBmpEx;
}
}
else
{
GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
- GraphicManager::ImplAdjust( aMtf, aAttr, GraphicAdjustmentFlags::ALL );
+ lclImplAdjust( aMtf, aAttr, GraphicAdjustmentFlags::ALL );
aGraphic = aMtf;
}
}
@@ -963,9 +1112,6 @@ bool GraphicObject::SwapOut()
{
const bool bRet = !mbAutoSwapped && maGraphic.SwapOut();
- if (bRet)
- mpGlobalMgr->ImplGraphicObjectWasSwappedOut( *this );
-
return bRet;
}
@@ -984,9 +1130,6 @@ bool GraphicObject::SwapOut( SvStream* pOStm )
{
bRet = bRet && maGraphic.SwapOut( pOStm );
}
-
- if (bRet)
- mpGlobalMgr->ImplGraphicObjectWasSwappedOut(*this);
}
catch(...)
{
@@ -1008,9 +1151,6 @@ bool GraphicObject::SwapIn()
else
{
bRet = maGraphic.SwapIn();
-
- if (bRet)
- mpGlobalMgr->ImplGraphicObjectWasSwappedIn(*this);
}
if( bRet )
@@ -1031,8 +1171,6 @@ void GraphicObject::SetSwapState()
if( !IsSwappedOut() )
{
mbAutoSwapped = true;
-
- mpGlobalMgr->ImplGraphicObjectWasSwappedOut(*this);
}
}
@@ -1069,6 +1207,12 @@ IMPL_LINK_NOARG(GraphicObject, ImplAutoSwapOutHdl, Timer *, void)
#define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
+bool GraphicObject::isGraphicObjectUniqueIdURL(OUString const & rURL)
+ {
+ const OUString aPrefix("vnd.sun.star.GraphicObject:");
+ return rURL.startsWith(aPrefix);
+ }
+
GraphicObject GraphicObject::CreateGraphicObjectFromURL( const OUString &rURL )
{
const OUString aPrefix( UNO_NAME_GRAPHOBJ_URLPREFIX );
diff --git a/vcl/source/graphic/GraphicObject2.cxx b/vcl/source/graphic/GraphicObject2.cxx
index 87122f5af02d..b96cd679c731 100644
--- a/vcl/source/graphic/GraphicObject2.cxx
+++ b/vcl/source/graphic/GraphicObject2.cxx
@@ -31,1605 +31,9 @@
#include <vcl/animate.hxx>
#include <vcl/alpha.hxx>
#include <vcl/virdev.hxx>
-#include "grfcache.hxx"
#include <vcl/GraphicObject.hxx>
#include <memory>
-
-#define WATERMARK_LUM_OFFSET 50
-#define WATERMARK_CON_OFFSET -70
-#define MAP( cVal0, cVal1, nFrac ) ((sal_uInt8)((((long)(cVal0)<<20)+nFrac*((long)(cVal1)-(cVal0)))>>20))
-
-
-GraphicManager::GraphicManager( sal_uLong nCacheSize, sal_uLong nMaxObjCacheSize ) :
- mnUsedSize(0),
- mpCache( new GraphicCache( nCacheSize, nMaxObjCacheSize ) )
-{
-}
-
-GraphicManager::~GraphicManager()
-{
- assert(maObjList.empty());
- delete mpCache;
-}
-
-void GraphicManager::SetMaxCacheSize( sal_uLong nNewCacheSize )
-{
- mpCache->SetMaxDisplayCacheSize( nNewCacheSize );
-}
-
-sal_uLong GraphicManager::GetMaxCacheSize() const
-{
- return mpCache->GetMaxDisplayCacheSize();
-}
-
-void GraphicManager::SetMaxObjCacheSize( sal_uLong nNewMaxObjSize )
-{
- mpCache->SetMaxObjDisplayCacheSize( nNewMaxObjSize );
-}
-
-void GraphicManager::SetCacheTimeout( sal_uLong nTimeoutSeconds )
-{
- mpCache->SetCacheTimeout( nTimeoutSeconds );
-}
-
-bool GraphicManager::IsInCache( OutputDevice* pOut, const Point& rPt,
- const Size& rSz, const GraphicObject& rObj,
- const GraphicAttr& rAttr ) const
-{
- return mpCache->IsInDisplayCache( pOut, rPt, rSz, rObj, rAttr );
-}
-
-bool GraphicManager::DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- GraphicObject& rObj, const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags, bool& rCached )
-{
- Point aPt( rPt );
- Size aSz( rSz );
- bool bRet = false;
-
- rCached = false;
-
- if( ( rObj.GetType() == GraphicType::Bitmap ) || ( rObj.GetType() == GraphicType::GdiMetafile ) )
- {
- // create output and fill cache
-
- if( rObj.IsAnimated() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ||
- ( !( nFlags & GraphicManagerDrawFlags::NO_SUBSTITUTE ) &&
- ( ( nFlags & GraphicManagerDrawFlags::SUBSTITUTE ) ||
- !( nFlags & GraphicManagerDrawFlags::CACHED ) ||
- ( pOut->GetConnectMetaFile() && !pOut->IsOutputEnabled() ) ) ) )
- {
- // simple output of transformed graphic
- const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
-
- if( aGraphic.IsSupportedGraphic() )
- {
- const sal_uInt16 nRot10 = rAttr.GetRotation() % 3600;
-
- if( nRot10 )
- {
- tools::Polygon aPoly( Rectangle( aPt, aSz ) );
-
- aPoly.Rotate( aPt, nRot10 );
- const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
- aPt = aRotBoundRect.TopLeft();
- aSz = aRotBoundRect.GetSize();
- }
-
- aGraphic.Draw( pOut, aPt, aSz );
- }
-
- bRet = true;
- }
-
- if( !bRet )
- {
- // cached/direct drawing
- if( !mpCache->DrawDisplayCacheObj( pOut, aPt, aSz, rObj, rAttr ) )
- bRet = ImplDraw( pOut, aPt, aSz, rObj, rAttr, nFlags, rCached );
- else
- bRet = rCached = true;
- }
- }
-
- return bRet;
-}
-
-void GraphicManager::ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute,
- const OString* pID, const GraphicObject* pCopyObj )
-{
- assert(maObjList.find(const_cast<GraphicObject*>(&rObj)) == maObjList.end());
-
- maObjList.emplace( const_cast<GraphicObject*>(&rObj) );
-
- mpCache->AddGraphicObject( rObj, rSubstitute, pID, pCopyObj );
- if( !rObj.IsSwappedOut() )
- mnUsedSize += rObj.maGraphic.GetSizeBytes();
-}
-
-void GraphicManager::ImplUnregisterObj( const GraphicObject& rObj )
-{
- mpCache->ReleaseGraphicObject( rObj );
- if( !rObj.IsSwappedOut() )
- {
- assert(mnUsedSize >= rObj.maGraphic.GetSizeBytes());
- mnUsedSize -= rObj.maGraphic.GetSizeBytes();
- }
- if ( 0 < maObjList.erase( const_cast<GraphicObject*>(&rObj) ) )
- return;
-
- assert(false); // surely it should have been registered?
-}
-
-void GraphicManager::ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj )
-{
- mpCache->GraphicObjectWasSwappedOut( rObj );
- assert(mnUsedSize >= rObj.GetGraphic().GetSizeBytes());
- mnUsedSize -= rObj.GetGraphic().GetSizeBytes();
-}
-
-OString GraphicManager::ImplGetUniqueID( const GraphicObject& rObj ) const
-{
- return mpCache->GetUniqueID( rObj );
-}
-
-namespace
-{
- struct simpleSortByDataChangeTimeStamp
- {
- bool operator() (GraphicObject* p1, GraphicObject* p2) const
- {
- return p1->GetDataChangeTimeStamp() < p2->GetDataChangeTimeStamp();
- }
- };
-} // end of anonymous namespace
-
-void GraphicManager::ImplCheckSizeOfSwappedInGraphics(const GraphicObject* pGraphicToIgnore)
-{
- // detect maximum allowed memory footprint. Use the user-settings of MaxCacheSize (defaulted
- // to 200MB).
- const sal_uLong nMaxCacheSize(GetMaxCacheSize());
-
- if(mnUsedSize > nMaxCacheSize)
- {
- // Copy the object list for now, because maObjList can change in the meantime unexpectedly.
- std::vector< GraphicObject* > aCandidates(maObjList.begin(), maObjList.end());
- // if we use more currently, sort by last DataChangeTimeStamp
- // sort by DataChangeTimeStamp so that the oldest get removed first
- std::sort(aCandidates.begin(), aCandidates.end(), simpleSortByDataChangeTimeStamp());
-
- for(decltype(aCandidates)::size_type a(0); mnUsedSize >= nMaxCacheSize && a < aCandidates.size(); a++)
- {
- // swap out until we have no more or the goal to use less than nMaxCacheSize
- // is reached
- GraphicObject* pObj = aCandidates[a];
- if( pObj == pGraphicToIgnore )
- {
- continue;
- }
- if (maObjList.find(pObj) == maObjList.end())
- {
- // object has been deleted when swapping out another one
- continue;
- }
-
- // do not swap out when we have less than 16KB data objects
- if(pObj->GetGraphic().GetSizeBytes() >= (16 * 1024))
- {
- pObj->FireSwapOutRequest();
- }
- }
- }
-}
-
-void GraphicManager::ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj )
-{
- mpCache->GraphicObjectWasSwappedIn( rObj );
- mnUsedSize += rObj.maGraphic.GetSizeBytes();
-}
-
-bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
- const Size& rSz, GraphicObject& rObj,
- const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags nFlags, bool& rCached )
-{
- const Graphic& rGraphic = rObj.GetGraphic();
- bool bRet = false;
-
- if( rGraphic.IsSupportedGraphic() && !rObj.IsSwappedOut() )
- {
- if( GraphicType::Bitmap == rGraphic.GetType() )
- {
- const BitmapEx aSrcBmpEx( rGraphic.GetBitmapEx() );
-
- // #i46805# No point in caching a bitmap that is rendered
- // via RectFill on the OutDev
- if( !(pOut->GetDrawMode() & ( DrawModeFlags::BlackBitmap | DrawModeFlags::WhiteBitmap )) &&
- mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
- {
- BitmapEx aDstBmpEx;
-
- if( ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags, &aDstBmpEx ) )
- {
- rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
- bRet = true;
- }
- }
-
- if( !bRet )
- bRet = ImplCreateOutput( pOut, rPt, rSz, aSrcBmpEx, rAttr, nFlags );
- }
- else
- {
- const GDIMetaFile& rSrcMtf = rGraphic.GetGDIMetaFile();
-
- if( mpCache->IsDisplayCacheable( pOut, rPt, rSz, rObj, rAttr ) )
- {
- GDIMetaFile aDstMtf;
- BitmapEx aContainedBmpEx;
-
- if( ImplCreateOutput( pOut, rPt, rSz, rSrcMtf, rAttr, nFlags, aDstMtf, aContainedBmpEx ) )
- {
- if( !!aContainedBmpEx )
- {
- // Use bitmap output method, if metafile basically contains only a single
- // bitmap (allows caching the resulting pixmap).
- BitmapEx aDstBmpEx;
-
- if( ImplCreateOutput( pOut, rPt, rSz, aContainedBmpEx, rAttr, nFlags, &aDstBmpEx ) )
- {
- rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstBmpEx );
- bRet = true;
- }
- }
- else
- {
- rCached = mpCache->CreateDisplayCacheObj( pOut, rPt, rSz, rObj, rAttr, aDstMtf );
- bRet = true;
- }
- }
- }
-
- if( !bRet )
- {
- const Graphic aGraphic( rObj.GetTransformedGraphic( &rAttr ) );
-
- if( aGraphic.IsSupportedGraphic() )
- {
- aGraphic.Draw( pOut, rPt, rSz );
- bRet = true;
- }
- }
- }
- }
-
- return bRet;
-}
-
-bool ImplCreateRotatedScaled( const BitmapEx& rBmpEx, const GraphicAttr& rAttributes,
- sal_uInt16 nRot10, const Size& rUnrotatedSzPix,
- long nStartX, long nEndX, long nStartY, long nEndY,
- BitmapEx& rOutBmpEx )
-{
- const long aUnrotatedWidth = rUnrotatedSzPix.Width();
- const long aUnrotatedHeight = rUnrotatedSzPix.Height();
- const long aBitmapWidth = rBmpEx.GetSizePixel().Width();
- const long aBitmapHeight = rBmpEx.GetSizePixel().Height();
-
- long nTmpX, nTmpY, nTmpFX, nTmpFY, nTmp;
- double fTmp;
-
- bool bHMirr( rAttributes.GetMirrorFlags() & BmpMirrorFlags::Horizontal );
- bool bVMirr( rAttributes.GetMirrorFlags() & BmpMirrorFlags::Vertical );
-
- std::unique_ptr<long[]> pMapIX(new long[ aUnrotatedWidth ]);
- std::unique_ptr<long[]> pMapFX(new long[ aUnrotatedWidth ]);
- std::unique_ptr<long[]> pMapIY(new long[ aUnrotatedHeight ]);
- std::unique_ptr<long[]> pMapFY(new long[ aUnrotatedHeight ]);
-
- double fRevScaleX;
- double fRevScaleY;
-
- bool scaleByAveraging = false;
-
- if(aBitmapWidth > 1 && aUnrotatedWidth > 1)
- {
- fRevScaleX = (double) ( aBitmapWidth - 1 ) / (double)( aUnrotatedWidth - 1 );
- // create horizontal mapping table
- long x;
- for( x = 0, nTmpX = aBitmapWidth - 1, nTmp = aBitmapWidth - 2 >= 0 ? aBitmapWidth -2 : 0L; x < aUnrotatedWidth; x++ )
- {
- fTmp = x * fRevScaleX;
-
- if( bHMirr )
- fTmp = nTmpX - fTmp;
-
- pMapIX[ x ] = MinMax( fTmp, 0, nTmp );
- pMapFX[ x ] = (long) ( ( fTmp - pMapIX[ x ] ) * 1048576.0 );
- }
- scaleByAveraging |= fRevScaleX > 5.0/3.0;
- }
- else
- {
- if(aBitmapWidth == 1)
- {
- fRevScaleX = 1.0 / (double)( aUnrotatedWidth );
- for ( long x = 0; x < aUnrotatedWidth ; x++)
- {
- pMapIX[x] = 0;
- pMapFX[x] = 0;
- }
- scaleByAveraging = true;
- }
- else
- {
- fRevScaleX = (double) aBitmapWidth / (double)( aUnrotatedWidth);
- fTmp = (double)aBitmapWidth / 2.0;
-
- pMapIX[ 0 ] = (long)fTmp;
- pMapFX[ 0 ] = (long)( ( fTmp - pMapIX[ 0 ] ) * 1048576.0 );
- scaleByAveraging = true;
- }
- }
- if(aBitmapHeight > 1 && aUnrotatedHeight > 1)
- {
- fRevScaleY = (double) ( aBitmapHeight - 1 ) / (double)( aUnrotatedHeight - 1 );
- // create vertical mapping table
- long y;
- for( y = 0, nTmpY = aBitmapHeight - 1, nTmp = aBitmapHeight - 2 >= 0 ? aBitmapHeight - 2 : 0L; y < aUnrotatedHeight; y++ )
- {
- fTmp = y * fRevScaleY;
-
- if( bVMirr )
- fTmp = nTmpY - fTmp;
-
- pMapIY[ y ] = MinMax( fTmp, 0, nTmp );
- pMapFY[ y ] = (long) ( ( fTmp - pMapIY[ y ] ) * 1048576.0 );
- }
- scaleByAveraging |= fRevScaleY > 5.0/3.0;
- }
- else
- {
- if(aBitmapHeight == 1)
- {
- fRevScaleY = 1.0 / (double)( aUnrotatedHeight);
- for (long y = 0; y < aUnrotatedHeight; ++y)
- {
- pMapIY[y] = 0;
- pMapFY[y] = 0;
- }
- scaleByAveraging = true;
- }
- else
- {
- fRevScaleY = (double) aBitmapHeight / (double)( aUnrotatedHeight);
- fTmp = (double)aBitmapHeight / 2.0;
-
- pMapIY[ 0 ] = (long)fTmp;
- pMapFY[ 0 ] = (long)( ( fTmp - pMapIY[ 0 ] ) * 1048576.0 );
- scaleByAveraging = true;
- }
- }
-
- Bitmap aBmp( rBmpEx.GetBitmap() );
- Bitmap aOutBmp;
- BitmapReadAccess* pReadAccess = aBmp.AcquireReadAccess();
- BitmapWriteAccess* pWriteAccess;
-
- const double fCosAngle = cos( nRot10 * F_PI1800 );
- const double fSinAngle = sin( nRot10 * F_PI1800 );
- const long aTargetWidth = nEndX - nStartX + 1;
- const long aTargetHeight = nEndY - nStartY + 1;
- std::unique_ptr<long[]> pCosX(new long[ aTargetWidth ]);
- std::unique_ptr<long[]> pSinX(new long[ aTargetWidth ]);
- std::unique_ptr<long[]> pCosY(new long[ aTargetHeight ]);
- std::unique_ptr<long[]> pSinY(new long[ aTargetHeight ]);
- long nUnRotX, nUnRotY, nSinY, nCosY;
- sal_uInt8 cR0, cG0, cB0, cR1, cG1, cB1;
- bool bRet = false;
-
- tools::Polygon aPoly( Rectangle( Point(), rUnrotatedSzPix ) );
- aPoly.Rotate( Point(), nRot10 );
- Rectangle aNewBound( aPoly.GetBoundRect() );
-
- // create horizontal mapping table
- long x;
- for( x = 0, nTmpX = aNewBound.Left() + nStartX; x < aTargetWidth; x++ )
- {
- pCosX[ x ] = FRound( fCosAngle * ( fTmp = nTmpX++ << 8 ) );
- pSinX[ x ] = FRound( fSinAngle * fTmp );
- }
-
- // create vertical mapping table
- long y;
- for( y = 0, nTmpY = aNewBound.Top() + nStartY; y < aTargetHeight; y++ )
- {
- pCosY[ y ] = FRound( fCosAngle * ( fTmp = nTmpY++ << 8 ) );
- pSinY[ y ] = FRound( fSinAngle * fTmp );
- }
-
- if( pReadAccess )
- {
- aOutBmp = Bitmap( Size( aTargetWidth, aTargetHeight ), 24 );
- pWriteAccess = aOutBmp.AcquireWriteAccess();
-
- if( pWriteAccess )
- {
- BitmapColor aColRes;
-
- if ( !scaleByAveraging )
- {
- if( pReadAccess->HasPalette() )
- {
- for( y = 0; y < aTargetHeight; y++ )
- {
- nSinY = pSinY[ y ];
- nCosY = pCosY[ y ];
-
- for( x = 0; x < aTargetWidth; x++ )
- {
- nUnRotX = ( pCosX[ x ] - nSinY ) >> 8;
- nUnRotY = ( pSinX[ x ] + nCosY ) >> 8;
-
- if( ( nUnRotX >= 0 ) && ( nUnRotX < aUnrotatedWidth ) &&
- ( nUnRotY >= 0 ) && ( nUnRotY < aUnrotatedHeight ) )
- {
- nTmpX = pMapIX[ nUnRotX ];
- nTmpFX = pMapFX[ nUnRotX ];
- nTmpY = pMapIY[ nUnRotY ];
- nTmpFY = pMapFY[ nUnRotY ];
-
- const BitmapColor& rCol0 = pReadAccess->GetPaletteColor( pReadAccess->GetPixelIndex( nTmpY, nTmpX ) );
- const BitmapColor& rCol1 = pReadAccess->GetPaletteColor( pReadAccess->GetPixelIndex( nTmpY, ++nTmpX ) );
- cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTmpFX );
- cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTmpFX );
- cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTmpFX );
-
- const BitmapColor& rCol3 = pReadAccess->GetPaletteColor( pReadAccess->GetPixelIndex( ++nTmpY, nTmpX ) );
- const BitmapColor& rCol2 = pReadAccess->GetPaletteColor( pReadAccess->GetPixelIndex( nTmpY, --nTmpX ) );
- cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTmpFX );
- cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTmpFX );
- cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTmpFX );
-
- aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
- aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
- aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
- pWriteAccess->SetPixel( y, x, aColRes );
- }
- }
- }
- }
- else
- {
- BitmapColor aCol0, aCol1;
-
- for( y = 0; y < aTargetHeight; y++ )
- {
- nSinY = pSinY[ y ];
- nCosY = pCosY[ y ];
-
- for( x = 0; x < aTargetWidth; x++ )
- {
- nUnRotX = ( pCosX[ x ] - nSinY ) >> 8;
- nUnRotY = ( pSinX[ x ] + nCosY ) >> 8;
-
- if( ( nUnRotX >= 0 ) && ( nUnRotX < aUnrotatedWidth ) &&
- ( nUnRotY >= 0 ) && ( nUnRotY < aUnrotatedHeight ) )
- {
- nTmpX = pMapIX[ nUnRotX ];
- nTmpFX = pMapFX[ nUnRotX ];
- nTmpY = pMapIY[ nUnRotY ];
- nTmpFY = pMapFY[ nUnRotY ];
-
- aCol0 = pReadAccess->GetPixel( nTmpY, nTmpX );
- aCol1 = pReadAccess->GetPixel( nTmpY, ++nTmpX );
- cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
- cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
- cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
-
- aCol1 = pReadAccess->GetPixel( ++nTmpY, nTmpX );
- aCol0 = pReadAccess->GetPixel( nTmpY, --nTmpX );
- cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTmpFX );
- cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTmpFX );
- cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTmpFX );
-
- aColRes.SetRed( MAP( cR0, cR1, nTmpFY ) );
- aColRes.SetGreen( MAP( cG0, cG1, nTmpFY ) );
- aColRes.SetBlue( MAP( cB0, cB1, nTmpFY ) );
- pWriteAccess->SetPixel( y, x, aColRes );
- }
- }
- }
- }
- }
- else // scaleByAveraging
- {
- double aSumRed, aSumGreen, aSumBlue, aCount;
- BitmapColor aColor;
- BitmapColor aResultColor;
-
- for( y = 0; y < aTargetHeight; y++ )
- {
- nSinY = pSinY[ y ];
- nCosY = pCosY[ y ];
-
- for( x = 0; x < aTargetWidth; x++ )
- {
- double aUnrotatedX = ( pCosX[ x ] - nSinY ) / 256.0;
- double aUnrotatedY = ( pSinX[ x ] + nCosY ) / 256.0;
-
- if ( bHMirr )
- aUnrotatedX = aUnrotatedWidth - aUnrotatedX - 1;
- if ( bVMirr )
- aUnrotatedY = aUnrotatedHeight - aUnrotatedY - 1;
-
- if( ( aUnrotatedX >= 0 ) && ( aUnrotatedX < aUnrotatedWidth ) &&
- ( aUnrotatedY >= 0 ) && ( aUnrotatedY < aUnrotatedHeight ) )
- {
- double dYStart = ((aUnrotatedY + 0.5) * fRevScaleY) - 0.5;
- double dYEnd = ((aUnrotatedY + 1.5) * fRevScaleY) - 0.5;
-
- int yStart = MinMax( dYStart, 0, aBitmapHeight - 1);
- int yEnd = MinMax( dYEnd, 0, aBitmapHeight - 1);
-
- double dXStart = ((aUnrotatedX + 0.5) * fRevScaleX) - 0.5;
- double dXEnd = ((aUnrotatedX + 1.5) * fRevScaleX) - 0.5;
-
- int xStart = MinMax( dXStart, 0, aBitmapWidth - 1);
- int xEnd = MinMax( dXEnd, 0, aBitmapWidth - 1);
-
- aSumRed = aSumGreen = aSumBlue = 0.0;
- aCount = 0;
-
- for (int yIn = yStart; yIn <= yEnd; yIn++)
- {
- for (int xIn = xStart; xIn <= xEnd; xIn++)
- {
- if( pReadAccess->HasPalette() )
- aColor = pReadAccess->GetPaletteColor( pReadAccess->GetPixelIndex( yIn, xIn ) );
- else
- aColor = pReadAccess->GetPixel( yIn, xIn );
-
- aSumRed += aColor.GetRed();
- aSumGreen += aColor.GetGreen();
- aSumBlue += aColor.GetBlue();
-
- aCount++;
- }
- }
-
- aResultColor.SetRed( MinMax( aSumRed / aCount, 0, 255) );
- aResultColor.SetGreen( MinMax( aSumGreen / aCount, 0, 255) );
- aResultColor.SetBlue( MinMax( aSumBlue / aCount, 0, 255) );
-
- pWriteAccess->SetPixel( y, x, aResultColor );
- }
- }
- }
- }
-
- Bitmap::ReleaseAccess( pWriteAccess );
- bRet = true;
- }
-
- Bitmap::ReleaseAccess( pReadAccess );
- }
-
- // mask processing
- if( bRet && ( rBmpEx.IsTransparent() || ( nRot10 != 0 && nRot10 != 900 && nRot10 != 1800 && nRot10 != 2700 ) ) )
- {
- bRet = false;
-
- if( rBmpEx.IsAlpha() )
- {
- AlphaMask aAlpha( rBmpEx.GetAlpha() );
- AlphaMask aOutAlpha;
-
- pReadAccess = aAlpha.AcquireReadAccess();
-
- if( pReadAccess )
- {
- aOutAlpha = AlphaMask( Size( aTargetWidth, aTargetHeight ) );
- pWriteAccess = aOutAlpha.AcquireWriteAccess();
-
- if( pWriteAccess )
- {
- if( pReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal &&
- pWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal )
- {
- if ( !scaleByAveraging )
- {
- Scanline pLine0, pLine1, pLineW;
-
- for( long nY = 0; nY < aTargetHeight; nY++ )
- {
- nSinY = pSinY[ nY ];
- nCosY = pCosY[ nY ];
- pLineW = pWriteAccess->GetScanline( nY );
-
- for( long nX = 0; nX < aTargetWidth; nX++ )
- {
- nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
- nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
-
- if( ( nUnRotX >= 0 ) && ( nUnRotX < aUnrotatedWidth ) &&
- ( nUnRotY >= 0 ) && ( nUnRotY < aUnrotatedHeight ) )
- {
- nTmpX = pMapIX[ nUnRotX ];
- nTmpFX = pMapFX[ nUnRotX ];
- nTmpY = pMapIY[ nUnRotY ];
- nTmpFY = pMapFY[ nUnRotY ];
-
- pLine0 = pReadAccess->GetScanline( nTmpY++ );
- pLine1 = pReadAccess->GetScanline( nTmpY );
-
- const long nAlpha0 = pLine0[ nTmpX ];
- const long nAlpha2 = pLine1[ nTmpX++ ];
- const long nAlpha1 = pLine0[ nTmpX ];
- const long nAlpha3 = pLine1[ nTmpX ];
- const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
- const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
-
- *pLineW++ = MAP( n0, n1, nTmpFY );
- }
- else
- *pLineW++ = 255;
- }
- }
- }
- else // scaleByAveraging
- {
- const BitmapColor aTrans( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
- BitmapColor aResultColor( 0 );
- double aSum, aCount;
-
- for( y = 0; y < aTargetHeight; y++ )
- {
- nSinY = pSinY[ y ];
- nCosY = pCosY[ y ];
-
- for( x = 0; x < aTargetWidth; x++ )
- {
-
- double aUnrotatedX = ( pCosX[ x ] - nSinY ) / 256.0;
- double aUnrotatedY = ( pSinX[ x ] + nCosY ) / 256.0;
-
- if ( bHMirr )
- aUnrotatedX = aUnrotatedWidth - aUnrotatedX - 1;
- if ( bVMirr )
- aUnrotatedY = aUnrotatedHeight - aUnrotatedY - 1;
-
- if( ( aUnrotatedX >= 0 ) && ( aUnrotatedX < aUnrotatedWidth ) &&
- ( aUnrotatedY >= 0 ) && ( aUnrotatedY < aUnrotatedHeight ) )
- {
- double dYStart = ((aUnrotatedY + 0.5) * fRevScaleY) - 0.5;
- double dYEnd = ((aUnrotatedY + 1.5) * fRevScaleY) - 0.5;
-
- int yStart = MinMax( dYStart, 0, aBitmapHeight - 1);
- int yEnd = MinMax( dYEnd, 0, aBitmapHeight - 1);
-
- double dXStart = ((aUnrotatedX + 0.5) * fRevScaleX) - 0.5;
- double dXEnd = ((aUnrotatedX + 1.5) * fRevScaleX) - 0.5;
-
- int xStart = MinMax( dXStart, 0, aBitmapWidth - 1);
- int xEnd = MinMax( dXEnd, 0, aBitmapWidth - 1);
-
- aSum = 0.0;
- aCount = 0;
-
- for (int yIn = yStart; yIn <= yEnd; yIn++)
- {
- for (int xIn = xStart; xIn <= xEnd; xIn++)
- {
- aSum += pReadAccess->GetPixel( yIn, xIn ).GetIndex();
- aCount++;
- }
- }
- aResultColor.SetIndex( MinMax( aSum / aCount, 0, 255) );
- pWriteAccess->SetPixel( y, x, aResultColor );
- }
- else
- {
- pWriteAccess->SetPixel( y, x, aTrans );
- }
- }
- }
- }
- }
- else
- {
- const BitmapColor aTrans( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
- BitmapColor aAlphaVal( 0 );
-
- for( long nY = 0; nY < aTargetHeight; nY++ )
- {
- nSinY = pSinY[ nY ];
- nCosY = pCosY[ nY ];
-
- for( long nX = 0; nX < aTargetWidth; nX++ )
- {
- nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
- nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
-
- if( ( nUnRotX >= 0 ) && ( nUnRotX < aUnrotatedWidth ) &&
- ( nUnRotY >= 0 ) && ( nUnRotY < aUnrotatedHeight ) )
- {
- nTmpX = pMapIX[ nUnRotX ];
- nTmpFX = pMapFX[ nUnRotX ];
- nTmpY = pMapIY[ nUnRotY ];
- nTmpFY = pMapFY[ nUnRotY ];
-
- const long nAlpha0 = pReadAccess->GetPixel( nTmpY, nTmpX ).GetIndex();
- const long nAlpha1 = pReadAccess->GetPixel( nTmpY, ++nTmpX ).GetIndex();
- const long nAlpha3 = pReadAccess->GetPixel( ++nTmpY, nTmpX ).GetIndex();
- const long nAlpha2 = pReadAccess->GetPixel( nTmpY, --nTmpX ).GetIndex();
- const long n0 = MAP( nAlpha0, nAlpha1, nTmpFX );
- const long n1 = MAP( nAlpha2, nAlpha3, nTmpFX );
-
- aAlphaVal.SetIndex( MAP( n0, n1, nTmpFY ) );
- pWriteAccess->SetPixel( nY, nX, aAlphaVal );
- }
- else
- pWriteAccess->SetPixel( nY, nX, aTrans );
- }
- }
- }
-
- aOutAlpha.ReleaseAccess( pWriteAccess );
- bRet = true;
- }
-
- aAlpha.ReleaseAccess( pReadAccess );
- }
-
- if( bRet )
- rOutBmpEx = BitmapEx( aOutBmp, aOutAlpha );
- }
- else
- {
- Bitmap aOutMsk( Size( aTargetWidth, aTargetHeight ), 1 );
- pWriteAccess = aOutMsk.AcquireWriteAccess();
-
- if( pWriteAccess )
- {
- Bitmap aMsk( rBmpEx.GetMask() );
- const BitmapColor aB( pWriteAccess->GetBestMatchingColor( Color( COL_BLACK ) ) );
- const BitmapColor aW( pWriteAccess->GetBestMatchingColor( Color( COL_WHITE ) ) );
- BitmapReadAccess* pMAcc = nullptr;
-
- if( !aMsk || ( ( pMAcc = aMsk.AcquireReadAccess() ) != nullptr ) )
- {
- std::unique_ptr<long[]> pMapLX(new long[ aUnrotatedWidth ]);
- std::unique_ptr<long[]> pMapLY(new long[ aUnrotatedHeight ]);
- BitmapColor aTestB;
-
- if( pMAcc )
- aTestB = pMAcc->GetBestMatchingColor( Color( COL_BLACK ) );
-
- // create new horizontal mapping table
- for( long nX = 0; nX < aUnrotatedWidth; nX++ )
- pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576.0 );
-
- // create new vertical mapping table
- for( long nY = 0; nY < aUnrotatedHeight; nY++ )
- pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576.0 );
-
- // do mask rotation
- for( long nY = 0; nY < aTargetHeight; nY++ )
- {
- nSinY = pSinY[ nY ];
- nCosY = pCosY[ nY ];
-
- for( long nX = 0; nX < aTargetWidth; nX++ )
- {
- nUnRotX = ( pCosX[ nX ] - nSinY ) >> 8;
- nUnRotY = ( pSinX[ nX ] + nCosY ) >> 8;
-
- if( ( nUnRotX >= 0 ) && ( nUnRotX < aUnrotatedWidth ) &&
- ( nUnRotY >= 0 ) && ( nUnRotY < aUnrotatedHeight ) )
- {
- if( pMAcc )
- {
- if( pMAcc->GetPixel( pMapLY[ nUnRotY ], pMapLX[ nUnRotX ] ) == aTestB )
- pWriteAccess->SetPixel( nY, nX, aB );
- else
- pWriteAccess->SetPixel( nY, nX, aW );
- }
- else
- pWriteAccess->SetPixel( nY, nX, aB );
- }
- else
- pWriteAccess->SetPixel( nY, nX, aW );
- }
- }
-
- pMapLX.reset();
- pMapLY.reset();
-
- if( pMAcc )
- Bitmap::ReleaseAccess( pMAcc );
-
- bRet = true;
- }
-
- Bitmap::ReleaseAccess( pWriteAccess );
- }
-
- if( bRet )
- rOutBmpEx = BitmapEx( aOutBmp, aOutMsk );
- }
-
- if( !bRet )
- rOutBmpEx = aOutBmp;
- }
- else
- rOutBmpEx = aOutBmp;
-
- return bRet;
-}
-
-bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
- const Point& rPoint, const Size& rSize,
- const BitmapEx& rBitmapEx, const GraphicAttr& rAttributes,
- const GraphicManagerDrawFlags /*nFlags*/, BitmapEx* pBmpEx )
-{
- sal_uInt16 nRot10 = rAttributes.GetRotation() % 3600;
-
- Point aOutputPointPix;
- Size aOutputSizePix;
- Point aUnrotatedPointPix( pOutputDevice->LogicToPixel( rPoint ) );
- Size aUnrotatedSizePix( pOutputDevice->LogicToPixel( rSize ) );
-
- bool bRet = false;
-
- if( nRot10 )
- {
- tools::Polygon aPoly( Rectangle( rPoint, rSize ) );
- aPoly.Rotate( rPoint, nRot10 );
- const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
- aOutputPointPix = pOutputDevice->LogicToPixel( aRotBoundRect.TopLeft() );
- aOutputSizePix = pOutputDevice->LogicToPixel( aRotBoundRect.GetSize() );
- }
- else
- {
- aOutputPointPix = aUnrotatedPointPix;
- aOutputSizePix = aUnrotatedSizePix;
- }
-
- if( aUnrotatedSizePix.Width() && aUnrotatedSizePix.Height() )
- {
- BitmapEx aOutBmpEx;
- Point aOutPoint;
- Size aOutSize;
- const Size& rBmpSzPix = rBitmapEx.GetSizePixel();
- const long nW = rBmpSzPix.Width();
- const long nH = rBmpSzPix.Height();
- long nStartX = -1, nStartY = -1, nEndX = -1, nEndY = -1;
- bool bHMirr( rAttributes.GetMirrorFlags() & BmpMirrorFlags::Horizontal );
- bool bVMirr( rAttributes.GetMirrorFlags() & BmpMirrorFlags::Vertical );
-
- // calculate output sizes
- if( !pBmpEx )
- {
- Point aPt;
- Rectangle aOutRect( aPt, pOutputDevice->GetOutputSizePixel() );
- Rectangle aBmpRect( aOutputPointPix, aOutputSizePix );
-
- if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
- {
- const vcl::Region aPaintRgn( static_cast<vcl::Window*>( pOutputDevice )->GetPaintRegion() );
- if( !aPaintRgn.IsNull() )
- aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRgn.GetBoundRect() ) );
- }
-
- aOutRect.Intersection( aBmpRect );
-
- if( !aOutRect.IsEmpty() )
- {
- aOutPoint = pOutputDevice->PixelToLogic( aOutRect.TopLeft() );
- aOutSize = pOutputDevice->PixelToLogic( aOutRect.GetSize() );
- nStartX = aOutRect.Left() - aBmpRect.Left();
- nStartY = aOutRect.Top() - aBmpRect.Top();
- nEndX = aOutRect.Right() - aBmpRect.Left();
- nEndY = aOutRect.Bottom() - aBmpRect.Top();
- }
- else
- {
- nStartX = -1; // invalid
- }
- }
- else
- {
- aOutPoint = pOutputDevice->PixelToLogic( aOutputPointPix );
- aOutSize = pOutputDevice->PixelToLogic( aOutputSizePix );
- nStartX = nStartY = 0;
- nEndX = aOutputSizePix.Width() - 1;
- nEndY = aOutputSizePix.Height() - 1;
- }
-
- // do transformation
- if( nStartX >= 0 )
- {
- const bool bSimple = ( 1 == nW || 1 == nH );
-
- if( nRot10 )
- {
- if( bSimple )
- {
- bRet = ( aOutBmpEx = rBitmapEx ).Scale( aUnrotatedSizePix );
-
- if( bRet )
- aOutBmpEx.Rotate( nRot10, COL_TRANSPARENT );
- }
- else
- {
- bRet = ImplCreateRotatedScaled( rBitmapEx, rAttributes,
- nRot10, aUnrotatedSizePix,
- nStartX, nEndX, nStartY, nEndY,
- aOutBmpEx );
- }
- }
- else
- {
- if( !bHMirr && !bVMirr && aOutputSizePix == rBmpSzPix )
- {
- aOutPoint = pOutputDevice->PixelToLogic( aOutputPointPix );
- aOutSize = pOutputDevice->PixelToLogic( aOutputSizePix );
- aOutBmpEx = rBitmapEx;
- bRet = true;
- }
- else
- {
- if( bSimple )
- {
- bRet = ( aOutBmpEx = rBitmapEx ).Scale( Size( nEndX - nStartX + 1, nEndY - nStartY + 1 ) );
- }
- else
- {
- bRet = ImplCreateRotatedScaled( rBitmapEx, rAttributes,
- nRot10, aUnrotatedSizePix,
- nStartX, nEndX, nStartY, nEndY,
- aOutBmpEx );
- }
- }
- }
-
- if( bRet )
- {
- // Attribute adjustment if necessary
- if( rAttributes.IsSpecialDrawMode() || rAttributes.IsAdjusted() || rAttributes.IsTransparent() )
- ImplAdjust( aOutBmpEx, rAttributes, GraphicAdjustmentFlags::DRAWMODE | GraphicAdjustmentFlags::COLORS | GraphicAdjustmentFlags::TRANSPARENCY );
-
- // OutDev adjustment if necessary
- if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER && pOutputDevice->GetBitCount() <= 8 && aOutBmpEx.GetBitCount() >= 8 )
- aOutBmpEx.Dither();
- }
- }
-
- // Create output
- if( bRet )
- {
- if( !pBmpEx )
- pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aOutBmpEx );
- else
- {
- if( !rAttributes.IsTransparent() && !aOutBmpEx.IsAlpha() )
- aOutBmpEx = BitmapEx( aOutBmpEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aOutBmpEx.GetMask() );
-
- pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, *pBmpEx = aOutBmpEx );
- }
- }
- }
-
- return bRet;
-}
-
-// This function checks whether the bitmap is usable for skipping
-// mtf rendering by using just this one bitmap (i.e. in case the metafile
-// contains just this one pixmap that covers the entire metafile area).
-static BitmapEx checkMetadataBitmap( const BitmapEx& rBmpEx,
- Point rSrcPoint,
- Size rSrcSize,
- const Point& rDestPoint,
- const Size& rDestSize,
- const Size& rRefSize,
- bool& o_rbNonBitmapActionEncountered )
-{
-// NOTE: If you do changes in this function, change checkMetadataBitmap() in grfcache.cxx too.
- BitmapEx aBmpEx;
- if( rSrcSize == Size())
- rSrcSize = rBmpEx.GetSizePixel();
-
- if( rDestPoint != Point( 0, 0 ))
- { // The pixmap in the metafile has an offset (and so would not cover)
- // the entire result -> fall back to mtf rendering.
- o_rbNonBitmapActionEncountered = true;
- return aBmpEx;
- }
- if( rDestSize != rRefSize )
- { // The pixmap is not fullscale (does not cover the entire metafile area).
- // HACK: The code here should refuse to use the bitmap directly
- // and fall back to mtf rendering, but there seem to be metafiles
- // that do not specify exactly their area (the Windows API requires apps
- // the specify it manually, the rectangle is specified as topleft/bottomright
- // rather than topleft/size [which may be confusing], and the docs
- // on the exact meaning are somewhat confusing as well), so if it turns
- // out this metafile really contains just one bitmap and no other painting,
- // and if the sizes almost match, just use the pixmap (which will be scaled
- // to fit exactly the requested size, so there should not be any actual problem
- // caused by this small difference). This will allow caching of the resulting
- // (scaled) pixmap, which can make a noticeable performance difference.
- if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
- && std::abs( rDestSize.Width() - rRefSize.Width()) < 5
- && std::abs( rDestSize.Height() - rRefSize.Height()) < 5 )
- ; // ok, assume it's close enough
- else
- { // fall back to mtf rendering
- o_rbNonBitmapActionEncountered = true;
- return aBmpEx;
- }
- }
-
- aBmpEx = rBmpEx;
-
- if( (rSrcPoint.X() != 0 && rSrcPoint.Y() != 0) ||
- rSrcSize != rBmpEx.GetSizePixel() )
- {
- // crop bitmap to given source rectangle (no
- // need to copy and convert the whole bitmap)
- const Rectangle aCropRect( rSrcPoint,
- rSrcSize );
- aBmpEx.Crop( aCropRect );
- }
-
- return aBmpEx;
-}
-
-bool GraphicManager::ImplCreateOutput( OutputDevice* pOut,
- const Point& rPt, const Size& rSz,
- const GDIMetaFile& rMtf, const GraphicAttr& rAttr,
- const GraphicManagerDrawFlags /*nFlags*/, GDIMetaFile& rOutMtf, BitmapEx& rOutBmpEx )
-{
- const Size aNewSize( rMtf.GetPrefSize() );
-
- rOutMtf = rMtf;
-
- // Count bitmap actions, and flag actions that paint, but
- // are no bitmaps.
- sal_Int32 nNumBitmaps(0);
- bool bNonBitmapActionEncountered(false);
- if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
- {
- const double fGrfWH = (double) aNewSize.Width() / aNewSize.Height();
- const double fOutWH = (double) rSz.Width() / rSz.Height();
-
- const double fScaleX = fOutWH / fGrfWH;
- const double fScaleY = 1.0;
-
- const MapMode& rPrefMapMode( rMtf.GetPrefMapMode() );
- const Size rSizePix( pOut->LogicToPixel( aNewSize, rPrefMapMode ) );
-
-// NOTE: If you do changes in this function, check GraphicDisplayCacheEntry::IsCacheableAsBitmap
-// in grfcache.cxx too.
-
- // Determine whether the metafile basically displays
- // a single bitmap (in which case that bitmap is simply used directly
- // instead of playing the metafile). Note that
- // the solution, as implemented here, is quite suboptimal (the
- // cases where a mtf consisting basically of a single bitmap,
- // that fail to pass the test below, are probably frequent). A
- // better solution would involve FSAA, but that's currently
- // expensive, and might trigger bugs on display drivers, if
- // VDevs get bigger than the actual screen.
- sal_uInt32 nCurPos;
- MetaAction* pAct;
- for( nCurPos = 0, pAct = rOutMtf.FirstAction(); pAct;
- pAct = rOutMtf.NextAction(), nCurPos++ )
- {
- MetaAction* pModAct = nullptr;
- switch( pAct->GetType() )
- {
- case MetaActionType::FONT:
- {
- // taking care of font width default if scaling metafile.
- MetaFontAction* pA = static_cast<MetaFontAction*>(pAct);
- vcl::Font aFont( pA->GetFont() );
- if ( !aFont.GetAverageFontWidth() )
- {
- FontMetric aFontMetric( pOut->GetFontMetric( aFont ) );
- aFont.SetAverageFontWidth( aFontMetric.GetAverageFontWidth() );
- pModAct = new MetaFontAction( aFont );
- }
- SAL_FALLTHROUGH;
- }
- case MetaActionType::NONE:
- SAL_FALLTHROUGH;
-
- // OutDev state changes (which don't affect bitmap
- // output)
- case MetaActionType::LINECOLOR:
- SAL_FALLTHROUGH;
- case MetaActionType::FILLCOLOR:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTCOLOR:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTFILLCOLOR:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTALIGN:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTLINECOLOR:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTLINE:
- SAL_FALLTHROUGH;
- case MetaActionType::PUSH:
- SAL_FALLTHROUGH;
- case MetaActionType::POP:
- SAL_FALLTHROUGH;
- case MetaActionType::LAYOUTMODE:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTLANGUAGE:
- SAL_FALLTHROUGH;
- case MetaActionType::COMMENT:
- break;
-
- // bitmap output methods
- case MetaActionType::BMP:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpAction* pAction = static_cast<MetaBmpAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap(
- BitmapEx( pAction->GetBitmap()),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmap().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPSCALE:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpScaleAction* pAction = static_cast<MetaBmpScaleAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap(
- BitmapEx( pAction->GetBitmap()),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPSCALEPART:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpScalePartAction* pAction = static_cast<MetaBmpScalePartAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap(
- BitmapEx( pAction->GetBitmap() ),
- pAction->GetSrcPoint(),
- pAction->GetSrcSize(),
- pOut->LogicToPixel( pAction->GetDestPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetDestSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEX:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExAction* pAction = static_cast<MetaBmpExAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap(
- pAction->GetBitmapEx(),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmapEx().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEXSCALE:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExScaleAction* pAction = static_cast<MetaBmpExScaleAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap(
- pAction->GetBitmapEx(),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEXSCALEPART:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExScalePartAction* pAction = static_cast<MetaBmpExScalePartAction*>(pAct);
-
- rOutBmpEx = checkMetadataBitmap( pAction->GetBitmapEx(),
- pAction->GetSrcPoint(),
- pAction->GetSrcSize(),
- pOut->LogicToPixel( pAction->GetDestPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetDestSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- // these actions actually output something (that's
- // different from a bitmap)
- case MetaActionType::RASTEROP:
- if( static_cast<MetaRasterOpAction*>(pAct)->GetRasterOp() == RasterOp::OverPaint )
- break;
- SAL_FALLTHROUGH;
- case MetaActionType::PIXEL:
- SAL_FALLTHROUGH;
- case MetaActionType::POINT:
- SAL_FALLTHROUGH;
- case MetaActionType::LINE:
- SAL_FALLTHROUGH;
- case MetaActionType::RECT:
- SAL_FALLTHROUGH;
- case MetaActionType::ROUNDRECT:
- SAL_FALLTHROUGH;
- case MetaActionType::ELLIPSE:
- SAL_FALLTHROUGH;
- case MetaActionType::ARC:
- SAL_FALLTHROUGH;
- case MetaActionType::PIE:
- SAL_FALLTHROUGH;
- case MetaActionType::CHORD:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYLINE:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYGON:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYPOLYGON:
- SAL_FALLTHROUGH;
-
- case MetaActionType::TEXT:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTARRAY:
- SAL_FALLTHROUGH;
- case MetaActionType::STRETCHTEXT:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTRECT:
- SAL_FALLTHROUGH;
-
- case MetaActionType::MASK:
- SAL_FALLTHROUGH;
- case MetaActionType::MASKSCALE:
- SAL_FALLTHROUGH;
- case MetaActionType::MASKSCALEPART:
- SAL_FALLTHROUGH;
-
- case MetaActionType::GRADIENT:
- SAL_FALLTHROUGH;
- case MetaActionType::HATCH:
- SAL_FALLTHROUGH;
- case MetaActionType::WALLPAPER:
- SAL_FALLTHROUGH;
-
- case MetaActionType::Transparent:
- SAL_FALLTHROUGH;
- case MetaActionType::EPS:
- SAL_FALLTHROUGH;
- case MetaActionType::FLOATTRANSPARENT:
- SAL_FALLTHROUGH;
- case MetaActionType::GRADIENTEX:
- SAL_FALLTHROUGH;
-
- // OutDev state changes that _do_ affect bitmap
- // output
- case MetaActionType::CLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::ISECTRECTCLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::ISECTREGIONCLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::MOVECLIPREGION:
- SAL_FALLTHROUGH;
-
- case MetaActionType::MAPMODE:
- SAL_FALLTHROUGH;
- case MetaActionType::REFPOINT:
- SAL_FALLTHROUGH;
- default:
- bNonBitmapActionEncountered = true;
- break;
- }
- if ( pModAct )
- {
- MetaAction* pDeleteAction = rOutMtf.ReplaceAction( pModAct, nCurPos );
- assert(pDeleteAction);
- pDeleteAction->Delete();
- }
- else
- {
- if( pAct->GetRefCount() > 1 )
- {
- MetaAction* pDeleteAction = rOutMtf.ReplaceAction( pModAct = pAct->Clone(), nCurPos );
- assert(pDeleteAction);
- pDeleteAction->Delete();
- }
- else
- pModAct = pAct;
- }
- pModAct->Scale( fScaleX, fScaleY );
- }
- rOutMtf.SetPrefSize( Size( FRound( aNewSize.Width() * fScaleX ),
- FRound( aNewSize.Height() * fScaleY ) ) );
- }
-
- if( nNumBitmaps != 1 || bNonBitmapActionEncountered )
- {
- if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsMirrored() || rAttr.IsRotated() || rAttr.IsTransparent() )
- ImplAdjust( rOutMtf, rAttr, GraphicAdjustmentFlags::ALL );
-
- ImplDraw( pOut, rPt, rSz, rOutMtf, rAttr );
- rOutBmpEx = BitmapEx();
- }
-
- return true;
-}
-
-void GraphicManager::ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
-{
- GraphicAttr aAttr( rAttr );
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
- {
- switch( aAttr.GetDrawMode() )
- {
- case GRAPHICDRAWMODE_MONO:
- rBmpEx.Convert( BmpConversion::N1BitThreshold );
- break;
-
- case GRAPHICDRAWMODE_GREYS:
- rBmpEx.Convert( BmpConversion::N8BitGreys );
- break;
-
- case GRAPHICDRAWMODE_WATERMARK:
- {
- aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
- aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
- }
- break;
-
- default:
- break;
- }
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
- {
- rBmpEx.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
- aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
- aAttr.GetGamma(), aAttr.IsInvert() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
- {
- rBmpEx.Mirror( aAttr.GetMirrorFlags() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
- {
- rBmpEx.Rotate( aAttr.GetRotation(), Color( COL_TRANSPARENT ) );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
- {
- AlphaMask aAlpha;
- sal_uInt8 cTrans = aAttr.GetTransparency();
-
- if( !rBmpEx.IsTransparent() )
- aAlpha = AlphaMask( rBmpEx.GetSizePixel(), &cTrans );
- else if( !rBmpEx.IsAlpha() )
- {
- aAlpha = rBmpEx.GetMask();
- aAlpha.Replace( 0, cTrans );
- }
- else
- {
- aAlpha = rBmpEx.GetAlpha();
- BitmapWriteAccess* pA = aAlpha.AcquireWriteAccess();
-
- if( pA )
- {
- sal_uLong nTrans = cTrans, nNewTrans;
- const long nWidth = pA->Width(), nHeight = pA->Height();
-
- if( pA->GetScanlineFormat() == ScanlineFormat::N8BitPal )
- {
- for( long nY = 0; nY < nHeight; nY++ )
- {
- Scanline pAScan = pA->GetScanline( nY );
-
- for( long nX = 0; nX < nWidth; nX++ )
- {
- nNewTrans = nTrans + *pAScan;
- *pAScan++ = (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans );
- }
- }
- }
- else
- {
- BitmapColor aAlphaValue( 0 );
-
- for( long nY = 0; nY < nHeight; nY++ )
- {
- for( long nX = 0; nX < nWidth; nX++ )
- {
- nNewTrans = nTrans + pA->GetPixel( nY, nX ).GetIndex();
- aAlphaValue.SetIndex( (sal_uInt8) ( ( nNewTrans & 0xffffff00 ) ? 255 : nNewTrans ) );
- pA->SetPixel( nY, nX, aAlphaValue );
- }
- }
- }
-
- aAlpha.ReleaseAccess( pA );
- }
- }
-
- rBmpEx = BitmapEx( rBmpEx.GetBitmap(), aAlpha );
- }
-}
-
-void GraphicManager::ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
-{
- GraphicAttr aAttr( rAttr );
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
- {
- switch( aAttr.GetDrawMode() )
- {
- case GRAPHICDRAWMODE_MONO:
- rMtf.Convert( MtfConversion::N1BitThreshold );
- break;
-
- case GRAPHICDRAWMODE_GREYS:
- rMtf.Convert( MtfConversion::N8BitGreys );
- break;
-
- case GRAPHICDRAWMODE_WATERMARK:
- {
- aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
- aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
- }
- break;
-
- default:
- break;
- }
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
- {
- rMtf.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
- aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
- aAttr.GetGamma(), aAttr.IsInvert() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
- {
- rMtf.Mirror( aAttr.GetMirrorFlags() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
- {
- rMtf.Rotate( aAttr.GetRotation() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
- {
- OSL_FAIL( "Missing implementation: Mtf-Transparency" );
- }
-}
-
-void GraphicManager::ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, GraphicAdjustmentFlags nAdjustmentFlags )
-{
- GraphicAttr aAttr( rAttr );
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::DRAWMODE ) && aAttr.IsSpecialDrawMode() )
- {
- switch( aAttr.GetDrawMode() )
- {
- case GRAPHICDRAWMODE_MONO:
- rAnimation.Convert( BmpConversion::N1BitThreshold );
- break;
-
- case GRAPHICDRAWMODE_GREYS:
- rAnimation.Convert( BmpConversion::N8BitGreys );
- break;
-
- case GRAPHICDRAWMODE_WATERMARK:
- {
- aAttr.SetLuminance( aAttr.GetLuminance() + WATERMARK_LUM_OFFSET );
- aAttr.SetContrast( aAttr.GetContrast() + WATERMARK_CON_OFFSET );
- }
- break;
-
- default:
- break;
- }
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::COLORS ) && aAttr.IsAdjusted() )
- {
- rAnimation.Adjust( aAttr.GetLuminance(), aAttr.GetContrast(),
- aAttr.GetChannelR(), aAttr.GetChannelG(), aAttr.GetChannelB(),
- aAttr.GetGamma(), aAttr.IsInvert() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::MIRROR ) && aAttr.IsMirrored() )
- {
- rAnimation.Mirror( aAttr.GetMirrorFlags() );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::ROTATE ) && aAttr.IsRotated() )
- {
- OSL_FAIL( "Missing implementation: Animation-Rotation" );
- }
-
- if( ( nAdjustmentFlags & GraphicAdjustmentFlags::TRANSPARENCY ) && aAttr.IsTransparent() )
- {
- OSL_FAIL( "Missing implementation: Animation-Transparency" );
- }
-}
-
-void GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GDIMetaFile& rMtf, const GraphicAttr& rAttr )
-{
- sal_uInt16 nRot10 = rAttr.GetRotation() % 3600;
- Point aOutPt( rPt );
- Size aOutSz( rSz );
-
- if( nRot10 )
- {
- tools::Polygon aPoly( Rectangle( aOutPt, aOutSz ) );
-
- aPoly.Rotate( aOutPt, nRot10 );
- const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
- aOutPt = aRotBoundRect.TopLeft();
- aOutSz = aRotBoundRect.GetSize();
- }
-
- pOut->Push( PushFlags::CLIPREGION );
- pOut->IntersectClipRegion( Rectangle( aOutPt, aOutSz ) );
-
- ( (GDIMetaFile&) rMtf ).WindStart();
- ( (GDIMetaFile&) rMtf ).Play( pOut, aOutPt, aOutSz );
- ( (GDIMetaFile&) rMtf ).WindStart();
-
- pOut->Pop();
-}
-
struct ImplTileInfo
{
ImplTileInfo() : aTileTopLeft(), aNextTileTopLeft(), aTileSizePixel(), nTilesEmptyX(0), nTilesEmptyY(0) {}
diff --git a/vcl/source/graphic/grfcache.cxx b/vcl/source/graphic/grfcache.cxx
deleted file mode 100644
index 6ff9424ca162..000000000000
--- a/vcl/source/graphic/grfcache.cxx
+++ /dev/null
@@ -1,1289 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <sal/config.h>
-
-#include <cstdlib>
-
-#include <salhelper/timer.hxx>
-#include <vcl/GraphicObject.hxx>
-#include <tools/debug.hxx>
-#include <vcl/metaact.hxx>
-#include <vcl/outdev.hxx>
-#include <tools/poly.hxx>
-#include <rtl/strbuf.hxx>
-#include "grfcache.hxx"
-#include <rtl/crc.h>
-#include <memory>
-
-#define MAX_BMP_EXTENT 4096
-
-using namespace com::sun::star;
-
-static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
-class GraphicID
-{
-private:
-
- sal_uInt32 mnID1;
- sal_uInt32 mnID2;
- sal_uInt32 mnID3;
- BitmapChecksum mnID4;
-
-public:
-
-
- explicit GraphicID( const GraphicObject& rObj );
- ~GraphicID() {}
-
- bool operator==( const GraphicID& rID ) const
- {
- return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
- rID.mnID3 == mnID3 && rID.mnID4 == mnID4 );
- }
-
- OString GetIDString() const;
- bool IsEmpty() const { return( 0 == mnID4 ); }
-};
-
-GraphicID::GraphicID( const GraphicObject& rObj )
-{
- const Graphic& rGraphic = rObj.GetGraphic();
-
- mnID1 = ( (sal_uLong) rGraphic.GetType() ) << 28;
-
- switch( rGraphic.GetType() )
- {
- case GraphicType::Bitmap:
- {
- if(rGraphic.getSvgData().get())
- {
- const SvgDataPtr& rSvgDataPtr = rGraphic.getSvgData();
- const basegfx::B2DRange& rRange = rSvgDataPtr->getRange();
-
- mnID1 |= rSvgDataPtr->getSvgDataArrayLength();
- mnID2 = basegfx::fround(rRange.getWidth());
- mnID3 = basegfx::fround(rRange.getHeight());
- mnID4 = vcl_get_checksum(0, rSvgDataPtr->getSvgDataArray().getConstArray(), rSvgDataPtr->getSvgDataArrayLength());
- }
- else if( rGraphic.IsAnimated() )
- {
- const Animation aAnimation( rGraphic.GetAnimation() );
-
- mnID1 |= ( aAnimation.Count() & 0x0fffffff );
- mnID2 = aAnimation.GetDisplaySizePixel().Width();
- mnID3 = aAnimation.GetDisplaySizePixel().Height();
- mnID4 = rGraphic.GetChecksum();
- }
- else
- {
- const BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
-
- mnID1 |= ( ( ( (sal_uLong) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
- mnID2 = aBmpEx.GetSizePixel().Width();
- mnID3 = aBmpEx.GetSizePixel().Height();
- mnID4 = rGraphic.GetChecksum();
- }
- }
- break;
-
- case GraphicType::GdiMetafile:
- {
- const GDIMetaFile& rMtf = rGraphic.GetGDIMetaFile();
-
- mnID1 |= ( rMtf.GetActionSize() & 0x0fffffff );
- mnID2 = rMtf.GetPrefSize().Width();
- mnID3 = rMtf.GetPrefSize().Height();
- mnID4 = rGraphic.GetChecksum();
- }
- break;
-
- default:
- mnID2 = mnID3 = mnID4 = 0;
- break;
- }
-}
-
-OString GraphicID::GetIDString() const
-{
- OStringBuffer aHexStr;
- sal_Int32 nShift, nIndex = 0;
- aHexStr.setLength(24 + (2 * BITMAP_CHECKSUM_SIZE));
-
- for( nShift = 28; nShift >= 0; nShift -= 4 )
- aHexStr[nIndex++] = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ];
-
- for( nShift = 28; nShift >= 0; nShift -= 4 )
- aHexStr[nIndex++] = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ];
-
- for( nShift = 28; nShift >= 0; nShift -= 4 )
- aHexStr[nIndex++] = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ];
-
- for( nShift = ( 8 * BITMAP_CHECKSUM_SIZE ) - 4; nShift >= 0; nShift -= 4 )
- aHexStr[nIndex++] = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ];
-
- return aHexStr.makeStringAndClear();
-}
-
-class GraphicCacheEntry
-{
-private:
-
- std::vector< GraphicObject* > maGraphicObjectList;
-
- GraphicID maID;
- GfxLink maGfxLink;
- BitmapEx* mpBmpEx;
- GDIMetaFile* mpMtf;
- Animation* mpAnimation;
- bool mbSwappedAll;
-
- // SvgData support
- SvgDataPtr maSvgData;
- std::shared_ptr<uno::Sequence<sal_Int8>> mpPdfData;
-
- bool ImplInit( const GraphicObject& rObj );
- void ImplFillSubstitute( Graphic& rSubstitute );
-
-public:
-
- explicit GraphicCacheEntry( const GraphicObject& rObj );
- ~GraphicCacheEntry();
-
- const GraphicID& GetID() const { return maID; }
-
- void AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute );
- bool ReleaseGraphicObjectReference( const GraphicObject& rObj );
- size_t GetGraphicObjectReferenceCount() { return maGraphicObjectList.size(); }
- bool HasGraphicObjectReference( const GraphicObject& rObj );
-
- void TryToSwapIn();
- void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
- void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
-};
-
-GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
- maID ( rObj ),
- mpBmpEx ( nullptr ),
- mpMtf ( nullptr ),
- mpAnimation ( nullptr ),
- mbSwappedAll ( true )
-{
- mbSwappedAll = !ImplInit( rObj );
- maGraphicObjectList.push_back( const_cast<GraphicObject*>(&rObj) );
-}
-
-GraphicCacheEntry::~GraphicCacheEntry()
-{
- DBG_ASSERT(
- maGraphicObjectList.empty(),
- "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry"
- );
-
- delete mpBmpEx;
- delete mpMtf;
- delete mpAnimation;
-}
-
-bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
-{
- bool bRet = false;
-
- if( !rObj.IsSwappedOut() )
- {
- const Graphic& rGraphic = rObj.GetGraphic();
-
- if( mpBmpEx )
- {
- delete mpBmpEx;
- mpBmpEx = nullptr;
- }
-
- if( mpMtf )
- {
- delete mpMtf;
- mpMtf = nullptr;
- }
-
- if( mpAnimation )
- {
- delete mpAnimation;
- mpAnimation = nullptr;
- }
-
- switch( rGraphic.GetType() )
- {
- case GraphicType::Bitmap:
- {
- if(rGraphic.getSvgData().get())
- {
- maSvgData = rGraphic.getSvgData();
- }
- else if( rGraphic.IsAnimated() )
- {
- mpAnimation = new Animation( rGraphic.GetAnimation() );
- }
- else
- {
- mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
- if (rGraphic.hasPdfData() && rGraphic.getPdfData()->hasElements())
- mpPdfData = rGraphic.getPdfData();
- }
- }
- break;
-
- case GraphicType::GdiMetafile:
- {
- mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
- }
- break;
-
- default:
- DBG_ASSERT( GetID().IsEmpty(), "GraphicCacheEntry::ImplInit: Could not initialize graphic! (=>KA)" );
- break;
- }
-
- if( rGraphic.IsGfxLink() )
- maGfxLink = rGraphic.GetGfxLink();
- else
- maGfxLink = GfxLink();
-
- bRet = true;
- }
-
- return bRet;
-}
-
-void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
-{
- // create substitute for graphic;
- const Size aPrefSize( rSubstitute.GetPrefSize() );
- const MapMode aPrefMapMode( rSubstitute.GetPrefMapMode() );
- const Link<Animation*,void> aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() );
- const GraphicType eOldType = rSubstitute.GetType();
- const bool bDefaultType = ( rSubstitute.GetType() == GraphicType::Default );
-
- if( rSubstitute.IsGfxLink() && ( GfxLinkType::NONE == maGfxLink.GetType() ) )
- maGfxLink = rSubstitute.GetGfxLink();
-
- if(maSvgData.get())
- {
- rSubstitute = maSvgData;
- }
- else if( mpBmpEx )
- {
- rSubstitute = *mpBmpEx;
- if (mpPdfData && mpPdfData->hasElements())
- rSubstitute.setPdfData(mpPdfData);
- }
- else if( mpAnimation )
- {
- rSubstitute = *mpAnimation;
- }
- else if( mpMtf )
- {
- rSubstitute = *mpMtf;
- }
- else
- {
- rSubstitute.Clear();
- }
-
- if( eOldType != GraphicType::NONE )
- {
- rSubstitute.SetPrefSize( aPrefSize );
- rSubstitute.SetPrefMapMode( aPrefMapMode );
- rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl );
- }
-
- if( GfxLinkType::NONE != maGfxLink.GetType() )
- {
- rSubstitute.SetGfxLink( maGfxLink );
- }
-
- if( bDefaultType )
- {
- rSubstitute.SetDefaultType();
- }
-}
-
-void GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute )
-{
- if( mbSwappedAll )
- mbSwappedAll = !ImplInit( rObj );
-
- ImplFillSubstitute( rSubstitute );
- maGraphicObjectList.push_back( const_cast<GraphicObject*>(&rObj) );
-}
-
-bool GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj )
-{
- for(
- auto it = maGraphicObjectList.begin();
- it != maGraphicObjectList.end();
- ++it
- ) {
- if( &rObj == *it )
- {
- maGraphicObjectList.erase( it );
- return true;
- }
- }
-
- return false;
-}
-
-bool GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj )
-{
- bool bRet = false;
-
- for( size_t i = 0, n = maGraphicObjectList.size(); ( i < n ) && !bRet; ++i )
- if( &rObj == maGraphicObjectList[ i ] )
- bRet = true;
-
- return bRet;
-}
-
-void GraphicCacheEntry::TryToSwapIn()
-{
- if( mbSwappedAll && !maGraphicObjectList.empty() )
- maGraphicObjectList.front()->FireSwapInRequest();
-}
-
-void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& /*rObj*/ )
-{
- mbSwappedAll = true;
-
- for( size_t i = 0, n = maGraphicObjectList.size(); ( i < n ) && mbSwappedAll; ++i )
- if( !maGraphicObjectList[ i ]->IsSwappedOut() )
- mbSwappedAll = false;
-
- if( mbSwappedAll )
- {
- delete mpBmpEx;
- mpBmpEx = nullptr;
- delete mpMtf;
- mpMtf = nullptr;
- delete mpAnimation;
- mpAnimation = nullptr;
-
- // #119176# also reset SvgData
- maSvgData.reset();
- mpPdfData.reset();
- }
-}
-
-void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
-{
- if( mbSwappedAll )
- mbSwappedAll = !ImplInit( rObj );
-}
-
-class GraphicDisplayCacheEntry
-{
-private:
-
- ::salhelper::TTimeValue maReleaseTime;
- const GraphicCacheEntry* mpRefCacheEntry;
- GDIMetaFile* mpMtf;
- BitmapEx* mpBmpEx;
- GraphicAttr maAttr;
- Size maOutSizePix;
- sal_uLong mnCacheSize;
- DrawModeFlags mnOutDevDrawMode;
- sal_uInt16 mnOutDevBitCount;
-
- static bool IsCacheableAsBitmap( const GDIMetaFile& rMtf, OutputDevice* pOut, const Size& rSz );
-
- // Copy assignment is forbidden and not implemented.
- GraphicDisplayCacheEntry (const GraphicDisplayCacheEntry &) = delete;
- GraphicDisplayCacheEntry & operator= (const GraphicDisplayCacheEntry &) = delete;
-
-public:
-
- static sal_uLong GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr );
-
-public:
-
- GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
- OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr,
- const BitmapEx& rBmpEx ) :
- mpRefCacheEntry( pRefCacheEntry ),
- mpMtf( nullptr ), mpBmpEx( new BitmapEx( rBmpEx ) ),
- maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
- mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
- mnOutDevDrawMode( pOut->GetDrawMode() ),
- mnOutDevBitCount( pOut->GetBitCount() )
- {
- }
-
- GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
- OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr,
- const GDIMetaFile& rMtf ) :
- mpRefCacheEntry( pRefCacheEntry ),
- mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( nullptr ),
- maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
- mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
- mnOutDevDrawMode( pOut->GetDrawMode() ),
- mnOutDevBitCount( pOut->GetBitCount() )
- {
- }
-
-
- ~GraphicDisplayCacheEntry();
-
- sal_uLong GetCacheSize() const { return mnCacheSize; }
- const GraphicCacheEntry* GetReferencedCacheEntry() const { return mpRefCacheEntry; }
-
- void SetReleaseTime( const ::salhelper::TTimeValue& rReleaseTime ) { maReleaseTime = rReleaseTime; }
- const ::salhelper::TTimeValue& GetReleaseTime() const { return maReleaseTime; }
-
- bool Matches( OutputDevice* pOut, const Point& /*rPtPixel*/, const Size& rSzPixel,
- const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const
- {
- // #i46805# Additional match
- // criteria: outdev draw mode and
- // bit count. One cannot reuse
- // this cache object, if it's
- // e.g. generated for
- // DrawModeFlags::GrayBitmap.
- return( ( pCacheEntry == mpRefCacheEntry ) &&
- ( maAttr == rAttr ) &&
- ( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) &&
- ( pOut->GetBitCount() == mnOutDevBitCount ) &&
- ( pOut->GetDrawMode() == mnOutDevDrawMode ) );
- }
-
- void Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const;
-};
-
-// This whole function is based on checkMetadataBitmap() from grfmgr2.cxx, see that one for details.
-// If you do changes here, change the original function too.
-static void checkMetadataBitmap( const BitmapEx& rBmpEx,
- Point /*rSrcPoint*/,
- Size rSrcSize,
- const Point& rDestPoint,
- const Size& rDestSize,
- const Size& rRefSize,
- bool& o_rbNonBitmapActionEncountered )
-{
- if( rSrcSize == Size())
- rSrcSize = rBmpEx.GetSizePixel();
-
- if( rDestPoint != Point( 0, 0 ))
- {
- o_rbNonBitmapActionEncountered = true;
- return;
- }
- if( rDestSize != rRefSize )
- { if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
- && std::abs( rDestSize.Width() - rRefSize.Width()) < 5
- && std::abs( rDestSize.Height() - rRefSize.Height()) < 5 )
- ; // ok, assume it's close enough
- else
- { // fall back to mtf rendering
- o_rbNonBitmapActionEncountered = true;
- return;
- }
- }
-}
-
-// This function is based on GraphicManager::ImplCreateOutput(), in fact it mostly copies
-// it, the difference is that this one does not create anything, it only checks if
-// ImplCreateOutput() would use the optimization of using the single bitmap.
-// If you do changes here, change the original function too.
-bool GraphicDisplayCacheEntry::IsCacheableAsBitmap( const GDIMetaFile& rMtf,
- OutputDevice* pOut, const Size& rSz )
-{
- const Size aNewSize( rMtf.GetPrefSize() );
- GDIMetaFile rOutMtf = rMtf;
-
- // Count bitmap actions, and flag actions that paint, but
- // are no bitmaps.
- sal_Int32 nNumBitmaps(0);
- bool bNonBitmapActionEncountered(false);
- if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
- {
- const MapMode& rPrefMapMode( rMtf.GetPrefMapMode() );
- const Size rSizePix( pOut->LogicToPixel( aNewSize, rPrefMapMode ) );
-
- sal_uInt32 nCurPos;
- MetaAction* pAct;
- for( nCurPos = 0, pAct = rOutMtf.FirstAction(); pAct;
- pAct = rOutMtf.NextAction(), nCurPos++ )
- {
- switch( pAct->GetType() )
- {
- case MetaActionType::FONT:
- // FALLTHROUGH intended
- case MetaActionType::NONE:
- // FALLTHROUGH intended
-
- // OutDev state changes (which don't affect bitmap
- // output)
- case MetaActionType::LINECOLOR:
- // FALLTHROUGH intended
- case MetaActionType::FILLCOLOR:
- // FALLTHROUGH intended
- case MetaActionType::TEXTCOLOR:
- // FALLTHROUGH intended
- case MetaActionType::TEXTFILLCOLOR:
- // FALLTHROUGH intended
- case MetaActionType::TEXTALIGN:
- // FALLTHROUGH intended
- case MetaActionType::TEXTLINECOLOR:
- // FALLTHROUGH intended
- case MetaActionType::TEXTLINE:
- // FALLTHROUGH intended
- case MetaActionType::PUSH:
- // FALLTHROUGH intended
- case MetaActionType::POP:
- // FALLTHROUGH intended
- case MetaActionType::LAYOUTMODE:
- // FALLTHROUGH intended
- case MetaActionType::TEXTLANGUAGE:
- // FALLTHROUGH intended
- case MetaActionType::COMMENT:
- break;
-
- // bitmap output methods
- case MetaActionType::BMP:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpAction* pAction = static_cast<MetaBmpAction*>(pAct);
-
- checkMetadataBitmap(
- BitmapEx( pAction->GetBitmap()),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmap().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPSCALE:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpScaleAction* pAction = static_cast<MetaBmpScaleAction*>(pAct);
-
- checkMetadataBitmap(
- BitmapEx( pAction->GetBitmap()),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPSCALEPART:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpScalePartAction* pAction = static_cast<MetaBmpScalePartAction*>(pAct);
-
- checkMetadataBitmap( BitmapEx( pAction->GetBitmap() ),
- pAction->GetSrcPoint(),
- pAction->GetSrcSize(),
- pOut->LogicToPixel( pAction->GetDestPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetDestSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEX:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExAction* pAction = static_cast<MetaBmpExAction*>(pAct);
-
- checkMetadataBitmap(
- pAction->GetBitmapEx(),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pAction->GetBitmapEx().GetSizePixel(),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEXSCALE:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExScaleAction* pAction = static_cast<MetaBmpExScaleAction*>(pAct);
-
- checkMetadataBitmap(
- pAction->GetBitmapEx(),
- Point(), Size(),
- pOut->LogicToPixel( pAction->GetPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- case MetaActionType::BMPEXSCALEPART:
- if( !nNumBitmaps && !bNonBitmapActionEncountered )
- {
- MetaBmpExScalePartAction* pAction = static_cast<MetaBmpExScalePartAction*>(pAct);
-
- checkMetadataBitmap( pAction->GetBitmapEx(),
- pAction->GetSrcPoint(),
- pAction->GetSrcSize(),
- pOut->LogicToPixel( pAction->GetDestPoint(),
- rPrefMapMode ),
- pOut->LogicToPixel( pAction->GetDestSize(),
- rPrefMapMode ),
- rSizePix,
- bNonBitmapActionEncountered );
- }
- ++nNumBitmaps;
- break;
-
- // these actions actually output something (that's
- // different from a bitmap)
- case MetaActionType::RASTEROP:
- if( static_cast<MetaRasterOpAction*>(pAct)->GetRasterOp() == RasterOp::OverPaint )
- break;
- SAL_FALLTHROUGH;
- case MetaActionType::PIXEL:
- SAL_FALLTHROUGH;
- case MetaActionType::POINT:
- SAL_FALLTHROUGH;
- case MetaActionType::LINE:
- SAL_FALLTHROUGH;
- case MetaActionType::RECT:
- SAL_FALLTHROUGH;
- case MetaActionType::ROUNDRECT:
- SAL_FALLTHROUGH;
- case MetaActionType::ELLIPSE:
- SAL_FALLTHROUGH;
- case MetaActionType::ARC:
- SAL_FALLTHROUGH;
- case MetaActionType::PIE:
- SAL_FALLTHROUGH;
- case MetaActionType::CHORD:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYLINE:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYGON:
- SAL_FALLTHROUGH;
- case MetaActionType::POLYPOLYGON:
- SAL_FALLTHROUGH;
-
- case MetaActionType::TEXT:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTARRAY:
- SAL_FALLTHROUGH;
- case MetaActionType::STRETCHTEXT:
- SAL_FALLTHROUGH;
- case MetaActionType::TEXTRECT:
- SAL_FALLTHROUGH;
-
- case MetaActionType::MASK:
- SAL_FALLTHROUGH;
- case MetaActionType::MASKSCALE:
- SAL_FALLTHROUGH;
- case MetaActionType::MASKSCALEPART:
- SAL_FALLTHROUGH;
-
- case MetaActionType::GRADIENT:
- SAL_FALLTHROUGH;
- case MetaActionType::HATCH:
- SAL_FALLTHROUGH;
- case MetaActionType::WALLPAPER:
- SAL_FALLTHROUGH;
-
- case MetaActionType::Transparent:
- SAL_FALLTHROUGH;
- case MetaActionType::EPS:
- SAL_FALLTHROUGH;
- case MetaActionType::FLOATTRANSPARENT:
- SAL_FALLTHROUGH;
- case MetaActionType::GRADIENTEX:
- SAL_FALLTHROUGH;
-
- // OutDev state changes that _do_ affect bitmap
- // output
- case MetaActionType::CLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::ISECTRECTCLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::ISECTREGIONCLIPREGION:
- SAL_FALLTHROUGH;
- case MetaActionType::MOVECLIPREGION:
- SAL_FALLTHROUGH;
-
- case MetaActionType::MAPMODE:
- SAL_FALLTHROUGH;
- case MetaActionType::REFPOINT:
- SAL_FALLTHROUGH;
- default:
- bNonBitmapActionEncountered = true;
- break;
- }
- }
- }
- return nNumBitmaps == 1 && !bNonBitmapActionEncountered;
-}
-
-sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr )
-{
- const Graphic& rGraphic = rObj.GetGraphic();
- const GraphicType eType = rGraphic.GetType();
-
- bool canCacheAsBitmap = false;
- if( GraphicType::Bitmap == eType )
- canCacheAsBitmap = true;
- else if( GraphicType::GdiMetafile == eType )
- canCacheAsBitmap = IsCacheableAsBitmap( rGraphic.GetGDIMetaFile(), pOut, rSz );
- else
- return 0;
- if( canCacheAsBitmap )
- {
- const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
- const long nBitCount = pOut->GetBitCount();
-
- if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) ||
- ( aOutSizePix.Height() > MAX_BMP_EXTENT ) )
- {
- return ULONG_MAX;
- }
- else if( nBitCount )
- {
- sal_uLong nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
- if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
- nNeededSize += nNeededSize / nBitCount;
- return nNeededSize;
- }
- else
- {
- OSL_FAIL( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
- return 256000;
- }
- }
- else
- return rGraphic.GetSizeBytes();
-}
-
-GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry()
-{
- delete mpMtf;
- delete mpBmpEx;
-}
-
-void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const
-{
- if( mpMtf )
- GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr );
- else if( mpBmpEx )
- {
- if( maAttr.IsRotated() )
- {
- tools::Polygon aPoly( Rectangle( rPt, rSz ) );
-
- aPoly.Rotate( rPt, maAttr.GetRotation() % 3600 );
- const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
- pOut->DrawBitmapEx( aRotBoundRect.TopLeft(), aRotBoundRect.GetSize(), *mpBmpEx );
- }
- else
- pOut->DrawBitmapEx( rPt, rSz, *mpBmpEx );
- }
-}
-
-GraphicCache::GraphicCache( sal_uLong nDisplayCacheSize, sal_uLong nMaxObjDisplayCacheSize ) :
- maReleaseTimer ( "svtools::GraphicCache maReleaseTimer" ),
- mnReleaseTimeoutSeconds ( 0UL ),
- mnMaxDisplaySize ( nDisplayCacheSize ),
- mnMaxObjDisplaySize ( nMaxObjDisplayCacheSize ),
- mnUsedDisplaySize ( 0UL )
-{
- maReleaseTimer.SetTimeoutHdl( LINK( this, GraphicCache, ReleaseTimeoutHdl ) );
- maReleaseTimer.SetTimeout( 10000 );
- maReleaseTimer.Start();
-}
-
-GraphicCache::~GraphicCache()
-{
- DBG_ASSERT( !maGraphicCache.size(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" );
- DBG_ASSERT( maDisplayCache.empty(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" );
-}
-
-void GraphicCache::AddGraphicObject(
- const GraphicObject& rObj,
- Graphic& rSubstitute,
- const OString* pID,
- const GraphicObject* pCopyObj
-)
-{
- bool bInserted = false;
-
- if( !rObj.IsSwappedOut()
- && ( pID
- || ( pCopyObj
- && ( pCopyObj->GetType() != GraphicType::NONE )
- )
- || ( rObj.GetType() != GraphicType::NONE )
- )
- )
- {
- if( pCopyObj
- && !maGraphicCache.empty()
- )
- {
- GraphicCacheEntryList::iterator it = maGraphicCache.begin();
- while( !bInserted
- && ( it != maGraphicCache.end() )
- )
- {
- if( (*it)->HasGraphicObjectReference( *pCopyObj ) )
- {
- (*it)->AddGraphicObjectReference( rObj, rSubstitute );
- bInserted = true;
- }
- else
- {
- ++it;
- }
- }
- }
-
- if( !bInserted )
- {
- GraphicCacheEntryList::iterator it = maGraphicCache.begin();
- std::unique_ptr< GraphicID > apID;
-
- if( !pID )
- {
- apID.reset( new GraphicID( rObj ) );
- }
-
- while( !bInserted
- && ( it != maGraphicCache.end() )
- )
- {
- const GraphicID& rEntryID = (*it)->GetID();
-
- if( pID )
- {
- if( rEntryID.GetIDString() == *pID )
- {
- (*it)->TryToSwapIn();
-
- // since pEntry->TryToSwapIn can modify our current list, we have to
- // iterate from beginning to add a reference to the appropriate
- // CacheEntry object; after this, quickly jump out of the outer iteration
- for( GraphicCacheEntryList::iterator jt = maGraphicCache.begin();
- !bInserted && jt != maGraphicCache.end();
- ++jt
- )
- {
- const GraphicID& rID = (*jt)->GetID();
-
- if( rID.GetIDString() == *pID )
- {
- (*jt)->AddGraphicObjectReference( rObj, rSubstitute );
- bInserted = true;
- }
- }
-
- if( !bInserted )
- {
- maGraphicCache.push_back( new GraphicCacheEntry( rObj ) );
- bInserted = true;
- }
- }
- }
- else
- {
- if( rEntryID == *apID )
- {
- (*it)->AddGraphicObjectReference( rObj, rSubstitute );
- bInserted = true;
- }
- }
-
- if( !bInserted )
- ++it;
- }
- }
- }
-
- if( !bInserted )
- maGraphicCache.push_back( new GraphicCacheEntry( rObj ) );
-}
-
-void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj )
-{
- // Release cached object
- bool bRemoved = false;
- GraphicCacheEntryList::iterator it = maGraphicCache.begin();
- while (!bRemoved && it != maGraphicCache.end())
- {
- bRemoved = (*it)->ReleaseGraphicObjectReference( rObj );
-
- if( bRemoved && (0 == (*it)->GetGraphicObjectReferenceCount()) )
- {
- // if graphic cache entry has no more references,
- // the corresponding display cache object can be removed
- GraphicDisplayCacheEntryList::iterator it2 = maDisplayCache.begin();
- while( it2 != maDisplayCache.end() )
- {
- GraphicDisplayCacheEntry* pDisplayEntry = *it2;
- if( pDisplayEntry->GetReferencedCacheEntry() == *it )
- {
- mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
- it2 = maDisplayCache.erase( it2 );
- delete pDisplayEntry;
- }
- else
- ++it2;
- }
-
- // delete graphic cache entry
- delete *it;
- it = maGraphicCache.erase( it );
- }
- else
- ++it;
- }
-
- DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" );
-}
-
-void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
-{
- // notify cache that rObj is swapped out (and can thus be pruned
- // from the cache)
- GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
-
- if( pEntry )
- pEntry->GraphicObjectWasSwappedOut( rObj );
-}
-
-void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
-{
- GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
-
- if( pEntry )
- {
- if( pEntry->GetID().IsEmpty() )
- {
- ReleaseGraphicObject( rObj );
- AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), nullptr, nullptr );
- }
- else
- pEntry->GraphicObjectWasSwappedIn( rObj );
- }
-}
-
-void GraphicCache::SetMaxDisplayCacheSize( sal_uLong nNewCacheSize )
-{
- mnMaxDisplaySize = nNewCacheSize;
-
- if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() )
- ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() );
-}
-
-void GraphicCache::SetMaxObjDisplayCacheSize( sal_uLong nNewMaxObjSize )
-{
- const bool bDestroy = nNewMaxObjSize < mnMaxObjDisplaySize;
-
- mnMaxObjDisplaySize = std::min( nNewMaxObjSize, mnMaxDisplaySize );
-
- if( bDestroy )
- {
- GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
- while( it != maDisplayCache.end() )
- {
- GraphicDisplayCacheEntry* pCacheObj = *it;
- if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize )
- {
- mnUsedDisplaySize -= pCacheObj->GetCacheSize();
- it = maDisplayCache.erase( it );
- delete pCacheObj;
- }
- else
- ++it;
- }
- }
-}
-
-void GraphicCache::SetCacheTimeout( sal_uLong nTimeoutSeconds )
-{
- if( mnReleaseTimeoutSeconds != nTimeoutSeconds )
- {
- ::salhelper::TTimeValue aReleaseTime;
-
- if( ( mnReleaseTimeoutSeconds = nTimeoutSeconds ) != 0 )
- {
- osl_getSystemTime( &aReleaseTime );
- aReleaseTime.addTime( ::salhelper::TTimeValue( nTimeoutSeconds, 0 ) );
- }
-
- for( GraphicDisplayCacheEntryList::const_iterator it = maDisplayCache.begin();
- it != maDisplayCache.end(); ++it )
- {
- (*it)->SetReleaseTime( aReleaseTime );
- }
- }
-}
-
-bool GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr ) const
-{
- return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <=
- GetMaxObjDisplayCacheSize() );
-}
-
-bool GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr ) const
-{
- const Point aPtPixel( pOut->LogicToPixel( rPt ) );
- const Size aSzPixel( pOut->LogicToPixel( rSz ) );
- const GraphicCacheEntry* pCacheEntry = const_cast<GraphicCache*>(this)->ImplGetCacheEntry( rObj );
- bool bFound = false;
-
- if( pCacheEntry )
- {
- for( GraphicDisplayCacheEntryList::const_iterator it = maDisplayCache.begin();
- !bFound && ( it != maDisplayCache.end() ); ++it )
- {
- if( (*it)->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
- bFound = true;
- }
- }
-
- return bFound;
-}
-
-OString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const
-{
- OString aRet;
- GraphicCacheEntry* pEntry = const_cast<GraphicCache*>(this)->ImplGetCacheEntry( rObj );
-
- // ensure that the entry is correctly initialized (it has to be read at least once)
- if( pEntry && pEntry->GetID().IsEmpty() )
- {
- pEntry->TryToSwapIn();
- // do another call to ImplGetCacheEntry in case of modified entry list
- pEntry = const_cast<GraphicCache*>(this)->ImplGetCacheEntry( rObj );
- }
-
- if( pEntry )
- aRet = pEntry->GetID().GetIDString();
-
- return aRet;
-}
-
-bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr,
- const BitmapEx& rBmpEx )
-{
- const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
- bool bRet = false;
-
- if( nNeededSize <= GetMaxObjDisplayCacheSize() )
- {
- if( nNeededSize > GetFreeDisplayCacheSize() )
- ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
-
- GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
- pOut, rPt, rSz, rObj, rAttr, rBmpEx );
-
- if( GetCacheTimeout() )
- {
- ::salhelper::TTimeValue aReleaseTime;
-
- osl_getSystemTime( &aReleaseTime );
- aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
- pNewEntry->SetReleaseTime( aReleaseTime );
- }
-
- maDisplayCache.push_back( pNewEntry );
- mnUsedDisplaySize += pNewEntry->GetCacheSize();
- bRet = true;
- }
-
- return bRet;
-}
-
-bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr,
- const GDIMetaFile& rMtf )
-{
- const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
- bool bRet = false;
-
- if( nNeededSize <= GetMaxObjDisplayCacheSize() )
- {
- if( nNeededSize > GetFreeDisplayCacheSize() )
- ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
-
- GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
- pOut, rPt, rSz, rObj, rAttr, rMtf );
-
- if( GetCacheTimeout() )
- {
- ::salhelper::TTimeValue aReleaseTime;
-
- osl_getSystemTime( &aReleaseTime );
- aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
- pNewEntry->SetReleaseTime( aReleaseTime );
- }
-
- maDisplayCache.push_back( pNewEntry );
- mnUsedDisplaySize += pNewEntry->GetCacheSize();
- bRet = true;
- }
-
- return bRet;
-}
-
-bool GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
- const GraphicObject& rObj, const GraphicAttr& rAttr )
-{
- const Point aPtPixel( pOut->LogicToPixel( rPt ) );
- const Size aSzPixel( pOut->LogicToPixel( rSz ) );
- const GraphicCacheEntry* pCacheEntry = ImplGetCacheEntry( rObj );
- GraphicDisplayCacheEntry* pDisplayCacheEntry = nullptr;
- GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
- bool bRet = false;
-
- while( !bRet && it != maDisplayCache.end() )
- {
- pDisplayCacheEntry = *it;
- if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
- {
- ::salhelper::TTimeValue aReleaseTime;
-
- // put found object at last used position
- it = maDisplayCache.erase( it );
- maDisplayCache.push_back( pDisplayCacheEntry );
-
- if( GetCacheTimeout() )
- {
- osl_getSystemTime( &aReleaseTime );
- aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
- }
-
- pDisplayCacheEntry->SetReleaseTime( aReleaseTime );
- bRet = true;
- }
- else
- ++it;
- }
-
- if( bRet )
- pDisplayCacheEntry->Draw( pOut, rPt, rSz );
-
- return bRet;
-}
-
-bool GraphicCache::ImplFreeDisplayCacheSpace( sal_uLong nSizeToFree )
-{
- sal_uLong nFreedSize = 0;
-
- if( nSizeToFree )
- {
- GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
-
- if( nSizeToFree > mnUsedDisplaySize )
- nSizeToFree = mnUsedDisplaySize;
-
- while( it != maDisplayCache.end() )
- {
- GraphicDisplayCacheEntry* pCacheObj = *it;
-
- nFreedSize += pCacheObj->GetCacheSize();
- mnUsedDisplaySize -= pCacheObj->GetCacheSize();
- it = maDisplayCache.erase( it );
- delete pCacheObj;
-
- if( nFreedSize >= nSizeToFree )
- break;
- }
- }
-
- return( nFreedSize >= nSizeToFree );
-}
-
-GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj )
-{
- GraphicCacheEntry* pRet = nullptr;
-
- for(
- GraphicCacheEntryList::iterator it = maGraphicCache.begin();
- !pRet && it != maGraphicCache.end();
- ++it
- ) {
- if( (*it)->HasGraphicObjectReference( rObj ) ) {
- pRet = *it;
- }
- }
-
- return pRet;
-}
-
-IMPL_LINK( GraphicCache, ReleaseTimeoutHdl, Timer*, pTimer, void )
-{
- pTimer->Stop();
-
- ::salhelper::TTimeValue aCurTime;
- GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
-
- osl_getSystemTime( &aCurTime );
-
- while( it != maDisplayCache.end() )
- {
- GraphicDisplayCacheEntry* pDisplayEntry = *it;
- const ::salhelper::TTimeValue& rReleaseTime = pDisplayEntry->GetReleaseTime();
-
- if( !rReleaseTime.isEmpty() && ( rReleaseTime < aCurTime ) )
- {
- mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
- it = maDisplayCache.erase( it );
- delete pDisplayEntry;
- }
- else
- ++it;
- }
-
- pTimer->Start();
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/graphic/grfcache.hxx b/vcl/source/graphic/grfcache.hxx
deleted file mode 100644
index 2e2d089eb2cb..000000000000
--- a/vcl/source/graphic/grfcache.hxx
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_VCL_SOURCE_GRAPHIC_GRFCACHE_HXX
-#define INCLUDED_VCL_SOURCE_GRAPHIC_GRFCACHE_HXX
-
-#include <vcl/graph.hxx>
-#include <vcl/timer.hxx>
-#include <list>
-
-
-class GraphicAttr;
-class GraphicCacheEntry;
-class GraphicDisplayCacheEntry;
-class GraphicObject;
-
-class GraphicCache
-{
-private:
- typedef std::list< GraphicCacheEntry* > GraphicCacheEntryList;
- typedef std::list< GraphicDisplayCacheEntry* > GraphicDisplayCacheEntryList;
-
- Timer maReleaseTimer;
- GraphicCacheEntryList maGraphicCache;
- GraphicDisplayCacheEntryList maDisplayCache;
- sal_uLong mnReleaseTimeoutSeconds;
- sal_uLong mnMaxDisplaySize;
- sal_uLong mnMaxObjDisplaySize;
- sal_uLong mnUsedDisplaySize;
-
- bool ImplFreeDisplayCacheSpace( sal_uLong nSizeToFree );
- GraphicCacheEntry* ImplGetCacheEntry( const GraphicObject& rObj );
-
-
- DECL_LINK( ReleaseTimeoutHdl, Timer*, void );
-
-public:
-
- GraphicCache(
- sal_uLong nDisplayCacheSize,
- sal_uLong nMaxObjDisplayCacheSize
- );
-
- ~GraphicCache();
-
-public:
-
- void AddGraphicObject(
- const GraphicObject& rObj,
- Graphic& rSubstitute,
- const OString* pID,
- const GraphicObject* pCopyObj
- );
-
- void ReleaseGraphicObject( const GraphicObject& rObj );
-
- void GraphicObjectWasSwappedOut( const GraphicObject& rObj );
- void GraphicObjectWasSwappedIn( const GraphicObject& rObj );
-
- OString GetUniqueID( const GraphicObject& rObj ) const;
-
-public:
-
- void SetMaxDisplayCacheSize( sal_uLong nNewCacheSize );
- sal_uLong GetMaxDisplayCacheSize() const { return mnMaxDisplaySize; };
-
- void SetMaxObjDisplayCacheSize( sal_uLong nNewMaxObjSize );
-
- sal_uLong GetMaxObjDisplayCacheSize() const { return mnMaxObjDisplaySize; }
-
- sal_uLong GetUsedDisplayCacheSize() const { return mnUsedDisplaySize; }
- sal_uLong GetFreeDisplayCacheSize() const { return( mnMaxDisplaySize - mnUsedDisplaySize ); }
-
- void SetCacheTimeout( sal_uLong nTimeoutSeconds );
- sal_uLong GetCacheTimeout() const { return mnReleaseTimeoutSeconds; }
-
- bool IsDisplayCacheable(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr
- ) const;
-
- bool IsInDisplayCache(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr
- ) const;
-
- bool CreateDisplayCacheObj(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr,
- const BitmapEx& rBmpEx
- );
-
- bool CreateDisplayCacheObj(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr,
- const GDIMetaFile& rMtf
- );
-
- bool DrawDisplayCacheObj(
- OutputDevice* pOut,
- const Point& rPt,
- const Size& rSz,
- const GraphicObject& rObj,
- const GraphicAttr& rAttr
- );
-};
-
-#endif // INCLUDED_VCL_SOURCE_GRAPHIC_GRFCACHE_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */