diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2019-01-11 00:06:49 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2019-01-11 05:38:52 +0100 |
commit | 98d71c4e0847797a4ba9229a8e6d832a8a3d5e0f (patch) | |
tree | 97012c315567a679abc827873746afa5fa90bdd0 | |
parent | 284a7f60fff72c4d8c011ff60ea2e40163cd25c3 (diff) |
tdf#69060: lock refreshing font data when loading a document
This accumulates all calls to OutputDevice::ImplRefreshAllFontData
while loading document's model, to avoid multiple updates for each
imported font. After loading, OutputDevice::ImplRefreshAllFontData
is executed once.
Change-Id: I5b23a2b8a3765dee9061b6479665d04c2ba11cbf
Reviewed-on: https://gerrit.libreoffice.org/47112
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | include/vcl/outdev.hxx | 3 | ||||
-rw-r--r-- | include/vcl/svapp.hxx | 11 | ||||
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 4 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 3 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 5 | ||||
-rw-r--r-- | vcl/source/outdev/font.cxx | 40 |
6 files changed, 65 insertions, 1 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 1d4a936e22a6..3fa9d2167d27 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1263,6 +1263,9 @@ public: //If bNewFontLists is true then drop and refetch lists of system fonts SAL_DLLPRIVATE static void ImplUpdateAllFontData( bool bNewFontLists ); + // Lock font updates for all output devices + static void LockFontUpdates(bool bLock); + protected: SAL_DLLPRIVATE const LogicalFontInstance* GetFontInstance() const; SAL_DLLPRIVATE long GetEmphasisAscent() const { return mnEmphasisAscent; } diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index ac1c0ddfb848..712f75a0f09d 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -1365,6 +1365,17 @@ public: ///@} + /** Lock font updates for all output devices + + @remark When performing operations that might involve multiple registration of fonts, such as + opening/closing documents with multiple embedded fonts, then each font addition/removal + might cause an event that initiates a rebuild of each OutputDevice's font lists. + + Locking font updates disables processing such events, and unlocking causes a single such + processing for all OutputDevices. + */ + static void LockFontUpdates(bool bLock); + // For vclbootstrapprotector: static void setDeInitHook(Link<LinkParamNone*,void> const & hook); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index f1ae5b009231..e83ff19c3186 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -581,6 +581,10 @@ bool SfxObjectShell::ImportFromGeneratedStream_Impl( bool SfxObjectShell::DoLoad( SfxMedium *pMed ) { ModifyBlocker_Impl aBlock( this ); + struct FontLockGuard { + FontLockGuard() { Application::LockFontUpdates(true); } + ~FontLockGuard() { Application::LockFontUpdates(false); } + } aFontLockGuard; pMedium = pMed; pMedium->CanDisposeStorage_Impl( true ); diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index beb877f728ff..ea48d774ccca 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -351,6 +351,9 @@ struct ImplSVData bool mbDeInit = false; // Is VCL deinitializing std::unique_ptr<SalI18NImeStatus> mpImeStatus; // interface to ime status window, only used by the X11 backend std::unique_ptr<SalSystem> mpSalSystem; // SalSystem interface + int mnFontUpdatesLockCount = 0; // avoid repeated font updates + bool mbFontUpdatesPending = false; // need to update font data after unlock + bool mbFontUpdatesNewLists = false; // generate new font lists bool mbResLocaleSet = false; // SV-Resource-Manager std::locale maResLocale; // Resource locale ImplSchedulerContext maSchedCtx; // indepen data for class Scheduler diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index c73769ebcc8a..c3f3b07827f0 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -987,6 +987,11 @@ void Application::RemoveUserEvent( ImplSVEvent * nUserEvent ) } } +void Application::LockFontUpdates(bool bLock) +{ + OutputDevice::LockFontUpdates(bLock); +} + WorkWindow* Application::GetAppWindow() { return ImplGetSVData()->maWinData.mpAppWin; diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 1e0cb553c04b..4d982e9d1f3a 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -595,9 +595,26 @@ void OutputDevice::ImplClearAllFontData(bool bNewFontLists) } } +namespace { +osl::Mutex& GetFontUpdatesLockMutex() +{ + static osl::Mutex aFontUpdatesMutex; + return aFontUpdatesMutex; +} +} + void OutputDevice::ImplRefreshAllFontData(bool bNewFontLists) { - ImplUpdateFontDataForAllFrames( &OutputDevice::ImplRefreshFontData, bNewFontLists ); + auto svdata = ImplGetSVData(); + osl::MutexGuard aGuard(GetFontUpdatesLockMutex()); + if (!svdata->mnFontUpdatesLockCount) + ImplUpdateFontDataForAllFrames(&OutputDevice::ImplRefreshFontData, bNewFontLists); + else + { + svdata->mbFontUpdatesPending = true; + if (bNewFontLists) + svdata->mbFontUpdatesNewLists = true; + } } void OutputDevice::ImplUpdateAllFontData(bool bNewFontLists) @@ -643,6 +660,27 @@ void OutputDevice::ImplUpdateFontDataForAllFrames( const FontUpdateHandler_t pHd } } +void OutputDevice::LockFontUpdates(bool bLock) +{ + auto svdata = ImplGetSVData(); + osl::MutexGuard aGuard(GetFontUpdatesLockMutex()); + if (bLock) + { + ++svdata->mnFontUpdatesLockCount; + } + else if (svdata->mnFontUpdatesLockCount > 0) + { + --svdata->mnFontUpdatesLockCount; + if (!svdata->mnFontUpdatesLockCount && svdata->mbFontUpdatesPending) + { + ImplRefreshAllFontData(svdata->mbFontUpdatesNewLists); + + svdata->mbFontUpdatesPending = false; + svdata->mbFontUpdatesNewLists = false; + } + } +} + void OutputDevice::BeginFontSubstitution() { ImplSVData* pSVData = ImplGetSVData(); |