basic/source/runtime/methods.cxx   |   63 ++++++++++++++++++++++---------------
 sc/source/filter/html/htmlpars.cxx |   10 +++++
 2 files changed, 48 insertions(+), 25 deletions(-)

New commits:
commit 23821b60107d4d2e46f8f0e17b016bc84379b29e
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Sat Feb 5 22:43:13 2022 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Feb 7 17:06:41 2022 +0100

    Resolves: tdf#74577 tdf#92960 Create missing offsets in very outer table
    
    ... if local table is outer table.
    
    Change-Id: I5996609264f4ad9efa8d76a8d0ab730bf1dded24
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129540
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    (cherry picked from commit 8a9b870a40c41c7cae6e43452b593804fa17f831)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129550
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>
    (cherry picked from commit 2ea7055ea6115051a92c66a439b02d83bb067db7)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129561
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/source/filter/html/htmlpars.cxx 
b/sc/source/filter/html/htmlpars.cxx
index 5ea874ac8841..7e735054a9db 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -755,6 +755,16 @@ void ScHTMLLayoutParser::SetWidths()
         sal_uInt16 nMax = static_cast<sal_uInt16>(pLocalColOffset->back());
         if ( aPageSize.Width() < nMax )
             aPageSize.setWidth( nMax );
+        if (nTableLevel == 0)
+        {
+            // Local table is very outer table, create missing offsets.
+            for (auto it = pLocalColOffset->begin(); it != 
pLocalColOffset->end(); ++it)
+            {
+                // Only exact offsets, do not use MakeColNoRef().
+                if (maColOffset.find(*it) == maColOffset.end())
+                    maColOffset.insert(*it);
+            }
+        }
     }
     for ( size_t i = nFirstTableCell, nListSize = maList.size(); i < 
nListSize; ++i )
     {
commit 3fa7c7618500bf5914e19cb3714f301f7bff305a
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Jan 30 14:12:46 2022 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Feb 7 17:06:31 2022 +0100

    tdf#132388: reimplement fix for tdf#142487
    
    Each call to css::i18n::XTextSearch::SearchForward transliterates input 
string,
    making performance of repeated calls unacceptable. So prepare the 
transliterated
    strings once, and use the offset sequence to map search results to indices 
into
    original string.
    
    Change-Id: Ie08dd5a408aca9a950067db285a480b41a3f9a16
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129162
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129208
    (cherry picked from commit 8efa3dd53aaf98ed258c9f340800504c9e874b78)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129257

diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index e3a30f324525..d4a4ce74ed0a 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -68,7 +68,7 @@
 #include <o3tl/char16_t2wchar_t.hxx>
 
 // include search util
-#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/i18n/Transliteration.hpp>
 #include <com/sun/star/util/SearchAlgorithms2.hpp>
 #include <i18nutil/searchopt.hxx>
 #include <unotools/textsearch.hxx>
@@ -1269,6 +1269,7 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool)
             return;
         }
     }
+    --lStartPos; // Make it 0-based
 
     sal_Int32 lCount = -1;
     if (nArgCount >= 5)
@@ -1304,40 +1305,52 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool)
     }
 
     const OUString aExpStr = rPar.Get(1)->GetOUString();
-    const OUString aFindStr = rPar.Get(2)->GetOUString();
+    OUString aFindStr = rPar.Get(2)->GetOUString();
     const OUString aReplaceStr = rPar.Get(3)->GetOUString();
-    const sal_Int32 nExpStrLen = aExpStr.getLength();
-    const sal_Int32 nFindStrLen = aFindStr.getLength();
 
-    // tdf#142487 - use utl::TextSearch in order to implement the replace 
algorithm
-    i18nutil::SearchOptions2 aSearchOptions;
-    aSearchOptions.searchString = aFindStr;
-    aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+    OUString aSrcStr(aExpStr);
+    sal_Int32 nPrevPos = std::min(lStartPos, aSrcStr.getLength());
+    css::uno::Sequence<sal_Int32> aOffset;
     if (bCaseInsensitive)
-        aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
-    utl::TextSearch textSearch(aSearchOptions);
+    {
+        // tdf#132389: case-insensitive operation for non-ASCII characters
+        // tdf#142487: use css::i18n::Transliteration to correctly handle ß -> 
ss expansion
+        // tdf#132388: We can't use utl::TextSearch (css::i18n::XTextSearch), 
because each call to
+        //             css::i18n::XTextSearch::SearchForward transliterates 
input string, making
+        //             performance of repeated calls unacceptable
+        auto xTrans = 
css::i18n::Transliteration::create(comphelper::getProcessComponentContext());
+        xTrans->loadModule(css::i18n::TransliterationModules_IGNORE_CASE, {});
+        aFindStr = xTrans->transliterate(aFindStr, 0, aFindStr.getLength(), 
aOffset);
+        aSrcStr = xTrans->transliterate(aSrcStr, nPrevPos, aSrcStr.getLength() 
- nPrevPos, aOffset);
+        nPrevPos = std::distance(aOffset.begin(),
+                                 std::lower_bound(aOffset.begin(), 
aOffset.end(), nPrevPos));
+    }
+
+    auto getExpStrPos = [aOffset, nExpLen = aExpStr.getLength()](sal_Int32 
nSrcStrPos) -> sal_Int32
+    {
+        assert(!aOffset.hasElements() || aOffset.getLength() >= nSrcStrPos);
+        if (!aOffset.hasElements())
+            return nSrcStrPos;
+        return aOffset.getLength() > nSrcStrPos ? aOffset[nSrcStrPos] : 
nExpLen;
+    };
 
     // Note: the result starts from lStartPos, removing everything to the 
left. See i#94895.
-    sal_Int32 nPrevPos = std::min(lStartPos - 1, nExpStrLen);
-    OUStringBuffer sResult(nExpStrLen - nPrevPos);
+    OUStringBuffer sResult(aSrcStr.getLength() - nPrevPos);
     sal_Int32 nCounts = 0;
     while (lCount == -1 || lCount > nCounts)
     {
-        sal_Int32 nStartPos = nPrevPos;
-        sal_Int32 aEndPos = aExpStr.getLength();
-        if (textSearch.SearchForward(aExpStr, &nStartPos, &aEndPos))
-        {
-            sResult.append(aExpStr.getStr() + nPrevPos, nStartPos - nPrevPos);
-            sResult.append(aReplaceStr);
-            nPrevPos = nStartPos + nFindStrLen;
-            nCounts++;
-        }
-        else
-        {
+        sal_Int32 nPos = aSrcStr.indexOf(aFindStr, nPrevPos);
+        if (nPos < 0)
             break;
-        }
+
+        lStartPos = getExpStrPos(nPrevPos);
+        sResult.append(aExpStr.getStr() + lStartPos, getExpStrPos(nPos) - 
lStartPos);
+        sResult.append(aReplaceStr);
+        nPrevPos = nPos + aFindStr.getLength();
+        nCounts++;
     }
-    sResult.append(aExpStr.getStr() + nPrevPos, nExpStrLen - nPrevPos);
+    lStartPos = getExpStrPos(nPrevPos);
+    sResult.append(aExpStr.getStr() + lStartPos, aExpStr.getLength() - 
lStartPos);
     rPar.Get(0)->PutString(sResult.makeStringAndClear());
 }
 

Reply via email to