From 4cde2a01be75552a0b7d37f65cc4134cb48fea26 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 5 Sep 2017 09:07:48 +0200 Subject: tdf#104936 RTF export: implement ZOrder of TextFrames / shapes This used to work by accident for the particular textbox, but broke with commit 38f2b8b3b16aab19a2564ec699d253d3dccecc3c (tdf#88811 SwXText::convertToTextFrame: handle shapes anchored to us, 2015-02-03), so write ZOrder explicitly, like other filters already do. Change-Id: Ie8f11f4ec77707fb5aec7a597544d589a99bf6ca Reviewed-on: https://gerrit.libreoffice.org/41921 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- sw/qa/extras/globalfilter/globalfilter.cxx | 27 +++++++++++++++++++++++++-- sw/qa/extras/rtfexport/data/tdf104936.rtf | 20 ++++++++++++++++++++ sw/qa/extras/rtfexport/rtfexport.cxx | 11 +++++++++++ sw/source/filter/ww8/rtfattributeoutput.cxx | 8 ++++++++ sw/source/filter/ww8/rtfsdrexport.cxx | 4 ++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 sw/qa/extras/rtfexport/data/tdf104936.rtf diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 51f021c5c83a..a81be11690c2 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -284,6 +284,29 @@ void Test::testImageWithSpecialID() } } +/// Gives the first embedded or linked image in a document. +uno::Reference lcl_getShape(const uno::Reference& xComponent, bool bEmbedded) +{ + uno::Reference xRet; + + uno::Reference xDrawPageSupplier(xComponent, uno::UNO_QUERY); + uno::Reference xDrawPage = xDrawPageSupplier->getDrawPage(); + for (sal_Int32 i = 0; i < xDrawPage->getCount(); ++i) + { + uno::Reference xShape(xDrawPage->getByIndex(i), uno::UNO_QUERY); + OUString sURL; + xShape->getPropertyValue("GraphicURL") >>= sURL; + // Linked image: working starts with file://, broken is e.g. 'vnd.sun.star.GraphicObject:3000000000000000000000000000000000000000'. + if ((sURL.startsWith("file://") || sURL.endsWith("0000000000000000")) != bEmbedded) + { + xRet.set(xShape, uno::UNO_QUERY); + break; + } + } + + return xRet; +} + void Test::testGraphicShape() { // There are two kind of images in Writer: 1) Writer specific handled by SwGrfNode and @@ -327,7 +350,7 @@ void Test::testGraphicShape() const OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter]; CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast(2), xDraws->getCount()); - uno::Reference xImage = getShape(1); + uno::Reference xImage = lcl_getShape(mxComponent, true); uno::Reference< beans::XPropertySet > XPropSet( xImage, uno::UNO_QUERY_THROW ); // First image is embedded // Check URL @@ -351,7 +374,7 @@ void Test::testGraphicShape() return; // Second image is a linked one - xImage = getShape(2); + xImage = lcl_getShape(mxComponent, false); XPropSet.set( xImage, uno::UNO_QUERY_THROW ); // Check URL { diff --git a/sw/qa/extras/rtfexport/data/tdf104936.rtf b/sw/qa/extras/rtfexport/data/tdf104936.rtf new file mode 100644 index 000000000000..3f854b642500 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf104936.rtf @@ -0,0 +1,20 @@ +{\rtf\ansi\ansicpg1251 +{\fonttbl +{\f1\fcharset204 Arial} +{\f2\fcharset204 Courier New} +} +{\colortbl;\red0\green0\blue0;} +\viewkind1\paperw11340\paperh16840\margl0\margr0\margt460\margb1240 +\viewkind1\paperw11340\paperh16840\margl0\margr0\margt460\margb1240 +\viewkind1\paperw11340\paperh16840\margl0\margr0\margt460\margb1240 +\viewkind1\paperw11340\paperh16840\margl0\margr0\margt460\margb1240 +{\do\dobxpage\dobypage\dprect +\dpx0\dpy450\dpxsize11160\dpysize1943 +\dpfillfgcr255\dpfillfgcg255\dpfillfgcb255 +\dpfillbgcr255\dpfillbgcg255\dpfillbgcb255\dpfillpat1 +\dplinew0 \dplinehollow +} +{\pard \qc \pvpg\phpg\posx2786\posy1218\absw1080 \absh-235 +{\f2\fs20 \cf1 \b Hello\par} +} +} diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index 4d46f82819df..7b9107819005 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -867,6 +867,17 @@ DECLARE_RTFEXPORT_TEST(testCjklist38, "cjklist38.rtf") CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_UPPER_ZH, numFormat); } +DECLARE_RTFEXPORT_TEST(testTdf104936, "tdf104936.rtf") +{ + uno::Reference xShape1(getShape(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast(0), getProperty(xShape1, "ZOrder")); + // This failed, the shape without text covered the shape with text. + CPPUNIT_ASSERT(xShape1->getString().isEmpty()); + uno::Reference xShape2(getShape(2), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast(1), getProperty(xShape2, "ZOrder")); + CPPUNIT_ASSERT_EQUAL(OUString("Hello"), xShape2->getString()); +} + DECLARE_RTFEXPORT_TEST(testTableRtl, "table-rtl.rtf") { uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index acb9385ebc6b..6c471942d80d 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -1864,6 +1864,14 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Poi m_rExport.m_bOutFlyFrameAttrs = m_rExport.m_bRTFFlySyntax = true; m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true); + + // Write ZOrder. + if (const SdrObject* pObject = rFrame.GetFrameFormat().FindRealSdrObject()) + { + m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPZ); + m_rExport.OutULong(pObject->GetOrdNum()); + } + m_rExport.Strm().WriteCharPtr(m_aRunText.makeStringAndClear().getStr()); m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr()); m_rExport.m_bOutFlyFrameAttrs = m_rExport.m_bRTFFlySyntax = false; diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx index b8d53faf704b..9241b6fe529d 100644 --- a/sw/source/filter/ww8/rtfsdrexport.cxx +++ b/sw/source/filter/ww8/rtfsdrexport.cxx @@ -497,6 +497,10 @@ sal_Int32 RtfSdrExport::StartShape() // Ignore \shpbypage, \shpbymargin, and \shpbycolumn, in favor of the posrelh property. m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE); + // Write ZOrder. + m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPZ); + m_rAttrOutput.RunText().append(OString::number(m_pSdrObject->GetOrdNum())); + for (auto it = m_aShapeProps.rbegin(); it != m_aShapeProps.rend(); ++it) lcl_AppendSP(m_rAttrOutput.RunText(), (*it).first.getStr(), (*it).second); -- cgit v1.2.3