diff options
-rw-r--r-- | sw/qa/extras/rtfimport/data/tdf104744.rtf | 24 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 7 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.cxx | 74 |
3 files changed, 76 insertions, 29 deletions
diff --git a/sw/qa/extras/rtfimport/data/tdf104744.rtf b/sw/qa/extras/rtfimport/data/tdf104744.rtf new file mode 100644 index 000000000000..ef329982bf3b --- /dev/null +++ b/sw/qa/extras/rtfimport/data/tdf104744.rtf @@ -0,0 +1,24 @@ +{\rtf1 +{\fonttbl +{\f3\fcharset2 Symbol;} +} +{\stylesheet +{\s15\li720 List Paragraph;} +} +{\*\listtable +{\list\listtemplateid1145476866\listhybrid +{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\levelspace360\levelindent0 +{\leveltext\leveltemplateid67698689\'01\u-3913 ?;} +{\levelnumbers;} +\f3\li720 } +\listid1805847239} +} +{\*\listoverridetable +{\listoverride\listid1805847239\listoverridecount0\ls1} +} +{\pard\plain \ltrpar\s15\li720\ls1 bullet +\par +} +{\pard\plain after} +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 2f554e1595fc..c860f3dcebcf 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -2721,6 +2721,13 @@ DECLARE_RTFIMPORT_TEST(testTdf104317, "tdf104317.rtf") CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount()); } +DECLARE_RTFIMPORT_TEST(testTdf104744, "tdf104744.rtf") +{ + // This was 0, as an unexpected "left margin is 0" token was created during + // import. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1270), getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx index c7096f1c8754..da7bc815c6ca 100644 --- a/writerfilter/source/rtftok/rtfsprm.cxx +++ b/writerfilter/source/rtftok/rtfsprm.cxx @@ -153,6 +153,43 @@ static RTFValue::Pointer_t getDefaultSPRM(Id const id) } } +/// Does the clone / deduplication of a single sprm. +static void cloneAndDeduplicateSprm(std::pair<Id, RTFValue::Pointer_t>& rSprm, RTFSprms& ret) +{ + RTFValue::Pointer_t const pValue(ret.find(rSprm.first)); + if (pValue) + { + if (rSprm.second->equals(*pValue)) + { + ret.erase(rSprm.first); // duplicate to style + } + else if (!rSprm.second->getSprms().empty() || !rSprm.second->getAttributes().empty()) + { + RTFSprms const sprms(pValue->getSprms().cloneAndDeduplicate(rSprm.second->getSprms())); + RTFSprms const attributes(pValue->getAttributes().cloneAndDeduplicate(rSprm.second->getAttributes())); + ret.set(rSprm.first, RTFValue::Pointer_t(pValue->CloneWithSprms(attributes, sprms))); + } + } + else + { + // not found - try to override style with default + RTFValue::Pointer_t const pDefault(getDefaultSPRM(rSprm.first)); + if (pDefault) + { + ret.set(rSprm.first, pDefault); + } + else if (!rSprm.second->getSprms().empty() || !rSprm.second->getAttributes().empty()) + { + RTFSprms const sprms(RTFSprms().cloneAndDeduplicate(rSprm.second->getSprms())); + RTFSprms const attributes(RTFSprms().cloneAndDeduplicate(rSprm.second->getAttributes())); + if (!sprms.empty() || !attributes.empty()) + { + ret.set(rSprm.first, std::make_shared<RTFValue>(attributes, sprms)); + } + } + } +} + RTFSprms RTFSprms::cloneAndDeduplicate(RTFSprms& rReference) const { RTFSprms ret(*this); @@ -162,38 +199,17 @@ RTFSprms RTFSprms::cloneAndDeduplicate(RTFSprms& rReference) const // it is probably a bad idea to mess with those in any way here? for (auto& rSprm : rReference) { - RTFValue::Pointer_t const pValue(ret.find(rSprm.first)); - if (pValue) + // Paragraph formatting sprms are directly contained in case of + // paragraphs, but they are below NS_ooxml::LN_CT_Style_pPr in case of + // styles. So handle those children directly, to avoid unexpected + // addition of direct formatting sprms at the paragraph level. + if (rSprm.first == NS_ooxml::LN_CT_Style_pPr) { - if (rSprm.second->equals(*pValue)) - { - ret.erase(rSprm.first); // duplicate to style - } - else if (!rSprm.second->getSprms().empty() || !rSprm.second->getAttributes().empty()) - { - RTFSprms const sprms(pValue->getSprms().cloneAndDeduplicate(rSprm.second->getSprms())); - RTFSprms const attributes(pValue->getAttributes().cloneAndDeduplicate(rSprm.second->getAttributes())); - ret.set(rSprm.first, RTFValue::Pointer_t(pValue->CloneWithSprms(attributes, sprms))); - } + for (auto& i : rSprm.second->getSprms()) + cloneAndDeduplicateSprm(i, ret); } else - { - // not found - try to override style with default - RTFValue::Pointer_t const pDefault(getDefaultSPRM(rSprm.first)); - if (pDefault) - { - ret.set(rSprm.first, pDefault); - } - else if (!rSprm.second->getSprms().empty() || !rSprm.second->getAttributes().empty()) - { - RTFSprms const sprms(RTFSprms().cloneAndDeduplicate(rSprm.second->getSprms())); - RTFSprms const attributes(RTFSprms().cloneAndDeduplicate(rSprm.second->getAttributes())); - if (!sprms.empty() || !attributes.empty()) - { - ret.set(rSprm.first, std::make_shared<RTFValue>(attributes, sprms)); - } - } - } + cloneAndDeduplicateSprm(rSprm, ret); } return ret; } |