summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Specht <oliver.specht@cib.de>2025-02-27 11:18:23 +0100
committerGabor Kelemen <gabor.kelemen.extern@allotropia.de>2025-03-07 15:45:20 +0100
commit38464825c8c80eed0d9b328a89cd96eb27175a0e (patch)
tree6f745845dc071bc5172159e5d79a216078b170e7
parent75135c6c7d43b9d4f979a026cdd2529209cb9dea (diff)
tdf#165483 style inherits only repated properties
Each attribute a style inherits from a parent style needs to be repeated at that style. Otherwise it is overwritten by a default attribute. Change-Id: I9cef60b0d1eaa16d212f091434e9896bfd4a44c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182284 Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de> Tested-by: Jenkins Reviewed-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
-rwxr-xr-xsw/qa/extras/rtfimport/data/165483.rtf12
-rw-r--r--sw/qa/extras/rtfimport/rtfimport.cxx12
-rw-r--r--sw/source/writerfilter/dmapper/DomainMapper.cxx11
-rw-r--r--sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx51
-rw-r--r--sw/source/writerfilter/rtftok/rtfsprm.cxx9
5 files changed, 80 insertions, 15 deletions
diff --git a/sw/qa/extras/rtfimport/data/165483.rtf b/sw/qa/extras/rtfimport/data/165483.rtf
new file mode 100755
index 000000000000..1c6eec96cdc9
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/165483.rtf
@@ -0,0 +1,12 @@
+{\rtf1\ansi
+{\stylesheet{\fs36 Normal;}
+{\*\ts11\sl400\slmult1\sa100 \snext11 \ssemihidden \sunhideused Normal Table;}
+{\ts12\sl400\slmult1\sa100 \snext11 \ssemihidden \sunhideused Normal Table Copy;}
+{\ts96 \sbasedon12\snext196 Based On Table Normal Copy;}
+}
+{\s96 This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. \par }
+{\s96 This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. \par }
+{\s96 This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. \par }
+{\s96 This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. This text should have single line spacing and no spacing below paragraph. \par }
+
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 6b854306dbe3..6a79ac33d5a2 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1995,6 +1995,18 @@ CPPUNIT_TEST_FIXTURE(Test, test165333Tdf)
CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xRun2, u"CharHidden"_ustr));
}
+CPPUNIT_TEST_FIXTURE(Test, test165483Tdf)
+{
+ createSwDoc("165483.rtf");
+ uno::Reference<text::XTextRange> const xRun1(
+ getRun(uno::Reference<text::XTextRange>(getParagraphOrTable(1), uno::UNO_QUERY), 1));
+ uno::Reference<beans::XPropertySet> xStyle(
+ getStyles(u"ParagraphStyles"_ustr)->getByName(u"Based On Table Normal Copy"_ustr),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun1, u"ParaBottomMargin"_ustr));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xStyle, u"ParaBottomMargin"_ustr));
+}
+
// tests should only be added to rtfIMPORT *if* they fail round-tripping in rtfEXPORT
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx b/sw/source/writerfilter/dmapper/DomainMapper.cxx
index 2e7bae42cbe1..18774537f6b7 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx
@@ -4252,8 +4252,9 @@ void DomainMapper::ResetStyleProperties()
pContext->Insert(ePropertyId, uno::Any(0l));
}
break;
+ case PROP_PARA_BOTTOM_MARGIN:
case PROP_PARA_RIGHT_MARGIN:
- pContext->Insert(ePropertyId, uno::Any(0l));
+ pContext->Insert(ePropertyId, uno::Any(sal_Int32(0)));
break;
case PROP_PARA_LAST_LINE_ADJUST:
case PROP_PARA_ADJUST:
@@ -4268,6 +4269,14 @@ void DomainMapper::ResetStyleProperties()
case PROP_FILL_COLOR:
pContext->Insert(ePropertyId, uno::Any(sal_Int32(COL_TRANSPARENT)));
break;
+ case PROP_PARA_LINE_SPACING:
+ {
+ style::LineSpacing aLineSpacing;
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = sal_Int32(100);
+ pContext->Insert(ePropertyId, uno::Any(aLineSpacing));
+ }
+ break;
case INVALID:
default:
break;
diff --git a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
index ce5b87f4f20c..e070c3a3908e 100644
--- a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
+++ b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
@@ -267,6 +267,32 @@ static void lcl_DestinationToMath(OUStringBuffer* pDestinationText,
rMathBuffer.appendClosingTag(M_TOKEN(r));
}
+static writerfilter::Reference<Properties>::Pointer_t
+lcl_findParentStyle(std::shared_ptr<RTFReferenceTable::Entries_t> pStyleTableEntries,
+ RTFValue::Pointer_t const pStyle, const OUString& rBase)
+{
+ writerfilter::Reference<Properties>::Pointer_t ret;
+ if (!pStyle)
+ return ret;
+ auto itParent = pStyleTableEntries->begin();
+ while (itParent != pStyleTableEntries->end())
+ {
+ RTFValue::Pointer_t const pParentName
+ = static_cast<RTFReferenceProperties&>(*itParent->second)
+ .getSprms()
+ .find(NS_ooxml::LN_CT_Style_name);
+ if (pParentName && pParentName->getString().equals(rBase)
+ && !pParentName->getString().equals(pStyle->getString()))
+ break;
+ ++itParent;
+ }
+ if (itParent != pStyleTableEntries->end())
+ {
+ ret = itParent->second;
+ }
+ return ret;
+}
+
RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext,
uno::Reference<io::XInputStream> const& xInputStream,
rtl::Reference<SwXTextDocument> const& xDstDoc,
@@ -519,6 +545,7 @@ RTFDocumentImpl::getProperties(const RTFSprms& rAttributes, RTFSprms const& rSpr
if (!m_aStates.empty())
nStyle = m_aStates.top().getCurrentStyleIndex();
auto it = m_pStyleTableEntries->find(nStyle);
+
if (it != m_pStyleTableEntries->end())
{
// cloneAndDeduplicate() wants to know about only a single "style", so
@@ -2177,12 +2204,9 @@ RTFError RTFDocumentImpl::pushState()
writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::createStyleProperties()
{
- int nBasedOn = 0;
RTFValue::Pointer_t pBasedOn
= m_aStates.top().getTableSprms().find(NS_ooxml::LN_CT_Style_basedOn);
- if (pBasedOn)
- nBasedOn = pBasedOn->getInt();
- if (nBasedOn == 0)
+ if (!pBasedOn)
{
// No parent style, then mimic what Word does: ignore attributes which
// would set a margin as formatting, but with a default value.
@@ -2235,13 +2259,13 @@ RTFReferenceTable::Entries_t RTFDocumentImpl::deduplicateStyleTable()
NS_ooxml::LN_CT_Style_basedOn));
if (pBasedOn)
{
- int const nBasedOn(pBasedOn->getInt());
- // don't deduplicate yourself - especially a potential problem for the default style.
- if (it.first == nBasedOn)
- continue;
+ RTFValue::Pointer_t const pStyleName(
+ static_cast<RTFReferenceProperties&>(*pStyle).getSprms().find(
+ NS_ooxml::LN_CT_Style_name));
+ writerfilter::Reference<Properties>::Pointer_t parentStyle
+ = lcl_findParentStyle(m_pStyleTableEntries, pStyleName, pBasedOn->getString());
- auto const itParent(m_pStyleTableEntries->find(nBasedOn)); // definition as read!
- if (itParent != m_pStyleTableEntries->end())
+ if (parentStyle.is())
{
auto const pStyleType(
static_cast<RTFReferenceProperties&>(*pStyle).getAttributes().find(
@@ -2250,20 +2274,19 @@ RTFReferenceTable::Entries_t RTFDocumentImpl::deduplicateStyleTable()
int const nStyleType(pStyleType->getInt());
RTFSprms sprms(
static_cast<RTFReferenceProperties&>(*pStyle).getSprms().cloneAndDeduplicate(
- static_cast<RTFReferenceProperties&>(*itParent->second).getSprms(),
- nStyleType));
+ static_cast<RTFReferenceProperties&>(*parentStyle).getSprms(), nStyleType));
RTFSprms attributes(
static_cast<RTFReferenceProperties&>(*pStyle)
.getAttributes()
.cloneAndDeduplicate(
- static_cast<RTFReferenceProperties&>(*itParent->second).getAttributes(),
+ static_cast<RTFReferenceProperties&>(*parentStyle).getAttributes(),
nStyleType));
ret[it.first] = new RTFReferenceProperties(std::move(attributes), std::move(sprms));
}
else
{
- SAL_WARN("writerfilter.rtf", "parent style not found: " << nBasedOn);
+ SAL_WARN("writerfilter.rtf", "parent style not found: " << pBasedOn->getString());
}
}
}
diff --git a/sw/source/writerfilter/rtftok/rtfsprm.cxx b/sw/source/writerfilter/rtftok/rtfsprm.cxx
index 8de1626f252f..f61ffb957240 100644
--- a/sw/source/writerfilter/rtftok/rtfsprm.cxx
+++ b/sw/source/writerfilter/rtftok/rtfsprm.cxx
@@ -180,6 +180,14 @@ static RTFValue::Pointer_t getDefaultSPRM(Id const id, Id nStyleType)
{
switch (id)
{
+ case NS_ooxml::LN_CT_PPrBase_spacing:
+ {
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ aAttributes.set(NS_ooxml::LN_CT_Spacing_after, new RTFValue(0l));
+ return new RTFValue(aAttributes, aSprms);
+ }
+ break;
case NS_ooxml::LN_CT_Spacing_before:
case NS_ooxml::LN_CT_Spacing_after:
case NS_ooxml::LN_CT_Ind_left:
@@ -222,6 +230,7 @@ static bool isSPRMDeduplicateDenylist(Id nId, RTFSprms* pDirect)
{
switch (nId)
{
+ case NS_ooxml::LN_CT_Style_type: //never remove the style type
// See the NS_ooxml::LN_CT_PPrBase_tabs handler in DomainMapper,
// deduplication is explicitly not wanted for these tokens.
case NS_ooxml::LN_CT_TabStop_val: