[Libreoffice-commits] core.git: include/vcl sfx2/source vcl/inc vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Jan 11 04:39:18 UTC 2019


 include/vcl/outdev.hxx      |    3 +++
 include/vcl/svapp.hxx       |   11 +++++++++++
 sfx2/source/doc/objstor.cxx |    4 ++++
 vcl/inc/svdata.hxx          |    3 +++
 vcl/source/app/svapp.cxx    |    5 +++++
 vcl/source/outdev/font.cxx  |   40 +++++++++++++++++++++++++++++++++++++++-
 6 files changed, 65 insertions(+), 1 deletion(-)

New commits:
commit 98d71c4e0847797a4ba9229a8e6d832a8a3d5e0f
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Fri Jan 11 00:06:49 2019 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Fri Jan 11 05:38:52 2019 +0100

    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 at collabora.com>

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();


More information about the Libreoffice-commits mailing list