From f208469414f0f8823fe8003fd0e4c78b3c51bb02 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 18 Sep 2020 11:47:56 +0200 Subject: tdf#136620 tdf#136708 filter,oox,sw: fix export of 2 different wraps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2cb90a5c87fe46737c8d840967d8836284f92ffd. Revert the change to EscherPropertyContainer, which was completely bogus, based on pre-existing bogus code in VMLExport::Commit(). The problem is that ESCHER_Wrap values are for wrapping text *inside* a text box, which is "mso-wrap-style" in VML, whereas VML's w10:wrap element defines how text wraps *around* a shape, doesn't exist as an ESCHER property and is specific to Word formats. Instead, export the w10:wrap element in VMLExport::EndShape(). This has 2 callers, WriteActiveXControl() and writeVMLDrawing(). Furthermore the value "none" wasn't written for WrapTextMode_THROUGH, which caused the wrap element to be omitted in that case. Change-Id: Id4a01fcb2ea73fa9bef4ee8769b5e0680e059f15 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103009 Tested-by: Jenkins Reviewed-by: Michael Stahl (cherry picked from commit fdc8590032b292dcb8152b328401e591fea642a4) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103090 Reviewed-by: Caolán McNamara (cherry picked from commit c54d697e2ac379d4b1a3ff5acb6f06bff30cadd6) --- filter/source/msfilter/escherex.cxx | 20 ------ include/oox/export/vmlexport.hxx | 7 ++- oox/source/export/vmlexport.cxx | 22 +++++-- sc/source/filter/xcl97/xcl97rec.cxx | 2 + sw/source/filter/ww8/docxattributeoutput.cxx | 91 ++++++++++++++++++---------- sw/source/filter/ww8/docxattributeoutput.hxx | 6 ++ sw/source/filter/ww8/docxsdrexport.cxx | 6 +- 7 files changed, 94 insertions(+), 60 deletions(-) diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx index a2071237deb7..f04043e9156a 100644 --- a/filter/source/msfilter/escherex.cxx +++ b/filter/source/msfilter/escherex.cxx @@ -66,7 +66,6 @@ #include #include #include -#include #include #include #include @@ -700,10 +699,6 @@ void EscherPropertyContainer::CreateTextProperties( bool bWordWrap ( false ); bool bAutoGrowSize ( false ); - uno::Any aTextWrap; - - EscherPropertyValueHelper::GetPropertyValue(aTextWrap, rXPropSet, "TextWrap", true); - if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, "TextWritingMode", true ) ) aAny >>= eWM; if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, "TextVerticalAdjust", true ) ) @@ -842,21 +837,6 @@ void EscherPropertyContainer::CreateTextProperties( nTextAttr |= 0x20002; } } - - if (aTextWrap.hasValue()) - { // explicit text wrap overrides whatever was inferred previously - switch (aTextWrap.get()) - { - case text::WrapTextMode_THROUGH: - eWrapMode = ESCHER_WrapNone; - break; - // in theory there are 3 more Escher_Wrap, but [MS-ODRAW] says they are useless - default: - eWrapMode = ESCHER_WrapSquare; - break; - } - } - AddOpt( ESCHER_Prop_dxTextLeft, nLeft * 360 ); AddOpt( ESCHER_Prop_dxTextRight, nRight * 360 ); AddOpt( ESCHER_Prop_dyTextTop, nTop * 360 ); diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx index 7c2d3a62da6f..3736420756a6 100644 --- a/include/oox/export/vmlexport.hxx +++ b/include/oox/export/vmlexport.hxx @@ -80,8 +80,9 @@ class OOX_DLLPUBLIC VMLExport : public EscherEx /// Parent exporter, used for text callback. VMLTextExport* m_pTextExport; - /// Anchoring. + /// Anchoring - Writer specific properties sal_Int16 m_eHOri, m_eVOri, m_eHRel, m_eVRel; + std::unique_ptr m_pWrapAttrList; bool m_bInline; // css::text::TextContentAnchorType_AS_CHARACTER /// The object we're exporting. @@ -139,7 +140,9 @@ public: /// Call this when you need to export the object as VML. OString const & AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri = -1, sal_Int16 eVOri = -1, sal_Int16 eHRel = -1, - sal_Int16 eVRel = -1, const bool bOOxmlExport = false ); + sal_Int16 eVRel = -1, + std::unique_ptr m_pWrapAttrList = nullptr, + const bool bOOxmlExport = false ); OString const & AddInlineSdrObject( const SdrObject& rObj, const bool bOOxmlExport ); virtual void AddSdrObjectVMLObject( const SdrObject& rObj) override; static bool IsWaterMarkShape(const OUString& rStr); diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index ee93cf32bd27..2009d9ccf055 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -421,11 +421,15 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle& case ESCHER_WrapSquare: case ESCHER_WrapByPoints: pWrapType = "square"; break; // these two are equivalent according to the docu case ESCHER_WrapNone: pWrapType = "none"; break; - case ESCHER_WrapTopBottom: pWrapType = "topAndBottom"; break; - case ESCHER_WrapThrough: pWrapType = "through"; break; + case ESCHER_WrapTopBottom: + case ESCHER_WrapThrough: + break; // last two are *undefined* in MS-ODRAW, don't exist in VML } if ( pWrapType ) - m_pSerializer->singleElementNS(XML_w10, XML_wrap, XML_type, pWrapType); + { + m_ShapeStyle.append(";mso-wrap-style:"); + m_ShapeStyle.append(pWrapType); + } } bAlreadyWritten[ ESCHER_Prop_WrapText ] = true; break; @@ -1477,18 +1481,27 @@ void VMLExport::EndShape( sal_Int32 nShapeElement ) m_pSerializer->endElementNS(XML_v, XML_textbox); } + if (m_pWrapAttrList) + { + sax_fastparser::XFastAttributeListRef const pWrapAttrList(m_pWrapAttrList.release()); + m_pSerializer->singleElementNS(XML_w10, XML_wrap, pWrapAttrList); + } + // end of the shape m_pSerializer->endElementNS( XML_v, nShapeElement ); } } -OString const & VMLExport::AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel, const bool bOOxmlExport ) +OString const & VMLExport::AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel, + std::unique_ptr pWrapAttrList, + const bool bOOxmlExport ) { m_pSdrObject = &rObj; m_eHOri = eHOri; m_eVOri = eVOri; m_eHRel = eHRel; m_eVRel = eVRel; + m_pWrapAttrList = std::move(pWrapAttrList); m_bInline = false; EscherEx::AddSdrObject(rObj, bOOxmlExport); return m_sShapeId; @@ -1501,6 +1514,7 @@ OString const & VMLExport::AddInlineSdrObject( const SdrObject& rObj, const bool m_eVOri = -1; m_eHRel = -1; m_eVRel = -1; + m_pWrapAttrList.reset(); m_bInline = true; EscherEx::AddSdrObject(rObj, bOOxmlExport); return m_sShapeId; diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 4a4656f57a94..58a4045cd7dd 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -59,6 +59,8 @@ #include #include #include + +#include #include #include #include diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 4256c8cf9cba..270ab6fe964f 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -5347,10 +5347,14 @@ void DocxAttributeOutput::WriteActiveXControl(const SdrObject* pObject, const Sw { const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient(); const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient(); + SwFormatSurround const& rSurround(rFrameFormat.GetSurround()); + std::unique_ptr pAttrList(docx::SurroundToVMLWrap(rSurround)); sShapeId = m_rExport.VMLExporter().AddSdrObject(*pObject, rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(), rHoriOri.GetRelationOrient(), - rVertOri.GetRelationOrient(), true); + rVertOri.GetRelationOrient(), + std::move(pAttrList), + true); } // Restore default values m_rExport.VMLExporter().SetSkipwzName(false); @@ -8352,43 +8356,64 @@ void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace ) } } -void DocxAttributeOutput::FormatSurround( const SwFormatSurround& rSurround ) +namespace docx { + +std::unique_ptr SurroundToVMLWrap(SwFormatSurround const& rSurround) { - if (m_rExport.SdrExporter().getTextFrameSyntax()) + FastAttributeList * pAttrList(nullptr); + OString sType; + OString sSide; + switch (rSurround.GetSurround()) + { + case css::text::WrapTextMode_NONE: + sType = "topAndBottom"; + break; + case css::text::WrapTextMode_PARALLEL: + sType = "square"; + break; + case css::text::WrapTextMode_DYNAMIC: + sType = "square"; + sSide = "largest"; + break; + case css::text::WrapTextMode_LEFT: + sType = "square"; + sSide = "left"; + break; + case css::text::WrapTextMode_RIGHT: + sType = "square"; + sSide = "right"; + break; + case css::text::WrapTextMode_THROUGH: + /* empty type and side means through */ + default: + sType = "none"; + break; + } + if (!sType.isEmpty() || !sSide.isEmpty()) { - OString sType, sSide; - switch (rSurround.GetSurround()) + pAttrList = FastSerializerHelper::createAttrList(); + if (!sType.isEmpty()) { - case css::text::WrapTextMode_NONE: - sType = "topAndBottom"; - break; - case css::text::WrapTextMode_PARALLEL: - sType = "square"; - break; - case css::text::WrapTextMode_DYNAMIC: - sType = "square"; - sSide = "largest"; - break; - case css::text::WrapTextMode_LEFT: - sType = "square"; - sSide = "left"; - break; - case css::text::WrapTextMode_RIGHT: - sType = "square"; - sSide = "right"; - break; - case css::text::WrapTextMode_THROUGH: - /* empty type and side means through */ - default: - break; + pAttrList->add(XML_type, sType); + } + if (!sSide.isEmpty()) + { + pAttrList->add(XML_side, sSide); } - if (!sType.isEmpty() || !sSide.isEmpty()) + } + return std::unique_ptr(pAttrList); +} + +} // namespace docx + +void DocxAttributeOutput::FormatSurround( const SwFormatSurround& rSurround ) +{ + if (m_rExport.SdrExporter().getTextFrameSyntax()) + { + std::unique_ptr pAttrList(docx::SurroundToVMLWrap(rSurround)); + if (pAttrList) { - m_rExport.SdrExporter().setFlyWrapAttrList(FastSerializerHelper::createAttrList()); - if (!sType.isEmpty()) - m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_type, sType); - if (!sSide.isEmpty()) - m_rExport.SdrExporter().getFlyWrapAttrList()->add(XML_side, sSide); + m_rExport.SdrExporter().setFlyWrapAttrList(pAttrList.release()); } } else if (m_rExport.SdrExporter().getDMLTextFrameSyntax()) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 2b6e83dde2d6..b04ad82cff7e 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -1045,6 +1045,12 @@ struct DocxTableExportContext ~DocxTableExportContext() { m_rOutput.popFromTableExportContext(*this); } }; +namespace docx { + +std::unique_ptr SurroundToVMLWrap(SwFormatSurround const& rSurround); + +} + #endif // INCLUDED_SW_SOURCE_FILTER_WW8_DOCXATTRIBUTEOUTPUT_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index b86c64daeb24..a1f8b7b2f5be 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -827,9 +827,13 @@ void DocxSdrExport::writeVMLDrawing(const SdrObject* sdrObj, const SwFrameFormat const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient(); const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient(); + SwFormatSurround const& rSurround(rFrameFormat.GetSurround()); + + std::unique_ptr pAttrList( + docx::SurroundToVMLWrap(rSurround)); m_pImpl->getExport().VMLExporter().AddSdrObject( *sdrObj, rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(), rHoriOri.GetRelationOrient(), - rVertOri.GetRelationOrient(), true); + rVertOri.GetRelationOrient(), std::move(pAttrList), true); m_pImpl->getSerializer()->endElementNS(XML_w, XML_pict); } -- cgit