[Libreoffice-commits] core.git: sw/qa writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Wed Apr 4 07:02:50 UTC 2018
sw/qa/extras/rtfimport/data/tdf116265.rtf | 28 ++++++++++
sw/qa/extras/rtfimport/rtfimport.cxx | 8 ++
writerfilter/source/rtftok/rtfdispatchdestination.cxx | 1
writerfilter/source/rtftok/rtfdispatchvalue.cxx | 2
writerfilter/source/rtftok/rtfdocumentimpl.cxx | 49 ++++++++++++------
writerfilter/source/rtftok/rtfdocumentimpl.hxx | 6 ++
writerfilter/source/rtftok/rtfsprm.cxx | 25 +++++++++
writerfilter/source/rtftok/rtfsprm.hxx | 3 +
8 files changed, 106 insertions(+), 16 deletions(-)
New commits:
commit 791fb3979df47a9fe21a1fbb9debbc955f3e035b
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Tue Apr 3 22:54:38 2018 +0200
tdf#116265 RTF import: ignore \fi in para if it repeats invalid \fi from list
The 2nd paragraph of the bugdoc has a \fi set, but it has to be ignored.
The reason for this is that the \fi is a repeated property from the list
definition, but there \levelnumbers has invalid contents, which means
its \fi has to be ignored, including their repeated values in paragraph
direct formatting.
There was already code to insert implicit defaults as paragraph direct
formatting based on list properties, this does the opposite: remove
paragraph direct formatting based on the list state.
This requires tracking the ignored values in a separate structure, since
the normal list properties no longer contain the information we need to
be able to remove paragraph formatting. (At the moment this tracks only
\fi, but can be extended to other properties if it'll be necessary.)
Change-Id: Iff542cb76c66b7fc7ae4e07ade84701e24a74f1a
Reviewed-on: https://gerrit.libreoffice.org/52352
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
diff --git a/sw/qa/extras/rtfimport/data/tdf116265.rtf b/sw/qa/extras/rtfimport/data/tdf116265.rtf
new file mode 100644
index 000000000000..c5ad557d289d
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/tdf116265.rtf
@@ -0,0 +1,28 @@
+{\rtf \ansi \ansicpg0 \deff0 \stshfdbch1 \stshfloch0 \stshfhich0 \deflang1033 \deflangfe1033
+{\fonttbl
+{\f0 \froman \fcharset0 \fprq2 Times New Roman;}
+}
+{\stylesheet
+{Normal;}
+{\s19 \li720 \ri0 ListParagraph;}
+}
+{\*\listtable
+{\list \listtemplateid700648999 \listhybrid
+{\listlevel \levelnfc0 \levelnfcn0 \leveljc0 \leveljcn0 \levelstartat1 \levelfollow0 \levelspace0 \levelindent0 \levellegal0 \levelnorestart0
+{\leveltext
+}
+{\levelnumbers \'01
+{\uc1 \u59 ?}
+}
+\li720 \fi-360 }
+{\listname ;}
+\listid697112958 }
+}
+{\*\listoverridetable
+{\listoverride \listid697112958 \listoverridecount0 \ls1 }
+}
+\paperw12240 \paperh15840 \margl1800 \margr1800 \margt1440 \margb1440
+\pard\plain We would add the following notes:\par
+\pard \plain \s19 \fi-360 \li720 \ls1
+Strictly speaking, PDF is also a revisable format, but it is most often used to create documents for viewing.\par
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index e4af20ddc392..4211c88429e7 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -636,6 +636,14 @@ DECLARE_RTFIMPORT_TEST(testTdf116269, "tdf116269.rtf")
getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
}
+DECLARE_RTFIMPORT_TEST(testTdf116265, "tdf116265.rtf")
+{
+ // This was -635, \fi as direct formatting has to be ignored due to
+ // matching \fi in list definition (and with invalid level numbers).
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0),
+ getProperty<sal_Int32>(getParagraph(2), "ParaFirstLineIndent"));
+}
+
DECLARE_RTFIMPORT_TEST(testFdo66565, "fdo66565.rtf")
{
uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
diff --git a/writerfilter/source/rtftok/rtfdispatchdestination.cxx b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
index af1a60d947ca..d67c043c08b2 100644
--- a/writerfilter/source/rtftok/rtfdispatchdestination.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchdestination.cxx
@@ -140,6 +140,7 @@ RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
break;
case RTF_LISTLEVEL:
m_aStates.top().eDestination = Destination::LISTLEVEL;
+ ++m_nListLevel;
break;
case RTF_LEVELTEXT:
m_aStates.top().eDestination = Destination::LEVELTEXT;
diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
index bad8111a77aa..27f3d9ae9de9 100644
--- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -1477,6 +1477,8 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
if (m_aStates.top().bLevelNumbersValid)
putNestedAttribute(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_PPrBase_ind,
NS_ooxml::LN_CT_Ind_firstLine, pIntValue);
+ else
+ m_aInvalidListLevelFirstIndents[m_nListLevel] = nParam;
}
else
putNestedAttribute(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_ind,
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 2e8ff1e9ab78..d0825e0ec275 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -443,6 +443,32 @@ static void lcl_copyFlatten(RTFReferenceProperties& rProps, RTFSprms& rStyleAttr
writerfilter::Reference<Properties>::Pointer_t
RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms, Id nStyleType)
{
+ RTFSprms aSprms(rSprms);
+ RTFValue::Pointer_t pAbstractList;
+ int nAbstractListId = -1;
+ RTFValue::Pointer_t pNumId
+ = getNestedSprm(aSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_numId);
+ if (pNumId)
+ {
+ // We have a numbering, look up the abstract list for property
+ // deduplication and duplication.
+ auto itNumId = m_aListOverrideTable.find(pNumId->getInt());
+ if (itNumId != m_aListOverrideTable.end())
+ {
+ nAbstractListId = itNumId->second;
+ auto itAbstract = m_aListTable.find(nAbstractListId);
+ if (itAbstract != m_aListTable.end())
+ pAbstractList = itAbstract->second;
+ }
+ }
+
+ if (pAbstractList)
+ {
+ auto it = m_aInvalidListTableFirstIndents.find(nAbstractListId);
+ if (it != m_aInvalidListTableFirstIndents.end())
+ aSprms.deduplicateList(it->second);
+ }
+
int nStyle = 0;
if (!m_aStates.empty())
nStyle = m_aStates.top().nCurrentStyleIndex;
@@ -476,26 +502,13 @@ RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms, Id nStyl
}
// Get rid of direct formatting what is already in the style.
- RTFSprms const sprms(rSprms.cloneAndDeduplicate(aStyleSprms));
+ RTFSprms const sprms(aSprms.cloneAndDeduplicate(aStyleSprms));
RTFSprms const attributes(rAttributes.cloneAndDeduplicate(aStyleAttributes));
return std::make_shared<RTFReferenceProperties>(attributes, sprms);
}
- RTFSprms aSprms(rSprms);
- RTFValue::Pointer_t pNumId
- = getNestedSprm(aSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_numId);
- if (pNumId)
- {
- // We have a numbering, see if defaults has to be inserted for not
- // repeated direct formatting.
- auto itNumId = m_aListOverrideTable.find(pNumId->getInt());
- if (itNumId != m_aListOverrideTable.end())
- {
- auto itAbstract = m_aListTable.find(itNumId->second);
- if (itAbstract != m_aListTable.end())
- aSprms.duplicateList(itAbstract->second);
- }
- }
+ if (pAbstractList)
+ aSprms.duplicateList(pAbstractList);
writerfilter::Reference<Properties>::Pointer_t pRet
= std::make_shared<RTFReferenceProperties>(rAttributes, aSprms);
return pRet;
@@ -3023,6 +3036,10 @@ RTFError RTFDocumentImpl::popState()
m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pValue,
RTFOverwrite::NO_APPEND);
m_aListTable[aState.nCurrentListIndex] = pValue;
+ m_nListLevel = -1;
+ m_aInvalidListTableFirstIndents[aState.nCurrentListIndex]
+ = m_aInvalidListLevelFirstIndents;
+ m_aInvalidListLevelFirstIndents.clear();
}
break;
case Destination::PARAGRAPHNUMBERING:
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 2200122ed030..cf099a9817fc 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -567,6 +567,12 @@ private:
std::map<int, int> m_aListOverrideTable;
/// Maps listtable indexes to listtable entries.
std::map<int, RTFValue::Pointer_t> m_aListTable;
+ /// Index of the current list level in a list table entry.
+ int m_nListLevel = -1;
+ /// Maps List level indexes to removed values in the current list entry.
+ std::map<int, int> m_aInvalidListLevelFirstIndents;
+ /// Maps list table indexes to levels (and their removed values).
+ std::map<int, std::map<int, int>> m_aInvalidListTableFirstIndents;
/// The settings table attributes.
RTFSprms m_aSettingsTableAttributes;
/// The settings table sprms.
diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx
index 8ebf9fd9ec5e..89d520c391bb 100644
--- a/writerfilter/source/rtftok/rtfsprm.cxx
+++ b/writerfilter/source/rtftok/rtfsprm.cxx
@@ -262,6 +262,31 @@ static RTFValue::Pointer_t getListLevel(RTFValue::Pointer_t pAbstract, int nLeve
return RTFValue::Pointer_t();
}
+void RTFSprms::deduplicateList(const std::map<int, int>& rInvalidListLevelFirstIndents)
+{
+ int nLevel = 0;
+ RTFValue::Pointer_t pLevelId
+ = getNestedSprm(*this, NS_ooxml::LN_CT_PPrBase_numPr, NS_ooxml::LN_CT_NumPr_ilvl);
+ if (pLevelId)
+ nLevel = pLevelId->getInt();
+
+ auto it = rInvalidListLevelFirstIndents.find(nLevel);
+ if (it == rInvalidListLevelFirstIndents.end())
+ return;
+
+ int nListValue = it->second;
+
+ RTFValue::Pointer_t pParagraphValue
+ = getNestedAttribute(*this, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine);
+ if (!pParagraphValue)
+ return;
+
+ int nParagraphValue = pParagraphValue->getInt();
+
+ if (nParagraphValue == nListValue)
+ eraseNestedAttribute(*this, NS_ooxml::LN_CT_PPrBase_ind, NS_ooxml::LN_CT_Ind_firstLine);
+}
+
void RTFSprms::duplicateList(RTFValue::Pointer_t pAbstract)
{
int nLevel = 0;
diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx
index 7232b04e9351..79694e5864bd 100644
--- a/writerfilter/source/rtftok/rtfsprm.hxx
+++ b/writerfilter/source/rtftok/rtfsprm.hxx
@@ -13,6 +13,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <map>
#include <tools/ref.hxx>
#include "rtfvalue.hxx"
@@ -58,6 +59,8 @@ public:
RTFSprms cloneAndDeduplicate(RTFSprms& rReference) const;
/// Inserts default values to override attributes of pAbstract.
void duplicateList(RTFValue::Pointer_t pAbstract);
+ /// Removes duplicated values based on in-list properties.
+ void deduplicateList(const std::map<int, int>& rInvalidListLevelFirstIndents);
std::size_t size() const { return m_pSprms->size(); }
bool empty() const { return m_pSprms->empty(); }
Entry_t& back() { return m_pSprms->back(); }
More information about the Libreoffice-commits
mailing list