[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-5-2+backports' - 5 commits - drawinglayer/source include/drawinglayer svx/source sw/inc sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Thu Aug 9 11:24:00 UTC 2018
drawinglayer/source/primitive2d/textlayoutdevice.cxx | 4
include/drawinglayer/primitive2d/textlayoutdevice.hxx | 2
svx/source/svdraw/svdotextdecomposition.cxx | 5
sw/inc/ndole.hxx | 17 +
sw/source/core/doc/notxtfrm.cxx | 37 +-
sw/source/core/ole/ndole.cxx | 234 +++++++++++++++++-
6 files changed, 270 insertions(+), 29 deletions(-)
New commits:
commit 949ecd96e8bec1709b89bca6177a1fbba6cc6f94
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Thu Jul 7 10:16:02 2016 +0200
Commit: Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Thu Aug 9 13:20:02 2018 +0200
Related: tdf#50613 use an own instance of ThreadPool
Using the global ThreadPool (getSharedOptimalPool()) can lead to
problems when more than one usage executes and one of them
already calls waitUntilEmpty() what of course influences the
other usage. Thus I added an own instance of ThreadPool for
async loading of chart models in writer
Change-Id: I4bea64af0d36e87081abec95c75574966d0fe5b9
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 903d96814bc1..1be81749133e 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -676,7 +676,36 @@ void SwOLENode::SetChanged()
}
}
//////////////////////////////////////////////////////////////////////////////
+// due to some problems in test cases with the SharedOptimalPool, use
+// an own instance of comphelper::ThreadPool. Problem is that other
+// usages of getSharedOptimalPool() may interfere if more than one
+// pool user calls waitUntilEmpty().
+//
+// It gets created on-demand and will be available during LO's
+// lifetime for loading chart models used in writer in parallel. It
+// would be possible to add a usage count, then trigger a timer and
+// clean it up (due to lifetime issues), but that's probably overkill.
+// It gets created on demand, is ready for global reuse and makes no
+// harm (not much ressources needed)
+static comphelper::ThreadPool* pLocalPool = 0;
+
+comphelper::ThreadPool* getLocalThreadPool()
+{
+ if (pLocalPool)
+ {
+ return pLocalPool;
+ }
+
+ if (0 == comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount())
+ {
+ return nullptr;
+ }
+
+ pLocalPool = new comphelper::ThreadPool(comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount());
+ return pLocalPool;
+}
+/// Holder for local data for a parallely-executed task to load a chart model
class DeflateData
{
private:
@@ -734,8 +763,7 @@ public:
}
};
-//////////////////////////////////////////////////////////////////////////////
-
+/// Task for parallely-executed task to load a chart model
class DeflateThread : public comphelper::ThreadTask
{
// the data to work on
@@ -1080,11 +1108,14 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
if(aXModel.is())
{
+ // loaded using own instance of comphelper::ThreadPool,
+ // see getLocalThreadPool(). Disable via bool below if
+ // trouble surfaces somewhere
static bool bAnynchronousLoadingAllowed = true;
if(bSynchron ||
!bAnynchronousLoadingAllowed ||
- 0 == comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount())
+ nullptr == getLocalThreadPool())
{
// load chart synchron in this Thread
m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
@@ -1100,7 +1131,7 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
{
m_pDeflateData = new DeflateData(aXModel);
DeflateThread* pNew = new DeflateThread(*m_pDeflateData);
- comphelper::ThreadPool::getSharedOptimalPool().pushTask(pNew);
+ getLocalThreadPool()->pushTask(pNew);
}
}
}
commit 2f91c89baae9b0cf9e11cff02cf56338ebdda177
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Fri Jul 1 15:10:00 2016 +0200
Commit: Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Thu Aug 9 13:19:52 2018 +0200
sw: tdf#50613 fix async chart load handling
Especially if synchronous loading is requested, an async worker is on the way
and we would need to 'wait' for the data.
Change-Id: I20f9938738c1b46bda6b9a7f5a761e82153aed3b
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index b6af9fb81b59..9f90c7ddad46 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -45,7 +45,7 @@ class SW_DLLPUBLIC SwOLEObj
// eventually buffered data if it is a chart OLE
drawinglayer::primitive2d::Primitive2DContainer m_aPrimitive2DSequence;
basegfx::B2DRange m_aRange;
- class DeflateData* m_aDeflateData;
+ class DeflateData* m_pDeflateData;
SwOLEObj( const SwOLEObj& rObj ) = delete;
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index d9cee6150602..903d96814bc1 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -681,18 +681,27 @@ class DeflateData
{
private:
friend class DeflateThread;
+ friend class SwOLEObj;
- const uno::Reference< frame::XModel > maXModel;
+ uno::Reference< frame::XModel > maXModel;
drawinglayer::primitive2d::Primitive2DContainer maPrimitive2DSequence;
basegfx::B2DRange maRange;
+
+ // set from the WorkerThread when done
std::atomic< bool> mbFinished;
+ // evtl.set from the SwOLEObj destructor when a WorkerThread is still active
+ // since it is not possible to kill it - let it terminate and delete the
+ // data working on itself
+ std::atomic< bool> mbKilled;
+
public:
DeflateData(const uno::Reference< frame::XModel >& rXModel)
: maXModel(rXModel),
maPrimitive2DSequence(),
maRange(),
- mbFinished(false)
+ mbFinished(false),
+ mbKilled(false)
{
}
@@ -713,11 +722,14 @@ public:
void waitFinished()
{
- const TimeValue aTimeValue(0, 100000); // 1/10th second
-
- while(!mbFinished)
+ while(!mbFinished && !mbKilled)
{
- osl_waitThread(&aTimeValue);
+ // need to wait until the load in progress is finished.
+ // to do so, Application::Yield() is needed since the execution
+ // here means that the SolarMutex is locked, but the
+ // WorkerThreads need it to be able to continue and finish
+ // the running import
+ Application::Yield();
}
}
};
@@ -726,6 +738,7 @@ public:
class DeflateThread : public comphelper::ThreadTask
{
+ // the data to work on
DeflateData& mrDeflateData;
public:
@@ -739,14 +752,24 @@ private:
{
try
{
+ // load the chart data and get the primitives
mrDeflateData.maPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
mrDeflateData.maXModel,
mrDeflateData.maRange);
+
+ // model no longer needed and done
+ mrDeflateData.maXModel.clear();
mrDeflateData.mbFinished = true;
}
catch (const uno::Exception&)
{
}
+
+ if(mrDeflateData.mbKilled)
+ {
+ // need to cleanup myself - data will not be used
+ delete &mrDeflateData;
+ }
}
};
@@ -758,7 +781,7 @@ SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
xOLERef( xObj ),
m_aPrimitive2DSequence(),
m_aRange(),
- m_aDeflateData(nullptr)
+ m_pDeflateData(nullptr)
{
xOLERef.Lock();
if ( xObj.is() )
@@ -775,7 +798,7 @@ SwOLEObj::SwOLEObj( const OUString &rString, sal_Int64 nAspect ) :
aName( rString ),
m_aPrimitive2DSequence(),
m_aRange(),
- m_aDeflateData(nullptr)
+ m_pDeflateData(nullptr)
{
xOLERef.Lock();
xOLERef.SetViewAspect( nAspect );
@@ -783,10 +806,12 @@ SwOLEObj::SwOLEObj( const OUString &rString, sal_Int64 nAspect ) :
SwOLEObj::~SwOLEObj()
{
- if(m_aDeflateData)
+ if(m_pDeflateData)
{
- m_aDeflateData->waitFinished();
- delete m_aDeflateData;
+ // set flag so that the worker thread will delete m_pDeflateData
+ // when finished and forget about it
+ m_pDeflateData->mbKilled = true;
+ m_pDeflateData = nullptr;
}
if( pListener )
@@ -1030,19 +1055,22 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
basegfx::B2DRange& rRange,
bool bSynchron)
{
- if(m_aDeflateData)
+ if(m_pDeflateData)
{
if(bSynchron)
{
- m_aDeflateData->waitFinished();
+ // data in high quality is requested, wait until the data is available
+ // since a WorkerThread was already started to load it
+ m_pDeflateData->waitFinished();
}
- if(m_aDeflateData->isFinished())
+ if(m_pDeflateData->isFinished())
{
- m_aPrimitive2DSequence = m_aDeflateData->getSequence();
- m_aRange = m_aDeflateData->getRange();
- delete m_aDeflateData;
- m_aDeflateData = nullptr;
+ // copy the result data and cleanup
+ m_aPrimitive2DSequence = m_pDeflateData->getSequence();
+ m_aRange = m_pDeflateData->getRange();
+ delete m_pDeflateData;
+ m_pDeflateData = nullptr;
}
}
@@ -1054,18 +1082,24 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
{
static bool bAnynchronousLoadingAllowed = true;
- if(bSynchron || !bAnynchronousLoadingAllowed)
+ if(bSynchron ||
+ !bAnynchronousLoadingAllowed ||
+ 0 == comphelper::ThreadPool::getSharedOptimalPool().getWorkerCount())
{
+ // load chart synchron in this Thread
m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
aXModel,
m_aRange);
}
else
{
- if(!m_aDeflateData)
+ // if not yet setup, initiate and start a WorkerThread to load the chart
+ // and it's primitives asynchron. If it already works, returning nothing
+ // is okay (preview will be reused)
+ if(!m_pDeflateData)
{
- m_aDeflateData = new DeflateData(aXModel);
- DeflateThread* pNew = new DeflateThread(*m_aDeflateData);
+ m_pDeflateData = new DeflateData(aXModel);
+ DeflateThread* pNew = new DeflateThread(*m_pDeflateData);
comphelper::ThreadPool::getSharedOptimalPool().pushTask(pNew);
}
}
@@ -1074,6 +1108,7 @@ drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAs
if(!m_aPrimitive2DSequence.empty() && !m_aRange.isEmpty())
{
+ // when we have data, also copy the buffered Range data as output
rRange = m_aRange;
}
@@ -1085,11 +1120,12 @@ void SwOLEObj::resetBufferedData()
m_aPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer();
m_aRange.reset();
- if(m_aDeflateData)
+ if(m_pDeflateData)
{
- m_aDeflateData->waitFinished();
- delete m_aDeflateData;
- m_aDeflateData = nullptr;
+ // load is in progress, wait until finished and cleanup without using it
+ m_pDeflateData->waitFinished();
+ delete m_pDeflateData;
+ m_pDeflateData = nullptr;
}
}
commit 6296e5ff06acb09b61ce731c6f820f35a695ee8a
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Fri Jul 1 14:50:00 2016 +0200
Commit: Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Thu Aug 9 13:19:43 2018 +0200
sw: tdf#50613 fix waitFinished into a loop
Change-Id: Ic8a720657c326d8d51bb3a73688b8f02b7096488
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 1e006320ece7..d9cee6150602 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -713,9 +713,10 @@ public:
void waitFinished()
{
- if(!mbFinished)
+ const TimeValue aTimeValue(0, 100000); // 1/10th second
+
+ while(!mbFinished)
{
- const TimeValue aTimeValue(0, 100000); // 1/10th second
osl_waitThread(&aTimeValue);
}
}
commit 385bba95ec2c5bc87aac4e2b2d2b458b05f68dd7
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Fri Jul 1 14:40:00 2016 +0200
Commit: Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Thu Aug 9 13:19:33 2018 +0200
tdf#50613 add support to load charts asynchronously
Generating primitives for chart visualisation can be moved to a
paralell executed task that loads the chart, thus speeding up
initial visualization. This is not possible for e.g. PDF or print
targets, only for edit visualization. On fallback, the replacement
images of the charts are used which are metafiles and have less
quality as primitives, but load quicker.
Change-Id: I68caa9e1bec50832bce535b5f54633d53cdef037
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 74067efb9569..7bbfdfaf3b6b 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -85,7 +85,6 @@ namespace
ImpTimedRefDev::~ImpTimedRefDev()
{
OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)");
- const SolarMutexGuard aGuard;
mpVirDev.disposeAndClear();
}
@@ -152,7 +151,8 @@ namespace drawinglayer
}
TextLayouterDevice::TextLayouterDevice()
- : mrDevice(acquireGlobalVirtualDevice())
+ : maSolarGuard(),
+ mrDevice(acquireGlobalVirtualDevice())
{
}
diff --git a/include/drawinglayer/primitive2d/textlayoutdevice.hxx b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
index e606f099a607..5761d3a03a9d 100644
--- a/include/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -26,6 +26,7 @@
#include <vector>
#include <com/sun/star/lang/Locale.hpp>
#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/svapp.hxx>
// predefines
class VirtualDevice;
@@ -57,6 +58,7 @@ namespace drawinglayer
class DRAWINGLAYER_DLLPUBLIC TextLayouterDevice
{
/// internally used VirtualDevice
+ SolarMutexGuard maSolarGuard;
VirtualDevice& mrDevice;
public:
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index c571f2a26ba8..efa1ea221b6f 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -694,6 +694,7 @@ void SdrTextObj::impDecomposeContourTextPrimitive(
aPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(fabs(aScale.getX()), fabs(aScale.getY())));
// prepare outliner
+ SolarMutexGuard aSolarGuard;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
const Size aNullSize;
rOutliner.SetPaperSize(aNullSize);
@@ -745,6 +746,7 @@ void SdrTextObj::impDecomposeAutoFitTextPrimitive(
// prepare outliner
const SfxItemSet& rTextItemSet = rSdrAutofitTextPrimitive.getSdrText()->GetItemSet();
+ SolarMutexGuard aSolarGuard;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
SdrTextVertAdjust eVAdj = GetTextVerticalAdjust(rTextItemSet);
SdrTextHorzAdjust eHAdj = GetTextHorizontalAdjust(rTextItemSet);
@@ -879,6 +881,7 @@ void SdrTextObj::impDecomposeBlockTextPrimitive(
// prepare outliner
const bool bIsCell(rSdrBlockTextPrimitive.getCellText());
+ SolarMutexGuard aSolarGuard;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
SdrTextHorzAdjust eHAdj = rSdrBlockTextPrimitive.getSdrTextHorzAdjust();
SdrTextVertAdjust eVAdj = rSdrBlockTextPrimitive.getSdrTextVertAdjust();
@@ -1127,6 +1130,7 @@ void SdrTextObj::impDecomposeStretchTextPrimitive(
aAnchorTextRange.expand(aTranslate + aScale);
// prepare outliner
+ SolarMutexGuard aSolarGuard;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
const EEControlBits nOriginalControlWord(rOutliner.GetControlWord());
const Size aNullSize;
@@ -1486,6 +1490,7 @@ void SdrTextObj::impDecomposeChainedTextPrimitive(
// prepare outliner
const SfxItemSet& rTextItemSet = rSdrChainedTextPrimitive.getSdrText()->GetItemSet();
+ SolarMutexGuard aSolarGuard;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
SdrTextVertAdjust eVAdj = GetTextVerticalAdjust(rTextItemSet);
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index 53de1090f94b..b6af9fb81b59 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -20,15 +20,16 @@
#define INCLUDED_SW_INC_NDOLE_HXX
#include <ndnotxt.hxx>
-
#include <svtools/embedhlp.hxx>
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
class SwGrfFormatColl;
class SwDoc;
class SwOLENode;
-
class SwOLEListener_Impl;
class SwEmbedObjectLink;
+class DeflateData;
+
class SW_DLLPUBLIC SwOLEObj
{
friend class SwOLENode;
@@ -44,6 +45,7 @@ class SW_DLLPUBLIC SwOLEObj
// eventually buffered data if it is a chart OLE
drawinglayer::primitive2d::Primitive2DContainer m_aPrimitive2DSequence;
basegfx::B2DRange m_aRange;
+ class DeflateData* m_aDeflateData;
SwOLEObj( const SwOLEObj& rObj ) = delete;
@@ -69,7 +71,9 @@ public:
// try to get OLE visualization in form of a Primitive2DSequence
// and the corresponding B2DRange. This data may be locally buffered
- drawinglayer::primitive2d::Primitive2DContainer tryToGetChartContentAsPrimitive2DSequence(basegfx::B2DRange& rRange);
+ drawinglayer::primitive2d::Primitive2DContainer tryToGetChartContentAsPrimitive2DSequence(
+ basegfx::B2DRange& rRange,
+ bool bSynchron);
void resetBufferedData();
};
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 555fd46bd69d..d5544d3928f0 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -1036,7 +1036,8 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
basegfx::B2DRange aSourceRange;
const drawinglayer::primitive2d::Primitive2DContainer aSequence(
pOLENd->GetOLEObj().tryToGetChartContentAsPrimitive2DSequence(
- aSourceRange));
+ aSourceRange,
+ bPrn));
if(!aSequence.empty() && !aSourceRange.isEmpty())
{
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 354c3404b427..1e006320ece7 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -58,7 +58,8 @@
#include <vcl/graphicfilter.hxx>
#include <comcore.hrc>
#include <svx/charthelper.hxx>
-
+#include <comphelper/threadpool.hxx>
+#include <atomic>
#include <deque>
using namespace utl;
@@ -674,13 +675,89 @@ void SwOLENode::SetChanged()
}
}
}
+//////////////////////////////////////////////////////////////////////////////
+
+class DeflateData
+{
+private:
+ friend class DeflateThread;
+
+ const uno::Reference< frame::XModel > maXModel;
+ drawinglayer::primitive2d::Primitive2DContainer maPrimitive2DSequence;
+ basegfx::B2DRange maRange;
+ std::atomic< bool> mbFinished;
+
+public:
+ DeflateData(const uno::Reference< frame::XModel >& rXModel)
+ : maXModel(rXModel),
+ maPrimitive2DSequence(),
+ maRange(),
+ mbFinished(false)
+ {
+ }
+
+ const drawinglayer::primitive2d::Primitive2DContainer& getSequence() const
+ {
+ return maPrimitive2DSequence;
+ }
+
+ const basegfx::B2DRange& getRange() const
+ {
+ return maRange;
+ }
+
+ bool isFinished() const
+ {
+ return mbFinished;
+ }
+
+ void waitFinished()
+ {
+ if(!mbFinished)
+ {
+ const TimeValue aTimeValue(0, 100000); // 1/10th second
+ osl_waitThread(&aTimeValue);
+ }
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+class DeflateThread : public comphelper::ThreadTask
+{
+ DeflateData& mrDeflateData;
+
+public:
+ DeflateThread(DeflateData& rDeflateData)
+ : mrDeflateData(rDeflateData)
+ {
+ }
+
+private:
+ virtual void doWork() override
+ {
+ try
+ {
+ mrDeflateData.maPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
+ mrDeflateData.maXModel,
+ mrDeflateData.maRange);
+ mrDeflateData.mbFinished = true;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
pOLENd( nullptr ),
pListener( nullptr ),
xOLERef( xObj ),
m_aPrimitive2DSequence(),
- m_aRange()
+ m_aRange(),
+ m_aDeflateData(nullptr)
{
xOLERef.Lock();
if ( xObj.is() )
@@ -696,7 +773,8 @@ SwOLEObj::SwOLEObj( const OUString &rString, sal_Int64 nAspect ) :
pListener( nullptr ),
aName( rString ),
m_aPrimitive2DSequence(),
- m_aRange()
+ m_aRange(),
+ m_aDeflateData(nullptr)
{
xOLERef.Lock();
xOLERef.SetViewAspect( nAspect );
@@ -704,6 +782,12 @@ SwOLEObj::SwOLEObj( const OUString &rString, sal_Int64 nAspect ) :
SwOLEObj::~SwOLEObj()
{
+ if(m_aDeflateData)
+ {
+ m_aDeflateData->waitFinished();
+ delete m_aDeflateData;
+ }
+
if( pListener )
{
if ( xOLERef.is() )
@@ -941,17 +1025,49 @@ OUString SwOLEObj::GetDescription()
return SW_RESSTR(STR_OLE);
}
-drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAsPrimitive2DSequence(basegfx::B2DRange& rRange)
+drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAsPrimitive2DSequence(
+ basegfx::B2DRange& rRange,
+ bool bSynchron)
{
+ if(m_aDeflateData)
+ {
+ if(bSynchron)
+ {
+ m_aDeflateData->waitFinished();
+ }
+
+ if(m_aDeflateData->isFinished())
+ {
+ m_aPrimitive2DSequence = m_aDeflateData->getSequence();
+ m_aRange = m_aDeflateData->getRange();
+ delete m_aDeflateData;
+ m_aDeflateData = nullptr;
+ }
+ }
+
if(m_aPrimitive2DSequence.empty() && m_aRange.isEmpty() && xOLERef.is() && xOLERef.IsChart())
{
const uno::Reference< frame::XModel > aXModel(xOLERef->getComponent(), uno::UNO_QUERY);
if(aXModel.is())
{
- m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
- aXModel,
- m_aRange);
+ static bool bAnynchronousLoadingAllowed = true;
+
+ if(bSynchron || !bAnynchronousLoadingAllowed)
+ {
+ m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
+ aXModel,
+ m_aRange);
+ }
+ else
+ {
+ if(!m_aDeflateData)
+ {
+ m_aDeflateData = new DeflateData(aXModel);
+ DeflateThread* pNew = new DeflateThread(*m_aDeflateData);
+ comphelper::ThreadPool::getSharedOptimalPool().pushTask(pNew);
+ }
+ }
}
}
@@ -967,6 +1083,13 @@ void SwOLEObj::resetBufferedData()
{
m_aPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer();
m_aRange.reset();
+
+ if(m_aDeflateData)
+ {
+ m_aDeflateData->waitFinished();
+ delete m_aDeflateData;
+ m_aDeflateData = nullptr;
+ }
}
SwOLELRUCache::SwOLELRUCache()
commit fd80334e0d9b6a0351278175e640659c779a93da
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Fri Jul 1 14:20:00 2016 +0200
Commit: Armin Le Grand <Armin.Le.Grand at cib.de>
CommitDate: Thu Aug 9 13:19:23 2018 +0200
tdf#50613 buffer OLE primitives for charts
If OLE is a chart, buffer the primitives used for presentation as
info at the SwOLEObj, after getting them the first time using the
ChartHelper.
Change-Id: I6d7486185f6eac450de9328d37ea800f424f351b
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index a1f25902d0ed..53de1090f94b 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -41,6 +41,10 @@ class SW_DLLPUBLIC SwOLEObj
svt::EmbeddedObjectRef xOLERef;
OUString aName;
+ // eventually buffered data if it is a chart OLE
+ drawinglayer::primitive2d::Primitive2DContainer m_aPrimitive2DSequence;
+ basegfx::B2DRange m_aRange;
+
SwOLEObj( const SwOLEObj& rObj ) = delete;
void SetNode( SwOLENode* pNode );
@@ -62,6 +66,11 @@ public:
const OUString& GetCurrentPersistName() const { return aName; }
OUString GetStyleString();
bool IsOleRef() const; ///< To avoid unnecessary loading of object.
+
+ // try to get OLE visualization in form of a Primitive2DSequence
+ // and the corresponding B2DRange. This data may be locally buffered
+ drawinglayer::primitive2d::Primitive2DContainer tryToGetChartContentAsPrimitive2DSequence(basegfx::B2DRange& rRange);
+ void resetBufferedData();
};
// SwOLENode
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index ebb083ac2741..555fd46bd69d 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -69,7 +69,6 @@
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <svtools/embedhlp.hxx>
-#include <svx/charthelper.hxx>
#include <dview.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
@@ -1034,29 +1033,22 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
if(bIsChart)
{
- const uno::Reference< frame::XModel > aXModel(pOLENd->GetOLEObj().GetOleRef()->getComponent(), uno::UNO_QUERY);
+ basegfx::B2DRange aSourceRange;
+ const drawinglayer::primitive2d::Primitive2DContainer aSequence(
+ pOLENd->GetOLEObj().tryToGetChartContentAsPrimitive2DSequence(
+ aSourceRange));
- if(aXModel.is())
+ if(!aSequence.empty() && !aSourceRange.isEmpty())
{
- basegfx::B2DRange aSourceRange;
-
- const drawinglayer::primitive2d::Primitive2DContainer aSequence(
- ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
- aXModel,
- aSourceRange));
-
- if(!aSequence.empty() && !aSourceRange.isEmpty())
- {
- const basegfx::B2DRange aTargetRange(
- aAlignedGrfArea.Left(), aAlignedGrfArea.Top(),
- aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom());
-
- bDone = paintUsingPrimitivesHelper(
- *pOut,
- aSequence,
- aSourceRange,
- aTargetRange);
- }
+ const basegfx::B2DRange aTargetRange(
+ aAlignedGrfArea.Left(), aAlignedGrfArea.Top(),
+ aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom());
+
+ bDone = paintUsingPrimitivesHelper(
+ *pOut,
+ aSequence,
+ aSourceRange,
+ aTargetRange);
}
}
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index c9f26b9b2156..354c3404b427 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -57,6 +57,7 @@
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/graphicfilter.hxx>
#include <comcore.hrc>
+#include <svx/charthelper.hxx>
#include <deque>
@@ -125,6 +126,10 @@ void SAL_CALL SwOLEListener_Impl::stateChanged( const lang::EventObject&, ::sal_
if (g_pOLELRU_Cache)
g_pOLELRU_Cache->RemoveObj( *mpObj );
}
+ else if(mpObj && nNewState == embed::EmbedStates::RUNNING)
+ {
+ mpObj->resetBufferedData();
+ }
}
void SwOLEListener_Impl::Release()
@@ -673,7 +678,9 @@ void SwOLENode::SetChanged()
SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
pOLENd( nullptr ),
pListener( nullptr ),
- xOLERef( xObj )
+ xOLERef( xObj ),
+ m_aPrimitive2DSequence(),
+ m_aRange()
{
xOLERef.Lock();
if ( xObj.is() )
@@ -687,7 +694,9 @@ SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
SwOLEObj::SwOLEObj( const OUString &rString, sal_Int64 nAspect ) :
pOLENd( nullptr ),
pListener( nullptr ),
- aName( rString )
+ aName( rString ),
+ m_aPrimitive2DSequence(),
+ m_aRange()
{
xOLERef.Lock();
xOLERef.SetViewAspect( nAspect );
@@ -932,6 +941,34 @@ OUString SwOLEObj::GetDescription()
return SW_RESSTR(STR_OLE);
}
+drawinglayer::primitive2d::Primitive2DContainer SwOLEObj::tryToGetChartContentAsPrimitive2DSequence(basegfx::B2DRange& rRange)
+{
+ if(m_aPrimitive2DSequence.empty() && m_aRange.isEmpty() && xOLERef.is() && xOLERef.IsChart())
+ {
+ const uno::Reference< frame::XModel > aXModel(xOLERef->getComponent(), uno::UNO_QUERY);
+
+ if(aXModel.is())
+ {
+ m_aPrimitive2DSequence = ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
+ aXModel,
+ m_aRange);
+ }
+ }
+
+ if(!m_aPrimitive2DSequence.empty() && !m_aRange.isEmpty())
+ {
+ rRange = m_aRange;
+ }
+
+ return m_aPrimitive2DSequence;
+}
+
+void SwOLEObj::resetBufferedData()
+{
+ m_aPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer();
+ m_aRange.reset();
+}
+
SwOLELRUCache::SwOLELRUCache()
: utl::ConfigItem(OUString("Office.Common/Cache"))
, m_nLRU_InitSize( 20 )
More information about the Libreoffice-commits
mailing list