summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2023-12-19 11:58:40 +0100
committerLászló Németh <nemeth@numbertext.org>2023-12-19 22:18:13 +0100
commit36bfc86e27fa03ee16f87819549ab126c5a68cac (patch)
treefec41a769296fbb0b63d95da8d928268a98d969c
parent9e127010a86b3521c803ac86c0b5f58dc8e2966b (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.cxx6
-rw-r--r--sw/source/core/text/guess.cxx15
-rw-r--r--sw/source/core/text/guess.hxx2
-rw-r--r--sw/source/core/text/portxt.cxx25
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