summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorDaniel Arato (NISZ) <arato.daniel@nisz.hu>2020-09-16 08:48:32 +0200
committerLászló Németh <nemeth@numbertext.org>2020-10-06 12:31:04 +0200
commitaf4e5ee0f93c1ff442d08caed5c875f2b2c1fd43 (patch)
treeacf3133451bec3246d8736268d48513efbe6c324 /writerfilter
parent94b73fb5e206a8718e5127cf58c826099ae92f5a (diff)
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@numbertext.org>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx21
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/frame-direction.docxbin0 -> 28204 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx30
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx6
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx21
5 files changed, 77 insertions, 1 deletions
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
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/frame-direction.docx
Binary files 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();