diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-02-08 16:49:45 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-02-08 17:53:27 +0100 |
commit | ffe7fd5c3f3de474b201fbb1e25b8251cb13574d (patch) | |
tree | 9a2abf5e1324a6eea30038bfcee3c2b5da2f7d87 | |
parent | 741c1b6bb1d10ab217c084278cd8ad5263a1a323 (diff) |
tdf#91920 sw page gutter margin: handle mirrored margins
- SwPageDesc::Mirror: generate "right gutter margin" from gutter margin
for mirrored pages, we just lost the gutter margin here previously
- SwBorderAttrs::CalcRight: handle right gutter margin, so gutter
increases the right margin, not the left margin on mirrored pages
- lcl_CalcBorderRect: similar to left and top margins, compensate for
right margin gutter as well, so borders are independent from the gutter
margin (Word compat)
Change-Id: Ie4d3459ab6edcc60b20c2fed08dbf45060ca9828
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110585
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | editeng/source/items/frmitems.cxx | 5 | ||||
-rw-r--r-- | include/editeng/lrspitem.hxx | 4 | ||||
-rw-r--r-- | sw/qa/core/layout/layout.cxx | 31 | ||||
-rw-r--r-- | sw/source/core/layout/frmtool.cxx | 13 | ||||
-rw-r--r-- | sw/source/core/layout/pagedesc.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/layout/paintfrm.cxx | 21 |
6 files changed, 69 insertions, 6 deletions
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx index c6b26c1c03a5..6e963e91cbaa 100644 --- a/editeng/source/items/frmitems.cxx +++ b/editeng/source/items/frmitems.cxx @@ -290,6 +290,7 @@ SvxLRSpaceItem::SvxLRSpaceItem( const sal_uInt16 nId ) : nLeftMargin ( 0 ), nRightMargin ( 0 ), m_nGutterMargin(0), + m_nRightGutterMargin(0), nPropFirstLineOffset( 100 ), nPropLeftMargin( 100 ), nPropRightMargin( 100 ), @@ -310,6 +311,7 @@ SvxLRSpaceItem::SvxLRSpaceItem( const tools::Long nLeft, const tools::Long nRigh nLeftMargin ( nLeft ), nRightMargin ( nRight ), m_nGutterMargin(0), + m_nRightGutterMargin(0), nPropFirstLineOffset( 100 ), nPropLeftMargin( 100 ), nPropRightMargin( 100 ), @@ -484,6 +486,7 @@ bool SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const nFirstLineOffset == rOther.GetTextFirstLineOffset() && nTxtLeft == rOther.GetTextLeft() && m_nGutterMargin == rOther.GetGutterMargin() && + m_nRightGutterMargin == rOther.GetRightGutterMargin() && nLeftMargin == rOther.GetLeft() && nRightMargin == rOther.GetRight() && nPropFirstLineOffset == rOther.GetPropTextFirstLineOffset() && @@ -608,6 +611,8 @@ void SvxLRSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRightMargin"), BAD_CAST(OString::number(nRightMargin).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nGutterMargin"), BAD_CAST(OString::number(m_nGutterMargin).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightGutterMargin"), + BAD_CAST(OString::number(m_nRightGutterMargin).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropFirstLineOffset"), BAD_CAST(OString::number(nPropFirstLineOffset).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLeftMargin"), BAD_CAST(OString::number(nPropLeftMargin).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropRightMargin"), BAD_CAST(OString::number(nPropRightMargin).getStr())); diff --git a/include/editeng/lrspitem.hxx b/include/editeng/lrspitem.hxx index 9b3ec7734a8e..0510ee47d521 100644 --- a/include/editeng/lrspitem.hxx +++ b/include/editeng/lrspitem.hxx @@ -53,6 +53,8 @@ class EDITENG_DLLPUBLIC SvxLRSpaceItem final : public SfxPoolItem tools::Long nRightMargin; // The unproblematic right edge /// The amount of extra space added to the left margin. tools::Long m_nGutterMargin; + /// The amount of extra space added to the right margin, on mirrored pages. + tools::Long m_nRightGutterMargin; sal_uInt16 nPropFirstLineOffset, nPropLeftMargin, nPropRightMargin; short nFirstLineOffset; // First-line indent _always_ relative to nTxtLeft @@ -120,6 +122,8 @@ public: { nFirstLineOffset = nValue; } void SetGutterMargin(const tools::Long nGutterMargin) { m_nGutterMargin = nGutterMargin; } tools::Long GetGutterMargin() const { return m_nGutterMargin; } + void SetRightGutterMargin(const tools::Long nRightGutterMargin) { m_nRightGutterMargin = nRightGutterMargin; } + tools::Long GetRightGutterMargin() const { return m_nRightGutterMargin; } void dumpAsXml(xmlTextWriterPtr pWriter) const override; virtual boost::property_tree::ptree dumpAsJSON() const override; diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx index ebf7f816b918..a9a738f26e1d 100644 --- a/sw/qa/core/layout/layout.cxx +++ b/sw/qa/core/layout/layout.cxx @@ -9,6 +9,8 @@ #include <swmodeltestbase.hxx> +#include <com/sun/star/style/PageStyleLayout.hpp> + #include <vcl/gdimtf.hxx> #include <svx/svdpage.hxx> @@ -326,6 +328,35 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testGutterTopMargin) CPPUNIT_ASSERT_EQUAL(nGutterTwips, nNewTop - nOldTop); } +CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testGutterMirrorMargin) +{ + SwDoc* pDoc = createSwDoc(); + SwDocShell* pDocShell = pDoc->GetDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->InsertPageBreak(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + SwFrame* pPage = pLayout->GetLower(); + tools::Long nOldLeft = pPage->getFramePrintArea().Left(); + SwFrame* pPage2 = pPage->GetNext(); + tools::Long nOldRight = pPage2->getFramePrintArea().Right(); + + uno::Reference<beans::XPropertySet> xStandard(getStyles("PageStyles")->getByName("Standard"), + uno::UNO_QUERY); + xStandard->setPropertyValue("PageStyleLayout", uno::makeAny(style::PageStyleLayout_MIRRORED)); + sal_Int32 nGutterMm100 = 2000; + xStandard->setPropertyValue("GutterMargin", uno::makeAny(nGutterMm100)); + + tools::Long nNewLeft = pPage->getFramePrintArea().Left(); + tools::Long nGutterTwips = convertMm100ToTwip(nGutterMm100); + CPPUNIT_ASSERT_EQUAL(nGutterTwips, nNewLeft - nOldLeft); + tools::Long nNewRight = pPage2->getFramePrintArea().Right(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1134 + // - Actual : 0 + // i.e. the gutter was missing on the second, mirrored page. + CPPUNIT_ASSERT_EQUAL(nGutterTwips, nOldRight - nNewRight); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 0cac4ad2ca96..baf24ba82a96 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -2263,6 +2263,19 @@ tools::Long SwBorderAttrs::CalcRight( const SwFrame* pCaller ) const nRight += static_cast<const SwTextFrame*>(pCaller)->GetTextNodeForParaProps()->GetLeftMarginWithNum(); } + if (pCaller->IsPageFrame() && m_rLR) + { + const auto pPageFrame = static_cast<const SwPageFrame*>(pCaller); + bool bGutterAtTop = pPageFrame->GetFormat()->getIDocumentSettingAccess().get( + DocumentSettingId::GUTTER_AT_TOP); + if (!bGutterAtTop) + { + // Decrease the print area: the right space is the sum of right and right gutter + // margins. + nRight += m_rLR->GetRightGutterMargin(); + } + } + return nRight; } diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx index 3fd05a3d70ae..3672a02bd9df 100644 --- a/sw/source/core/layout/pagedesc.cxx +++ b/sw/source/core/layout/pagedesc.cxx @@ -151,6 +151,7 @@ void SwPageDesc::Mirror() const SvxLRSpaceItem &rLR = m_Master.GetLRSpace(); aLR.SetLeft( rLR.GetRight() ); aLR.SetRight( rLR.GetLeft() ); + aLR.SetRightGutterMargin(rLR.GetGutterMargin()); SfxItemSet aSet( *m_Master.GetAttrSet().GetPool(), m_Master.GetAttrSet().GetRanges() ); diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index e941c68988a9..dd3def6e8dc9 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -1292,19 +1292,28 @@ static void lcl_CalcBorderRect( SwRect &rRect, const SwFrame *pFrame, if (pFrame->IsPageFrame() && rAttrs.GetLRSpace()) { tools::Long nGutterMargin = rAttrs.GetLRSpace()->GetGutterMargin(); + tools::Long nRightGutterMargin = rAttrs.GetLRSpace()->GetRightGutterMargin(); const auto pPageFrame = static_cast<const SwPageFrame*>(pFrame); bool bGutterAtTop = pPageFrame->GetFormat()->getIDocumentSettingAccess().get( DocumentSettingId::GUTTER_AT_TOP); - if (nGutterMargin && !bGutterAtTop) - { - // Paint the left border based on the left margin, ignoring the gutter margin. - (rRect.*fnRect->fnSubLeft)(nGutterMargin); - } - else if (nGutterMargin) + if (bGutterAtTop) { // Paint the top border based on the top margin, ignoring the gutter margin. (rRect.*fnRect->fnSubTop)(nGutterMargin); } + else + { + if (nGutterMargin) + { + // Paint the left border based on the left margin, ignoring the gutter margin. + (rRect.*fnRect->fnSubLeft)(nGutterMargin); + } + if (nRightGutterMargin) + { + // Paint the right border based on the right margin, ignoring the gutter margin. + (rRect.*fnRect->fnAddRight)(nRightGutterMargin); + } + } } const SvxBoxItem &rBox = rAttrs.GetBox(); |