[Libreoffice-commits] core.git: sw/source writerfilter/qa writerfilter/source

Daniel Arato (NISZ) (via logerrit) logerrit at kemper.freedesktop.org
Tue Oct 6 10:31:54 UTC 2020


 sw/source/core/unocore/unoframe.cxx                            |   17 +++++
 writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx     |   21 +++++++
 writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx                   |   30 ++++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx              |    6 +-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx              |   21 +++++++
 6 files changed, 94 insertions(+), 1 deletion(-)

New commits:
commit af4e5ee0f93c1ff442d08caed5c875f2b2c1fd43
Author:     Daniel Arato (NISZ) <arato.daniel at nisz.hu>
AuthorDate: Wed Sep 16 08:48:32 2020 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue Oct 6 12:31:04 2020 +0200

    tdf#97128 DOCX import: fix frame direction
    
    Frames used to be imported with zero rotation even if a w:textDirection
    tag explicitly called for a non-default orientation.
    
    I found no other solution to pass the incoming frame direction property
    on to the SwXFrame about to be created.
    
    1. If you put the property into the GetSectionContext(), it gets
    overwritten when the next w:pPr tag is parsed, so all three frames will
    end up having the same direction.
    
    2. If you put the property into the GetTopContextOfType(CONTEXT_PARAGRAPH)
    that context gets popped off the stack before control even gets to
    CheckUnregisteredFrameConversion().
    
    3. If you use PushStyleSheetProperties (which is bad in and of itself),
    the order will be messed up because the frames are not necessarily
    created in the same order as they are described in the file, so each
    frame gets a wrong frame direction in the end.
    
    Follow-up of commit 5a5597655a4bf12e4ca07c9c2b6f6221e217f080
    (tentative fix for fdo#30474# [DOCX rotated text import failure]).
    
    Change-Id: I6e3d68fe60c6e2a5b6684c65a964dd86d0168181
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103553
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>

diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index e8461393ea6f..a73b8e74fa95 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -1402,6 +1402,23 @@ void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any&
 {
     SolarMutexGuard aGuard;
     SwFrameFormat* pFormat = GetFrameFormat();
+
+    // Hack to support hidden property to transfer textDirection
+    if(rPropertyName == "FRMDirection")
+    {
+        if (pFormat)
+        {
+            SvxFrameDirectionItem aItem(SvxFrameDirection::Environment, RES_FRAMEDIR);
+            aItem.PutValue(_rValue, 0);
+            GetFrameFormat()->SetFormatAttr(aItem);
+        }
+        else if(IsDescriptor())
+        {
+            m_pProps->SetProperty(static_cast<sal_uInt16>(RES_FRAMEDIR), 0, _rValue);
+        }
+        return;
+    }
+
     const ::SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
 
     if (!pEntry)
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index 893db1607112..de63ec4084d9 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -14,6 +14,8 @@
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
 
 using namespace ::com::sun::star;
 
@@ -104,6 +106,25 @@ CPPUNIT_TEST_FIXTURE(Test, testNumberingRestartStyleParent)
     xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString("2."), xPara->getPropertyValue(aProp).get<OUString>());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFrameDirection)
+{
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "frame-direction.docx";
+    getComponent() = loadFromDesktop(aURL);
+
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xDrawPage = xDrawPageSupplier->getDrawPage();
+    uno::Reference<beans::XPropertySet> xFrame0(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFrame1(xDrawPage->getByIndex(1), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFrame2(xDrawPage->getByIndex(2), uno::UNO_QUERY);
+    // Without the accompanying fix in place, all of the following values would be text::WritingMode2::CONTEXT
+    CPPUNIT_ASSERT_EQUAL(text::WritingMode2::CONTEXT,
+                         xFrame0->getPropertyValue("WritingMode").get<sal_Int16>());
+    CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR,
+                         xFrame1->getPropertyValue("WritingMode").get<sal_Int16>());
+    CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL,
+                         xFrame2->getPropertyValue("WritingMode").get<sal_Int16>());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx b/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx
new file mode 100644
index 000000000000..33f191e80350
Binary files /dev/null and b/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index b3faa5682ab6..ca118c0f9c9b 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1501,6 +1501,35 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
         }
         break;
     case NS_ooxml::LN_CT_PPrBase_textDirection:
+        {
+            switch (nIntValue)
+            {
+                case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
+                {
+                    m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL);
+                    break;
+                }
+                case NS_ooxml::LN_Value_ST_TextDirection_btLr:
+                {
+                    m_pImpl->SetFrameDirection(text::WritingMode2::BT_LR);
+                    break;
+                }
+                case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
+                {
+                    m_pImpl->SetFrameDirection(text::WritingMode2::LR_TB);
+                    break;
+                }
+                case NS_ooxml::LN_Value_ST_TextDirection_tbRlV:
+                {
+                    m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL);
+                    break;
+                }
+                case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
+                case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
+                default:
+                    SAL_WARN("writerfilter", "DomainMapper::sprmWithProps: unhandled textDirection");
+            }
+        }
         break;
     case NS_ooxml::LN_CT_PPrBase_outlineLvl:
         {
@@ -2088,6 +2117,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
         {
             //TODO: What about style sheet import of frame properties
         }
+        m_pImpl->NewFrameDirection();
         resolveSprmProps(*this, rSprm);
     }
     break;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index cd78ab36bd0a..2fcd6ba2e362 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1155,6 +1155,11 @@ void DomainMapper_Impl::CheckUnregisteredFrameConversion( )
 
             aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), bAutoWidth ?  text::SizeType::MIN : text::SizeType::FIX));
 
+            if (const std::optional<sal_Int16> nDirection = PopFrameDirection())
+            {
+                aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_FRM_DIRECTION), *nDirection));
+            }
+
             sal_Int16 nHoriOrient = sal_Int16(
                 rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
                     rAppendContext.pLastParagraphProperties->GetxAlign() :
@@ -1538,7 +1543,6 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
     if ( hasTableManager() && getTableManager().isInCell() )
         getTableManager().setCellLastParaAfterAutospacing( bApplyAutospacing );
 
-
     if (xTextAppend.is() && pParaContext && hasTableManager() && !getTableManager().isIgnore())
     {
         try
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 1a9f9340bac6..ba81c4c55e39 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -490,6 +490,8 @@ private:
     //each context needs a stack of currently used attributes
     std::stack<PropertyMapPtr>  m_aPropertyStacks[NUMBER_OF_CONTEXTS];
     std::stack<ContextType> m_aContextStack;
+    std::queue<std::optional<sal_Int16>> m_aFrameDirectionQueue;
+    bool                    m_bFrameDirectionSet;
     FontTablePtr            m_pFontTable;
     ListsManager::Pointer   m_pListTable;
     std::deque< css::uno::Reference<css::drawing::XShape> > m_aPendingShapes;
@@ -954,6 +956,25 @@ public:
         return m_aTextAppendStack.empty() ? nullptr : m_aTextAppendStack.top().xTextAppend;
     }
 
+    void NewFrameDirection() {
+        m_aFrameDirectionQueue.push(std::nullopt);
+        m_bFrameDirectionSet = false;
+    }
+    void SetFrameDirection(sal_Int16 nDirection) {
+        if (!m_bFrameDirectionSet) {
+            assert(!m_aFrameDirectionQueue.empty());
+            m_aFrameDirectionQueue.back() = nDirection;
+            m_bFrameDirectionSet = true;
+        }
+    }
+    std::optional<sal_Int16> PopFrameDirection() {
+        if (m_aFrameDirectionQueue.empty())
+            return {};
+        const std::optional<sal_Int16> nDirection = m_aFrameDirectionQueue.front();
+        m_aFrameDirectionQueue.pop();
+        return nDirection;
+    }
+
     SectionPropertyMap * GetSectionContext();
     /// If the current paragraph has a numbering style associated, this method returns its character style (part of the numbering rules)
     css::uno::Reference<css::beans::XPropertySet> GetCurrentNumberingCharStyle();


More information about the Libreoffice-commits mailing list