From 9d4674b99da973a8b4be6e30ae8cd8ae2e86e316 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 11 Feb 2022 18:28:42 +0100 Subject: sw: layout: fix overlapped table rows in --convert-to pdf If the document is loaded via UI, the first layout action is triggered from resizing the Window and the table is positioned properly on the first try. If the document is loaded via --convert-to, only getRendererCount() formats the content of the table, and positioning goes wrong. Somehow the 2 rows of the table in the fly end up on the same Y position, because when the text frame in the 1st row is formatted and grows from 0 to 230, the already-valid position of the cell frame in the 2nd row is not invalidated. This happens since the earliest version checked, OOo 3.4 beta. This fix is somewhat similar to commit 068c133ac41c97652909b88c432e3b73010efc3e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129851 Tested-by: Jenkins Reviewed-by: Michael Stahl (cherry picked from commit e7874c936dd1ff9b3423eb7477cbee2494535176) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129845 Reviewed-by: Thorsten Behrens (cherry picked from commit 06bb600ce3445abe095b8011ec7e66b33badb4ef) Change-Id: I3259c440265cfe40dc7731cb4830bfe2487acf38 --- sw/qa/extras/layout/data/table_cell_overlap.fodt | 161 +++++++++++++++++++++++ sw/qa/extras/layout/layout.cxx | 56 ++++++++ sw/source/core/layout/wsfrm.cxx | 4 + 3 files changed, 221 insertions(+) create mode 100644 sw/qa/extras/layout/data/table_cell_overlap.fodt diff --git a/sw/qa/extras/layout/data/table_cell_overlap.fodt b/sw/qa/extras/layout/data/table_cell_overlap.fodt new file mode 100644 index 000000000000..e9565054de88 --- /dev/null +++ b/sw/qa/extras/layout/data/table_cell_overlap.fodt @@ -0,0 +1,161 @@ + + + 2022-02-11T15:45:44.5250152262022-02-11T15:51:17.840027874PT5M32S4LibreOfficeDev/6.3.6.11$Linux_X86_64 LibreOffice_project/798c41960be08155f4f9734c6307615ab45c134e + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ONE: + + + + + TWO: + + + + + + + + + + diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 0bd25d45b4b6..8f6ca8a92580 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -3017,6 +3017,62 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf122607) "Portion", "Fax:"); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTableCellInvalidate) +{ + discardDumpedLayout(); + if (mxComponent.is()) + mxComponent->dispose(); + + OUString const pName("table_cell_overlap.fodt"); + + OUString const url(m_directories.getURLFromSrc(DATA_DIRECTORY) + pName); + + // note: must set Hidden property, so that SfxFrameViewWindow_Impl::Resize() + // does *not* forward initial VCL Window Resize and thereby triggers a + // layout which does not happen on soffice --convert-to pdf. + std::vector aFilterOptions = { + { beans::PropertyValue("Hidden", -1, uno::Any(true), beans::PropertyState_DIRECT_VALUE) }, + }; + + std::cout << pName << ":\n"; + + // inline the loading because currently properties can't be passed... + mxComponent = loadFromDesktop(url, "com.sun.star.text.TextDocument", + comphelper::containerToSequence(aFilterOptions)); + uno::Sequence props(comphelper::InitPropertySequence({ + { "FilterName", uno::Any(OUString("writer_pdf_Export")) }, + })); + utl::TempFile aTempFile; + uno::Reference xStorable(mxComponent, uno::UNO_QUERY); + xStorable->storeToURL(aTempFile.GetURL(), props); + + xmlDocPtr pXmlDoc = parseLayoutDump(); + // somehow these 2 rows overlapped in the PDF unless CalcLayout() runs + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/infos/bounds", "top", "6969"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/infos/bounds", "height", "231"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/infos/bounds", "top", + "6969"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/infos/bounds", "height", + "231"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds", + "top", "6969"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds", + "height", "231"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/infos/bounds", "top", "7200"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/infos/bounds", "height", "231"); + // this was 6969, causing the overlap + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/infos/bounds", "top", + "7200"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/infos/bounds", "height", + "231"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds", + "top", "7200"); + assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds", + "height", "231"); + + aTempFile.EnableKillingFile(); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf122607_regression) { discardDumpedLayout(); diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index b396b4f0f407..b7e5e3149403 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -2736,6 +2736,10 @@ SwTwips SwLayoutFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo ) if ( GetNext() ) { GetNext()->InvalidatePos_(); + if (GetNext()->IsRowFrame()) + { // also invalidate first cell + static_cast(GetNext())->Lower()->InvalidatePos_(); + } if ( GetNext()->IsContentFrame() ) GetNext()->InvalidatePage( pPage ); } -- cgit