[Libreoffice-commits] .: Branch 'libreoffice-3-5' - i18npool/source sw/inc sw/source

Michael Meeks michael at kemper.freedesktop.org
Wed May 2 04:22:25 PDT 2012


 i18npool/source/breakiterator/breakiterator_unicode.cxx |   27 ++++++++++++++--
 sw/inc/breakit.hxx                                      |    7 +++-
 sw/source/core/bastyp/breakit.cxx                       |   19 +++++++----
 sw/source/core/txtnode/txtedt.cxx                       |    2 -
 4 files changed, 44 insertions(+), 11 deletions(-)

New commits:
commit 5730b57700045c49e039ca9bd357f40c5a43313f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue May 1 16:30:52 2012 +0100

    Resolves: fdo#49208 performance problems with very long paragraphs
    
    Signed-off-by: Michael Meeks <michael.meeks at suse.com>

diff --git a/i18npool/source/breakiterator/breakiterator_unicode.cxx b/i18npool/source/breakiterator/breakiterator_unicode.cxx
index aa5e1d8..5e5f6d5 100644
--- a/i18npool/source/breakiterator/breakiterator_unicode.cxx
+++ b/i18npool/source/breakiterator/breakiterator_unicode.cxx
@@ -34,6 +34,7 @@
 #include <unicode/udata.h>
 #include <rtl/strbuf.hxx>
 #include <rtl/ustring.hxx>
+#include <string.h>
 
 U_CDECL_BEGIN
 extern const char OpenOffice_dat[];
@@ -94,6 +95,24 @@ class OOoRuleBasedBreakIterator : public RuleBasedBreakIterator {
 
 };
 
+namespace
+{
+    bool isEqual(const UnicodeString &rOne, const rtl::OUString &rOther)
+    {
+        sal_Int32 nLength = rOne.length();
+        if (nLength != rOther.getLength())
+            return false;
+
+        //fdo#49208 operator== is implemented by compareTo etc in icu which is
+        //horrifically slow when all you want to know is that they're the same
+        //or not
+        const UChar *pOne = rOne.getBuffer();
+        // UChar != sal_Unicode in MinGW
+        const UChar *pOther = reinterpret_cast<const UChar *>(rOther.getStr());
+        return memcmp(pOne, pOther, nLength * sizeof(UChar)) == 0;
+    }
+}
+
 // loading ICU breakiterator on demand.
 void SAL_CALL BreakIterator_Unicode::loadICUBreakIterator(const com::sun::star::lang::Locale& rLocale,
         sal_Int16 rBreakType, sal_Int16 rWordType, const sal_Char *rule, const OUString& rText) throw(uno::RuntimeException)
@@ -199,13 +218,15 @@ void SAL_CALL BreakIterator_Unicode::loadICUBreakIterator(const com::sun::star::
         }
     }
 
-    if (newBreak || icuBI->aICUText.compare(UnicodeString(reinterpret_cast<const UChar *>(rText.getStr()), rText.getLength()))) {   // UChar != sal_Unicode in MinGW
-        icuBI->aICUText=UnicodeString(reinterpret_cast<const UChar *>(rText.getStr()), rText.getLength());
+    if (newBreak || !isEqual(icuBI->aICUText, rText))
+    {
+        // UChar != sal_Unicode in MinGW
+        const UChar *pText = reinterpret_cast<const UChar *>(rText.getStr());
+        icuBI->aICUText=UnicodeString(pText, rText.getLength());
         icuBI->aBreakIterator->setText(icuBI->aICUText);
     }
 }
 
-
 sal_Int32 SAL_CALL BreakIterator_Unicode::nextCharacters( const OUString& Text,
         sal_Int32 nStartPos, const lang::Locale &rLocale,
         sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone )
diff --git a/sw/inc/breakit.hxx b/sw/inc/breakit.hxx
index 3075fc9..0bdce8c 100644
--- a/sw/inc/breakit.hxx
+++ b/sw/inc/breakit.hxx
@@ -112,7 +112,12 @@ public:
     sal_uInt16 GetRealScriptOfText( const String& rTxt, xub_StrLen nPos ) const;
     sal_uInt16 GetAllScriptsOfText( const String& rTxt ) const;
 
-    sal_Int32 getGraphemeCount(const rtl::OUString& rStr) const;
+    sal_Int32 getGraphemeCount(const rtl::OUString& rStr,
+        sal_Int32 nStart, sal_Int32 nEnd) const;
+    sal_Int32 getGraphemeCount(const rtl::OUString& rStr) const
+    {
+        return getGraphemeCount(rStr, 0, rStr.getLength());
+    }
 };
 
 #define SW_BREAKITER()  SwBreakIt::Get()
diff --git a/sw/source/core/bastyp/breakit.cxx b/sw/source/core/bastyp/breakit.cxx
index bb93660..c35afa0 100644
--- a/sw/source/core/bastyp/breakit.cxx
+++ b/sw/source/core/bastyp/breakit.cxx
@@ -168,16 +168,23 @@ sal_uInt16 SwBreakIt::GetAllScriptsOfText( const String& rTxt ) const
     return nRet;
 }
 
-sal_Int32 SwBreakIt::getGraphemeCount(const rtl::OUString& rText) const
+sal_Int32 SwBreakIt::getGraphemeCount(const rtl::OUString& rText, sal_Int32 nStart, sal_Int32 nEnd) const
 {
     sal_Int32 nGraphemeCount = 0;
 
-    sal_Int32 nCurPos = 0;
-    while (nCurPos < rText.getLength())
+    sal_Int32 nCurPos = nStart;
+    while (nCurPos < nEnd)
     {
-        sal_Int32 nCount2 = 1;
-        nCurPos = xBreak->nextCharacters(rText, nCurPos, lang::Locale(),
-            i18n::CharacterIteratorMode::SKIPCELL, nCount2, nCount2);
+        //fdo#49208 cheat and assume that nothing can combine with a space
+        //to form a single grapheme
+        if (rText[nCurPos] == ' ')
+            ++nCurPos;
+        else
+        {
+            sal_Int32 nCount2 = 1;
+            nCurPos = xBreak->nextCharacters(rText, nCurPos, lang::Locale(),
+                i18n::CharacterIteratorMode::SKIPCELL, nCount2, nCount2);
+        }
         ++nGraphemeCount;
     }
 
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 86e4b69..186d4ea 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1863,7 +1863,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
         }
     }
 
-    nTmpChars = pBreakIt->getGraphemeCount(aExpandText.copy(nExpandBegin, nExpandEnd - nExpandBegin));
+    nTmpChars = pBreakIt->getGraphemeCount(aExpandText, nExpandBegin, nExpandEnd);
     nTmpChars -= nNumOfMaskedChars;
 
     // no nTmpCharsExcludingSpaces adjust needed neither for blanked out MaskedChars


More information about the Libreoffice-commits mailing list