LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - docxsdrexport.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 848 918 92.4 %
Date: 2015-06-13 12:38:46 Functions: 46 47 97.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <docxsdrexport.hxx>
      11             : #include <com/sun/star/drawing/LineStyle.hpp>
      12             : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
      13             : #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
      14             : #include <com/sun/star/xml/sax/Writer.hpp>
      15             : #include <editeng/unoprnms.hxx>
      16             : #include <editeng/charrotateitem.hxx>
      17             : #include <svx/svdogrp.hxx>
      18             : #include <oox/export/utils.hxx>
      19             : #include <oox/token/properties.hxx>
      20             : #include <textboxhelper.hxx>
      21             : #include <fmtanchr.hxx>
      22             : #include <fmtsrnd.hxx>
      23             : #include <fmtcntnt.hxx>
      24             : #include <ndtxt.hxx>
      25             : #include <txatbase.hxx>
      26             : #include <fmtfsize.hxx>
      27             : #include <drawdoc.hxx>
      28             : #include <docxattributeoutput.hxx>
      29             : #include <docxexportfilter.hxx>
      30             : #include <comphelper/seqstream.hxx>
      31             : #include <comphelper/sequence.hxx>
      32             : 
      33             : #include <IDocumentDrawModelAccess.hxx>
      34             : 
      35             : using namespace com::sun::star;
      36             : using namespace oox;
      37             : 
      38             : namespace
      39             : {
      40             : 
      41        1303 : uno::Sequence<beans::PropertyValue> lclGetProperty(uno::Reference<drawing::XShape> rShape, const OUString& rPropName)
      42             : {
      43        1303 :     uno::Sequence<beans::PropertyValue> aResult;
      44        2606 :     uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
      45        2606 :     uno::Reference<beans::XPropertySetInfo> xPropSetInfo;
      46             : 
      47        1303 :     if (!xPropertySet.is())
      48           0 :         return aResult;
      49             : 
      50        1303 :     xPropSetInfo = xPropertySet->getPropertySetInfo();
      51        1303 :     if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(rPropName))
      52             :     {
      53        1220 :         xPropertySet->getPropertyValue(rPropName) >>= aResult;
      54             :     }
      55        1303 :     return aResult;
      56             : }
      57             : 
      58         612 : OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj)
      59             : {
      60         612 :     OUString aResult;
      61        1224 :     uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObj)->getUnoShape(), uno::UNO_QUERY);
      62        1224 :     OUString aGrabBagName;
      63        1224 :     uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
      64         612 :     if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
      65         189 :         aGrabBagName = "FrameInteropGrabBag";
      66             :     else
      67         423 :         aGrabBagName = "InteropGrabBag";
      68        1224 :     uno::Sequence< beans::PropertyValue > propList = lclGetProperty(xShape, aGrabBagName);
      69        1004 :     for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp)
      70             :     {
      71         606 :         OUString aPropName = propList[nProp].Name;
      72         606 :         if (aPropName == "AnchorId")
      73             :         {
      74         214 :             propList[nProp].Value >>= aResult;
      75         214 :             break;
      76             :         }
      77         392 :     }
      78        1224 :     return aResult;
      79             : }
      80             : 
      81         355 : void lclMovePositionWithRotation(awt::Point& aPos, const Size& rSize, sal_Int64 nRotation)
      82             : {
      83             :     // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx)
      84             :     // TODO: refactor
      85             : 
      86         355 :     if (nRotation == 0)
      87         664 :         return;
      88             : 
      89          46 :     if (nRotation < 0)
      90           1 :         nRotation = (36000 + nRotation) % 36000;
      91          46 :     if (nRotation % 18000 == 0)
      92          26 :         nRotation = 0;
      93         109 :     while (nRotation > 9000)
      94          17 :         nRotation = (18000 - (nRotation % 18000));
      95             : 
      96          46 :     double fVal = (double) nRotation * F_PI18000;
      97          46 :     double  fCos = cos(fVal);
      98          46 :     double  fSin = sin(fVal);
      99             : 
     100          46 :     double  nWidthHalf = (double) rSize.Width() / 2;
     101          46 :     double  nHeightHalf = (double) rSize.Height() / 2;
     102             : 
     103          46 :     double nXDiff = fSin * nHeightHalf + fCos * nWidthHalf  - nWidthHalf;
     104          46 :     double nYDiff = fSin * nWidthHalf  + fCos * nHeightHalf - nHeightHalf;
     105             : 
     106          46 :     aPos.X += nXDiff;
     107          46 :     aPos.Y += nYDiff;
     108             : }
     109             : 
     110             : }
     111             : 
     112         326 : ExportDataSaveRestore::ExportDataSaveRestore(DocxExport& rExport, sal_uLong nStt, sal_uLong nEnd, sw::Frame* pParentFrame)
     113         326 :     : m_rExport(rExport)
     114             : {
     115         326 :     m_rExport.SaveData(nStt, nEnd);
     116         326 :     m_rExport.m_pParentFrame = pParentFrame;
     117         326 : }
     118             : 
     119         326 : ExportDataSaveRestore::~ExportDataSaveRestore()
     120             : {
     121         326 :     m_rExport.RestoreData();
     122         326 : }
     123             : 
     124             : /// Holds data used by DocxSdrExport only.
     125             : struct DocxSdrExport::Impl
     126             : {
     127             :     DocxSdrExport& m_rSdrExport;
     128             :     DocxExport& m_rExport;
     129             :     sax_fastparser::FSHelperPtr m_pSerializer;
     130             :     oox::drawingml::DrawingML* m_pDrawingML;
     131             :     const Size* m_pFlyFrameSize;
     132             :     bool m_bTextFrameSyntax;
     133             :     bool m_bDMLTextFrameSyntax;
     134             :     std::unique_ptr<sax_fastparser::FastAttributeList> m_pFlyAttrList;
     135             :     std::unique_ptr<sax_fastparser::FastAttributeList> m_pTextboxAttrList;
     136             :     OStringBuffer m_aTextFrameStyle;
     137             :     bool m_bFrameBtLr;
     138             :     bool m_bDrawingOpen;
     139             :     bool m_bParagraphSdtOpen;
     140             :     bool m_bParagraphHasDrawing; ///Flag for checking drawing in a paragraph.
     141             :     bool m_bFlyFrameGraphic;
     142             :     std::unique_ptr<sax_fastparser::FastAttributeList> m_pFlyFillAttrList;
     143             :     sax_fastparser::FastAttributeList* m_pFlyWrapAttrList;
     144             :     sax_fastparser::FastAttributeList* m_pBodyPrAttrList;
     145             :     std::unique_ptr<sax_fastparser::FastAttributeList> m_pDashLineStyleAttr;
     146             :     sal_Int32 m_nId ;
     147             :     sal_Int32 m_nSeq ;
     148             :     bool m_bDMLAndVMLDrawingOpen;
     149             :     /// List of TextBoxes in this document: they are exported as part of their shape, never alone.
     150             :     std::set<const SwFrameFormat*> m_aTextBoxes;
     151             :     /// Preserved rotation for TextFrames.
     152             :     sal_Int32 m_nDMLandVMLTextFrameRotation;
     153             : 
     154         482 :     Impl(DocxSdrExport& rSdrExport, DocxExport& rExport, sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML)
     155             :         : m_rSdrExport(rSdrExport),
     156             :           m_rExport(rExport),
     157             :           m_pSerializer(pSerializer),
     158             :           m_pDrawingML(pDrawingML),
     159             :           m_pFlyFrameSize(0),
     160             :           m_bTextFrameSyntax(false),
     161             :           m_bDMLTextFrameSyntax(false),
     162             :           m_bFrameBtLr(false),
     163             :           m_bDrawingOpen(false),
     164             :           m_bParagraphSdtOpen(false),
     165             :           m_bParagraphHasDrawing(false),
     166             :           m_bFlyFrameGraphic(false),
     167             :           m_pFlyWrapAttrList(0),
     168             :           m_pBodyPrAttrList(0),
     169             :           m_nId(0),
     170             :           m_nSeq(0),
     171             :           m_bDMLAndVMLDrawingOpen(false),
     172             :           m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport.m_pDoc)),
     173         482 :           m_nDMLandVMLTextFrameRotation(0)
     174             :     {
     175         482 :     }
     176             : 
     177         482 :     ~Impl()
     178         482 :     {
     179         482 :     }
     180             : 
     181             :     /// Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax.
     182             : 
     183             :     void textFrameShadow(const SwFrameFormat& rFrameFormat);
     184             :     static bool isSupportedDMLShape(uno::Reference<drawing::XShape> xShape);
     185             :     /// Undo the text direction mangling done by the frame btLr handler in writerfilter::dmapper::DomainMapper::lcl_startCharacterGroup()
     186             :     bool checkFrameBtlr(SwNode* pStartNode, bool bDML);
     187             : };
     188             : 
     189         482 : DocxSdrExport::DocxSdrExport(DocxExport& rExport, sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML)
     190         482 :     : m_pImpl(o3tl::make_unique<Impl>(*this, rExport, pSerializer, pDrawingML))
     191             : {
     192         482 : }
     193             : 
     194         482 : DocxSdrExport::~DocxSdrExport()
     195             : {
     196         482 : }
     197             : 
     198         556 : void DocxSdrExport::setSerializer(sax_fastparser::FSHelperPtr pSerializer)
     199             : {
     200         556 :     m_pImpl->m_pSerializer = pSerializer;
     201         556 : }
     202             : 
     203         282 : const Size* DocxSdrExport::getFlyFrameSize()
     204             : {
     205         282 :     return m_pImpl->m_pFlyFrameSize;
     206             : }
     207             : 
     208       12346 : bool DocxSdrExport::getTextFrameSyntax()
     209             : {
     210       12346 :     return m_pImpl->m_bTextFrameSyntax;
     211             : }
     212             : 
     213       12026 : bool DocxSdrExport::getDMLTextFrameSyntax()
     214             : {
     215       12026 :     return m_pImpl->m_bDMLTextFrameSyntax;
     216             : }
     217             : 
     218       15489 : std::unique_ptr<sax_fastparser::FastAttributeList>& DocxSdrExport::getFlyAttrList()
     219             : {
     220       15489 :     return m_pImpl->m_pFlyAttrList;
     221             : }
     222             : 
     223         122 : std::unique_ptr<sax_fastparser::FastAttributeList>& DocxSdrExport::getTextboxAttrList()
     224             : {
     225         122 :     return m_pImpl->m_pTextboxAttrList;
     226             : }
     227             : 
     228        1516 : OStringBuffer& DocxSdrExport::getTextFrameStyle()
     229             : {
     230        1516 :     return m_pImpl->m_aTextFrameStyle;
     231             : }
     232             : 
     233          12 : bool DocxSdrExport::getFrameBtLr()
     234             : {
     235          12 :     return m_pImpl->m_bFrameBtLr;
     236             : }
     237             : 
     238           5 : bool DocxSdrExport::IsDrawingOpen()
     239             : {
     240           5 :     return m_pImpl->m_bDrawingOpen;
     241             : }
     242             : 
     243           2 : void DocxSdrExport::setParagraphSdtOpen(bool bParagraphSdtOpen)
     244             : {
     245           2 :     m_pImpl->m_bParagraphSdtOpen = bParagraphSdtOpen;
     246           2 : }
     247             : 
     248       14611 : bool DocxSdrExport::IsDMLAndVMLDrawingOpen()
     249             : {
     250       14611 :     return m_pImpl->m_bDMLAndVMLDrawingOpen;
     251             : }
     252             : 
     253          85 : bool DocxSdrExport::IsParagraphHasDrawing()
     254             : {
     255          85 :     return m_pImpl->m_bParagraphHasDrawing;
     256             : }
     257             : 
     258        7529 : void DocxSdrExport::setParagraphHasDrawing(bool bParagraphHasDrawing)
     259             : {
     260        7529 :     m_pImpl->m_bParagraphHasDrawing = bParagraphHasDrawing;
     261        7529 : }
     262             : 
     263          21 : std::unique_ptr<sax_fastparser::FastAttributeList>& DocxSdrExport::getFlyFillAttrList()
     264             : {
     265          21 :     return m_pImpl->m_pFlyFillAttrList;
     266             : }
     267             : 
     268          50 : sax_fastparser::FastAttributeList* DocxSdrExport::getFlyWrapAttrList()
     269             : {
     270          50 :     return m_pImpl->m_pFlyWrapAttrList;
     271             : }
     272             : 
     273         272 : sax_fastparser::FastAttributeList* DocxSdrExport::getBodyPrAttrList()
     274             : {
     275         272 :     return m_pImpl->m_pBodyPrAttrList;
     276             : }
     277             : 
     278           0 : std::unique_ptr<sax_fastparser::FastAttributeList>& DocxSdrExport::getDashLineStyle()
     279             : {
     280           0 :     return m_pImpl->m_pDashLineStyleAttr;
     281             : }
     282             : 
     283          38 : void DocxSdrExport::setFlyWrapAttrList(sax_fastparser::FastAttributeList* pAttrList)
     284             : {
     285          38 :     m_pImpl->m_pFlyWrapAttrList = pAttrList;
     286          38 : }
     287             : 
     288         503 : void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, const Size& rSize)
     289             : {
     290         503 :     m_pImpl->m_bDrawingOpen = true;
     291         503 :     m_pImpl->m_bParagraphHasDrawing = true;
     292         503 :     m_pImpl->m_pSerializer->startElementNS(XML_w, XML_drawing, FSEND);
     293             : 
     294         503 :     const SvxLRSpaceItem pLRSpaceItem = pFrameFormat->GetLRSpace(false);
     295        1006 :     const SvxULSpaceItem pULSpaceItem = pFrameFormat->GetULSpace(false);
     296             : 
     297             :     bool isAnchor;
     298             : 
     299         503 :     if (m_pImpl->m_bFlyFrameGraphic)
     300             :     {
     301          38 :         isAnchor = false; // make Graphic object inside DMLTextFrame & VMLTextFrame as Inline
     302             :     }
     303             :     else
     304             :     {
     305         465 :         isAnchor = pFrameFormat->GetAnchor().GetAnchorId() != FLY_AS_CHAR;
     306             :     }
     307             : 
     308             :     // Count effectExtent values, their value is needed before dist{T,B,L,R} is written.
     309        1006 :     SvxShadowItem aShadowItem = pFrameFormat->GetShadow();
     310         503 :     sal_Int32 nLeftExt = 0, nRightExt = 0, nTopExt = 0, nBottomExt = 0;
     311         503 :     if (aShadowItem.GetLocation() != SVX_SHADOW_NONE)
     312             :     {
     313           5 :         sal_Int32 nShadowWidth(TwipsToEMU(aShadowItem.GetWidth()));
     314           5 :         switch (aShadowItem.GetLocation())
     315             :         {
     316             :         case SVX_SHADOW_TOPLEFT:
     317           0 :             nTopExt = nLeftExt = nShadowWidth;
     318           0 :             break;
     319             :         case SVX_SHADOW_TOPRIGHT:
     320           0 :             nTopExt = nRightExt = nShadowWidth;
     321           0 :             break;
     322             :         case SVX_SHADOW_BOTTOMLEFT:
     323           0 :             nBottomExt = nLeftExt = nShadowWidth;
     324           0 :             break;
     325             :         case SVX_SHADOW_BOTTOMRIGHT:
     326           5 :             nBottomExt = nRightExt = nShadowWidth;
     327           5 :             break;
     328             :         case SVX_SHADOW_NONE:
     329             :         case SVX_SHADOW_END:
     330           0 :             break;
     331             :         }
     332             :     }
     333         498 :     else if (const SdrObject* pObject = pFrameFormat->FindRealSdrObject())
     334             :     {
     335             :         // No shadow, but we have an idea what was the original effectExtent.
     336         478 :         uno::Any aAny;
     337         478 :         pObject->GetGrabBagItem(aAny);
     338         956 :         comphelper::SequenceAsHashMap aGrabBag(aAny);
     339         478 :         comphelper::SequenceAsHashMap::iterator it = aGrabBag.find("CT_EffectExtent");
     340         478 :         if (it != aGrabBag.end())
     341             :         {
     342         243 :             comphelper::SequenceAsHashMap aEffectExtent(it->second);
     343        1215 :             for (std::pair<const OUString, uno::Any>& rDirection : aEffectExtent)
     344             :             {
     345         972 :                 if (rDirection.first == "l" && rDirection.second.has<sal_Int32>())
     346         243 :                     nLeftExt = rDirection.second.get<sal_Int32>();
     347         729 :                 else if (rDirection.first == "t" && rDirection.second.has<sal_Int32>())
     348         243 :                     nTopExt = rDirection.second.get<sal_Int32>();
     349         486 :                 else if (rDirection.first == "r" && rDirection.second.has<sal_Int32>())
     350         243 :                     nRightExt = rDirection.second.get<sal_Int32>();
     351         243 :                 else if (rDirection.first == "b" && rDirection.second.has<sal_Int32>())
     352         243 :                     nBottomExt = rDirection.second.get<sal_Int32>();
     353         243 :             }
     354         478 :         }
     355             :     }
     356             : 
     357         503 :     if (isAnchor)
     358             :     {
     359         364 :         sax_fastparser::FastAttributeList* attrList = sax_fastparser::FastSerializerHelper::createAttrList();
     360         364 :         bool bOpaque = pFrameFormat->GetOpaque().GetValue();
     361         364 :         awt::Point aPos(pFrameFormat->GetHoriOrient().GetPos(), pFrameFormat->GetVertOrient().GetPos());
     362         364 :         const SdrObject* pObj = pFrameFormat->FindRealSdrObject();
     363         364 :         if (pObj != NULL)
     364             :         {
     365             :             // SdrObjects know their layer, consider that instead of the frame format.
     366         355 :             bOpaque = pObj->GetLayer() != pFrameFormat->GetDoc()->getIDocumentDrawModelAccess().GetHellId() && pObj->GetLayer() != pFrameFormat->GetDoc()->getIDocumentDrawModelAccess().GetInvisibleHellId();
     367             : 
     368         355 :             lclMovePositionWithRotation(aPos, rSize, pObj->GetRotateAngle());
     369             :         }
     370         364 :         attrList->add(XML_behindDoc, bOpaque ? "0" : "1");
     371         364 :         attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper()) - nTopExt).getStr());
     372         364 :         attrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower()) - nBottomExt).getStr());
     373         364 :         attrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft()) - nLeftExt).getStr());
     374         364 :         attrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight()) - nRightExt).getStr());
     375         364 :         attrList->add(XML_simplePos, "0");
     376         364 :         attrList->add(XML_locked, "0");
     377         364 :         attrList->add(XML_layoutInCell, "1");
     378         364 :         attrList->add(XML_allowOverlap, "1");   // TODO
     379         364 :         if (pObj != NULL)
     380             :             // It seems 0 and 1 have special meaning: just start counting from 2 to avoid issues with that.
     381         355 :             attrList->add(XML_relativeHeight, OString::number(pObj->GetOrdNum() + 2));
     382             :         else
     383             :             // relativeHeight is mandatory attribute, if value is not present, we must write default value
     384           9 :             attrList->add(XML_relativeHeight, "0");
     385         364 :         if (pObj != NULL)
     386             :         {
     387         355 :             OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
     388         355 :             if (!sAnchorId.isEmpty())
     389         186 :                 attrList->addNS(XML_wp14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
     390             :         }
     391         364 :         sax_fastparser::XFastAttributeListRef xAttrList(attrList);
     392         364 :         m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_anchor, xAttrList);
     393         364 :         m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND);   // required, unused
     394             :         const char* relativeFromH;
     395             :         const char* relativeFromV;
     396         364 :         const char* alignH = NULL;
     397         364 :         const char* alignV = NULL;
     398         364 :         switch (pFrameFormat->GetVertOrient().GetRelationOrient())
     399             :         {
     400             :         case text::RelOrientation::PAGE_PRINT_AREA:
     401          10 :             relativeFromV = "margin";
     402          10 :             break;
     403             :         case text::RelOrientation::PAGE_FRAME:
     404          47 :             relativeFromV = "page";
     405          47 :             break;
     406             :         case text::RelOrientation::FRAME:
     407         304 :             relativeFromV = "paragraph";
     408         304 :             break;
     409             :         case text::RelOrientation::TEXT_LINE:
     410             :         default:
     411           3 :             relativeFromV = "line";
     412           3 :             break;
     413             :         }
     414         364 :         switch (pFrameFormat->GetVertOrient().GetVertOrient())
     415             :         {
     416             :         case text::VertOrientation::TOP:
     417             :         case text::VertOrientation::CHAR_TOP:
     418             :         case text::VertOrientation::LINE_TOP:
     419          19 :             if (pFrameFormat->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE)
     420           0 :                 alignV = "bottom";
     421             :             else
     422          19 :                 alignV = "top";
     423          19 :             break;
     424             :         case text::VertOrientation::BOTTOM:
     425             :         case text::VertOrientation::CHAR_BOTTOM:
     426             :         case text::VertOrientation::LINE_BOTTOM:
     427           1 :             if (pFrameFormat->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE)
     428           0 :                 alignV = "top";
     429             :             else
     430           1 :                 alignV = "bottom";
     431           1 :             break;
     432             :         case text::VertOrientation::CENTER:
     433             :         case text::VertOrientation::CHAR_CENTER:
     434             :         case text::VertOrientation::LINE_CENTER:
     435           5 :             alignV = "center";
     436           5 :             break;
     437             :         default:
     438         339 :             break;
     439             :         }
     440         364 :         switch (pFrameFormat->GetHoriOrient().GetRelationOrient())
     441             :         {
     442             :         case text::RelOrientation::PAGE_PRINT_AREA:
     443          22 :             relativeFromH = "margin";
     444          22 :             break;
     445             :         case text::RelOrientation::PAGE_FRAME:
     446          42 :             relativeFromH = "page";
     447          42 :             break;
     448             :         case text::RelOrientation::CHAR:
     449           0 :             relativeFromH = "character";
     450           0 :             break;
     451             :         case text::RelOrientation::PAGE_RIGHT:
     452           2 :             relativeFromH = "page";
     453           2 :             alignH = "right";
     454           2 :             break;
     455             :         case text::RelOrientation::FRAME:
     456             :         default:
     457         298 :             relativeFromH = "column";
     458         298 :             break;
     459             :         }
     460         364 :         switch (pFrameFormat->GetHoriOrient().GetHoriOrient())
     461             :         {
     462             :         case text::HoriOrientation::LEFT:
     463           1 :             alignH = "left";
     464           1 :             break;
     465             :         case text::HoriOrientation::RIGHT:
     466           6 :             alignH = "right";
     467           6 :             break;
     468             :         case text::HoriOrientation::CENTER:
     469          30 :             alignH = "center";
     470          30 :             break;
     471             :         case text::HoriOrientation::INSIDE:
     472           0 :             alignH = "inside";
     473           0 :             break;
     474             :         case text::HoriOrientation::OUTSIDE:
     475           0 :             alignH = "outside";
     476           0 :             break;
     477             :         default:
     478         327 :             break;
     479             :         }
     480         364 :         m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND);
     481             :         /**
     482             :         * Sizes of integral types
     483             :         * climits header defines constants with the limits of integral types for the specific system and compiler implemetation used.
     484             :         * Use of this might cause platform dependent problem like posOffset exceed the limit.
     485             :         **/
     486         364 :         const sal_Int64 MAX_INTEGER_VALUE = SAL_MAX_INT32;
     487         364 :         const sal_Int64 MIN_INTEGER_VALUE = SAL_MIN_INT32;
     488         364 :         if (alignH != NULL)
     489             :         {
     490          39 :             m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND);
     491          39 :             m_pImpl->m_pSerializer->write(alignH);
     492          39 :             m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_align);
     493             :         }
     494             :         else
     495             :         {
     496         325 :             m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND);
     497         325 :             sal_Int64 nTwipstoEMU = TwipsToEMU(aPos.X);
     498             : 
     499             :             /* Absolute Position Offset Value is of type Int. Hence it should not be greater than
     500             :              * Maximum value for Int OR Less than the Minimum value for Int.
     501             :              * - Maximum value for Int = 2147483647
     502             :              * - Minimum value for Int = -2147483648
     503             :              *
     504             :              * As per ECMA Specification : ECMA-376, Second Edition,
     505             :              * Part 1 - Fundamentals And Markup Language Reference[20.4.3.3 ST_PositionOffset (Absolute Position Offset Value)]
     506             :              *
     507             :              * Please refer : http://www.schemacentral.com/sc/xsd/t-xsd_int.html
     508             :              */
     509             : 
     510         325 :             if (nTwipstoEMU > MAX_INTEGER_VALUE)
     511             :             {
     512           0 :                 nTwipstoEMU = MAX_INTEGER_VALUE;
     513             :             }
     514         325 :             else if (nTwipstoEMU < MIN_INTEGER_VALUE)
     515             :             {
     516           0 :                 nTwipstoEMU = MIN_INTEGER_VALUE;
     517             :             }
     518         325 :             m_pImpl->m_pSerializer->write(nTwipstoEMU);
     519         325 :             m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
     520             :         }
     521         364 :         m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionH);
     522         364 :         m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND);
     523         364 :         if (alignV != NULL)
     524             :         {
     525          25 :             m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND);
     526          25 :             m_pImpl->m_pSerializer->write(alignV);
     527          25 :             m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_align);
     528             :         }
     529             :         else
     530             :         {
     531         339 :             m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND);
     532         339 :             sal_Int64 nTwipstoEMU = TwipsToEMU(aPos.Y);
     533         339 :             if (nTwipstoEMU > MAX_INTEGER_VALUE)
     534             :             {
     535           0 :                 nTwipstoEMU = MAX_INTEGER_VALUE;
     536             :             }
     537         339 :             else if (nTwipstoEMU < MIN_INTEGER_VALUE)
     538             :             {
     539           0 :                 nTwipstoEMU = MIN_INTEGER_VALUE;
     540             :             }
     541         339 :             m_pImpl->m_pSerializer->write(nTwipstoEMU);
     542         339 :             m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
     543             :         }
     544         364 :         m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionV);
     545             :     }
     546             :     else
     547             :     {
     548         139 :         sax_fastparser::FastAttributeList* aAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
     549         139 :         aAttrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr());
     550         139 :         aAttrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower())).getStr());
     551         139 :         aAttrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft())).getStr());
     552         139 :         aAttrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight())).getStr());
     553         139 :         const SdrObject* pObj = pFrameFormat->FindRealSdrObject();
     554         139 :         if (pObj != NULL)
     555             :         {
     556         128 :             OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
     557         128 :             if (!sAnchorId.isEmpty())
     558          28 :                 aAttrList->addNS(XML_wp14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
     559             :         }
     560         139 :         m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_inline, aAttrList);
     561             :     }
     562             : 
     563             :     // now the common parts
     564             :     // extent of the image
     565             :     /**
     566             :     * Extent width is of type long ( i.e cx & cy ) as
     567             :     *
     568             :     * per ECMA-376, Second Edition, Part 1 - Fundamentals And Markup Language Reference
     569             :     * [ 20.4.2.7 extent (Drawing Object Size)]
     570             :     *
     571             :     * cy is of type a:ST_PositiveCoordinate.
     572             :     * Minimum inclusive: 0
     573             :     * Maximum inclusive: 27273042316900
     574             :     *
     575             :     * reference : http://www.schemacentral.com/sc/ooxml/e-wp_extent-1.html
     576             :     *
     577             :     *   Though ECMA mentions the max value as aforementioned. It appears that MSO does not
     578             :     *  handle for the same, infact it acutally can handles a max value of int32 i.e
     579             :     *   2147483647( MAX_INTEGER_VALUE ).
     580             :     *  Therefore changing the following accordingly so that LO sync's up with MSO.
     581             :     **/
     582         503 :     sal_uInt64 cx = 0 ;
     583         503 :     sal_uInt64 cy = 0 ;
     584         503 :     const sal_Int64 MAX_INTEGER_VALUE = SAL_MAX_INT32;
     585             : 
     586             :     // the 'Size' type uses 'long' for width and height, so on
     587             :     // platforms where 'long' is 32 bits they can obviously never be
     588             :     // larger than the max signed 32-bit integer.
     589             : #if SAL_TYPES_SIZEOFLONG > 4
     590         503 :     if (rSize.Width() > MAX_INTEGER_VALUE)
     591           0 :         cx = MAX_INTEGER_VALUE ;
     592             :     else
     593             : #endif
     594             :     {
     595         503 :         if (0 > rSize.Width())
     596           0 :             cx = 0 ;
     597             :         else
     598         503 :             cx = rSize.Width();
     599             :     }
     600             : 
     601             : #if SAL_TYPES_SIZEOFLONG > 4
     602         503 :     if (rSize.Height() > MAX_INTEGER_VALUE)
     603           0 :         cy = MAX_INTEGER_VALUE ;
     604             :     else
     605             : #endif
     606             :     {
     607         503 :         if (0 > rSize.Height())
     608           0 :             cy = 0 ;
     609             :         else
     610         503 :             cy = rSize.Height();
     611             :     }
     612             : 
     613         503 :     OString aWidth(OString::number(TwipsToEMU(cx)));
     614             :     //we explicitly check the converted EMU value for the range as mentioned in above comment.
     615         503 :     aWidth = (aWidth.toInt64() > 0 ? (aWidth.toInt64() > MAX_INTEGER_VALUE ? I64S(MAX_INTEGER_VALUE) : aWidth.getStr()): "0");
     616        1006 :     OString aHeight(OString::number(TwipsToEMU(cy)));
     617         503 :     aHeight = (aHeight.toInt64() > 0 ? (aHeight.toInt64() > MAX_INTEGER_VALUE ? I64S(MAX_INTEGER_VALUE) : aHeight.getStr()): "0");
     618             : 
     619         503 :     m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_extent,
     620             :                                             XML_cx, aWidth,
     621             :                                             XML_cy, aHeight,
     622         503 :                                             FSEND);
     623             : 
     624             :     // effectExtent, extent including the effect (shadow only for now)
     625         503 :     m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_effectExtent,
     626             :                                             XML_l, OString::number(nLeftExt),
     627             :                                             XML_t, OString::number(nTopExt),
     628             :                                             XML_r, OString::number(nRightExt),
     629             :                                             XML_b, OString::number(nBottomExt),
     630        1006 :                                             FSEND);
     631             : 
     632             :     // See if we know the exact wrap type from grab-bag.
     633         503 :     sal_Int32 nWrapToken = 0;
     634         503 :     if (const SdrObject* pObject = pFrameFormat->FindRealSdrObject())
     635             :     {
     636         483 :         uno::Any aAny;
     637         483 :         pObject->GetGrabBagItem(aAny);
     638         966 :         comphelper::SequenceAsHashMap aGrabBag(aAny);
     639         483 :         comphelper::SequenceAsHashMap::iterator it = aGrabBag.find("EG_WrapType");
     640         483 :         if (it != aGrabBag.end())
     641             :         {
     642           7 :             OUString sType = it->second.get<OUString>();
     643           7 :             if (sType == "wrapTight")
     644           1 :                 nWrapToken = XML_wrapTight;
     645           6 :             else if (sType == "wrapThrough")
     646           6 :                 nWrapToken = XML_wrapThrough;
     647             :             else
     648             :                 SAL_WARN("sw.ww8", "DocxSdrExport::startDMLAnchorInline: unexpected EG_WrapType value");
     649             : 
     650           7 :             m_pImpl->m_pSerializer->startElementNS(XML_wp, nWrapToken,
     651           7 :                                                    XML_wrapText, "bothSides", FSEND);
     652             : 
     653           7 :             it = aGrabBag.find("CT_WrapPath");
     654           7 :             if (it != aGrabBag.end())
     655             :             {
     656           7 :                 m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_wrapPolygon,
     657             :                                                        XML_edited, "0",
     658           7 :                                                        FSEND);
     659           7 :                 drawing::PointSequenceSequence aSeqSeq = it->second.get< drawing::PointSequenceSequence >();
     660          14 :                 std::vector<awt::Point> aPoints(comphelper::sequenceToContainer<std::vector<awt::Point> >(aSeqSeq[0]));
     661          91 :                 for (std::vector<awt::Point>::iterator i = aPoints.begin(); i != aPoints.end(); ++i)
     662             :                 {
     663          84 :                     awt::Point& rPoint = *i;
     664         252 :                     m_pImpl->m_pSerializer->singleElementNS(XML_wp, (i == aPoints.begin() ? XML_start : XML_lineTo),
     665             :                                                             XML_x, OString::number(rPoint.X),
     666             :                                                             XML_y, OString::number(rPoint.Y),
     667         336 :                                                             FSEND);
     668             :                 }
     669          14 :                 m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_wrapPolygon);
     670             :             }
     671             : 
     672           7 :             m_pImpl->m_pSerializer->endElementNS(XML_wp, nWrapToken);
     673         483 :         }
     674             :     }
     675             : 
     676             :     // Or if we have a contour.
     677         503 :     if (!nWrapToken && pFrameFormat->GetSurround().IsContour())
     678             :     {
     679           3 :         if (const SwNoTextNode* pNd = sw::util::GetNoTextNodeFromSwFrameFormat(*pFrameFormat))
     680             :         {
     681           2 :             const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
     682           2 :             if (pPolyPoly && pPolyPoly->Count())
     683             :             {
     684           2 :                 nWrapToken = XML_wrapTight;
     685           2 :                 m_pImpl->m_pSerializer->startElementNS(XML_wp, nWrapToken,
     686           2 :                                                        XML_wrapText, "bothSides", FSEND);
     687             : 
     688           2 :                 m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_wrapPolygon,
     689             :                                                        XML_edited, "0",
     690           2 :                                                        FSEND);
     691           2 :                 Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd);
     692          18 :                 for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
     693          16 :                     m_pImpl->m_pSerializer->singleElementNS(XML_wp, (i == 0 ? XML_start : XML_lineTo),
     694          16 :                                                             XML_x, OString::number(aPoly[i].X()),
     695          16 :                                                             XML_y, OString::number(aPoly[i].Y()),
     696          48 :                                                             FSEND);
     697           2 :                 m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_wrapPolygon);
     698             : 
     699           2 :                 m_pImpl->m_pSerializer->endElementNS(XML_wp, nWrapToken);
     700             :             }
     701             :         }
     702             :     }
     703             : 
     704             :     // No? Then just approximate based on what we have.
     705         503 :     if (isAnchor && !nWrapToken)
     706             :     {
     707         355 :         switch (pFrameFormat->GetSurround().GetValue())
     708             :         {
     709             :         case SURROUND_NONE:
     710           8 :             m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapTopAndBottom, FSEND);
     711           8 :             break;
     712             :         case SURROUND_THROUGHT:
     713         280 :             m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapNone, FSEND);
     714         280 :             break;
     715             :         case SURROUND_PARALLEL:
     716          46 :             m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapSquare,
     717          46 :                                                     XML_wrapText, "bothSides", FSEND);
     718          46 :             break;
     719             :         case SURROUND_IDEAL:
     720             :         default:
     721          21 :             m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapSquare,
     722          21 :                                                     XML_wrapText, "largest", FSEND);
     723          21 :             break;
     724             :         }
     725        1006 :     }
     726         503 : }
     727             : 
     728         503 : void DocxSdrExport::endDMLAnchorInline(const SwFrameFormat* pFrameFormat)
     729             : {
     730             :     bool isAnchor;
     731         503 :     if (m_pImpl->m_bFlyFrameGraphic)
     732             :     {
     733          38 :         isAnchor = false; // end Inline Graphic object inside DMLTextFrame
     734             :     }
     735             :     else
     736             :     {
     737         465 :         isAnchor = pFrameFormat->GetAnchor().GetAnchorId() != FLY_AS_CHAR;
     738             :     }
     739         503 :     m_pImpl->m_pSerializer->endElementNS(XML_wp, isAnchor ? XML_anchor : XML_inline);
     740             : 
     741         503 :     m_pImpl->m_pSerializer->endElementNS(XML_w, XML_drawing);
     742         503 :     m_pImpl->m_bDrawingOpen = false;
     743         503 : }
     744             : 
     745         355 : void DocxSdrExport::writeVMLDrawing(const SdrObject* sdrObj, const SwFrameFormat& rFrameFormat,const Point& rNdTopLeft)
     746             : {
     747         355 :     bool bSwapInPage = false;
     748         355 :     if (!(sdrObj)->GetPage())
     749             :     {
     750           0 :         if (SdrModel* pModel = m_pImpl->m_rExport.m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
     751             :         {
     752           0 :             if (SdrPage* pPage = pModel->GetPage(0))
     753             :             {
     754           0 :                 bSwapInPage = true;
     755           0 :                 const_cast< SdrObject* >(sdrObj)->SetPage(pPage);
     756             :             }
     757             :         }
     758             :     }
     759             : 
     760         355 :     m_pImpl->m_pSerializer->startElementNS(XML_w, XML_pict, FSEND);
     761         355 :     m_pImpl->m_pDrawingML->SetFS(m_pImpl->m_pSerializer);
     762             :     // See WinwordAnchoring::SetAnchoring(), these are not part of the SdrObject, have to be passed around manually.
     763             : 
     764         355 :     SwFormatHoriOrient rHoriOri = (rFrameFormat).GetHoriOrient();
     765         710 :     SwFormatVertOrient rVertOri = (rFrameFormat).GetVertOrient();
     766         355 :     m_pImpl->m_rExport.VMLExporter().AddSdrObject(*(sdrObj),
     767         710 :             rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(),
     768         355 :             rHoriOri.GetRelationOrient(),
     769        1775 :             rVertOri.GetRelationOrient(), (&rNdTopLeft), true);
     770         355 :     m_pImpl->m_pSerializer->endElementNS(XML_w, XML_pict);
     771             : 
     772         355 :     if (bSwapInPage)
     773         355 :         const_cast< SdrObject* >(sdrObj)->SetPage(0);
     774         355 : }
     775             : 
     776         691 : bool lcl_isLockedCanvas(uno::Reference<drawing::XShape> xShape)
     777             : {
     778         691 :     bool bRet = false;
     779             :     uno::Sequence< beans::PropertyValue > propList =
     780         691 :         lclGetProperty(xShape, "InteropGrabBag");
     781        3369 :     for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
     782             :     {
     783        2686 :         OUString propName = propList[nProp].Name;
     784        2686 :         if (propName == "LockedCanvas")
     785             :         {
     786             :             /*
     787             :              * Export as Locked Canvas only if the property
     788             :              * is in the PropertySet
     789             :              */
     790           8 :             bRet = true;
     791           8 :             break;
     792             :         }
     793        2678 :     }
     794         691 :     return bRet;
     795             : }
     796             : 
     797         336 : void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrameFormat* pFrameFormat, int nAnchorId)
     798             : {
     799         336 :     uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY_THROW);
     800         336 :     if (!Impl::isSupportedDMLShape(xShape))
     801         336 :         return;
     802             : 
     803         336 :     m_pImpl->m_rExport.DocxAttrOutput().GetSdtEndBefore(pSdrObject);
     804             : 
     805         672 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
     806         336 :     Size aSize(pSdrObject->GetLogicRect().GetWidth(), pSdrObject->GetLogicRect().GetHeight());
     807         336 :     startDMLAnchorInline(pFrameFormat, aSize);
     808             : 
     809         336 :     sax_fastparser::FastAttributeList* pDocPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
     810         336 :     pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
     811         336 :     pDocPrAttrList->add(XML_name, OUStringToOString(pSdrObject->GetName(), RTL_TEXTENCODING_UTF8).getStr());
     812         336 :     if (!pSdrObject->GetTitle().isEmpty())
     813           3 :         pDocPrAttrList->add(XML_title, OUStringToOString(pSdrObject->GetTitle(), RTL_TEXTENCODING_UTF8));
     814         336 :     if (!pSdrObject->GetDescription().isEmpty())
     815           1 :         pDocPrAttrList->add(XML_descr, OUStringToOString(pSdrObject->GetDescription(), RTL_TEXTENCODING_UTF8));
     816         672 :     sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
     817         336 :     pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
     818             : 
     819         672 :     uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
     820         336 :     const char* pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
     821         336 :     if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
     822          29 :         pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
     823         307 :     else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
     824          34 :         pNamespace = "http://schemas.openxmlformats.org/drawingml/2006/picture";
     825             :     pFS->startElementNS(XML_a, XML_graphic,
     826             :                         FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
     827         336 :                         FSEND);
     828             :     pFS->startElementNS(XML_a, XML_graphicData,
     829             :                         XML_uri, pNamespace,
     830         336 :                         FSEND);
     831             : 
     832         336 :     bool bLockedCanvas = lcl_isLockedCanvas(xShape);
     833         336 :     if (bLockedCanvas)
     834             :         pFS->startElementNS(XML_lc, XML_lockedCanvas,
     835             :                             FSNS(XML_xmlns, XML_lc), "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas",
     836           4 :                             FSEND);
     837             : 
     838         336 :     m_pImpl->m_rExport.OutputDML(xShape);
     839             : 
     840         336 :     if (bLockedCanvas)
     841           4 :         pFS->endElementNS(XML_lc, XML_lockedCanvas);
     842         336 :     pFS->endElementNS(XML_a, XML_graphicData);
     843         336 :     pFS->endElementNS(XML_a, XML_graphic);
     844             : 
     845             :     // Relative size of the drawing.
     846         336 :     if (pSdrObject->GetRelativeWidth())
     847             :     {
     848             :         // At the moment drawinglayer objects are always relative from page.
     849             :         pFS->startElementNS(XML_wp14, XML_sizeRelH,
     850          17 :                             XML_relativeFrom, (pSdrObject->GetRelativeWidthRelation() == text::RelOrientation::FRAME ? "margin" : "page"),
     851          17 :                             FSEND);
     852          17 :         pFS->startElementNS(XML_wp14, XML_pctWidth, FSEND);
     853          17 :         pFS->writeEscaped(OUString::number(*pSdrObject->GetRelativeWidth() * 100 * oox::drawingml::PER_PERCENT));
     854          17 :         pFS->endElementNS(XML_wp14, XML_pctWidth);
     855          17 :         pFS->endElementNS(XML_wp14, XML_sizeRelH);
     856             :     }
     857         336 :     if (pSdrObject->GetRelativeHeight())
     858             :     {
     859             :         pFS->startElementNS(XML_wp14, XML_sizeRelV,
     860          15 :                             XML_relativeFrom, (pSdrObject->GetRelativeHeightRelation() == text::RelOrientation::FRAME ? "margin" : "page"),
     861          15 :                             FSEND);
     862          15 :         pFS->startElementNS(XML_wp14, XML_pctHeight, FSEND);
     863          15 :         pFS->writeEscaped(OUString::number(*pSdrObject->GetRelativeHeight() * 100 * oox::drawingml::PER_PERCENT));
     864          15 :         pFS->endElementNS(XML_wp14, XML_pctHeight);
     865          15 :         pFS->endElementNS(XML_wp14, XML_sizeRelV);
     866             :     }
     867             : 
     868         672 :     endDMLAnchorInline(pFrameFormat);
     869             : }
     870             : 
     871          68 : void DocxSdrExport::Impl::textFrameShadow(const SwFrameFormat& rFrameFormat)
     872             : {
     873          68 :     SvxShadowItem aShadowItem = rFrameFormat.GetShadow();
     874          68 :     if (aShadowItem.GetLocation() == SVX_SHADOW_NONE)
     875          63 :         return;
     876             : 
     877          10 :     OString aShadowWidth(OString::number(double(aShadowItem.GetWidth()) / 20) + "pt");
     878          10 :     OString aOffset;
     879           5 :     switch (aShadowItem.GetLocation())
     880             :     {
     881             :     case SVX_SHADOW_TOPLEFT:
     882           0 :         aOffset = "-" + aShadowWidth + ",-" + aShadowWidth;
     883           0 :         break;
     884             :     case SVX_SHADOW_TOPRIGHT:
     885           0 :         aOffset = aShadowWidth + ",-" + aShadowWidth;
     886           0 :         break;
     887             :     case SVX_SHADOW_BOTTOMLEFT:
     888           0 :         aOffset = "-" + aShadowWidth + "," + aShadowWidth;
     889           0 :         break;
     890             :     case SVX_SHADOW_BOTTOMRIGHT:
     891           5 :         aOffset = aShadowWidth + "," + aShadowWidth;
     892           5 :         break;
     893             :     case SVX_SHADOW_NONE:
     894             :     case SVX_SHADOW_END:
     895           0 :         break;
     896             :     }
     897           5 :     if (aOffset.isEmpty())
     898           0 :         return;
     899             : 
     900           5 :     OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
     901             :     m_pSerializer->singleElementNS(XML_v, XML_shadow,
     902             :                                    XML_on, "t",
     903          10 :                                    XML_color, "#" + aShadowColor,
     904             :                                    XML_offset, aOffset,
     905          15 :                                    FSEND);
     906             : }
     907             : 
     908         680 : bool DocxSdrExport::Impl::isSupportedDMLShape(uno::Reference<drawing::XShape> xShape)
     909             : {
     910         680 :     bool supported = true;
     911             : 
     912         680 :     uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
     913         680 :     if (xServiceInfo->supportsService("com.sun.star.drawing.PolyPolygonShape") || xServiceInfo->supportsService("com.sun.star.drawing.PolyLineShape"))
     914           3 :         supported = false;
     915             : 
     916         680 :     return supported;
     917             : }
     918             : 
     919         355 : void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject* sdrObj, const SwFrameFormat& rFrameFormat,const Point& rNdTopLeft, int nAnchorId)
     920             : {
     921         355 :     bool bDMLAndVMLDrawingOpen = m_pImpl->m_bDMLAndVMLDrawingOpen;
     922         355 :     m_pImpl->m_bDMLAndVMLDrawingOpen = true;
     923             : 
     924             :     // Depending on the shape type, we actually don't write the shape as DML.
     925         355 :     OUString sShapeType;
     926         355 :     sal_uInt32 nMirrorFlags = 0;
     927         710 :     uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(sdrObj)->getUnoShape(), uno::UNO_QUERY_THROW);
     928             : 
     929             :     // Locked canvas is OK inside DML.
     930         355 :     if (lcl_isLockedCanvas(xShape))
     931           4 :         bDMLAndVMLDrawingOpen = false;
     932             : 
     933         355 :     MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType(xShape, nMirrorFlags, sShapeType);
     934             : 
     935             :     // In case we are already inside a DML block, then write the shape only as VML, turn out that's allowed to do.
     936             :     // A common service created in util to check for VML shapes which are allowed to have textbox in content
     937         355 :     if ((msfilter::util::HasTextBoxContent(eShapeType)) && Impl::isSupportedDMLShape(xShape) && !bDMLAndVMLDrawingOpen)
     938             :     {
     939         336 :         m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND);
     940             : 
     941         336 :         const SdrObjGroup* pObjGroup = dynamic_cast<const SdrObjGroup*>(sdrObj);
     942         336 :         m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_Choice,
     943             :                                                XML_Requires, (pObjGroup ? "wpg" : "wps"),
     944         672 :                                                FSEND);
     945         336 :         writeDMLDrawing(sdrObj, &rFrameFormat, nAnchorId);
     946         336 :         m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_Choice);
     947             : 
     948         336 :         m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND);
     949         336 :         writeVMLDrawing(sdrObj, rFrameFormat, rNdTopLeft);
     950         336 :         m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_Fallback);
     951             : 
     952         336 :         m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_AlternateContent);
     953             :     }
     954             :     else
     955          19 :         writeVMLDrawing(sdrObj, rFrameFormat, rNdTopLeft);
     956             : 
     957         710 :     m_pImpl->m_bDMLAndVMLDrawingOpen = false;
     958         355 : }
     959             : 
     960             : // Converts ARGB transparency (0..255) to drawingml alpha (opposite, and 0..100000)
     961           5 : OString lcl_ConvertTransparency(const Color& rColor)
     962             : {
     963           5 :     if (rColor.GetTransparency() > 0)
     964             :     {
     965           0 :         sal_Int32 nTransparencyPercent = 100 - float(rColor.GetTransparency()) / 2.55;
     966           0 :         return OString::number(nTransparencyPercent * oox::drawingml::PER_PERCENT);
     967             :     }
     968             :     else
     969           5 :         return OString("");
     970             : }
     971             : 
     972         160 : void DocxSdrExport::writeDMLEffectLst(const SwFrameFormat& rFrameFormat)
     973             : {
     974         160 :     SvxShadowItem aShadowItem = rFrameFormat.GetShadow();
     975             : 
     976             :     // Output effects
     977         160 :     if (aShadowItem.GetLocation() != SVX_SHADOW_NONE)
     978             :     {
     979             :         // Distance is measured diagonally from corner
     980           5 :         double nShadowDist = sqrt((double)aShadowItem.GetWidth()*aShadowItem.GetWidth()*2.0);
     981           5 :         OString aShadowDist(OString::number(TwipsToEMU(nShadowDist)));
     982          10 :         OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
     983          10 :         OString aShadowAlpha = lcl_ConvertTransparency(aShadowItem.GetColor());
     984           5 :         sal_uInt32 nShadowDir = 0;
     985           5 :         switch (aShadowItem.GetLocation())
     986             :         {
     987             :         case SVX_SHADOW_TOPLEFT:
     988           0 :             nShadowDir = 13500000;
     989           0 :             break;
     990             :         case SVX_SHADOW_TOPRIGHT:
     991           0 :             nShadowDir = 18900000;
     992           0 :             break;
     993             :         case SVX_SHADOW_BOTTOMLEFT:
     994           0 :             nShadowDir = 8100000;
     995           0 :             break;
     996             :         case SVX_SHADOW_BOTTOMRIGHT:
     997           5 :             nShadowDir = 2700000;
     998           5 :             break;
     999             :         case SVX_SHADOW_NONE:
    1000             :         case SVX_SHADOW_END:
    1001           0 :             break;
    1002             :         }
    1003           5 :         OString aShadowDir(OString::number(nShadowDir));
    1004             : 
    1005           5 :         m_pImpl->m_pSerializer->startElementNS(XML_a, XML_effectLst, FSEND);
    1006           5 :         m_pImpl->m_pSerializer->startElementNS(XML_a, XML_outerShdw,
    1007             :                                                XML_dist, aShadowDist.getStr(),
    1008          10 :                                                XML_dir, aShadowDir.getStr(), FSEND);
    1009           5 :         if (aShadowAlpha.isEmpty())
    1010           5 :             m_pImpl->m_pSerializer->singleElementNS(XML_a, XML_srgbClr,
    1011          10 :                                                     XML_val, aShadowColor.getStr(), FSEND);
    1012             :         else
    1013             :         {
    1014           0 :             m_pImpl->m_pSerializer->startElementNS(XML_a, XML_srgbClr, XML_val, aShadowColor.getStr(), FSEND);
    1015           0 :             m_pImpl->m_pSerializer->singleElementNS(XML_a, XML_alpha, XML_val, aShadowAlpha.getStr(), FSEND);
    1016           0 :             m_pImpl->m_pSerializer->endElementNS(XML_a, XML_srgbClr);
    1017             :         }
    1018           5 :         m_pImpl->m_pSerializer->endElementNS(XML_a, XML_outerShdw);
    1019          10 :         m_pImpl->m_pSerializer->endElementNS(XML_a, XML_effectLst);
    1020         160 :     }
    1021             : 
    1022         160 : }
    1023             : 
    1024          13 : void DocxSdrExport::writeDiagramRels(uno::Reference<xml::dom::XDocument> xDom,
    1025             :                                      const uno::Sequence< uno::Sequence< uno::Any > >& xRelSeq,
    1026             :                                      uno::Reference< io::XOutputStream > xOutStream, const OUString& sGrabBagProperyName,
    1027             :                                      int nAnchorId)
    1028             : {
    1029             :     // add image relationships of OOXData, OOXDiagram
    1030          13 :     OUString sType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
    1031          26 :     uno::Reference< xml::sax::XSAXSerializable > xSerializer(xDom, uno::UNO_QUERY);
    1032          26 :     uno::Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(comphelper::getProcessComponentContext());
    1033          13 :     xWriter->setOutputStream(xOutStream);
    1034             : 
    1035             :     // retrieve the relationships from Sequence
    1036          39 :     for (sal_Int32 j = 0; j < xRelSeq.getLength(); j++)
    1037             :     {
    1038             :         // diagramDataRelTuple[0] => RID,
    1039             :         // diagramDataRelTuple[1] => xInputStream
    1040             :         // diagramDataRelTuple[2] => extension
    1041          26 :         uno::Sequence< uno::Any > diagramDataRelTuple = xRelSeq[j];
    1042             : 
    1043          52 :         OUString sRelId, sExtension;
    1044          26 :         diagramDataRelTuple[0] >>= sRelId;
    1045          26 :         diagramDataRelTuple[2] >>= sExtension;
    1046          52 :         OUString sContentType;
    1047          26 :         if (sExtension.equalsIgnoreAsciiCase(".WMF"))
    1048           4 :             sContentType = "image/x-wmf";
    1049             :         else
    1050          22 :             sContentType = "image/" + sExtension.copy(1);
    1051          26 :         sRelId = sRelId.copy(3);
    1052             : 
    1053          52 :         StreamDataSequence dataSeq;
    1054          26 :         diagramDataRelTuple[1] >>= dataSeq;
    1055          52 :         uno::Reference<io::XInputStream> dataImagebin(new ::comphelper::SequenceInputStream(dataSeq));
    1056             : 
    1057          52 :         OUString sFragment("../media/");
    1058             :         //nAnchorId is used to make the name unique irrespective of the number of smart arts.
    1059          26 :         sFragment += sGrabBagProperyName + OUString::number(nAnchorId) + "_" + OUString::number(j) + sExtension;
    1060             : 
    1061          52 :         PropertySet aProps(xOutStream);
    1062          26 :         aProps.setAnyProperty(PROP_RelId, uno::makeAny(sal_Int32(sRelId.toInt32())));
    1063             : 
    1064          26 :         m_pImpl->m_rExport.GetFilter().addRelation(xOutStream, sType, sFragment);
    1065             : 
    1066          26 :         sFragment = sFragment.replaceFirst("..","word");
    1067          52 :         uno::Reference< io::XOutputStream > xBinOutStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(sFragment, sContentType);
    1068             : 
    1069             :         try
    1070             :         {
    1071          26 :             sal_Int32 nBufferSize = 512;
    1072          26 :             uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
    1073             :             sal_Int32 nRead;
    1074        2516 :             do
    1075             :             {
    1076        2516 :                 nRead = dataImagebin->readBytes(aDataBuffer, nBufferSize);
    1077        2516 :                 if (nRead)
    1078             :                 {
    1079        2490 :                     if (nRead < nBufferSize)
    1080             :                     {
    1081          26 :                         nBufferSize = nRead;
    1082          26 :                         aDataBuffer.realloc(nRead);
    1083             :                     }
    1084        2490 :                     xBinOutStream->writeBytes(aDataBuffer);
    1085             :                 }
    1086             :             }
    1087             :             while (nRead);
    1088          26 :             xBinOutStream->flush();
    1089             :         }
    1090           0 :         catch (const uno::Exception& rException)
    1091             :         {
    1092             :             SAL_WARN("sw.ww8", "DocxSdrExport::writeDiagramRels Failed to copy grabbaged Image: " << rException.Message);
    1093             :         }
    1094          26 :         dataImagebin->closeInput();
    1095          39 :     }
    1096          13 : }
    1097             : 
    1098           7 : void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrameFormat& rFrameFormat,  int nAnchorId)
    1099             : {
    1100           7 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
    1101          14 :     uno::Reference< drawing::XShape > xShape(const_cast<SdrObject*>(sdrObject)->getUnoShape(), uno::UNO_QUERY);
    1102          14 :     uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
    1103             : 
    1104          14 :     uno::Reference<xml::dom::XDocument> dataDom;
    1105          14 :     uno::Reference<xml::dom::XDocument> layoutDom;
    1106          14 :     uno::Reference<xml::dom::XDocument> styleDom;
    1107          14 :     uno::Reference<xml::dom::XDocument> colorDom;
    1108          14 :     uno::Reference<xml::dom::XDocument> drawingDom;
    1109          14 :     uno::Sequence< uno::Sequence< uno::Any > > xDataRelSeq;
    1110          14 :     uno::Sequence< uno::Any > diagramDrawing;
    1111             : 
    1112             :     // retrieve the doms from the GrabBag
    1113          14 :     OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
    1114          14 :     uno::Sequence< beans::PropertyValue > propList;
    1115           7 :     xPropSet->getPropertyValue(pName) >>= propList;
    1116          47 :     for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
    1117             :     {
    1118          40 :         OUString propName = propList[nProp].Name;
    1119          40 :         if (propName == "OOXData")
    1120           7 :             propList[nProp].Value >>= dataDom;
    1121          33 :         else if (propName == "OOXLayout")
    1122           7 :             propList[nProp].Value >>= layoutDom;
    1123          26 :         else if (propName == "OOXStyle")
    1124           7 :             propList[nProp].Value >>= styleDom;
    1125          19 :         else if (propName == "OOXColor")
    1126           7 :             propList[nProp].Value >>= colorDom;
    1127          12 :         else if (propName == "OOXDrawing")
    1128             :         {
    1129           6 :             propList[nProp].Value >>= diagramDrawing;
    1130           6 :             diagramDrawing[0] >>= drawingDom; // if there is OOXDrawing property then set drawingDom here only.
    1131             :         }
    1132           6 :         else if (propName == "OOXDiagramDataRels")
    1133           4 :             propList[nProp].Value >>= xDataRelSeq;
    1134          40 :     }
    1135             : 
    1136             :     // check that we have the 4 mandatory XDocuments
    1137             :     // if not, there was an error importing and we won't output anything
    1138           7 :     if (!dataDom.is() || !layoutDom.is() || !styleDom.is() || !colorDom.is())
    1139           7 :         return;
    1140             : 
    1141             :     // write necessary tags to document.xml
    1142           7 :     Size aSize(sdrObject->GetSnapRect().GetWidth(), sdrObject->GetSnapRect().GetHeight());
    1143           7 :     startDMLAnchorInline(&rFrameFormat, aSize);
    1144             : 
    1145             :     // generate an unique id
    1146           7 :     sax_fastparser::FastAttributeList* pDocPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
    1147           7 :     pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
    1148          14 :     OUString sName = "Diagram" + OUString::number(nAnchorId);
    1149           7 :     pDocPrAttrList->add(XML_name, OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
    1150          14 :     sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
    1151           7 :     pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
    1152             : 
    1153             :     sal_Int32 diagramCount;
    1154           7 :     diagramCount = nAnchorId;
    1155             : 
    1156             :     pFS->singleElementNS(XML_wp, XML_cNvGraphicFramePr,
    1157           7 :                          FSEND);
    1158             : 
    1159             :     pFS->startElementNS(XML_a, XML_graphic,
    1160             :                         FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
    1161           7 :                         FSEND);
    1162             : 
    1163             :     pFS->startElementNS(XML_a, XML_graphicData,
    1164             :                         XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/diagram",
    1165           7 :                         FSEND);
    1166             : 
    1167             :     // add data relation
    1168          14 :     OUString dataFileName = "diagrams/data" + OUString::number(diagramCount) + ".xml";
    1169           7 :     OString dataRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
    1170             :                                           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData",
    1171          21 :                                           dataFileName, false), RTL_TEXTENCODING_UTF8);
    1172             : 
    1173             : 
    1174             :     // add layout relation
    1175          14 :     OUString layoutFileName = "diagrams/layout" + OUString::number(diagramCount) + ".xml";
    1176           7 :     OString layoutRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
    1177             :                                             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout",
    1178          21 :                                             layoutFileName, false), RTL_TEXTENCODING_UTF8);
    1179             : 
    1180             :     // add style relation
    1181          14 :     OUString styleFileName = "diagrams/quickStyle" + OUString::number(diagramCount) + ".xml";
    1182           7 :     OString styleRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
    1183             :                                            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle",
    1184          21 :                                            styleFileName , false), RTL_TEXTENCODING_UTF8);
    1185             : 
    1186             :     // add color relation
    1187          14 :     OUString colorFileName = "diagrams/colors" + OUString::number(diagramCount) + ".xml";
    1188           7 :     OString colorRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
    1189             :                                            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors",
    1190          21 :                                            colorFileName, false), RTL_TEXTENCODING_UTF8);
    1191             : 
    1192          14 :     OUString drawingFileName;
    1193           7 :     if (drawingDom.is())
    1194             :     {
    1195             :         // add drawing relation
    1196           6 :         drawingFileName = "diagrams/drawing" + OUString::number(diagramCount) + ".xml";
    1197           6 :         OUString drawingRelId = m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
    1198             :                                 "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing",
    1199          12 :                                 drawingFileName , false);
    1200             : 
    1201             :         // the data dom contains a reference to the drawing relation. We need to update it with the new generated
    1202             :         // relation value before writing the dom to a file
    1203             : 
    1204             :         // Get the dsp:damaModelExt node from the dom
    1205             :         uno::Reference< xml::dom::XNodeList > nodeList =
    1206          12 :             dataDom->getElementsByTagNameNS("http://schemas.microsoft.com/office/drawing/2008/diagram", "dataModelExt");
    1207             : 
    1208             :         // There must be one element only so get it
    1209          12 :         uno::Reference< xml::dom::XNode > node = nodeList->item(0);
    1210             : 
    1211             :         // Get the list of attributes of the node
    1212          12 :         uno::Reference< xml::dom::XNamedNodeMap > nodeMap = node->getAttributes();
    1213             : 
    1214             :         // Get the node with the relId attribute and set its new value
    1215          12 :         uno::Reference< xml::dom::XNode > relIdNode = nodeMap->getNamedItem("relId");
    1216          12 :         relIdNode->setNodeValue(drawingRelId);
    1217             :     }
    1218             : 
    1219             :     pFS->singleElementNS(XML_dgm, XML_relIds,
    1220             :                          FSNS(XML_xmlns, XML_dgm), "http://schemas.openxmlformats.org/drawingml/2006/diagram",
    1221             :                          FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
    1222             :                          FSNS(XML_r, XML_dm), dataRelId.getStr(),
    1223             :                          FSNS(XML_r, XML_lo), layoutRelId.getStr(),
    1224             :                          FSNS(XML_r, XML_qs), styleRelId.getStr(),
    1225             :                          FSNS(XML_r, XML_cs), colorRelId.getStr(),
    1226           7 :                          FSEND);
    1227             : 
    1228           7 :     pFS->endElementNS(XML_a, XML_graphicData);
    1229           7 :     pFS->endElementNS(XML_a, XML_graphic);
    1230           7 :     endDMLAnchorInline(&rFrameFormat);
    1231             : 
    1232          14 :     uno::Reference< xml::sax::XSAXSerializable > serializer;
    1233          14 :     uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
    1234             : 
    1235             :     // write data file
    1236           7 :     serializer.set(dataDom, uno::UNO_QUERY);
    1237           7 :     uno::Reference< io::XOutputStream > xDataOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(
    1238          21 :                 "word/" + dataFileName, "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml");
    1239           7 :     writer->setOutputStream(xDataOutputStream);
    1240           7 :     serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
    1241           7 :                           uno::Sequence< beans::StringPair >());
    1242             : 
    1243             :     // write the associated Images and rels for data file
    1244           7 :     writeDiagramRels(dataDom, xDataRelSeq, xDataOutputStream, OUString("OOXDiagramDataRels"), nAnchorId);
    1245             : 
    1246             :     // write layout file
    1247           7 :     serializer.set(layoutDom, uno::UNO_QUERY);
    1248          28 :     writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + layoutFileName,
    1249          28 :                             "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"));
    1250           7 :     serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
    1251           7 :                           uno::Sequence< beans::StringPair >());
    1252             : 
    1253             :     // write style file
    1254           7 :     serializer.set(styleDom, uno::UNO_QUERY);
    1255          28 :     writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + styleFileName,
    1256          28 :                             "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"));
    1257           7 :     serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
    1258           7 :                           uno::Sequence< beans::StringPair >());
    1259             : 
    1260             :     // write color file
    1261           7 :     serializer.set(colorDom, uno::UNO_QUERY);
    1262          28 :     writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + colorFileName,
    1263          28 :                             "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"));
    1264           7 :     serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
    1265           7 :                           uno::Sequence< beans::StringPair >());
    1266             : 
    1267             :     // write drawing file
    1268             : 
    1269           7 :     if (drawingDom.is())
    1270             :     {
    1271           6 :         serializer.set(drawingDom, uno::UNO_QUERY);
    1272          18 :         uno::Reference< io::XOutputStream > xDrawingOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + drawingFileName,
    1273          24 :                 "application/vnd.openxmlformats-officedocument.drawingml.diagramDrawing+xml");
    1274           6 :         writer->setOutputStream(xDrawingOutputStream);
    1275           6 :         serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
    1276           6 :                               uno::Sequence< beans::StringPair >());
    1277             : 
    1278             :         // write the associated Images and rels for drawing file
    1279          12 :         uno::Sequence< uno::Sequence< uno::Any > > xDrawingRelSeq;
    1280           6 :         diagramDrawing[1] >>= xDrawingRelSeq;
    1281          12 :         writeDiagramRels(drawingDom, xDrawingRelSeq, xDrawingOutputStream, OUString("OOXDiagramDrawingRels"), nAnchorId);
    1282           7 :     }
    1283             : }
    1284             : 
    1285           1 : void DocxSdrExport::writeOnlyTextOfFrame(sw::Frame* pParentFrame)
    1286             : {
    1287           1 :     const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
    1288           1 :     const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
    1289           1 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
    1290             : 
    1291           1 :     sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
    1292           1 :     sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
    1293             : 
    1294             :     //Save data here and restore when out of scope
    1295           2 :     ExportDataSaveRestore aDataGuard(m_pImpl->m_rExport, nStt, nEnd, pParentFrame);
    1296             : 
    1297           1 :     m_pImpl->m_pBodyPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
    1298           1 :     m_pImpl->m_bFrameBtLr = m_pImpl->checkFrameBtlr(m_pImpl->m_rExport.m_pDoc->GetNodes()[nStt], /*bDML=*/true);
    1299           1 :     m_pImpl->m_bFlyFrameGraphic = true;
    1300           1 :     m_pImpl->m_rExport.WriteText();
    1301           1 :     m_pImpl->m_bFlyFrameGraphic = false;
    1302           2 :     m_pImpl->m_bFrameBtLr = false;
    1303           1 : }
    1304             : 
    1305          21 : void DocxSdrExport::writeBoxItemLine(const SvxBoxItem& rBox)
    1306             : {
    1307          21 :     const editeng::SvxBorderLine* pBorderLine = 0;
    1308             : 
    1309          21 :     if (rBox.GetTop())
    1310             :     {
    1311          21 :         pBorderLine = rBox.GetTop();
    1312             :     }
    1313           0 :     else if (rBox.GetLeft())
    1314             :     {
    1315           0 :         pBorderLine = rBox.GetLeft();
    1316             :     }
    1317           0 :     else if (rBox.GetBottom())
    1318             :     {
    1319           0 :         pBorderLine = rBox.GetBottom();
    1320             :     }
    1321           0 :     else if (rBox.GetRight())
    1322             :     {
    1323           0 :         pBorderLine = rBox.GetRight();
    1324             :     }
    1325             : 
    1326          21 :     if (!pBorderLine)
    1327             :     {
    1328          21 :         return;
    1329             :     }
    1330             : 
    1331          21 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
    1332          21 :     double fConverted(editeng::ConvertBorderWidthToWord(pBorderLine->GetBorderLineStyle(), pBorderLine->GetWidth()));
    1333          42 :     OString sWidth(OString::number(TwipsToEMU(fConverted)));
    1334             :     pFS->startElementNS(XML_a, XML_ln,
    1335             :                         XML_w, sWidth.getStr(),
    1336          21 :                         FSEND);
    1337             : 
    1338          21 :     pFS->startElementNS(XML_a, XML_solidFill, FSEND);
    1339          42 :     OString sColor(msfilter::util::ConvertColor(pBorderLine->GetColor()));
    1340             :     pFS->singleElementNS(XML_a, XML_srgbClr,
    1341             :                          XML_val, sColor,
    1342          21 :                          FSEND);
    1343          21 :     pFS->endElementNS(XML_a, XML_solidFill);
    1344             : 
    1345          21 :     if (drawing::LineStyle_DASH == pBorderLine->GetBorderLineStyle()) // Line Style is Dash type
    1346           0 :         pFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dash", FSEND);
    1347             : 
    1348          42 :     pFS->endElementNS(XML_a, XML_ln);
    1349             : }
    1350             : 
    1351         184 : void DocxSdrExport::writeDMLTextFrame(sw::Frame* pParentFrame, int nAnchorId, bool bTextBoxOnly)
    1352             : {
    1353         184 :     bool bDMLAndVMLDrawingOpen = m_pImpl->m_bDMLAndVMLDrawingOpen;
    1354         184 :     m_pImpl->m_bDMLAndVMLDrawingOpen = true;
    1355             : 
    1356         184 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
    1357         184 :     const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
    1358         184 :     const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
    1359             : 
    1360         184 :     sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
    1361         184 :     sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
    1362             : 
    1363             :     //Save data here and restore when out of scope
    1364         368 :     ExportDataSaveRestore aDataGuard(m_pImpl->m_rExport, nStt, nEnd, pParentFrame);
    1365             : 
    1366             :     // When a frame has some low height, but automatically expanded due
    1367             :     // to lots of contents, this size contains the real size.
    1368         184 :     const Size aSize = pParentFrame->GetSize();
    1369             : 
    1370         368 :     uno::Reference< drawing::XShape > xShape;
    1371         184 :     const SdrObject* pSdrObj = rFrameFormat.FindRealSdrObject();
    1372         184 :     if (pSdrObj)
    1373         173 :         xShape = uno::Reference< drawing::XShape >(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
    1374         368 :     uno::Reference< beans::XPropertySet > xPropertySet(xShape, uno::UNO_QUERY);
    1375         368 :     uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
    1376         184 :     if (xPropertySet.is())
    1377         173 :         xPropSetInfo = xPropertySet->getPropertySetInfo();
    1378             : 
    1379         184 :     m_pImpl->m_pBodyPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
    1380             :     {
    1381         184 :         drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
    1382         184 :         if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("TextVerticalAdjust"))
    1383         173 :             xPropertySet->getPropertyValue("TextVerticalAdjust") >>= eAdjust;
    1384         184 :         m_pImpl->m_pBodyPrAttrList->add(XML_anchor, oox::drawingml::GetTextVerticalAdjust(eAdjust));
    1385             :     }
    1386             : 
    1387         184 :     if (!bTextBoxOnly)
    1388             :     {
    1389          68 :         startDMLAnchorInline(&rFrameFormat, aSize);
    1390             : 
    1391          68 :         sax_fastparser::FastAttributeList* pDocPrAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
    1392          68 :         pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
    1393          68 :         pDocPrAttrList->add(XML_name, OUStringToOString(rFrameFormat.GetName(), RTL_TEXTENCODING_UTF8).getStr());
    1394          68 :         sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
    1395          68 :         pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
    1396             : 
    1397             :         pFS->startElementNS(XML_a, XML_graphic,
    1398             :                             FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
    1399          68 :                             FSEND);
    1400             :         pFS->startElementNS(XML_a, XML_graphicData,
    1401             :                             XML_uri, "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
    1402          68 :                             FSEND);
    1403          68 :         pFS->startElementNS(XML_wps, XML_wsp, FSEND);
    1404             :         pFS->singleElementNS(XML_wps, XML_cNvSpPr,
    1405             :                              XML_txBox, "1",
    1406          68 :                              FSEND);
    1407             : 
    1408         136 :         uno::Any aRotation ;
    1409          68 :         m_pImpl->m_nDMLandVMLTextFrameRotation = 0;
    1410          68 :         if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
    1411             :         {
    1412          60 :             uno::Sequence< beans::PropertyValue > propList;
    1413          60 :             xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
    1414          95 :             for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
    1415             :             {
    1416          36 :                 OUString propName = propList[nProp].Name;
    1417          36 :                 if (propName == "mso-rotation-angle")
    1418             :                 {
    1419           1 :                     aRotation = propList[nProp].Value ;
    1420           1 :                     break;
    1421             :                 }
    1422          95 :             }
    1423             :         }
    1424          68 :         aRotation >>= m_pImpl->m_nDMLandVMLTextFrameRotation ;
    1425         136 :         OString sRotation(OString::number((OOX_DRAWINGML_EXPORT_ROTATE_CLOCKWISIFY(m_pImpl->m_nDMLandVMLTextFrameRotation))));
    1426             :         // Shape properties
    1427          68 :         pFS->startElementNS(XML_wps, XML_spPr, FSEND);
    1428          68 :         if (m_pImpl->m_nDMLandVMLTextFrameRotation)
    1429             :         {
    1430             :             pFS->startElementNS(XML_a, XML_xfrm,
    1431             :                                 XML_rot, sRotation.getStr(),
    1432           1 :                                 FSEND);
    1433             :         }
    1434             :         else
    1435             :         {
    1436          67 :             pFS->startElementNS(XML_a, XML_xfrm, FSEND);
    1437             :         }
    1438             :         pFS->singleElementNS(XML_a, XML_off,
    1439             :                              XML_x, "0",
    1440             :                              XML_y, "0",
    1441          68 :                              FSEND);
    1442         136 :         OString aWidth(OString::number(TwipsToEMU(aSize.Width())));
    1443         136 :         OString aHeight(OString::number(TwipsToEMU(aSize.Height())));
    1444             :         pFS->singleElementNS(XML_a, XML_ext,
    1445             :                              XML_cx, aWidth.getStr(),
    1446             :                              XML_cy, aHeight.getStr(),
    1447          68 :                              FSEND);
    1448          68 :         pFS->endElementNS(XML_a, XML_xfrm);
    1449         136 :         OUString shapeType = "rect";
    1450          68 :         if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
    1451             :         {
    1452          60 :             uno::Sequence< beans::PropertyValue > propList;
    1453          60 :             xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
    1454          96 :             for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
    1455             :             {
    1456          36 :                 OUString propName = propList[nProp].Name;
    1457          36 :                 if (propName == "mso-orig-shape-type")
    1458             :                 {
    1459           0 :                     propList[nProp].Value >>= shapeType;
    1460           0 :                     break;
    1461             :                 }
    1462          96 :             }
    1463             :         }
    1464             :         //Empty shapeType will lead to corruption so to avoid that shapeType is set to default i.e. "rect"
    1465          68 :         if (shapeType.isEmpty())
    1466           0 :             shapeType = "rect";
    1467             : 
    1468             :         pFS->singleElementNS(XML_a, XML_prstGeom,
    1469             :                              XML_prst, OUStringToOString(shapeType, RTL_TEXTENCODING_UTF8).getStr(),
    1470          68 :                              FSEND);
    1471          68 :         m_pImpl->m_bDMLTextFrameSyntax = true;
    1472          68 :         m_pImpl->m_rExport.OutputFormat(pParentFrame->GetFrameFormat(), false, false, true);
    1473          68 :         m_pImpl->m_bDMLTextFrameSyntax = false;
    1474          68 :         writeDMLEffectLst(rFrameFormat);
    1475         136 :         pFS->endElementNS(XML_wps, XML_spPr);
    1476             :     }
    1477             : 
    1478         184 :     m_pImpl->m_rExport.m_pParentFrame = NULL;
    1479         184 :     bool skipTxBxContent = false ;
    1480         184 :     bool isTxbxLinked = false ;
    1481             : 
    1482             :     /* Check if the text box is linked and then decides whether
    1483             :        to write the tag txbx or linkedTxbx
    1484             :     */
    1485         714 :     if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("ChainPrevName") &&
    1486         530 :             xPropSetInfo->hasPropertyByName("ChainNextName"))
    1487             :     {
    1488         173 :         OUString sChainPrevName;
    1489         346 :         OUString sChainNextName;
    1490             : 
    1491         173 :         xPropertySet->getPropertyValue("ChainPrevName") >>= sChainPrevName ;
    1492         173 :         xPropertySet->getPropertyValue("ChainNextName") >>= sChainNextName ;
    1493             : 
    1494         173 :         if (!sChainPrevName.isEmpty())
    1495             :         {
    1496             :             /* no text content should be added to this tag,
    1497             :                since the textbox is linked, the entire content
    1498             :                is written in txbx block
    1499             :             */
    1500           1 :             ++m_pImpl->m_nSeq ;
    1501             :             pFS->singleElementNS(XML_wps, XML_linkedTxbx,
    1502           1 :                                  XML_id,  I32S(m_pImpl->m_nId),
    1503           1 :                                  XML_seq, I32S(m_pImpl->m_nSeq),
    1504           2 :                                  FSEND);
    1505           1 :             skipTxBxContent = true ;
    1506             : 
    1507             :             //Text box chaining for a group of textboxes ends here,
    1508             :             //therefore reset the seq.
    1509           1 :             if (sChainNextName.isEmpty())
    1510           1 :                 m_pImpl->m_nSeq = 0 ;
    1511             :         }
    1512         172 :         else if (sChainPrevName.isEmpty() && !sChainNextName.isEmpty())
    1513             :         {
    1514             :             /* this is the first textbox in the chaining, we add the text content
    1515             :                to this block*/
    1516           1 :             ++m_pImpl->m_nId ;
    1517             :             //since the text box is linked, it needs an id.
    1518             :             pFS->startElementNS(XML_wps, XML_txbx,
    1519           1 :                                 XML_id, I32S(m_pImpl->m_nId),
    1520           1 :                                 FSEND);
    1521           1 :             isTxbxLinked = true ;
    1522         173 :         }
    1523             :     }
    1524             : 
    1525         184 :     if (!skipTxBxContent)
    1526             :     {
    1527         183 :         if (!isTxbxLinked)
    1528         182 :             pFS->startElementNS(XML_wps, XML_txbx, FSEND);//text box is not linked, therefore no id.
    1529             : 
    1530         183 :         pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
    1531             : 
    1532         183 :         m_pImpl->m_bFrameBtLr = m_pImpl->checkFrameBtlr(m_pImpl->m_rExport.m_pDoc->GetNodes()[nStt], /*bDML=*/true);
    1533         183 :         m_pImpl->m_bFlyFrameGraphic = true;
    1534         183 :         m_pImpl->m_rExport.WriteText();
    1535         183 :         if (m_pImpl->m_bParagraphSdtOpen)
    1536             :         {
    1537           1 :             m_pImpl->m_rExport.DocxAttrOutput().EndParaSdtBlock();
    1538           1 :             m_pImpl->m_bParagraphSdtOpen = false;
    1539             :         }
    1540         183 :         m_pImpl->m_bFlyFrameGraphic = false;
    1541         183 :         m_pImpl->m_bFrameBtLr = false;
    1542             : 
    1543         183 :         pFS->endElementNS(XML_w, XML_txbxContent);
    1544         183 :         pFS->endElementNS(XML_wps, XML_txbx);
    1545             :     }
    1546         368 :     sax_fastparser::XFastAttributeListRef xBodyPrAttrList(m_pImpl->m_pBodyPrAttrList);
    1547         184 :     m_pImpl->m_pBodyPrAttrList = NULL;
    1548         184 :     if (!bTextBoxOnly)
    1549             :     {
    1550          68 :         pFS->startElementNS(XML_wps, XML_bodyPr, xBodyPrAttrList);
    1551             :         // AutoSize of the Text Frame.
    1552          68 :         const SwFormatFrmSize& rSize = rFrameFormat.GetFrmSize();
    1553          68 :         pFS->singleElementNS(XML_a, (rSize.GetHeightSizeType() == ATT_VAR_SIZE ? XML_spAutoFit : XML_noAutofit), FSEND);
    1554          68 :         pFS->endElementNS(XML_wps, XML_bodyPr);
    1555             : 
    1556          68 :         pFS->endElementNS(XML_wps, XML_wsp);
    1557          68 :         pFS->endElementNS(XML_a, XML_graphicData);
    1558          68 :         pFS->endElementNS(XML_a, XML_graphic);
    1559             : 
    1560             :         // Relative size of the Text Frame.
    1561          68 :         if (rSize.GetWidthPercent())
    1562             :         {
    1563             :             pFS->startElementNS(XML_wp14, XML_sizeRelH,
    1564           2 :                                 XML_relativeFrom, (rSize.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME ? "page" : "margin"),
    1565           2 :                                 FSEND);
    1566           2 :             pFS->startElementNS(XML_wp14, XML_pctWidth, FSEND);
    1567           2 :             pFS->writeEscaped(OUString::number(rSize.GetWidthPercent() * oox::drawingml::PER_PERCENT));
    1568           2 :             pFS->endElementNS(XML_wp14, XML_pctWidth);
    1569           2 :             pFS->endElementNS(XML_wp14, XML_sizeRelH);
    1570             :         }
    1571          68 :         if (rSize.GetHeightPercent())
    1572             :         {
    1573             :             pFS->startElementNS(XML_wp14, XML_sizeRelV,
    1574           0 :                                 XML_relativeFrom, (rSize.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME ? "page" : "margin"),
    1575           0 :                                 FSEND);
    1576           0 :             pFS->startElementNS(XML_wp14, XML_pctHeight, FSEND);
    1577           0 :             pFS->writeEscaped(OUString::number(rSize.GetHeightPercent() * oox::drawingml::PER_PERCENT));
    1578           0 :             pFS->endElementNS(XML_wp14, XML_pctHeight);
    1579           0 :             pFS->endElementNS(XML_wp14, XML_sizeRelV);
    1580             :         }
    1581             : 
    1582          68 :         endDMLAnchorInline(&rFrameFormat);
    1583             :     }
    1584         368 :     m_pImpl->m_bDMLAndVMLDrawingOpen = bDMLAndVMLDrawingOpen;
    1585         184 : }
    1586             : 
    1587         141 : void DocxSdrExport::writeVMLTextFrame(sw::Frame* pParentFrame, bool bTextBoxOnly)
    1588             : {
    1589         141 :     bool bDMLAndVMLDrawingOpen = m_pImpl->m_bDMLAndVMLDrawingOpen;
    1590         141 :     m_pImpl->m_bDMLAndVMLDrawingOpen = true;
    1591             : 
    1592         141 :     sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
    1593         141 :     const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
    1594         141 :     const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
    1595             : 
    1596         141 :     sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
    1597         141 :     sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
    1598             : 
    1599             :     //Save data here and restore when out of scope
    1600         282 :     ExportDataSaveRestore aDataGuard(m_pImpl->m_rExport, nStt, nEnd, pParentFrame);
    1601             : 
    1602             :     // When a frame has some low height, but automatically expanded due
    1603             :     // to lots of contents, this size contains the real size.
    1604         141 :     const Size aSize = pParentFrame->GetSize();
    1605         141 :     m_pImpl->m_pFlyFrameSize = &aSize;
    1606             : 
    1607         141 :     m_pImpl->m_bTextFrameSyntax = true;
    1608         141 :     m_pImpl->m_pFlyAttrList.reset(sax_fastparser::FastSerializerHelper::createAttrList());
    1609         141 :     m_pImpl->m_pTextboxAttrList.reset(sax_fastparser::FastSerializerHelper::createAttrList());
    1610         141 :     m_pImpl->m_aTextFrameStyle = "position:absolute";
    1611         141 :     if (!bTextBoxOnly)
    1612             :     {
    1613          68 :         OString sRotation(OString::number(m_pImpl->m_nDMLandVMLTextFrameRotation / -100));
    1614          68 :         m_pImpl->m_rExport.SdrExporter().getTextFrameStyle().append(";rotation:").append(sRotation);
    1615             :     }
    1616         141 :     m_pImpl->m_rExport.OutputFormat(pParentFrame->GetFrameFormat(), false, false, true);
    1617         141 :     m_pImpl->m_pFlyAttrList->add(XML_style, m_pImpl->m_aTextFrameStyle.makeStringAndClear());
    1618             : 
    1619         141 :     const SdrObject* pObject = pParentFrame->GetFrameFormat().FindRealSdrObject();
    1620         141 :     if (pObject != NULL)
    1621             :     {
    1622         129 :         OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObject);
    1623         129 :         if (!sAnchorId.isEmpty())
    1624           0 :             m_pImpl->m_pFlyAttrList->addNS(XML_w14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
    1625             :     }
    1626         282 :     sax_fastparser::XFastAttributeListRef xFlyAttrList(m_pImpl->m_pFlyAttrList.release());
    1627         141 :     m_pImpl->m_bFrameBtLr = m_pImpl->checkFrameBtlr(m_pImpl->m_rExport.m_pDoc->GetNodes()[nStt], /*bDML=*/false);
    1628         282 :     sax_fastparser::XFastAttributeListRef xTextboxAttrList(m_pImpl->m_pTextboxAttrList.release());
    1629         141 :     m_pImpl->m_bTextFrameSyntax = false;
    1630         141 :     m_pImpl->m_pFlyFrameSize = 0;
    1631         141 :     m_pImpl->m_rExport.m_pParentFrame = NULL;
    1632             : 
    1633         141 :     if (!bTextBoxOnly)
    1634             :     {
    1635          68 :         pFS->startElementNS(XML_w, XML_pict, FSEND);
    1636          68 :         pFS->startElementNS(XML_v, XML_rect, xFlyAttrList);
    1637          68 :         m_pImpl->textFrameShadow(rFrameFormat);
    1638          68 :         if (m_pImpl->m_pFlyFillAttrList)
    1639             :         {
    1640          14 :             sax_fastparser::XFastAttributeListRef xFlyFillAttrList(m_pImpl->m_pFlyFillAttrList.release());
    1641          14 :             pFS->singleElementNS(XML_v, XML_fill, xFlyFillAttrList);
    1642             :         }
    1643          68 :         if (m_pImpl->m_pDashLineStyleAttr)
    1644             :         {
    1645           0 :             sax_fastparser::XFastAttributeListRef xDashLineStyleAttr(m_pImpl->m_pDashLineStyleAttr.release());
    1646           0 :             pFS->singleElementNS(XML_v, XML_stroke, xDashLineStyleAttr);
    1647             :         }
    1648          68 :         pFS->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
    1649             :     }
    1650         141 :     pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
    1651         141 :     m_pImpl->m_bFlyFrameGraphic = true;
    1652         141 :     m_pImpl->m_rExport.WriteText();
    1653         141 :     if (m_pImpl->m_bParagraphSdtOpen)
    1654             :     {
    1655           1 :         m_pImpl->m_rExport.DocxAttrOutput().EndParaSdtBlock();
    1656           1 :         m_pImpl->m_bParagraphSdtOpen = false;
    1657             :     }
    1658         141 :     m_pImpl->m_bFlyFrameGraphic = false;
    1659         141 :     pFS->endElementNS(XML_w, XML_txbxContent);
    1660         141 :     if (!bTextBoxOnly)
    1661             :     {
    1662          68 :         pFS->endElementNS(XML_v, XML_textbox);
    1663             : 
    1664          68 :         if (m_pImpl->m_pFlyWrapAttrList)
    1665             :         {
    1666          38 :             sax_fastparser::XFastAttributeListRef xFlyWrapAttrList(m_pImpl->m_pFlyWrapAttrList);
    1667          38 :             m_pImpl->m_pFlyWrapAttrList = NULL;
    1668          38 :             pFS->singleElementNS(XML_w10, XML_wrap, xFlyWrapAttrList);
    1669             :         }
    1670             : 
    1671          68 :         pFS->endElementNS(XML_v, XML_rect);
    1672          68 :         pFS->endElementNS(XML_w, XML_pict);
    1673             :     }
    1674         141 :     m_pImpl->m_bFrameBtLr = false;
    1675             : 
    1676         282 :     m_pImpl->m_bDMLAndVMLDrawingOpen = bDMLAndVMLDrawingOpen;
    1677         141 : }
    1678             : 
    1679         325 : bool DocxSdrExport::Impl::checkFrameBtlr(SwNode* pStartNode, bool bDML)
    1680             : {
    1681             :     // The intended usage is to pass either a valid VML or DML attribute list.
    1682             :     if (bDML)
    1683             :         assert(m_pBodyPrAttrList);
    1684             :     else
    1685             :         assert(m_pTextboxAttrList);
    1686             : 
    1687         325 :     if (!pStartNode->IsTextNode())
    1688          31 :         return false;
    1689             : 
    1690         294 :     SwTextNode* pTextNode = pStartNode->GetTextNode();
    1691             : 
    1692         294 :     const SfxPoolItem* pItem = 0; // explicitly init to avoid warnings
    1693         294 :     bool bItemSet = false;
    1694         294 :     if (pTextNode->HasSwAttrSet())
    1695             :     {
    1696         216 :         const SwAttrSet& rAttrSet = pTextNode->GetSwAttrSet();
    1697         216 :         bItemSet = rAttrSet.GetItemState(RES_CHRATR_ROTATE, true, &pItem) == SfxItemState::SET;
    1698             :     }
    1699             : 
    1700         294 :     if (!bItemSet)
    1701             :     {
    1702         290 :         if (!pTextNode->HasHints())
    1703         255 :             return false;
    1704             : 
    1705         193 :         SwTextAttr* pTextAttr = pTextNode->GetTextAttrAt(0, RES_TXTATR_AUTOFMT);
    1706             : 
    1707         193 :         if (!pTextAttr || pTextAttr->Which() != RES_TXTATR_AUTOFMT)
    1708          61 :             return false;
    1709             : 
    1710         132 :         std::shared_ptr<SfxItemSet> pItemSet = pTextAttr->GetAutoFormat().GetStyleHandle();
    1711         132 :         bItemSet = pItemSet->GetItemState(RES_CHRATR_ROTATE, true, &pItem) == SfxItemState::SET;
    1712             :     }
    1713             : 
    1714         136 :     if (bItemSet)
    1715             :     {
    1716           6 :         const SvxCharRotateItem& rCharRotate = static_cast<const SvxCharRotateItem&>(*pItem);
    1717           6 :         if (rCharRotate.GetValue() == 900)
    1718             :         {
    1719           6 :             if (bDML)
    1720           3 :                 m_pBodyPrAttrList->add(XML_vert, "vert270");
    1721             :             else
    1722           3 :                 m_pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
    1723           6 :             return true;
    1724             :         }
    1725             :     }
    1726         130 :     return false;
    1727             : }
    1728             : 
    1729         187 : bool DocxSdrExport::isTextBox(const SwFrameFormat& rFrameFormat)
    1730             : {
    1731         187 :     return m_pImpl->m_aTextBoxes.find(&rFrameFormat) != m_pImpl->m_aTextBoxes.end();
    1732          60 : }
    1733             : 
    1734             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11