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: */