tdf#137683 sw ms formats Char highlight: export "none"
NONE settings need to be exported in order
to cancel out a CharHighlight set
at a higher style level.
This patch has two main parts.
1.) Export none for DOCX/DOC/RTF
2.) Only export necessary "none" highlights.
I am unpleasantly surprised that I did not find
any existing functions that avoided spamming
unnecessary settings into the export. Perhaps
in the default case things are more complicated,
but in this case, only paragraph styles are
expected to have any hierarchical impact.
This could be made into a more general function
at some point, but at the moment I don't have
anywhere else to apply it, and I would be
terribly afraid to try to add it at some
general level... Imagine the regressions.
Change-Id: I83e5e3496e3ad78c8e2698a6b331c871f842f259
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106315
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 65baba8..1170bdc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -721,10 +721,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf136441_commentInFootnote, "tdf136441_
DECLARE_OOXMLEXPORT_TEST(testTdf137683_charHighlightTests, "tdf137683_charHighlightTests.docx")
{
// Don't export unnecessary w:highlight="none" (Unnecessary one intentionally hand-added to original .docx)
xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
if (pXmlStyles)
assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Normal']/w:rPr/w:highlight", 0);
uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(10), 2, "no highlight"), uno::UNO_QUERY_THROW);
// This test was failing with a cyan charHighlight of 65535 (0x00FFFF), instead of COL_TRANSPARENT (0xFFFFFFFF)
if ( !mbExported ) //TODO: export COL_TRANSPARENT
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharHighlight"));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharHighlight"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf134063, "tdf134063.docx")
diff --git a/sw/qa/extras/rtfexport/data/tdf137683_charHighlightNone.rtf b/sw/qa/extras/rtfexport/data/tdf137683_charHighlightNone.rtf
new file mode 100644
index 0000000..4a1eba7
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf137683_charHighlightNone.rtf
@@ -0,0 +1,18 @@
{\rtf1\ansi\deff4\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq0\fcharset0 Times New Roman;}{\f5\fnil\fprq2\fcharset0 DejaVu Sans;}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red255\green151\blue47;}
{\stylesheet{\s0\snext0\hich\af4\dbch\af5\langfe2052\dbch\af4\afs24\alang1025\widctlpar\hyphpar0\aspalpha\ltrpar\fs48\b\highlight14\cf0\loch\f4\lang255\kerning1 Normal;}
{\s15\sbasedon0\snext16\dbch\af5\dbch\af4\afs28\sb240\sa120\keepn\loch\f4\fs28\b\highlight14 Heading;}
{\s16\sbasedon0\snext16\sl276\slmult1\sb0\sa140\fs48\b\highlight14 Text Body;}
{\s17\sbasedon16\snext17\dbch\af4\sl276\slmult1\sb0\sa140\loch\f4\fs48\b\highlight14 List;}
{\s18\sbasedon0\snext18\dbch\af4\afs24\ai\sb120\sa120\noline\loch\f4\fs24\i\b\highlight14 Caption;}
{\s19\sbasedon0\snext19\dbch\af4\noline\loch\f4\fs48\b\highlight14 Index;}
{\s20\sbasedon0\snext20\qc\fs96\b\highlight0 noHighlight;}
}{\*\generator LibreOfficeDev/7.1.0.0.alpha1$Linux_X86_64 LibreOffice_project/1d485c8880d4a5a379bc0d23553f956b5eedc1bd}{\info{\creatim\yr2020\mo11\dy21\hr14\min20}{\revtim\yr2020\mo11\dy21\hr14\min35}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab709
\hyphauto1\viewscale100
{\*\pgdsctbl
{\pgdsc0\pgdscuse451\lndscpsxn\pgwsxn8391\pghsxn5953\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default Page Style;}}
\formshade\landscape\paperh5953\paperw8391\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\pgndec\sftnnar\saftnnrlc\sectunlocked1\lndscpsxn\pgwsxn8391\pghsxn5953\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
{\*\ftnsep\chftnsep}\pgndec\pard\plain \s20\qc\fs96\b\highlight0\qc\ltrpar{\loch
A white background is so nice.}
\par }
\ No newline at end of file
diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx
index 442a508..696e6ad 100644
--- a/sw/qa/extras/rtfexport/rtfexport3.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport3.cxx
@@ -85,6 +85,14 @@ DECLARE_RTFEXPORT_TEST(testTdf130817, "tdf130817.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("$"), xEndnote1->getAnchor()->getString());
}
DECLARE_RTFEXPORT_TEST(testTdf137683_charHighlightNone, "tdf137683_charHighlightNone.rtf")
{
uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1), uno::UNO_QUERY_THROW);
// This test was failing with a brown charHighlight of 8421376 (0x808000), instead of COL_TRANSPARENT (0xFFFFFFFF)
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO),
getProperty<sal_Int32>(xRun, "CharHighlight"));
}
DECLARE_RTFEXPORT_TEST(testTdf116436_tableBackground, "tdf116436_tableBackground.odt")
{
CPPUNIT_ASSERT_EQUAL(1, getPages());
diff --git a/sw/qa/extras/ww8export/data/tdf138345_paraCharHighlight.doc b/sw/qa/extras/ww8export/data/tdf138345_paraCharHighlight.doc
new file mode 100644
index 0000000..3da7e92
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf138345_paraCharHighlight.doc
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx
index c32ff27..5e0124e 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -69,6 +69,20 @@ DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.d
CPPUNIT_ASSERT_EQUAL_MESSAGE("Last printed date", sal_Int16(2009), xDPS->getDocumentProperties()->getPrintDate().Year);
}
DECLARE_WW8EXPORT_TEST(testTdf138345_paraCharHighlight, "tdf138345_paraCharHighlight.doc")
{
uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(9), 1, "A side benefit is that "), uno::UNO_QUERY_THROW);
// Paragraph style paraNoCharBackground cancel paraCharBackground using COL_TRANSPARENT.
// Before this fix, the paragraph was by default covered with a yellow CharHighlight.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharHighlight"));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharBackColor"));
xRun.set(getRun(getParagraph(9), 2), uno::UNO_QUERY_THROW);
// Character style formatting must not contain a highlight setting at all.
//CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharHighlight"));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_AUTO), getProperty<sal_Int32>(xRun, "CharBackColor"));
}
DECLARE_WW8EXPORT_TEST(testTdf104596_wrapInHeaderTable, "tdf104596_wrapInHeaderTable.doc")
{
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 5a58b84..5b246d9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -7076,6 +7076,7 @@ OString DocxAttributeOutput::TransHighlightColor( sal_uInt8 nIco )
{
switch (nIco)
{
case 0: return "none"; break;
case 1: return "black"; break;
case 2: return "blue"; break;
case 3: return "cyan"; break;
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 23dc3af..bfea2e3 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -2803,11 +2803,8 @@ void RtfAttributeOutput::CharBorder(const editeng::SvxBorderLine* pAllBorder,
void RtfAttributeOutput::CharHighlight(const SvxBrushItem& rBrush)
{
if (!rBrush.GetColor().GetTransparency())
{
m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
m_aStyles.append(static_cast<sal_Int32>(msfilter::util::TransColToIco(rBrush.GetColor())));
}
m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
m_aStyles.append(static_cast<sal_Int32>(msfilter::util::TransColToIco(rBrush.GetColor())));
}
void RtfAttributeOutput::TextINetFormat(const SwFormatINetFormat& rURL)
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index ef5ea8b..1cd22f2 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -278,6 +278,23 @@ void MSWordExportBase::ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16
AttrOutput().OutputItem( *pItem );
}
}
else if (nWhich == RES_CHRATR_HIGHLIGHT)
{
const SvxBrushItem& rBrush = static_cast< const SvxBrushItem& >( *pItem );
// The UI easily adds unnecessary highlights, so identify and avoid exporting those.
// Highlight is not valid in character styles, so must not check there.
// Check the (para) style hierarchy to find the nearest defined highlight.
const SfxPoolItem* pInherited = nullptr;
if ( auto pNd = dynamic_cast< const SwContentNode *>( m_pOutFormatNode ) ) //paragraph
pInherited = static_cast<SwTextFormatColl&>( pNd->GetAnyFormatColl() ).GetAttrSet().GetItem(nWhich);
else if ( m_bStyDef && m_pCurrentStyle && m_pCurrentStyle->DerivedFrom() ) //style
pInherited = &m_pCurrentStyle->DerivedFrom()->GetFormatAttr(nWhich);
// Ignore highlight if style already sets the same one.
// Also ignore a transparent highlight if there is no inherited highlight to cancel
if ( (pInherited && *pInherited != *pItem) || (!pInherited && rBrush.GetColor() != COL_TRANSPARENT) )
AttrOutput().OutputItem( *pItem );
}
else
{
AttrOutput().OutputItem( *pItem );
@@ -1235,13 +1252,9 @@ void WW8AttributeOutput::CharBorder( const SvxBorderLine* pAllBorder, const sal_
void WW8AttributeOutput::CharHighlight( const SvxBrushItem& rBrush )
{
if (rBrush.GetColor() != COL_TRANSPARENT)
{
sal_uInt8 nColor = msfilter::util::TransColToIco( rBrush.GetColor() );
// sprmCHighlight
m_rWW8Export.InsUInt16( NS_sprm::CHighlight::val );
m_rWW8Export.pO->push_back( nColor );
}
sal_uInt8 nColor = msfilter::util::TransColToIco( rBrush.GetColor() );
m_rWW8Export.InsUInt16( NS_sprm::CHighlight::val );
m_rWW8Export.pO->push_back( nColor );
}
void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )