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.dan...@nisz.hu> AuthorDate: Wed Sep 16 08:48:32 2020 +0200 Commit: László Németh <nem...@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 <nem...@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(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits