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