sw/qa/core/layout/data/endnote-cont-separator.docx |binary sw/qa/core/layout/paintfrm.cxx | 27 +++++++++++++++++++++ sw/source/core/inc/ftnfrm.hxx | 1 sw/source/core/layout/findfrm.cxx | 11 ++++++++ sw/source/core/layout/paintfrm.cxx | 16 ++++++++++-- 5 files changed, 52 insertions(+), 3 deletions(-)
New commits: commit 6450159e0e7c5fac9c998087e99f3fec602ff84d Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu May 30 15:23:45 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri May 31 17:01:33 2024 +0200 tdf#160984 sw continuous endnotes: fix the endnote continuation separator len See e.g. <https://bug-attachments.documentfoundation.org/attachment.cgi?id=194455>, one remaining difference for the Word vs Writer note separator is the length of the endnote continuation separator: it's body frame width in Word, shorter in Writer. Seems this is specific to the endnote continuation separator, i.e. normal endnote separator, footnote separator and footnote continuation separator is not affected. Additionally, it's really footnote vs endnote: if you put footnotes to the end of the document in Word, it still doesn't make the separator longer. Fix the problem by extending SwFootnoteContFrame::PaintLine() to handle this: if in Word compat mode, first note frame is a follow endnote frame, then paint the longer separator. The usual render test way via SfxObjectShell::GetPreviewMetaFile() only works with 1st pages and we want to assert the 2nd page here, so go via DocumentToGraphicRenderer, similar to how EPUBExportFilter::CreateMetafiles() does it. Change-Id: Ia0ba1138070f1a68f62ea6f5a6a85fbe0f76d482 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168263 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/layout/data/endnote-cont-separator.docx b/sw/qa/core/layout/data/endnote-cont-separator.docx new file mode 100644 index 000000000000..2e01a5c91354 Binary files /dev/null and b/sw/qa/core/layout/data/endnote-cont-separator.docx differ diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx index a5213c57d639..464979c988a6 100644 --- a/sw/qa/core/layout/paintfrm.cxx +++ b/sw/qa/core/layout/paintfrm.cxx @@ -10,6 +10,7 @@ #include <swmodeltestbase.hxx> #include <o3tl/string_view.hxx> +#include <svtools/DocumentToGraphicRenderer.hxx> #include <docsh.hxx> #include <unotxdoc.hxx> @@ -188,6 +189,32 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition) // i.e. the separator wasn't 2 inches long, but was shorter vs Word. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2880), nEndnoteSeparatorLength); } + +CPPUNIT_TEST_FIXTURE(Test, testEndnoteContSeparator) +{ + // Given a document with a Word-style endnote continuation separator: + createSwDoc("endnote-cont-separator.docx"); + + // When rendering page 2: + sal_Int32 nPage = 2; + DocumentToGraphicRenderer aRenderer(mxComponent, /*bSelectionOnly=*/false); + Size aSize = aRenderer.getDocumentSizeInPixels(nPage); + Graphic aGraphic = aRenderer.renderToGraphic(nPage, aSize, aSize, COL_WHITE, + /*bExtOutDevData=*/false); + auto& xMetaFile = const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile()); + + // Then make sure the separator length is correct: + MetafileXmlDump aDumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, xMetaFile); + auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, "x"_ostr).toInt32(); + auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, "x"_ostr).toInt32(); + sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - nEndnoteSeparatorStart; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 9360 (page print area width) + // - Actual : 2880 (2 inches) + // i.e. the separator was too short vs Word. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(9360), nEndnoteSeparatorLength); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx index 558c4941bf06..7331ef07d100 100644 --- a/sw/source/core/inc/ftnfrm.hxx +++ b/sw/source/core/inc/ftnfrm.hxx @@ -51,6 +51,7 @@ public: SwFootnoteContFrame( SwFrameFormat*, SwFrame* ); const SwFootnoteFrame* FindFootNote() const; + const SwFootnoteFrame* FindEndNote() const; static inline SwFootnoteFrame* AppendChained(SwFrame* pThis, bool bDefaultFormat); static inline SwFootnoteFrame* PrependChained(SwFrame* pThis, bool bDefaultFormat); diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index e83f4f8414a0..5f0cc8a0f256 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -698,6 +698,17 @@ const SwFootnoteFrame* SwFootnoteContFrame::FindFootNote() const return nullptr; } +const SwFootnoteFrame* SwFootnoteContFrame::FindEndNote() const +{ + auto pRet = static_cast<const SwFootnoteFrame*>(Lower()); + if (pRet && pRet->GetAttr()->GetFootnote().IsEndNote()) + { + return pRet; + } + + return nullptr; +} + const SwPageFrame* SwRootFrame::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const { const SwPageFrame* pRet = nullptr; diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 754495f2c8d4..c572585e597a 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -5826,12 +5826,22 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect, auto nPrintAreaTop = static_cast<double>(getFramePrintArea().Top()); aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6); - // Length is 2 inches, but don't paint outside the container frame. - nWidth = o3tl::convert(2, o3tl::Length::in, o3tl::Length::twip); - if (nWidth > nPrtWidth) + const SwFootnoteFrame* pEndnoteFrame = FindEndNote(); + bool bEndnoteContinuation = pEndnoteFrame && pEndnoteFrame->GetMaster(); + if (bEndnoteContinuation) { + // Endnote continuation separator is print area wide. nWidth = nPrtWidth; } + else + { + // Length is 2 inches, but don't paint outside the container frame. + nWidth = o3tl::convert(2, o3tl::Length::in, o3tl::Length::twip); + if (nWidth > nPrtWidth) + { + nWidth = nPrtWidth; + } + } } oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth())); }