diff options
author | László Németh <nemeth@numbertext.org> | 2023-12-19 11:58:40 +0100 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2023-12-19 22:18:13 +0100 |
commit | 36bfc86e27fa03ee16f87819549ab126c5a68cac (patch) | |
tree | fec41a769296fbb0b63d95da8d928268a98d969c | |
parent | 9e127010a86b3521c803ac86c0b5f58dc8e2966b (diff) |
tdf#119908 tdf#158776 sw smart justify: shrink only spaces
For interoperability, only shrink spaces up to 20%,
not the lines up to 2%.
Follow-up to commit 20cbe88ce5610fd8ee302e5780a4c0821ddb3db4
"tdf#119908 tdf#158419 sw smart justify: fix cursor position"
and commit 7d08767b890e723cd502b1c61d250924f695eb98
"tdf#130088 tdf#119908 smart justify: fix DOCX line count + compat opt."
Change-Id: Idb43161cb5a57c3412abd3f0eb266c6afbe5363c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160988
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/layout/layout3.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/text/guess.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/text/guess.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/portxt.cxx | 25 |
4 files changed, 37 insertions, 11 deletions
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index ea2c3a52d24e..ec7d740cf74f 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -236,6 +236,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333) "portion"_ostr, // This was "...et ", not "...et magnis " "consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis "); + + // tdf#158776 don't shrink line 11 of paragraph 4 + assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout[11]"_ostr, + "portion"_ostr, + // This was "...quis curcus ", not "...quis " + "venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis "); } CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158419) diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index 37a2147d0987..6123ad1b6767 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -50,7 +50,7 @@ bool IsBlank(sal_Unicode ch) { return ch == CH_BLANK || ch == CH_FULL_BLANK || c // returns true if no line break has to be performed // otherwise possible break or hyphenation position is determined bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, - const sal_uInt16 nPorHeight ) + const sal_uInt16 nPorHeight, sal_Int32 nSpacesInLine ) { m_nCutPos = rInf.GetIdx(); @@ -80,15 +80,12 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, const SvxAdjust& rAdjust = rInf.GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust(); - // allow shrinking, i.e. more text in justified lines, depending on the justification algorithm - if ( rAdjust == SvxAdjust::Block && rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get( - DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING) && - // tdf#158436 avoid shrinking at underflow, e.g. no-break space - // after a very short word resulted endless loop - !rInf.IsUnderflow() ) + // allow up to 20% shrinking of the spaces + if ( nSpacesInLine ) { - // allow up to 2% shrinking of the line - nLineWidth = nLineWidth / 0.98 + rInf.X() / 0.98 - rInf.X(); + static constexpr OUStringLiteral STR_BLANK = u" "; + sal_Int16 nSpaceWidth = rInf.GetTextSize(STR_BLANK).Width(); + nLineWidth += nSpacesInLine * (nSpaceWidth/0.8 - nSpaceWidth); } // tdf#104668 space chars at the end should be cut if the compatibility option is enabled diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx index f83c7e280ae4..5a7a9ac1cfa2 100644 --- a/sw/source/core/text/guess.hxx +++ b/sw/source/core/text/guess.hxx @@ -46,7 +46,7 @@ public: // true, if current portion still fits to current line bool Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, - const sal_uInt16 nHeight ); + const sal_uInt16 nHeight, sal_Int32 nSpacesInLine = 0 ); bool AlternativeSpelling( const SwTextFormatInfo &rInf, const TextFrameIndex nPos ); SwHangingPortion* GetHangingPortion() const { return m_pHanging.get(); } diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 9631fc232dc3..0d3960c1bcbc 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -302,7 +302,30 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) } SwTextGuess aGuess; - const bool bFull = !aGuess.Guess( *this, rInf, Height() ); + bool bFull = !aGuess.Guess( *this, rInf, Height() ); + + // tdf#158776 for the last full text portion, call Guess() again to allow more text in the + // adjusted line by shrinking spaces using the know space count from the first Guess() call + const SvxAdjust& rAdjust = rInf.GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust().GetAdjust(); + if ( bFull && rAdjust == SvxAdjust::Block && + rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING) && + // tdf#158436 avoid shrinking at underflow, e.g. no-break space after a + // very short word resulted endless loop + !rInf.IsUnderflow() ) + { + sal_Int32 nSpacesInLine(0); + for (sal_Int32 i = sal_Int32(rInf.GetLineStart()); i < sal_Int32(aGuess.BreakPos()); ++i) + { + sal_Unicode cChar = rInf.GetText()[i]; + if ( cChar == CH_BLANK ) + ++nSpacesInLine; + } + + // call with an extra space: shrinking can result a new word in the line + // and a new space before that, which is also a shrank space + bFull = !aGuess.Guess( *this, rInf, Height(), nSpacesInLine + 1 ); + } // these are the possible cases: // A Portion fits to current line |