tdf#119908 tdf#166113 cool#15973 sw smart justify: fix DOCX hyphenation
Setting 150% maximum word spacing instead of 133% during DOCX import, the improved line breaking fixes DOCX layout interoperability in the case of hyphenation, too. Note: justification of MSO 2013 and later uses also a "less hyphenation" strategy, not only "better word spacing", resulting different line breaking, when hyphenation is enabled. Follow-up to commitd572576dd6"tdf#119908 cool#15973 sw smart justify: fix "smart" hyphenation", commit529755f091"tdf#166113 sw smart justify: adjust algorithm for interoperability" and commit7d08767b89"tdf#130088 tdf#119908 smart justify: fix DOCX line count + compat opt." Change-Id: I85410b4a73c96dab4ddfc25d894e72780ebe4728 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207508 Tested-by: László Németh <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Binary file not shown.
@@ -397,6 +397,149 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf119908_smart_hyphenation)
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt/SwParaPortion/SwLineLayout/SwHyphPortion", 4);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf119908_DOCX_smart_hyphenation)
|
||||
{
|
||||
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
|
||||
if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, OUString())))
|
||||
return;
|
||||
|
||||
createSwDoc("tdf119908_smart_hyphenation.docx");
|
||||
// Ensure that all text portions are calculated before testing.
|
||||
SwViewShell* pViewShell = getSwDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
|
||||
|
||||
CPPUNIT_ASSERT(pViewShell);
|
||||
pViewShell->Reformat();
|
||||
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
|
||||
// 2 hyphenations on page 1
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"Whereas it is essential to promote the development of friendly relations between na");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"Whereas a common understanding of these rights and freedoms is of the greatest im");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt/SwParaPortion/SwLineLayout/SwHyphPortion", 2);
|
||||
|
||||
// delete first page to update hyphenation on the next page
|
||||
|
||||
SwWrtShell* const pWrtShell = getSwDocShell()->GetWrtShell();
|
||||
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 2836, /*bBasicCall=*/false);
|
||||
pWrtShell->Delete();
|
||||
|
||||
// 3 hyphenations on page 2
|
||||
|
||||
pViewShell->Reformat();
|
||||
pXmlDoc = parseLayoutDump();
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"No one shall be held in slavery or servitude; slavery and the slave trade shall be pro");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"All are equal before the law and are entitled without any discrimination to equal pro");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[24]/SwParaPortion/SwLineLayout[2]", "portion",
|
||||
u"political crimes or from acts contrary to the purposes and principles of the United Na");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[24]/SwParaPortion/SwLineLayout[2]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt/SwParaPortion/SwLineLayout/SwHyphPortion", 3);
|
||||
|
||||
// delete second page to update hyphenation on the next page
|
||||
|
||||
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2336, /*bBasicCall=*/false);
|
||||
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 2336, /*bBasicCall=*/false);
|
||||
pWrtShell->Delete();
|
||||
|
||||
// 5 hyphenations on page 3
|
||||
|
||||
pViewShell->Reformat();
|
||||
pXmlDoc = parseLayoutDump();
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"The family is the natural and fundamental group unit of society and is entitled to pro");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"Everyone has the right to freedom of thought, conscience and religion; this right in");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[2]", "portion",
|
||||
u"cludes freedom to change his religion or belief, and freedom, either alone or in com");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[2]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[3]", "portion",
|
||||
u"munity with others and in public or private, to manifest his religion or belief "
|
||||
u"in teach");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout[3]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[12]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"Everyone has the right to freedom of opinion and expression; this right includes free");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[12]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt/SwParaPortion/SwLineLayout/SwHyphPortion", 5);
|
||||
|
||||
// delete second page to update hyphenation on the next page
|
||||
|
||||
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2646, /*bBasicCall=*/false);
|
||||
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 2646, /*bBasicCall=*/false);
|
||||
pWrtShell->Delete();
|
||||
|
||||
// 4 hyphenations on page 4
|
||||
|
||||
pViewShell->Reformat();
|
||||
pXmlDoc = parseLayoutDump();
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"Everyone has the right to form and to join trade unions for the protection of his inter");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout[2]", "portion",
|
||||
u"himself and of his family, including food, clothing, housing and medical care and nec");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout[2]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout[2]", "portion",
|
||||
u"and fundamental stages. Elementary education shall be compulsory. Technical and pro");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout[2]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(
|
||||
pXmlDoc, "/root/page[1]/body/txt[18]/SwParaPortion/SwLineLayout[1]", "portion",
|
||||
u"In the exercise of his rights and freedoms, everyone shall be subject only to such limi");
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[18]/SwParaPortion/SwLineLayout[1]/SwHyphPortion",
|
||||
1);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt/SwParaPortion/SwLineLayout/SwHyphPortion", 4);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333)
|
||||
{
|
||||
createSwDoc("tdf130088.docx");
|
||||
|
||||
@@ -9432,7 +9432,9 @@ void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
|
||||
switch ( rAdjust.GetPropWordSpacingMinimum() )
|
||||
{
|
||||
case 133:
|
||||
if ( rAdjust.GetPropWordSpacingMaximum() == 133 )
|
||||
case 150:
|
||||
if ( rAdjust.GetPropWordSpacingMaximum() == 133 ||
|
||||
rAdjust.GetPropWordSpacingMaximum() == 150 )
|
||||
pAdjustString = "lowKashida";
|
||||
break;
|
||||
case 200:
|
||||
|
||||
@@ -5133,13 +5133,13 @@ void DomainMapper::handleParaJustification(const sal_Int32 nIntValue,
|
||||
if ( GetSettingsTable()->GetWordCompatibilityMode() >= 15 )
|
||||
{
|
||||
rContext->Insert( PROP_PARA_WORD_SPACING_MINIMUM, uno::Any( sal_uInt16(75) ) );
|
||||
rContext->Insert( PROP_PARA_WORD_SPACING_MAXIMUM, uno::Any( sal_uInt16(133) ) );
|
||||
rContext->Insert( PROP_PARA_WORD_SPACING_MAXIMUM, uno::Any( sal_uInt16(150) ) );
|
||||
}
|
||||
break;
|
||||
case NS_ooxml::LN_Value_ST_Jc_lowKashida:
|
||||
nAdjust = style::ParagraphAdjust_BLOCK;
|
||||
// modify this value also in sw/source/filter/ww8/docxattributeoutput.cxx
|
||||
nWordSpacing = 133;
|
||||
nWordSpacing = 150;
|
||||
break;
|
||||
case NS_ooxml::LN_Value_ST_Jc_mediumKashida:
|
||||
nAdjust = style::ParagraphAdjust_BLOCK;
|
||||
|
||||
Reference in New Issue
Block a user