summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-03-01 10:37:49 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-03-01 20:56:03 +0100
commitebceee31d92f04b58e795d02a26f62b717c47737 (patch)
tree137df2f7e371a7183de62f2b62ecc77462e7dc4e
parent7def8c3cd8a1d9b4df2478210055b06382e6d493 (diff)
tdf#140342 sw layout: remove explicit gutter handling when positioning borders
Word has two modes the specify border positions: the distance can be measured from the edge of the page or from text. Similar to how documents that have page borders but no gutter, page page border + gutter documents should be always measured "from text" by the layout. "From page" should be a concern for Word filters. "From page" was already working -- fix "from text" by changing the layout to do "from text" and then extending DOCX import/export to handle gutter while handling the "from page" page borders. This also requires allowing nominally negative top margins, because we want to have the gutter unchanged, but the border might want to be on the gutter area, which is only possible with a negative top margin. Change-Id: I7f2c9943357359e76cb554cb2a65b93a492e694b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111735 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--editeng/source/items/frmitems.cxx2
-rw-r--r--sw/qa/core/layout/layout.cxx30
-rw-r--r--sw/source/core/layout/paintfrm.cxx27
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx9
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx26
-rw-r--r--writerfilter/source/dmapper/PropertyMap.hxx3
6 files changed, 65 insertions, 32 deletions
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index 45cd825eab54..d010089b3052 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -725,7 +725,7 @@ bool SvxULSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
}
break;
case MID_UP_MARGIN :
- if(!(rVal >>= nVal) || nVal < 0)
+ if(!(rVal >>= nVal))
return false;
SetUpper(static_cast<sal_uInt16>(bConvert ? convertMm100ToTwip(nVal) : nVal));
break;
diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index a9a738f26e1d..7cd052725639 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -357,6 +357,36 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testGutterMirrorMargin)
CPPUNIT_ASSERT_EQUAL(nGutterTwips, nOldRight - nNewRight);
}
+CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testGutterMarginPageBorder)
+{
+// FIXME this is 3369 on macOS -- calculate this number dynamically?
+#if !defined(MACOSX)
+ // Given a document with a non-0 gutter margin.
+ SwDoc* pDoc = createSwDoc();
+ uno::Reference<beans::XPropertySet> xStandard(getStyles("PageStyles")->getByName("Standard"),
+ uno::UNO_QUERY);
+ sal_Int32 nGutterMm100 = 2000;
+ xStandard->setPropertyValue("GutterMargin", uno::makeAny(nGutterMm100));
+
+ // When setting a left border.
+ table::BorderLine2 aBorder;
+ aBorder.LineWidth = 2;
+ aBorder.OuterLineWidth = 2;
+ xStandard->setPropertyValue("LeftBorder", uno::makeAny(aBorder));
+
+ // Then make sure border is at the left edge of the text area.
+ SwDocShell* pShell = pDoc->GetDocShell();
+ std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
+ MetafileXmlDump dumper;
+ xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2565
+ // - Actual : 1425
+ // Where 2565 is close to the left edge of the text area (2553).
+ assertXPath(pXmlDoc, "//polyline[@style='solid']/point[1]", "x", "2565");
+#endif
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index ef69c5ff81ba..b3c940b87cea 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1289,33 +1289,6 @@ static void lcl_CalcBorderRect( SwRect &rRect, const SwFrame *pFrame,
SwRectFn fnRect = pFrame->IsVertical() ? ( pFrame->IsVertLR() ? (pFrame->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
- 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 (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();
const bool bTop = 0 != (pFrame->*fnRect->fnGetTopMargin)();
if ( bTop )
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index b5a793ec196f..67d6aa748df4 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6743,6 +6743,15 @@ void DocxAttributeOutput::SectionPageBorders( const SwFrameFormat* pFormat, cons
if (aGlue.HasFooter())
aMargins.nBottom = aGlue.dyaHdrBottom;
+ if (pFormat->GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP))
+ {
+ aMargins.nTop += pFormat->GetLRSpace().GetGutterMargin();
+ }
+ else
+ {
+ aMargins.nLeft += pFormat->GetLRSpace().GetGutterMargin();
+ }
+
aOutputBorderOptions.pDistances = std::make_shared<editeng::WordBorderDistances>();
editeng::BorderDistancesToWord(rBox, aMargins, *aOutputBorderOptions.pDistances);
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 50af6463fcf1..f7a8f800d7d0 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -620,10 +620,10 @@ void SectionPropertyMap::ApplyBorderToPageStyles( DomainMapper_Impl& rDM_Impl,
nLineWidth = m_oBorderLines[nBorder]->LineWidth;
if ( xFirst.is() )
SetBorderDistance( xFirst, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
- m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth );
+ m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth, rDM_Impl );
if ( xSecond.is() )
SetBorderDistance( xSecond, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
- m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth );
+ m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth, rDM_Impl );
}
}
@@ -655,7 +655,8 @@ void SectionPropertyMap::SetBorderDistance( const uno::Reference< beans::XProper
PropertyIds eDistId,
sal_Int32 nDistance,
BorderOffsetFrom eOffsetFrom,
- sal_uInt32 nLineWidth )
+ sal_uInt32 nLineWidth,
+ DomainMapper_Impl& rDM_Impl )
{
if (!xStyle.is())
return;
@@ -667,6 +668,25 @@ void SectionPropertyMap::SetBorderDistance( const uno::Reference< beans::XProper
editeng::BorderDistanceFromWord(eOffsetFrom == BorderOffsetFrom::Edge, nMargin, nDistance,
nLineWidth);
+ if (eOffsetFrom == BorderOffsetFrom::Edge)
+ {
+ uno::Any aGutterMargin = xStyle->getPropertyValue( "GutterMargin" );
+ sal_Int32 nGutterMargin = 0;
+ aGutterMargin >>= nGutterMargin;
+
+ if (eMarginId == PROP_LEFT_MARGIN && !rDM_Impl.GetSettingsTable()->GetGutterAtTop())
+ {
+ nMargin -= nGutterMargin;
+ nDistance += nGutterMargin;
+ }
+
+ if (eMarginId == PROP_TOP_MARGIN && rDM_Impl.GetSettingsTable()->GetGutterAtTop())
+ {
+ nMargin -= nGutterMargin;
+ nDistance += nGutterMargin;
+ }
+ }
+
// Change the margins with the border distance
uno::Reference< beans::XMultiPropertySet > xMultiSet( xStyle, uno::UNO_QUERY_THROW );
uno::Sequence<OUString> aProperties { sMarginName, sBorderDistanceName };
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx
index f8c976abd388..718c946234fd 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -316,7 +316,8 @@ private:
PropertyIds eDistId,
sal_Int32 nDistance,
BorderOffsetFrom eOffsetFrom,
- sal_uInt32 nLineWidth );
+ sal_uInt32 nLineWidth,
+ DomainMapper_Impl& rDM_Impl );
// Determines if conversion of a given floating table is wanted or not.
bool FloatingTableConversion( const DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo );