i18npool/source/breakiterator/breakiteratorImpl.cxx | 4 +-- i18npool/source/breakiterator/breakiterator_unicode.cxx | 15 +++++++----- sw/qa/core/crsr/crsr.cxx | 19 ++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-)
New commits: commit 70c99eef1643a17b2c1f0dba38b55a58cdb9aafc Author: Andreas Heinisch <andreas.heini...@yahoo.de> AuthorDate: Fri Jul 29 09:29:33 2022 +0200 Commit: Andreas Heinisch <andreas.heini...@yahoo.de> CommitDate: Sun Aug 21 14:12:43 2022 +0200 tdf#135451 - Change the skipSpace implementation of the break iterator Change the ICU whitespace function of the break iterator from u_isWhitespace to u_isUWhiteSpace to include no-break spaces. u_isWhitespace includes Java isWhitespace; Z + whitespace ISO controls but excludes no-break spaces u_isUWhiteSpace includes all code points with the Unicode White_Space property; most of general categories "Z" (separators) + most whitespace ISO controls (including no-break spaces, but excluding IS1..IS4) See https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/uchar_8h.html for further details. Change-Id: I21fddefaf2149096824908f644310a59d6e2f38d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137582 Tested-by: Jenkins Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de> diff --git a/i18npool/source/breakiterator/breakiteratorImpl.cxx b/i18npool/source/breakiterator/breakiteratorImpl.cxx index 71f371a7eddc..71d794e2c9d4 100644 --- a/i18npool/source/breakiterator/breakiteratorImpl.cxx +++ b/i18npool/source/breakiterator/breakiteratorImpl.cxx @@ -82,7 +82,7 @@ static sal_Int32 skipSpace(const OUString& Text, sal_Int32 nPos, sal_Int32 len, while (nPos < len) { ch = Text.iterateCodePoints(&pos); - if (!u_isWhitespace(ch) && !isZWSP(ch)) + if (!u_isUWhiteSpace(ch) && !isZWSP(ch)) break; nPos = pos; } @@ -90,7 +90,7 @@ static sal_Int32 skipSpace(const OUString& Text, sal_Int32 nPos, sal_Int32 len, while (nPos > 0) { ch = Text.iterateCodePoints(&pos, -1); - if (!u_isWhitespace(ch) && !isZWSP(ch)) + if (!u_isUWhiteSpace(ch) && !isZWSP(ch)) break; nPos = pos; } diff --git a/i18npool/source/breakiterator/breakiterator_unicode.cxx b/i18npool/source/breakiterator/breakiterator_unicode.cxx index a4a00c46a1ad..cfac4ddea89d 100644 --- a/i18npool/source/breakiterator/breakiterator_unicode.cxx +++ b/i18npool/source/breakiterator/breakiterator_unicode.cxx @@ -379,9 +379,10 @@ Boundary SAL_CALL BreakIterator_Unicode::nextWord( const OUString& Text, sal_Int if( rv.startPos >= Text.getLength() || rv.startPos == icu::BreakIterator::DONE ) rv.endPos = result.startPos; else { - if ( (rWordType == WordType::ANYWORD_IGNOREWHITESPACES || - rWordType == WordType::DICTIONARY_WORD ) && - u_isWhitespace(Text.iterateCodePoints(&rv.startPos, 0)) ) + if ((rWordType == WordType::ANYWORD_IGNOREWHITESPACES + && u_isUWhiteSpace(Text.iterateCodePoints(&rv.startPos, 0))) + || (rWordType == WordType::DICTIONARY_WORD + && u_isWhitespace(Text.iterateCodePoints(&rv.startPos, 0)))) rv.startPos = icuBI->mpValue->mpBreakIterator->following(rv.startPos); rv.endPos = icuBI->mpValue->mpBreakIterator->following(rv.startPos); @@ -402,9 +403,11 @@ Boundary SAL_CALL BreakIterator_Unicode::previousWord(const OUString& Text, sal_ if( rv.startPos < 0) rv.endPos = rv.startPos; else { - if ( (rWordType == WordType::ANYWORD_IGNOREWHITESPACES || - rWordType == WordType::DICTIONARY_WORD) && - u_isWhitespace(Text.iterateCodePoints(&rv.startPos, 0)) ) + + if ((rWordType == WordType::ANYWORD_IGNOREWHITESPACES + && u_isUWhiteSpace(Text.iterateCodePoints(&rv.startPos, 0))) + || (rWordType == WordType::DICTIONARY_WORD + && u_isWhitespace(Text.iterateCodePoints(&rv.startPos, 0)))) rv.startPos = icuBI->mpValue->mpBreakIterator->preceding(rv.startPos); rv.endPos = icuBI->mpValue->mpBreakIterator->following(rv.startPos); diff --git a/sw/qa/core/crsr/crsr.cxx b/sw/qa/core/crsr/crsr.cxx index c0713389bec3..759b236d16ac 100644 --- a/sw/qa/core/crsr/crsr.cxx +++ b/sw/qa/core/crsr/crsr.cxx @@ -164,6 +164,25 @@ CPPUNIT_TEST_FIXTURE(SwCoreCrsrTest, testContentControlReadOnly) CPPUNIT_ASSERT(pWrtShell->HasReadonlySel()); } +CPPUNIT_TEST_FIXTURE(SwCoreCrsrTest, testTdf135451) +{ + SwDoc* pDoc = createSwDoc(); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // Insert narrow no-break space and move the cursor right before it + pWrtShell->Insert(u"a" + OUStringChar(CHAR_NNBSP) + "b"); + pWrtShell->EndPara(/*bSelect=*/false); + pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); + pWrtShell->GoPrevWord(); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: a + // - Actual : CHAR_NNBSP + // i.e., the cursor did not move over the narrow no-break space (CHAR_NNBSP) + CPPUNIT_ASSERT_EQUAL(OUString("a"), pWrtShell->GetSelText()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */