tdf#158900: make sure to not break after spaces before \n
Change-Id: I9af98e270090530fc9bd621fbbcdf0ba35d0107c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161378
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/sw/qa/extras/layout/data/space+break.fodt b/sw/qa/extras/layout/data/space+break.fodt
new file mode 100644
index 0000000..fbd81f3
--- /dev/null
+++ b/sw/qa/extras/layout/data/space+break.fodt
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:settings>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverSpacing" config:type="boolean">false</config:config-item>
</config:config-item-set>
</office:settings>
<office:font-face-decls>
<style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="12.5mm" style:writing-mode="page"/>
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text"/>
</office:styles>
<office:automatic-styles>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:text-align="justify" fo:text-align-last="justify" style:justify-single-word="false"/>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="7mm" style:layout-grid-ruby-height="3.5mm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0mm"/>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
</office:master-styles>
<office:body>
<office:text>
<text:p text:style-name="P1">Lorem ipsum <text:s text:c="10"/><text:line-break/>Lorem ipsum <text:s text:c="1000"/><text:line-break/>Lorem ipsum <text:s text:c="1000"/>Lorem ipsum</text:p>
</office:text>
</office:body>
</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index 5af5c7e..15f1137 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -2125,6 +2125,28 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf152307)
CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), nTabBottom < nFooterTop);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158900)
{
// Given a document with a single paragraph, having some long space runs and line breaks
createSwDoc("space+break.fodt");
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
// Make sure there is only one page, one paragraph, and four lines
assertXPath(pXmlDoc, "/root/page"_ostr, 1);
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion"_ostr, 1);
// Without the fix in place, this would fail: there used to be 5 lines
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 4);
// Check that the second line has correct portions
// Without the fix in place, this would fail: the line had only 2 portions (text + hole),
// and the break was on a separate third line
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*"_ostr, 3);
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[1]"_ostr, "type"_ostr,
u"PortionType::Text"_ustr);
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[2]"_ostr, "type"_ostr,
u"PortionType::Hole"_ustr);
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[3]"_ostr, "type"_ostr,
u"PortionType::Break"_ustr);
}
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 0d3960c..bcc547d 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -360,7 +360,7 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf )
new SwKernPortion( *this, nKern );
}
// special case: hanging portion
else if( bFull && aGuess.GetHangingPortion() )
else if( aGuess.GetHangingPortion() )
{
Width( aGuess.BreakWidth() );
SetLen( aGuess.BreakPos() - rInf.GetIdx() );
@@ -431,6 +431,11 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf )
pNew->Width(0);
pNew->ExtraBlankWidth( aGuess.ExtraBlankWidth() );
Insert( pNew );
// UAX #14 Unicode Line Breaking Algorithm Non-tailorable Line breaking rule LB6:
// https://www.unicode.org/reports/tr14/#LB6 Do not break before hard line breaks
if (rInf.GetChar(aGuess.BreakStart()) == CH_BREAK)
bFull = false; // Keep following SwBreakPortion in the same line
}
}
else // case C2, last exit