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 e316524d9fe7720ed0a5eaf94999e54d211a8395
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Jan 23 08:08:29 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jan 23 08:37:33 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

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)

Reply via email to