sw/qa/filter/ww8/data/floattable-then-floattable.doc |binary sw/qa/filter/ww8/ww8.cxx | 23 +++++++++++++++++++ sw/source/filter/ww8/ww8par6.cxx | 17 ++++++++++++++ 3 files changed, 40 insertions(+)
New commits: commit 2529a44931a2646af6f8beeecd18abb710c6d2e5 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Jul 11 08:21:20 2023 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Jul 12 07:18:44 2023 +0200 sw floattable: make sure floattable after floattable gets own anch pos from DOC The bugdoc has 2 floating tables next to each other, which overlap in Writer, but not in Word. This looks quite similar to the DOCX case, which was solved in commit 01ad8ec4bb5425446e95dbada81de435646824b4 (sw floattable: fix lost tables around a floating table from DOCX, 2023-06-05). Fix the problem by improving SwWW8ImplReader::StartApo() so it inserts a fake paragraph when a floating table is immediately followed by a floating table. A similar case, floating table followed immediately by an inline table was already handled like this in WW8TabDesc::CreateSwTable(). Creating a reproducer document from scratch is quite tricky, as Word will also insert a fake paragraph on the first save of the DOC test file (so the doc model will be floattable-para-floattable-para) and manual edit of binary DOC files is also not easy. So the compromise is that the testcase file has 2 floating tables anchored to the same paragraph, but they don't overlap visually, while they do overlap in the original, internal bugdoc. With this, finally the bnc#816603 DOC bugdoc renders without overlaps, which was the case before my multi-page floating table changes. Change-Id: Ib1b4c7c80833db5a7bde38092c8c3ed6fd1d2462 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154290 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 663db89378aa1f0425e795ef5d471f134e658dc4) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154262 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/filter/ww8/data/floattable-then-floattable.doc b/sw/qa/filter/ww8/data/floattable-then-floattable.doc new file mode 100644 index 000000000000..6e694140740b Binary files /dev/null and b/sw/qa/filter/ww8/data/floattable-then-floattable.doc differ diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx index d7af2b675f24..68bbc28fcfc3 100644 --- a/sw/qa/filter/ww8/ww8.cxx +++ b/sw/qa/filter/ww8/ww8.cxx @@ -387,6 +387,29 @@ CPPUNIT_TEST_FIXTURE(Test, testDOCVerticalFlyOffset) // Page 2 starts with an inline table: CPPUNIT_ASSERT(pTable2->IsTabFrame()); } + +CPPUNIT_TEST_FIXTURE(Test, testFloattableThenFloattable) +{ + // Given a document that contains a floating table, immediately followed by an other floating + // table: + // When importing the document & laying it out: + createSwDoc("floattable-then-floattable.doc"); + calcLayout(); + + // Then make sure that the two floating table has different anchors: + SwDoc* pDoc = getSwDoc(); + auto& rFlys = *pDoc->GetSpzFrameFormats(); + auto pFly1 = rFlys[0]; + SwNodeOffset nFly1Anchor = pFly1->GetAttrSet().GetAnchor().GetAnchorContentNode()->GetIndex(); + auto pFly2 = rFlys[1]; + SwNodeOffset nFly2Anchor = pFly2->GetAttrSet().GetAnchor().GetAnchorContentNode()->GetIndex(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 42 + // - Actual : 41 + // i.e. the two anchor positions were the same instead of first anchor followed by the second + // anchor. + CPPUNIT_ASSERT_EQUAL(nFly1Anchor + 1, nFly2Anchor); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx index ca3a2ed1f101..0043678affb3 100644 --- a/sw/source/filter/ww8/ww8par6.cxx +++ b/sw/source/filter/ww8/ww8par6.cxx @@ -2516,6 +2516,23 @@ bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo, const WW8_TablePos *p if (pTabPos) { + if (m_xFormatOfJustInsertedApo) + { + // We just inserted a floating table and we'll insert a next one. + SwFrameFormat* pFormat = m_xFormatOfJustInsertedApo->GetFormat(); + if (pFormat) + { + const SwNode* pAnchorNode = pFormat->GetAnchor().GetAnchorNode(); + SwPosition* pPoint = m_pPaM->GetPoint(); + if (pAnchorNode && *pAnchorNode == pPoint->GetNode()) + { + // The two fly frames would have the same anchor position, leading to + // potentially overlapping text, prevent that. + AppendTextNode(*pPoint); + } + } + } + // Map a positioned table to a split fly. aFlySet.Put(SwFormatFlySplit(true)); }