sw/qa/core/objectpositioning/objectpositioning.cxx | 48 ++++++++++++ sw/source/core/objectpositioning/anchoredobjectposition.cxx | 5 + 2 files changed, 52 insertions(+), 1 deletion(-)
New commits: commit 016b2f2f9194a4a1997d0e7bb51bbd1b10bc27ec Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Apr 30 08:22:03 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Apr 30 09:45:40 2024 +0200 tdf#160833 sw DoNotMirrorRtlDrawObjs: add layout In case this flag is active (intended for DOCX files), then don't automatically mirror the position of drawing objects, just because they are anchored in an RTL text node. Change-Id: Ie743d94ecb511d7de89e8e1e8303896370ce58c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166883 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx b/sw/qa/core/objectpositioning/objectpositioning.cxx index 717d63ded052..60a14c90547a 100644 --- a/sw/qa/core/objectpositioning/objectpositioning.cxx +++ b/sw/qa/core/objectpositioning/objectpositioning.cxx @@ -24,6 +24,10 @@ #include <anchoredobject.hxx> #include <flyfrm.hxx> #include <frmatr.hxx> +#include <IDocumentSettingAccess.hxx> +#include <view.hxx> +#include <fmtanchr.hxx> +#include <fmtfsize.hxx> #include <vcl/scheduler.hxx> @@ -418,6 +422,50 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableOverlapCell) CPPUNIT_ASSERT(pPage1); CPPUNIT_ASSERT(!pPage1->GetNext()); } + +CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjsLayout) +{ + // Given a document with an RTL paragraph, Word-style compat flag is enabled: + createSwDoc(); + SwDoc* pDoc = getSwDoc(); + auto& rIDSA = pDoc->getIDocumentSettingAccess(); + rIDSA.set(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, true); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + SwView& rView = pWrtShell->GetView(); + SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aSet(rView.GetPool()); + SvxFrameDirectionItem aDirection(SvxFrameDirection::Horizontal_RL_TB, RES_FRAMEDIR); + aSet.Put(aDirection); + pWrtShell->SetAttrSet(aSet, SetAttrMode::DEFAULT, nullptr, /*bParagraphSetting=*/true); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPageFrame = pLayout->Lower()->DynCastPageFrame(); + SwFrame* pBodyFrame = pPageFrame->GetLower(); + + // When inserting a graphic on the middle of the right margin: + SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>); + SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR); + aFrameSet.Put(aAnchor); + // Default margin is 1440, this is 1440/2. + SwFormatFrameSize aSize(SwFrameSize::Fixed, 720, 720); + aFrameSet.Put(aSize); + // This is 1440/4. + SwFormatHoriOrient aOrient(pBodyFrame->getFrameArea().Right() + 360); + aFrameSet.Put(aOrient); + Graphic aGrf; + pWrtShell->SwFEShell::Insert(OUString(), OUString(), &aGrf, &aFrameSet); + + // Then make sure that the image is on the right margin: + SwTwips nBodyRight = pBodyFrame->getFrameArea().Right(); + CPPUNIT_ASSERT(pPageFrame->GetSortedObjs()); + const SwSortedObjs& rPageObjs = *pPageFrame->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size()); + const SwAnchoredObject* pAnchored = rPageObjs[0]; + Point aAnchoredCenter = pAnchored->GetDrawObj()->GetLastBoundRect().Center(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected greater than: 11389 + // - Actual : 643 + // i.e. the graphic was on the left margin, not on the right margin. + CPPUNIT_ASSERT_GREATER(nBodyRight, aAnchoredCenter.getX()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx index ab35ae7af738..4af3af542b27 100644 --- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx @@ -852,7 +852,10 @@ SwTwips SwAnchoredObjectPosition::CalcRelPosX( if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE ) { // 'manual' horizontal position - const bool bR2L = rAnchorFrame.IsRightToLeft(); + const IDocumentSettingAccess& rIDSA = mpFrameFormat->getIDocumentSettingAccess(); + // If compat flag is active, then disable automatic mirroring for RTL. + bool bMirrorRtlDrawObjs = !rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS); + const bool bR2L = rAnchorFrame.IsRightToLeft() && bMirrorRtlDrawObjs; if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient ) { if( bR2L )