comphelper/source/misc/lok.cxx                 |   15 ++++++++++++++
 desktop/source/lib/init.cxx                    |   15 ++++++++++++++
 include/comphelper/lok.hxx                     |    8 +++++++
 sw/qa/extras/tiledrendering/data/3pages.odt    |binary
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   26 +++++++++++++++++++++++++
 sw/source/core/view/vnew.cxx                   |    9 ++++++++
 6 files changed, 73 insertions(+)

New commits:
commit 7c15c0e8070d0810954c4e65c84687f188781b18
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri Feb 7 14:09:22 2025 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Fri Feb 7 20:38:31 2025 +0100

    cool#11064 sw lok: allow specifying the visible area during doc load
    
    Large enough documents significantly faster on the desktop than in LOK
    mode for some reason.
    
    Investigating the reason, it turns out that the layout mechanism to
    layout the visible area (first page, typically) of the document as part
    of doc load goes wrong in the LOK case, where nominally the entire
    document is visible.
    
    Fix the problem by adding new "ClientVisibleArea" option to
    lo_documentLoadWithOptions(), so the LOK client can inform us about what
    is the visible area before SwXTextDocument::setClientVisibleArea() can
    be called.
    
    lok::Office::documentLoad() cost for the bugdoc:
    - before: 540 ms
    - after: 112 ms
    
    Change-Id: Ib1df71e768fc42cf92b858a717d7a0e5d51678b6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181249
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Tested-by: Caolán McNamara <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx
index b576b340e6b7..0f7925e0fa96 100644
--- a/comphelper/source/misc/lok.cxx
+++ b/comphelper/source/misc/lok.cxx
@@ -8,12 +8,17 @@
  */
 
 #include <comphelper/lok.hxx>
+
+#include <com/sun/star/awt/Rectangle.hpp>
+
 #include <osl/process.h>
 #include <i18nlangtag/languagetag.hxx>
 #include <sal/log.hxx>
 
 #include <iostream>
 
+using namespace com::sun::star;
+
 namespace comphelper::LibreOfficeKit
 {
 
@@ -45,6 +50,9 @@ static void* g_pAnyInputCallbackData;
 static std::function<void(int)> g_pViewSetter;
 static std::function<int()> g_pViewGetter;
 
+/// Visible area of the first view during document load.
+static awt::Rectangle g_aInitialClientVisibleArea;
+
 namespace
 {
 
@@ -382,6 +390,13 @@ int getView()
     return g_pViewGetter();
 }
 
+void setInitialClientVisibleArea(const awt::Rectangle& rClientVisibleArea)
+{
+    g_aInitialClientVisibleArea = rClientVisibleArea;
+}
+
+awt::Rectangle getInitialClientVisibleArea() { return 
g_aInitialClientVisibleArea; }
+
 } // namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 9266cb5648e8..2178ce893d43 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2891,6 +2891,21 @@ static LibreOfficeKitDocument* 
lo_documentLoadWithOptions(LibreOfficeKit* pThis,
         }
         SvtSecurityOptions::SetMacroSecurityLevel(nMacroSecurityLevel);
 
+        OUString aClientVisibleArea = extractParameter(aOptions, 
u"ClientVisibleArea");
+        if (!aClientVisibleArea.isEmpty())
+        {
+            std::vector<OUString> aTokens = 
comphelper::string::split(aClientVisibleArea, ';');
+            if (aTokens.size() >= 4)
+            {
+                awt::Rectangle aRectangle;
+                aRectangle.X = aTokens[0].toInt32();
+                aRectangle.Y = aTokens[1].toInt32();
+                aRectangle.Width = aTokens[2].toInt32();
+                aRectangle.Height = aTokens[3].toInt32();
+                
comphelper::LibreOfficeKit::setInitialClientVisibleArea(aRectangle);
+            }
+        }
+
 #if defined(ANDROID) && HAVE_FEATURE_ANDROID_LOK
         sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
 #else
diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx
index 6b83c3d3b6df..ef9278b977fc 100644
--- a/include/comphelper/lok.hxx
+++ b/include/comphelper/lok.hxx
@@ -16,6 +16,10 @@
 #include <rtl/ustring.hxx>
 
 class LanguageTag;
+namespace com::sun::star::awt
+{
+struct Rectangle;
+}
 
 // Interface between the LibreOfficeKit implementation called by 
LibreOfficeKit clients and other
 // LibreOffice code.
@@ -148,6 +152,10 @@ COMPHELPER_DLLPUBLIC void 
setViewSetter(std::function<void(int)> pViewSetter);
 COMPHELPER_DLLPUBLIC void setView(int nView);
 COMPHELPER_DLLPUBLIC void setViewGetter(std::function<int()> pViewGetter);
 COMPHELPER_DLLPUBLIC int getView();
+
+COMPHELPER_DLLPUBLIC void
+setInitialClientVisibleArea(const css::awt::Rectangle& rClientVisibleArea);
+COMPHELPER_DLLPUBLIC css::awt::Rectangle getInitialClientVisibleArea();
 }
 
 #endif // INCLUDED_COMPHELPER_LOK_HXX
diff --git a/sw/qa/extras/tiledrendering/data/3pages.odt 
b/sw/qa/extras/tiledrendering/data/3pages.odt
new file mode 100644
index 000000000000..565cdeae77a5
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/3pages.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 0f4cac7793cc..580fb56df46c 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -57,6 +57,7 @@
 #include <comphelper/propertyvalue.hxx>
 #include <test/lokcallback.hxx>
 #include <sfx2/msgpool.hxx>
+#include <comphelper/scopeguard.hxx>
 
 #include <drawdoc.hxx>
 #include <ndtxt.hxx>
@@ -4750,6 +4751,31 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testPDFExportViewSwitch)
     CPPUNIT_ASSERT(!aView2.m_aExportFile.isEmpty());
 }
 
+CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testLoadVisibleArea)
+{
+    // Given a document with 3 pages, the LOK visible area at load time is set 
to the first page:
+    awt::Rectangle aVisibleArea{ 0, 0, 12240, 15840 };
+    comphelper::LibreOfficeKit::setInitialClientVisibleArea(aVisibleArea);
+    comphelper::ScopeGuard g([] { 
comphelper::LibreOfficeKit::setInitialClientVisibleArea({}); });
+
+    // When loading that document:
+    OUString aURL = createFileURL(u"3pages.odt");
+    UnoApiXmlTest::load(aURL);
+
+    // Then make sure only the first page is laid out:
+    SwDocShell* pDocShell = getSwDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    SwRootFrame* pLayout = pWrtShell->GetLayout();
+    SwPageFrame* pPage1 = pLayout->GetLower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(!pPage1->IsInvalidContent());
+    SwPageFrame* pPage2 = pPage1->GetNext()->DynCastPageFrame();
+    // Without the accompanying fix in place, this test failed, as the entire 
document was laid out
+    // before the loading finished.
+    CPPUNIT_ASSERT(pPage2->IsInvalidContent());
+    SwPageFrame* pPage3 = pPage2->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage3->IsInvalidContent());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/view/vnew.cxx b/sw/source/core/view/vnew.cxx
index 613a15df633b..4c19f954d699 100644
--- a/sw/source/core/view/vnew.cxx
+++ b/sw/source/core/view/vnew.cxx
@@ -20,6 +20,7 @@
 #include <sfx2/printer.hxx>
 #include <sal/log.hxx>
 #include <osl/diagnose.h>
+#include <comphelper/lok.hxx>
 #include <doc.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <IDocumentUndoRedo.hxx>
@@ -138,6 +139,14 @@ void SwViewShell::Init( const SwViewOption *pNewOpt )
             MakeDrawView();
         mpOpt->SetFormView( ! GetDrawView()->IsDesignMode() );
     }
+
+    awt::Rectangle aClientVisibleArea = 
comphelper::LibreOfficeKit::getInitialClientVisibleArea();
+    if (aClientVisibleArea.Width && aClientVisibleArea.Height)
+    {
+        maLOKVisibleArea
+            = tools::Rectangle(Point(aClientVisibleArea.X, 
aClientVisibleArea.Y),
+                               Size(aClientVisibleArea.Width, 
aClientVisibleArea.Height));
+    }
 }
 
 /// CTor for the first Shell.

Reply via email to