sw/inc/swscanner.hxx              |    4 ++++
 sw/source/core/txtnode/txtedt.cxx |   25 +++++++++++++++++--------
 2 files changed, 21 insertions(+), 8 deletions(-)

New commits:
commit 50e722923d4efaadac7a11ec523501cebd341cb1
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Mar 14 15:49:32 2025 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Mar 14 18:01:51 2025 +0100

    cool#1125 Reduce cost of spell checking in writer
    
    Loading a new CharClass for each NextWord() call can add up.
    
    Change-Id: Ie15f2adcd4c603074320b49d5c0276f558aab3e9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182920
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/inc/swscanner.hxx b/sw/inc/swscanner.hxx
index 88433bfe4bb1..8a26085bc40f 100644
--- a/sw/inc/swscanner.hxx
+++ b/sw/inc/swscanner.hxx
@@ -22,8 +22,10 @@
 
 #include <i18nlangtag/lang.h>
 #include "modeltoviewhelper.hxx"
+#include <unotools/charclass.hxx>
 
 #include <functional>
+#include <optional>
 
 class SwTextNode;
 
@@ -43,6 +45,8 @@ class SwScanner
     sal_Int32 m_nBegin;
     sal_Int32 m_nLength;
     sal_Int32 m_nOverriddenDashCount;
+    // caches the CharClass for m_aCurrentLang, which can be expensive to 
repeatedly retrieve
+    std::optional<CharClass> moCharClass;
     LanguageType m_aCurrentLang;
     sal_uInt16 m_nWordType;
     bool m_bClip;
diff --git a/sw/source/core/txtnode/txtedt.cxx 
b/sw/source/core/txtnode/txtedt.cxx
index df0582e1f058..87ef9fa945e1 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -35,7 +35,6 @@
 #include <osl/diagnose.h>
 #include <officecfg/Office/Writer.hxx>
 #include <unotools/transliterationwrapper.hxx>
-#include <unotools/charclass.hxx>
 #include <sal/log.hxx>
 #include <swmodule.hxx>
 #include <splargs.hxx>
@@ -778,15 +777,21 @@ 
SwScanner::SwScanner(std::function<LanguageType(sal_Int32, sal_Int32, bool)> aGe
 
     assert(m_aPreDashReplacementText.getLength() == m_aText.getLength());
 
+    LanguageType aNewLang;
     if ( m_pLanguage )
     {
-        m_aCurrentLang = *m_pLanguage;
+        aNewLang = *m_pLanguage;
     }
     else
     {
         ModelToViewHelper::ModelPosition aModelBeginPos =
             m_ModelToView.ConvertToModelPosition( m_nBegin );
-        m_aCurrentLang = m_pGetLangOfChar(aModelBeginPos.mnPos, 0, true);
+        aNewLang = m_pGetLangOfChar(aModelBeginPos.mnPos, 0, true);
+    }
+    if (m_aCurrentLang != aNewLang)
+    {
+        m_aCurrentLang = aNewLang;
+        moCharClass.reset();
     }
 }
 
@@ -855,8 +860,6 @@ bool SwScanner::NextWord()
     m_nBegin = m_nBegin + m_nLength;
     Boundary aBound;
 
-    std::optional<CharClass> xLocalCharClass;
-
     while ( true )
     {
         // skip non-letter characters:
@@ -869,13 +872,19 @@ bool SwScanner::NextWord()
                     const sal_uInt16 nNextScriptType = 
g_pBreakIt->GetBreakIter()->getScriptType( m_aText, m_nBegin );
                     ModelToViewHelper::ModelPosition aModelBeginPos =
                         m_ModelToView.ConvertToModelPosition( m_nBegin );
-                    m_aCurrentLang = m_pGetLangOfChar(aModelBeginPos.mnPos, 
nNextScriptType, false);
+                    LanguageType aNewLang = 
m_pGetLangOfChar(aModelBeginPos.mnPos, nNextScriptType, false);
+                    if (aNewLang != m_aCurrentLang)
+                    {
+                        m_aCurrentLang = aNewLang;
+                        moCharClass.reset();
+                    }
                 }
 
                 if ( m_nWordType != i18n::WordType::WORD_COUNT )
                 {
-                    xLocalCharClass.emplace(LanguageTag( 
g_pBreakIt->GetLocale( m_aCurrentLang ) ));
-                    if ( 
xLocalCharClass->isLetterNumeric(OUString(m_aText[m_nBegin])) )
+                    if (!moCharClass)
+                        moCharClass.emplace(LanguageTag( 
g_pBreakIt->GetLocale( m_aCurrentLang ) ));
+                    if ( 
moCharClass->isLetterNumeric(OUString(m_aText[m_nBegin])) )
                         break;
                 }
                 else

Reply via email to