tdf#168528 sw letter spacing: fix freezing with minimum spacing/scaling

Fix never-ending loop in SwTextFrame::Format_() resulted by bad compression of lines with COMPLETE_STRING cut position.

Note: to test the fix of the rare freezing, a subset font has been
created from Source Serif 4 Variable, and embedded in the test file.

Follow-up to commit 33f20d0a0f
"tdf#168351 sw letter spacing: fix spaces in the last line",
commit 45ec7bd761
"tdf#168251 cui offapi xmloff sw glyph scaling: extend UNO/UX/ODF",
commit 3c53797210
"tdf#167648 sw letter spacing: implement minimum letter spacing"
and commit f83a04c510
"tdf#167648 cui offapi xmloff sw: add DTP-feature maximum letter
spacing".

Change-Id: I517f2b878421df40d69c785155107cf7380f0c0c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191432
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
László Németh
2025-09-25 10:04:24 +02:00
parent 93d74ca574
commit 8306c4e86a
4 changed files with 18 additions and 2 deletions
Binary file not shown.
+8
View File
@@ -837,6 +837,14 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf168448)
}
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf168528)
{
//just care it doesn't freeze
// embedded font subset created with:
// hb-subset SourceSerif4Variable-Roman.ttf -u '20,3a,61,64,65,66,67,68,6c,6d,6e,6f,72,73,74,75,79' -o subset.ttf
createSwDoc("tdf168528.odt");
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf164499)
{
createSwDoc("tdf164499.docx");
+7 -2
View File
@@ -502,7 +502,9 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
// tdf#168251 minimum glyph scaling allows more text in the line
// TODO don't be greedy, allow only an extra word or word part
const sal_Int16 nScaleWidthMinimum = aAdjustItem.GetPropScaleWidthMinimum();
if ( nScaleWidthMinimum < 100 )
if ( nScaleWidthMinimum < 100 &&
// tdf#168528 avoid freezing
m_nCutPos < TextFrameIndex(rInf.GetText().getLength()) )
{
SwTwips nExtraSpace = nLineWidth / (nScaleWidthMinimum / 100.0) - nLineWidth;
nLineWidth += nExtraSpace;
@@ -512,7 +514,10 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
// tdf#167648 minimum letter spacing allows more text in the line
// TODO don't be greedy, allow only an extra word or word part
if ( const sal_Int16 nLetterSpacingMinimum = aAdjustItem.GetPropLetterSpacingMinimum() )
const sal_Int16 nLetterSpacingMinimum = aAdjustItem.GetPropLetterSpacingMinimum();
if ( nLetterSpacingMinimum &&
// tdf#168528 avoid freezing
m_nCutPos < TextFrameIndex(rInf.GetText().getLength()) )
{
SwTwips nExtraSpace = sal_Int32(m_nCutPos - rInf.GetIdx()) *
nSpaceWidth / 10.0 * nLetterSpacingMinimum / 100.0;
@@ -1265,6 +1265,9 @@ void PrintFontManager::Substitute(vcl::font::FontSelectPattern &rPattern, OUStri
}
if (rPattern.maTargetName == "Linux Libertine G" && rPattern.maSearchName == "Linux Libertine O")
return;
// tdf#168528 allow testing with embedded subset
if (rPattern.maTargetName == "Source Serif 4 Variable" && rPattern.maSearchName == "DejaVu Serif")
return;
SAL_WARN("vcl.fonts", "PrintFontManager::Substitute: missing font: '" << rPattern.maTargetName <<
"' try: " << rPattern.maSearchName << " instead");
std::cerr << "terminating test due to missing font: " << rPattern.maTargetName << std::endl;