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()));
     }

Reply via email to