diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2023-10-01 18:08:49 +1100 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2023-12-28 02:33:50 +0100 |
commit | 938d3b35b83093de4e310d32de5137f6bdbcf22b (patch) | |
tree | a50d65c7f47243f3c10f7a093959b4323d5fdc29 /vcl/source | |
parent | 9157281deb81522bb02af73a08c4d7beed7aab75 (diff) |
vcl: test BreakLinesWithIterator with hyphens
Change-Id: Ied5e688b9eec19c2f1b3d1289cc4a6605703c3e4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157904
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/text/textlayout.cxx | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/vcl/source/text/textlayout.cxx b/vcl/source/text/textlayout.cxx index 095c087d5377..e90c56b6355a 100644 --- a/vcl/source/text/textlayout.cxx +++ b/vcl/source/text/textlayout.cxx @@ -218,12 +218,18 @@ namespace vcl return aStr; } - sal_Int32 TextLayoutCommon::BreakLinesWithIterator(const tools::Long nWidth, OUString const& rStr, + std::tuple<sal_Int32, sal_Int32> TextLayoutCommon::BreakLines(const tools::Long nWidth, OUString const& rStr, css::uno::Reference< css::linguistic2::XHyphenator > const& xHyph, - css::uno::Reference<css::i18n::XBreakIterator> const& xBI, - const bool bHyphenate, + css::uno::Reference<css::i18n::XBreakIterator>& xBI, + const bool bHyphenate, const tools::Long nOrigLineWidth, const sal_Int32 nPos, const sal_Int32 nLen) { + if (!xBI.is()) + xBI = vcl::unohelper::CreateBreakIterator(); + + if (!xBI.is()) + return BreakLinesSimple(nWidth, rStr, nPos, nLen, nOrigLineWidth); + const css::lang::Locale& rDefLocale(Application::GetSettings().GetUILanguageTag().getLocale()); sal_Int32 nSoftBreak = GetTextBreak(rStr, nWidth, nPos, nLen - nPos); @@ -241,16 +247,14 @@ namespace vcl if (nBreakPos <= nPos) nBreakPos = nSoftBreak; - if (!bHyphenate) - return nBreakPos; + if (!bHyphenate || !xHyph.is()) + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; // Whether hyphen or not: Put the word after the hyphen through // the word boundary. // We run into a problem if the doc is so narrow, that a word // is broken into more than two lines ... - if ( !xHyph.is() ) - return nBreakPos; css::i18n::Boundary aBoundary = xBI->getWordBoundary( rStr, nBreakPos, rDefLocale, css::i18n::WordType::DICTIONARY_WORD, true ); sal_Int32 nWordStart = nPos; @@ -258,27 +262,28 @@ namespace vcl SAL_WARN_IF(nWordEnd <= nWordStart, "vcl", "Start >= End?"); sal_Int32 nWordLen = nWordEnd - nWordStart; - if ( ( nWordEnd < nSoftBreak ) || ( nWordLen <= 3 ) ) - return nBreakPos; + if ((nWordEnd < nSoftBreak) || (nWordLen <= 3)) + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; OUString aWord = rStr.copy( nWordStart, nWordLen ); sal_Int32 nMinTrail = nWordEnd-nSoftBreak+1; //+1: Before the "broken off" char css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord; if (xHyph.is()) xHyphWord = xHyph->hyphenate( aWord, rDefLocale, aWord.getLength() - nMinTrail, css::uno::Sequence< css::beans::PropertyValue >() ); + if (!xHyphWord.is()) - return nBreakPos; + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; bool bAlternate = xHyphWord->isAlternativeSpelling(); sal_Int32 _nWordLen = 1 + xHyphWord->getHyphenPos(); - if ( ( _nWordLen < 2 ) || ( (nWordStart+_nWordLen) < 2 ) ) - return nBreakPos; + if ((_nWordLen < 2 ) || ( (nWordStart + _nWordLen) < 2)) + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; - if ( bAlternate ) + if (bAlternate) { nBreakPos = nWordStart + _nWordLen; - return nBreakPos; + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; } OUString aAlt( xHyphWord->getHyphenatedWord() ); @@ -329,14 +334,18 @@ namespace vcl nBreakPos = nWordStart + nTxtStart; if ( cAlternateReplChar ) nBreakPos++; - return nBreakPos; + + return { nBreakPos, GetTextWidth(rStr, nPos, nBreakPos - nPos) }; } - sal_Int32 TextLayoutCommon::BreakLinesSimple(const tools::Long nWidth, OUString const& rStr, - const sal_Int32 nPos, sal_Int32 nBreakPos, tools::Long& nLineWidth) + std::tuple<sal_Int32, sal_Int32> TextLayoutCommon::BreakLinesSimple(const tools::Long nWidth, OUString const& rStr, + const sal_Int32 nPos, const sal_Int32 nLen, const tools::Long nOrigLineWidth) { + sal_Int32 nBreakPos = nLen; + tools::Long nLineWidth = nOrigLineWidth; sal_Int32 nSpacePos = rStr.getLength(); tools::Long nW = 0; + do { nSpacePos = rStr.lastIndexOf( ' ', nSpacePos ); @@ -355,7 +364,8 @@ namespace vcl if( nBreakPos < rStr.getLength()-1 ) nBreakPos++; } - return nBreakPos; + + return { nBreakPos, nLineWidth }; } namespace @@ -413,20 +423,9 @@ namespace vcl sal_Int32 nBreakPos = lcl_GetEndOfLine(rStr, nPos, nLen); tools::Long nLineWidth = GetTextWidth(rStr, nPos, nBreakPos-nPos); + if (lcl_ShouldBreakWord(nLineWidth, nWidth, nStyle)) - { - if (!xBI.is()) - xBI = vcl::unohelper::CreateBreakIterator(); - - if (xBI.is()) - { - nBreakPos = BreakLinesWithIterator(nWidth, rStr, xHyph, xBI, bHyphenate, nPos, nBreakPos); - nLineWidth = GetTextWidth(rStr, nPos, nBreakPos - nPos); - } - else - // fallback to something really simple - nBreakPos = BreakLinesSimple(nWidth, rStr, nPos, nBreakPos, nLineWidth); - } + std::tie(nBreakPos, nLineWidth) = BreakLines(nWidth, rStr, xHyph, xBI, bHyphenate, nLineWidth, nPos, nBreakPos); if ( nLineWidth > nMaxLineWidth ) nMaxLineWidth = nLineWidth; |