writerfilter/qa/cppunittests/rtftok/data/center-after-page.rtf | 10 ++++ writerfilter/qa/cppunittests/rtftok/rtfdispatchsymbol.cxx | 24 ++++++++++ writerfilter/source/rtftok/rtfdispatchsymbol.cxx | 7 ++ 3 files changed, 40 insertions(+), 1 deletion(-)
New commits: commit 2bd2089467a4db5fd5fc59d00d6687ccb52b4548 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Jan 23 08:08:29 2023 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jan 23 10:55:10 2023 +0000 tdf#153046 RTF import: fix lost paragraph alignment after page break The bugdoc had a page break, and the paragraph after the page break is meant to be centered, but it was aligned to the left. This went wrong with 3c610336a58f644525d5e4d2566c35eee6f7a618 (tdf#148214 RTF import: avoid fake paragraph for \page when possible, 2022-09-08), previously we emitted fake paragraphs in most cases, which allowed simpler handling of pending paragraph properties. Now we have to be careful to call checkNeedPap() exactly when parBreak() in called, otherwise checkNeedPap() sends paragraph properties, and paragraph properties noticed later will be lost. Fix the problem by not sending paragraph properties unconditionally, only in case we send the fake paragraph break as well. This continues to allow the unwanted fake paragraphs in some cases, but it restores the lost paragraph properties, since m_bNeedPap will be still true after we hit the first character in the last paragraph, so \qc is sent to dmapper. Note that we don't have to check m_bNeedPap before checkNeedPap(), as it returns early already when m_bNeedPap is false. Change-Id: I683d42208072a84fe578e397ac3e29585da5aa89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145990 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit e316524d9fe7720ed0a5eaf94999e54d211a8395) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145945 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/writerfilter/qa/cppunittests/rtftok/data/center-after-page.rtf b/writerfilter/qa/cppunittests/rtftok/data/center-after-page.rtf new file mode 100644 index 000000000000..c4713906ed4c --- /dev/null +++ b/writerfilter/qa/cppunittests/rtftok/data/center-after-page.rtf @@ -0,0 +1,10 @@ +{\rtf1 +{\stylesheet +{\s20\qc Title;} +} +\paperw11908\paperh8833 +\plain\plain +first page\par +\ql\par +\page\pard\s20\qc second page\par +} diff --git a/writerfilter/qa/cppunittests/rtftok/rtfdispatchsymbol.cxx b/writerfilter/qa/cppunittests/rtftok/rtfdispatchsymbol.cxx index 25e87099abe7..fa491121656a 100644 --- a/writerfilter/qa/cppunittests/rtftok/rtfdispatchsymbol.cxx +++ b/writerfilter/qa/cppunittests/rtftok/rtfdispatchsymbol.cxx @@ -10,6 +10,8 @@ #include <test/unoapi_test.hxx> #include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> using namespace ::com::sun::star; @@ -40,6 +42,28 @@ CPPUNIT_TEST_FIXTURE(Test, testPage) // paragraphs, not 2. CPPUNIT_ASSERT(!xParagraphs->hasMoreElements()); } + +CPPUNIT_TEST_FIXTURE(Test, testCenterAfterPage) +{ + // Given a file with a \page, followed by a \qc: + // When loading that file: + loadFromURL(u"center-after-page.rtf"); + + // Then make sure that the last paragraph is centered: + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xText(xTextDocument->getText(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParagraphs = xText->createEnumeration(); + xParagraphs->nextElement(); + xParagraphs->nextElement(); + uno::Reference<beans::XPropertySet> xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY); + sal_Int16 eActual{}; + CPPUNIT_ASSERT(xParagraph->getPropertyValue("ParaAdjust") >>= eActual); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 3 (CENTER) + // - Actual : 0 (LEFT) + // i.e. the paragraph alignment on the second page was lost. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(style::ParagraphAdjust_CENTER), eActual); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx index c884ba592f6a..9aa9a2ce4a2e 100644 --- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx +++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx @@ -391,7 +391,12 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) { bool bFirstRun = m_bFirstRun; checkFirstRun(); - checkNeedPap(); + if (bFirstRun || m_bNeedCr) + { + // Only send the paragraph properties early if we'll create a new paragraph in a + // bit anyway. + checkNeedPap(); + } sal_uInt8 const sBreak[] = { 0xc }; Mapper().text(sBreak, 1); if (bFirstRun || m_bNeedCr)