summaryrefslogtreecommitdiffstats
path: root/writerfilter/source/rtftok
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--writerfilter/source/rtftok/rtfdispatchsymbol.cxx9
-rw-r--r--writerfilter/source/rtftok/rtfdispatchvalue.cxx12
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx41
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx2
-rw-r--r--writerfilter/source/rtftok/rtfsprm.cxx20
-rw-r--r--writerfilter/source/rtftok/rtfsprm.hxx2
-rw-r--r--writerfilter/source/rtftok/rtfvalue.cxx4
7 files changed, 71 insertions, 19 deletions
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index aa1360f6dc..0f01d79f5c 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -131,11 +131,8 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
break;
case RTFKeyword::SECT:
{
- if (m_bNeedCr)
- dispatchSymbol(RTFKeyword::PAR);
-
m_bHadSect = true;
- if (m_bIgnoreNextContSectBreak)
+ if (m_bIgnoreNextContSectBreak || m_aStates.top().getFrame().hasProperties())
{
// testContSectionPageBreak: need \par now
dispatchSymbol(RTFKeyword::PAR);
@@ -143,6 +140,10 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
}
else
{
+ if (m_bNeedCr)
+ { // tdf#158586 don't dispatch \par here, it eats deferred page breaks
+ setNeedPar(true);
+ }
sectBreak();
if (m_nResetBreakOnSectBreak != RTFKeyword::invalid)
{
diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
index 69157a9782..f699b0ed39 100644
--- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -1342,6 +1342,18 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w,
pIntValue);
break;
+ case RTFKeyword::BINFSXN:
+ putNestedAttribute(m_aStates.top().getSectionSprms(),
+ NS_ooxml::LN_EG_SectPrContents_paperSrc,
+ NS_ooxml::LN_CT_PaperSource_first, pIntValue);
+ break;
+ case RTFKeyword::BINSXN:
+ {
+ putNestedAttribute(m_aStates.top().getSectionSprms(),
+ NS_ooxml::LN_EG_SectPrContents_paperSrc,
+ NS_ooxml::LN_CT_PaperSource_other, pIntValue);
+ }
+ break;
case RTFKeyword::MARGL:
putNestedAttribute(m_aDefaultState.getSectionSprms(),
NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left,
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 1d0c2d7dde..e82674930b 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -653,6 +653,7 @@ void RTFDocumentImpl::runBreak()
void RTFDocumentImpl::tableBreak()
{
+ checkFirstRun(); // ooo113308-1.rtf has a header at offset 151084 that doesn't startParagraphGroup() without this
runBreak();
Mapper().endParagraphGroup();
Mapper().startParagraphGroup();
@@ -671,7 +672,10 @@ void RTFDocumentImpl::parBreak()
m_bHadPicture = false;
// start new one
- Mapper().startParagraphGroup();
+ if (!m_bParAtEndOfSection)
+ {
+ Mapper().startParagraphGroup();
+ }
}
void RTFDocumentImpl::sectBreak(bool bFinal)
@@ -685,14 +689,26 @@ void RTFDocumentImpl::sectBreak(bool bFinal)
// unless this is the end of the doc, we had nothing since the last section break and this is not a continuous one.
// Also, when pasting, it's fine to not have any paragraph inside the document at all.
if (m_bNeedPar && (!bFinal || m_bNeedSect || bContinuous) && !isSubstream() && m_bIsNewDoc)
+ {
+ m_bParAtEndOfSection = true;
dispatchSymbol(RTFKeyword::PAR);
+ }
// It's allowed to not have a non-table paragraph at the end of an RTF doc, add it now if required.
if (m_bNeedFinalPar && bFinal)
{
dispatchFlag(RTFKeyword::PARD);
+ m_bParAtEndOfSection = true;
dispatchSymbol(RTFKeyword::PAR);
m_bNeedSect = bNeedSect;
}
+ // testTdf148515, if RTF ends with \row, endParagraphGroup() must be called!
+ if (!m_bParAtEndOfSection || m_aStates.top().getCurrentBuffer())
+ {
+ Mapper().endParagraphGroup(); // < top para context dies with page break
+ }
+ m_bParAtEndOfSection = false;
+ // paragraph properties are *done* now - only section properties following
+
while (!m_nHeaderFooterPositions.empty())
{
std::pair<Id, std::size_t> aPair = m_nHeaderFooterPositions.front();
@@ -725,7 +741,6 @@ void RTFDocumentImpl::sectBreak(bool bFinal)
// The trick is that we send properties of the previous section right now, which will be exactly what dmapper expects.
Mapper().props(pProperties);
- Mapper().endParagraphGroup();
// End Section
if (!m_pSuperstream)
@@ -2119,6 +2134,8 @@ RTFError RTFDocumentImpl::pushState()
case Destination::FIELDRESULT:
case Destination::SHAPETEXT:
case Destination::FORMFIELD:
+ //TODO: if this is pushed then the font encoding is used which results in a broken command string
+ // if it is not pushed to NORMAL then it is not restored in time.
case Destination::FIELDINSTRUCTION:
case Destination::PICT:
m_aStates.top().setDestination(Destination::NORMAL);
@@ -2342,7 +2359,7 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& rState)
if (m_aStates.top().isFieldLocked())
singleChar(cFieldLock);
- singleChar(cFieldSep);
+ singleChar(cFieldSep, true);
}
break;
case Destination::FIELDRESULT:
@@ -2569,7 +2586,7 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& rState)
str = OUString::Concat(field) + " \"" + str.replaceAll("\"", "\\\"") + "\"";
singleChar(cFieldStart);
Mapper().utext(str.getStr(), str.getLength());
- singleChar(cFieldSep);
+ singleChar(cFieldSep, true);
// no result
singleChar(cFieldEnd);
}
@@ -3654,8 +3671,15 @@ RTFError RTFDocumentImpl::popState()
// \par means an empty paragraph at the end of footnotes/endnotes, but
// not in case of other substreams, like headers.
if (m_bNeedCr && m_nStreamType != NS_ooxml::LN_footnote
- && m_nStreamType != NS_ooxml::LN_endnote && m_bIsNewDoc)
+ && m_nStreamType != NS_ooxml::LN_endnote)
+ {
+ if (!m_bIsNewDoc)
+ {
+ // Make sure all the paragraph settings are set, but do not add next paragraph
+ Mapper().markLastParagraph();
+ }
dispatchSymbol(RTFKeyword::PAR);
+ }
if (m_bNeedSect) // may be set by dispatchSymbol above!
sectBreak(true);
else if (!m_pSuperstream)
@@ -3782,8 +3806,11 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
if (bHex && !m_aHexBuffer.isEmpty())
{
rtl_TextEncoding nEncoding = m_aStates.top().getCurrentEncoding();
- if (m_aStates.top().getDestination() == Destination::FONTENTRY
- && m_aStates.top().getCurrentEncoding() == RTL_TEXTENCODING_SYMBOL)
+ if (nEncoding == RTL_TEXTENCODING_SYMBOL
+ && (m_aStates.top().getDestination() == Destination::FONTENTRY
+ || (m_aStates.size() > 1
+ && m_aStates[m_aStates.size() - 2].getDestination()
+ == Destination::FIELDINSTRUCTION)))
nEncoding = RTL_TEXTENCODING_MS_1252;
OUString aString = OStringToOUString(m_aHexBuffer, nEncoding);
m_aHexBuffer.setLength(0);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index eb50e3c7e0..f05f7d321c 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -852,6 +852,8 @@ private:
bool m_bNeedPar;
/// If set, an empty paragraph will be added at the end of the document.
bool m_bNeedFinalPar;
+ /// a synthetic \par was dispatched at the end of the current section
+ bool m_bParAtEndOfSection = false;
/// The list table and list override table combined.
RTFSprms m_aListTableSprms;
/// Maps between listoverridetable and listtable indexes.
diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx
index 5d57348f20..148d39c2e4 100644
--- a/writerfilter/source/rtftok/rtfsprm.cxx
+++ b/writerfilter/source/rtftok/rtfsprm.cxx
@@ -437,12 +437,22 @@ RTFSprms RTFSprms::cloneAndDeduplicate(RTFSprms& rReference, Id const nStyleType
return ret;
}
-bool RTFSprms::equals(const RTFValue& rOther) const
+bool RTFSprms::equals(const RTFSprms& rOther) const
{
- return std::all_of(m_pSprms->cbegin(), m_pSprms->cend(),
- [&](const std::pair<Id, RTFValue::Pointer_t>& raPair) -> bool {
- return raPair.second->equals(rOther);
- });
+ auto it1 = m_pSprms->cbegin();
+ auto it1End = m_pSprms->cend();
+ auto it2 = rOther.m_pSprms->cbegin();
+ auto it2End = rOther.m_pSprms->cend();
+ while (it1 != it1End && it2 != it2End)
+ {
+ if (it1->first != it2->first)
+ return false;
+ if (!it1->second->equals(*it2->second))
+ return false;
+ ++it1;
+ ++it2;
+ }
+ return it1 == it1End && it2 == it2End;
}
void RTFSprms::ensureCopyBeforeWrite()
diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx
index 9f3bbd78b3..132a2bbcbe 100644
--- a/writerfilter/source/rtftok/rtfsprm.hxx
+++ b/writerfilter/source/rtftok/rtfsprm.hxx
@@ -73,7 +73,7 @@ public:
Iterator_t begin() { return m_pSprms->begin(); }
Iterator_t end() { return m_pSprms->end(); }
void clear();
- bool equals(const RTFValue& rOther) const;
+ bool equals(const RTFSprms& rOther) const;
private:
void ensureCopyBeforeWrite();
diff --git a/writerfilter/source/rtftok/rtfvalue.cxx b/writerfilter/source/rtftok/rtfvalue.cxx
index 373fb7521b..7a9137f5db 100644
--- a/writerfilter/source/rtftok/rtfvalue.cxx
+++ b/writerfilter/source/rtftok/rtfvalue.cxx
@@ -172,7 +172,7 @@ bool RTFValue::equals(const RTFValue& rOther) const
{
if (m_pAttributes->size() != rOther.m_pAttributes->size())
return false;
- if (!m_pAttributes->equals(rOther))
+ if (!m_pAttributes->equals(*rOther.m_pAttributes))
return false;
}
else if (m_pAttributes && m_pAttributes->size())
@@ -188,7 +188,7 @@ bool RTFValue::equals(const RTFValue& rOther) const
{
if (m_pSprms->size() != rOther.m_pSprms->size())
return false;
- if (!m_pSprms->equals(rOther))
+ if (!m_pSprms->equals(*rOther.m_pSprms))
return false;
}
else if (m_pSprms && m_pSprms->size())