From c8a99cb8dce54de506ba66d1cc0818b9b5f7858b Mon Sep 17 00:00:00 2001 From: László Németh Date: Mon, 6 May 2024 17:17:43 +0200 Subject: tdf#132599 sw schema xmloff: add hyphenation-keep-type='always' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new hyphenation option to limit hyphenation of the last full line of the hyphenated paragraph. Move also loext:hyphenation-keep-type to paragraph-properties, following the associated hyphenation-keep. Note: value "always" is defined by CSS 4 hyphenate-limit-last, see https://www.w3.org/TR/css-text-4/#hyphenate-line-limits. Follow-up to commit 6e8819f29b6051a0e551d77512830539913ec277 "tdf#132599 cui offapi sw xmloff: add hyphenation-keep-type". Change-Id: I2121269205fc89fb5367dccdca00195aac68f3e5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167232 Tested-by: Jenkins Reviewed-by: László Németh --- sw/source/core/text/guess.cxx | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'sw/source') diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index c3a94187a7ea..f5bdb8524eef 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "porfld.hxx" @@ -349,11 +350,29 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, // search start of the last word, if needed if ( bHyph ) { - // nLastWord is the space character before the last word + // nLastWord is the space character before the last word of the line sal_Int32 nLastWord = rInf.GetText().getLength() - 1; - bool bHyphenationNoLastWord = false; + bool bDoNotHyphenateLastLine = false; // don't hyphenate last full line of the paragraph + bool bHyphenationNoLastWord = false; // do not hyphenate the last word of the paragraph assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == UPN_HYPH_NO_LAST_WORD ); - if ( rHyphValues[3].Value >>= bHyphenationNoLastWord ) + assert( rHyphValues.getLength() > 6 && rHyphValues[6].Name == UPN_HYPH_KEEP_TYPE ); + assert( rHyphValues.getLength() > 8 && rHyphValues[8].Name == UPN_HYPH_KEEP ); + rHyphValues[3].Value >>= bHyphenationNoLastWord; + rHyphValues[8].Value >>= bDoNotHyphenateLastLine; + if ( bDoNotHyphenateLastLine ) + { + sal_Int16 nKeepType = css::text::ParagraphHyphenationKeepType::COLUMN; + rHyphValues[6].Value >>= nKeepType; + if ( nKeepType == css::text::ParagraphHyphenationKeepType::ALWAYS ) + { + if ( TextFrameIndex(COMPLETE_STRING) != m_nCutPos ) + nLastWord = sal_Int32(m_nCutPos); + } + else + bDoNotHyphenateLastLine = false; + } + + if ( bHyphenationNoLastWord || bDoNotHyphenateLastLine ) { // skip spaces after the last word bool bCutBlank = false; @@ -367,14 +386,23 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, } } - // don't hyphenate the last word of the paragraph - if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord && + // don't hyphenate the last word of the paragraph line + if ( ( bHyphenationNoLastWord || bDoNotHyphenateLastLine ) && + sal_Int32(m_nCutPos) > nLastWord && TextFrameIndex(COMPLETE_STRING) != m_nCutPos && // if the last word is multiple line long, e.g. an URL, // apply this only if the space before the word is there // in the actual line, i.e. start the long word in a new // line, but still allows to break its last parts - sal_Int32(rInf.GetIdx()) < nLastWord ) + sal_Int32(rInf.GetIdx()) < nLastWord && + // if the case of bDoNotHyphenateLastLine == true, skip hyphenation + // only if the character length of the very last line of the paragraph + // would be still less, than the length of the recent last but one line + // with hyphenation, i.e. don't skip hyphenation, if the last paragraph + // line is already near full. + ( !bDoNotHyphenateLastLine || + rInf.GetText().getLength() - sal_Int32(nLastWord) < + sal_Int32(m_nCutPos) - sal_Int32(rInf.GetIdx() ) ) ) { m_nCutPos = TextFrameIndex(nLastWord); } -- cgit