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

Generated by: LCOV version 1.10