sw/CppunitTest_sw_writerfilter_filter.mk                                |   59 
++++++++++
 sw/Module_sw.mk                                                         |    1 
 sw/qa/core/objectpositioning/objectpositioning.cxx                      |   48 
++++++++
 sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx                 |   57 
+++++++++
 sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx |binary
 sw/source/core/objectpositioning/anchoredobjectposition.cxx             |    5 
 writerfilter/source/filter/WriterFilter.cxx                             |    1 
 7 files changed, 170 insertions(+), 1 deletion(-)

New commits:
commit 7d75210808f8d8be7ee226031ae27b724cfcfbcc
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu May 2 08:42:25 2024 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon May 6 10:24:00 2024 +0200

    tdf#160833 DOCX import: use the DoNotMirrorRtlDrawObjs compat flag
    
    The bugdoc has a shape which should be on the right page margin, but it
    was on the left page margin.
    
    Use the new compat flag to have a layout that matches Word.
    
    This way we don't need to unmap the tweaked position at export time (a
    limitation that the DOC filter has).
    
    Change-Id: I38dfae370f275d9f0897198e7b0569f2d91dd352
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166993
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167044

diff --git a/sw/CppunitTest_sw_writerfilter_filter.mk 
b/sw/CppunitTest_sw_writerfilter_filter.mk
new file mode 100644
index 000000000000..ad61c66f1ed4
--- /dev/null
+++ b/sw/CppunitTest_sw_writerfilter_filter.mk
@@ -0,0 +1,59 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_writerfilter_filter,\
+       boost_headers \
+       libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_writerfilter_filter, \
+    sw/qa/writerfilter/cppunittests/filter/WriterFilter \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_writerfilter_filter, \
+    basegfx \
+    comphelper \
+    cppu \
+    cppuhelper \
+    oox \
+    sal \
+    subsequenttest \
+    test \
+    unotest \
+    utl \
+    tl \
+    vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_writerfilter_filter))
+$(eval $(call gb_CppunitTest_use_vcl,sw_writerfilter_filter))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_writerfilter_filter,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_writerfilter_filter,\
+       officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_writerfilter_filter))
+
+# we need to explicitly depend on library sw_writerfilter because it is not 
implied
+# by a link relation
+$(call gb_CppunitTest_get_target,sw_writerfilter_filter) : $(call 
gb_Library_get_target,sw_writerfilter)
+
+ifneq ($(filter MORE_FONTS,$(BUILD_TYPE)),)
+$(eval $(call 
gb_CppunitTest_set_non_application_font_use,sw_writerfilter_filter,abort))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 7d5679e52f3c..7556ecf33778 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -168,6 +168,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
     CppunitTest_sw_a11y \
     CppunitTest_sw_core_theme \
     CppunitTest_sw_pdf_test \
+    CppunitTest_sw_writerfilter_filter \
 ))
 
 ifneq ($(DISABLE_GUI),TRUE)
diff --git a/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx 
b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
new file mode 100644
index 000000000000..10b8cab57a45
--- /dev/null
+++ b/sw/qa/writerfilter/cppunittests/filter/WriterFilter.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/unoapixml_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/ColorMode.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/qa/XDumper.hpp>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for sw/source/writerfilter/filter/WriterFilter.cxx.
+class Test : public UnoApiXmlTest
+{
+public:
+    Test()
+        : UnoApiXmlTest("/sw/qa/writerfilter/cppunittests/filter/data/")
+    {
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjs)
+{
+    // Given a document with a shape, anchored in an RTL paragraph:
+    // When loading that document:
+    loadFromFile(u"draw-obj-rtl-no-mirror.docx");
+
+    // Then make sure the shape is on the right margin:
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    css::uno::Reference<qa::XDumper> xDumper(xModel->getCurrentController(), 
uno::UNO_QUERY);
+    OString aDump = xDumper->dump("layout").toUtf8();
+    auto pCharBuffer = reinterpret_cast<const xmlChar*>(aDump.getStr());
+    xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer));
+    sal_Int32 nBodyRight = getXPath(pXmlDoc, "//body/infos/bounds"_ostr, 
"right"_ostr).toInt32();
+    sal_Int32 nShapeLeft
+        = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds"_ostr, 
"left"_ostr).toInt32();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected greater than: 11083
+    // - Actual  : 722
+    // i.e. the shape was on the left margin.
+    CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx 
b/sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx
new file mode 100644
index 000000000000..7988384b2c90
Binary files /dev/null and 
b/sw/qa/writerfilter/cppunittests/filter/data/draw-obj-rtl-no-mirror.docx differ
diff --git a/writerfilter/source/filter/WriterFilter.cxx 
b/writerfilter/source/filter/WriterFilter.cxx
index 8935f462636f..44efc0c42cfc 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -331,6 +331,7 @@ void WriterFilter::setTargetDocument(const 
uno::Reference<lang::XComponent>& xDo
     xSettings->setPropertyValue("DropCapPunctuation", uno::Any(true));
     // rely on default for HyphenateURLs=false
     // rely on default for 
APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true
+    xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
 }
 
 void WriterFilter::setSourceDocument(const uno::Reference<lang::XComponent>& 
xDoc)
commit 3fd55489b73fc8fd03a5271567153c9852986e39
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Apr 30 08:22:03 2024 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon May 6 10:23:54 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
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167043

diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx 
b/sw/qa/core/objectpositioning/objectpositioning.cxx
index bf560cbdaf90..a1805bf4508e 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>
 
 namespace
 {
@@ -404,6 +408,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 )

Reply via email to