tdf#160984 sw continuous endnotes: fix the endnote separator position

See <https://bugs.documentfoundation.org/attachment.cgi?id=194306>, the
total height of the endnote separator is now correct, but the
distribution of upper space, line width, lower space is still bad, when
compared to Word.

Our model is 2 spacings and a line width, while Word seems to simply
split the amount of available space: 60% goes above the separator and
the rest goes below.

Fix the problem by breaking up the monster expression for the separator
rectangle in SwFootnoteContFrame::PaintLine(), and then the compat +
horizontal case can do the 60% spacing in the Word compat mode.

The width of the separator is still not correct.

Change-Id: Ic065c138041892225b3c1b7d4bd64d4f1c625611
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167990
Reviewed-by: Miklos Vajna <[email protected]>
Tested-by: Jenkins
diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index b599064..8e7154d 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -158,6 +158,26 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableMergedBorder)
    // bottom border.
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aHorizontalBorderEnds.size());
}

CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition)
{
    // Given a document with a Word-style endnote separator:
    createSwDoc("inline-endnote-position.docx");
    SwDocShell* pDocShell = getSwDocShell();

    // When rendering that document:
    std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();

    // Then make sure the separator upper spacing is 60% of all space, matching Word:
    MetafileXmlDump aDumper;
    xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
    auto nEndnoteSeparatorY = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, "y"_ostr).toInt32();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 2164
    // - Actual  : 2060
    // i.e. the upper spacing was too low.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2164), nEndnoteSeparatorY);
}
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 8c0f4f8..b139a75 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5788,13 +5788,26 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
            assert(false);
    }
    SwTwips nLineWidth = rInf.GetLineWidth();
    const SwRect aLineRect = aRectFnSet.IsVert() ?
        SwRect( Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
                      nX), Size( nLineWidth, nWidth ) )
            : SwRect( Point( nX, getFrameArea().Pos().Y() + rInf.GetTopDist() ),
                            Size( nWidth, rInf.GetLineWidth()));
    if ( aLineRect.HasArea() && rInf.GetLineStyle() != SvxBorderLineStyle::NONE)
        PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor(),
    std::optional<SwRect> oLineRect;
    if (aRectFnSet.IsVert())
    {
        oLineRect.emplace(Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
                      nX), Size( nLineWidth, nWidth ) );
    }
    else
    {
        Point aPoint(nX, getFrameArea().Pos().Y() + rInf.GetTopDist());
        const IDocumentSettingAccess& rIDSA = GetFormat()->getIDocumentSettingAccess();
        if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
        {
            // Word style: instead of fixed value, upper spacing is 60% of all space.
            auto nPrintAreaTop = static_cast<double>(getFramePrintArea().Top());
            aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
        }
        oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
    }
    if ( oLineRect->HasArea() && rInf.GetLineStyle() != SvxBorderLineStyle::NONE)
        PaintBorderLine( rRect, *oLineRect , pPage, &rInf.GetLineColor(),
                rInf.GetLineStyle() );
}