From 44befa2b6c447fcf9f4b13dbb3c5ffd62a5bdbac Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 31 Jul 2017 22:43:51 +0200 Subject: tdf#109790 RTF import: keep remembering paragraph style between \cell and \row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the opposite situation as tdf#44715, where the problem was that style was not reset between in-cell paragraphs. Here we don't want to reset the paragraph style too early, so that direct (character) formatting isn't lost just because the theoretical end-of-row character would not have the same direct formatting. (cherry picked from commit aaa6a5202a447fb4e86d5f016d8e79fbc34a3ed7) Conflicts: writerfilter/source/rtftok/rtfdocumentimpl.cxx writerfilter/source/rtftok/rtfdocumentimpl.hxx Change-Id: I9bb54f37804f5889fb10504ae890362a2e42122c Reviewed-on: https://gerrit.libreoffice.org/40625 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- sw/qa/extras/rtfexport/data/tdf109790.rtf | 16 ++++++++++++++++ sw/qa/extras/rtfexport/rtfexport.cxx | 8 ++++++++ writerfilter/source/rtftok/rtfdispatchflag.cxx | 10 +++++++++- writerfilter/source/rtftok/rtfdispatchsymbol.cxx | 4 ++++ writerfilter/source/rtftok/rtfdocumentimpl.cxx | 3 ++- writerfilter/source/rtftok/rtfdocumentimpl.hxx | 3 +++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 sw/qa/extras/rtfexport/data/tdf109790.rtf diff --git a/sw/qa/extras/rtfexport/data/tdf109790.rtf b/sw/qa/extras/rtfexport/data/tdf109790.rtf new file mode 100644 index 000000000000..c25c11622812 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf109790.rtf @@ -0,0 +1,16 @@ +{\rtf1\adeflang1037\ansi\ansicpg1252\uc1\adeff0\deff0 +\noqfpromote +{\stylesheet +{\ql \li0\ri0\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \afs20\alang1037 \ltrch\fcs0 +\fs20\lang1033\langfe1033\loch\f0\hich\dbch\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;} +{\s26\fs44 \sbasedon0 \snext26 \slink27 \sqformat Subtitle;} +} +\paperw12240\paperh15840 +\pard\plain Start.\par +\trowd\cellx2310\pard\plain\s26\intbl +{\fs20 XXXX} +{\fs20 \cell } +\pard +{\row } +\pard\plain End.\par +} diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index 85f1c83a988b..bfa59514ff59 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -1232,6 +1232,14 @@ DECLARE_RTFEXPORT_TEST(testWatermark, "watermark.rtf") CPPUNIT_ASSERT_EQUAL((float)66, nFontSize); } +DECLARE_RTFEXPORT_TEST(testTdf109790, "tdf109790.rtf") +{ + uno::Reference xTable(getParagraphOrTable(2), uno::UNO_QUERY); + uno::Reference xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); + // Style information was reset, which caused character height to be 22. + CPPUNIT_ASSERT_EQUAL(10.f, getProperty(getRun(getParagraphOfText(1, xCell->getText()), 1), "CharHeight")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtfdispatchflag.cxx b/writerfilter/source/rtftok/rtfdispatchflag.cxx index 93d5eeb8f6a7..5f512b94df77 100644 --- a/writerfilter/source/rtftok/rtfdispatchflag.cxx +++ b/writerfilter/source/rtftok/rtfdispatchflag.cxx @@ -461,9 +461,12 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) } break; case RTF_PARD: + { if (m_bHadPicture) dispatchSymbol(RTF_PAR); // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table. + // It should not reset the paragraph style, either, so remember the old paragraph style. + RTFValue::Pointer_t pOldStyle = m_aStates.top().aParagraphSprms.find(NS_ooxml::LN_CT_PPrBase_pStyle); m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms; m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes; @@ -476,13 +479,17 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { // We are still in a table. m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_inTbl, std::make_shared(1)); + if (m_bAfterCellBeforeRow && pOldStyle) + // And we still have the same paragraph style. + m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_pStyle, pOldStyle); // Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering. m_aStates.top().aParagraphSprms.set(NS_ooxml::LN_CT_PPrBase_tabs, std::make_shared()); } resetFrame(); - // Reset currently selected paragraph style as well. + // Reset currently selected paragraph style as well, unless we are in the special "after \cell, before \row" state. // By default the style with index 0 is applied. + if (!m_bAfterCellBeforeRow) { OUString const aName = getStyleName(0); // But only in case it's not a character style. @@ -499,6 +506,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) // Need to send paragraph properties again, if there will be any. m_bNeedPap = true; break; + } case RTF_SECTD: { m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms; diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx index 19040d06fd74..09b9b6c9c5ed 100644 --- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx +++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx @@ -174,6 +174,9 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) case RTF_CELL: case RTF_NESTCELL: { + if (nKeyword == RTF_CELL) + m_bAfterCellBeforeRow = true; + checkFirstRun(); if (m_bNeedPap) { @@ -230,6 +233,7 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) break; case RTF_ROW: { + m_bAfterCellBeforeRow = false; if (m_aStates.top().nTableRowWidthAfter > 0) { // Add fake cellx / cell, RTF equivalent of diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 1668d70f5c30..2150266930be 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -286,7 +286,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference const& x m_nCellxMax(0), m_nListPictureId(0), m_bIsNewDoc(!rMediaDescriptor.getUnpackedValueOrDefault("InsertMode", false)), - m_rMediaDescriptor(rMediaDescriptor) + m_rMediaDescriptor(rMediaDescriptor), + m_bAfterCellBeforeRow(false) { OSL_ASSERT(xInputStream.is()); m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, true)); diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 34ba2750a685..bcd2aa90d39e 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -650,6 +650,9 @@ private: bool m_bIsNewDoc; /// The media descriptor contains e.g. the base URL of the document. const utl::MediaDescriptor& m_rMediaDescriptor; + + /// Are we after a \cell, but before a \row? + bool m_bAfterCellBeforeRow; }; } // namespace rtftok } // namespace writerfilter -- cgit v1.2.3