1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <com/sun/star/drawing/XShape.hpp>
11 #include <com/sun/star/xml/dom/XDocument.hpp>
12 #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
13 #include <com/sun/star/xml/sax/Writer.hpp>
14 #include <editeng/lrspitem.hxx>
15 #include <editeng/ulspitem.hxx>
16 #include <editeng/opaqitem.hxx>
17 #include <editeng/shaditem.hxx>
18 #include <editeng/unoprnms.hxx>
19 #include <editeng/charrotateitem.hxx>
20 #include <svx/svdobj.hxx>
21 #include <svx/svdmodel.hxx>
22 #include <svx/svdogrp.hxx>
23 #include <oox/token/tokens.hxx>
24 #include <oox/export/drawingml.hxx>
25 #include <oox/drawingml/drawingmltypes.hxx>
26 #include <oox/export/utils.hxx>
27 #include <oox/export/vmlexport.hxx>
28 #include <oox/token/properties.hxx>
32 #include <textboxhelper.hxx>
33 #include <fmtanchr.hxx>
34 #include <fmtornt.hxx>
35 #include <fmtsrnd.hxx>
36 #include <fmtcntnt.hxx>
38 #include <txatbase.hxx>
39 #include <fmtautofmt.hxx>
40 #include <fmtfsize.hxx>
42 #include <drawdoc.hxx>
43 #include <docxsdrexport.hxx>
44 #include <docxexport.hxx>
45 #include <docxexportfilter.hxx>
46 #include <writerhelper.hxx>
47 #include <comphelper/seqstream.hxx>
50 #include <IDocumentDrawModelAccess.hxx>
52 using namespace com::sun::star
;
58 uno::Sequence
<beans::PropertyValue
> lclGetProperty(uno::Reference
<drawing::XShape
> rShape
, const OUString
& rPropName
)
60 uno::Sequence
<beans::PropertyValue
> aResult
;
61 uno::Reference
<beans::XPropertySet
> xPropertySet(rShape
, uno::UNO_QUERY
);
62 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
;
64 if (!xPropertySet
.is())
67 xPropSetInfo
= xPropertySet
->getPropertySetInfo();
68 if (xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(rPropName
))
70 xPropertySet
->getPropertyValue(rPropName
) >>= aResult
;
75 OUString
lclGetAnchorIdFromGrabBag(const SdrObject
* pObj
)
78 uno::Reference
<drawing::XShape
> xShape(const_cast<SdrObject
*>(pObj
)->getUnoShape(), uno::UNO_QUERY
);
79 OUString aGrabBagName
;
80 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xShape
, uno::UNO_QUERY
);
81 if (xServiceInfo
->supportsService("com.sun.star.text.TextFrame"))
82 aGrabBagName
= "FrameInteropGrabBag";
84 aGrabBagName
= "InteropGrabBag";
85 uno::Sequence
< beans::PropertyValue
> propList
= lclGetProperty(xShape
, aGrabBagName
);
86 for (sal_Int32 nProp
= 0; nProp
< propList
.getLength(); ++nProp
)
88 OUString aPropName
= propList
[nProp
].Name
;
89 if (aPropName
== "AnchorId")
91 propList
[nProp
].Value
>>= aResult
;
98 void lclMovePositionWithRotation(awt::Point
& aPos
, const Size
& rSize
, sal_Int64 nRotation
)
100 // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx)
107 nRotation
= (36000 + nRotation
) % 36000;
108 if (nRotation
% 18000 == 0)
110 while (nRotation
> 9000)
111 nRotation
= (18000 - (nRotation
% 18000));
113 double fVal
= (double) nRotation
* F_PI18000
;
114 double fCos
= cos(fVal
);
115 double fSin
= sin(fVal
);
117 double nWidthHalf
= (double) rSize
.Width() / 2;
118 double nHeightHalf
= (double) rSize
.Height() / 2;
120 double nXDiff
= fSin
* nHeightHalf
+ fCos
* nWidthHalf
- nWidthHalf
;
121 double nYDiff
= fSin
* nWidthHalf
+ fCos
* nHeightHalf
- nHeightHalf
;
129 ExportDataSaveRestore::ExportDataSaveRestore(DocxExport
& rExport
, sal_uLong nStt
, sal_uLong nEnd
, sw::Frame
* pParentFrame
)
132 m_rExport
.SaveData(nStt
, nEnd
);
133 m_rExport
.mpParentFrame
= pParentFrame
;
136 ExportDataSaveRestore::~ExportDataSaveRestore()
138 m_rExport
.RestoreData();
141 /// Holds data used by DocxSdrExport only.
142 struct DocxSdrExport::Impl
144 DocxSdrExport
& m_rSdrExport
;
145 DocxExport
& m_rExport
;
146 sax_fastparser::FSHelperPtr m_pSerializer
;
147 oox::drawingml::DrawingML
* m_pDrawingML
;
148 const Size
* m_pFlyFrameSize
;
149 bool m_bTextFrameSyntax
;
150 bool m_bDMLTextFrameSyntax
;
151 sax_fastparser::FastAttributeList
* m_pFlyAttrList
;
152 sax_fastparser::FastAttributeList
* m_pTextboxAttrList
;
153 OStringBuffer m_aTextFrameStyle
;
156 bool m_bParagraphHasDrawing
; ///Flag for checking drawing in a paragraph.
157 bool m_bFlyFrameGraphic
;
158 sax_fastparser::FastAttributeList
* m_pFlyFillAttrList
;
159 sax_fastparser::FastAttributeList
* m_pFlyWrapAttrList
;
160 sax_fastparser::FastAttributeList
* m_pBodyPrAttrList
;
161 sax_fastparser::FastAttributeList
* m_pDashLineStyleAttr
;
164 bool m_bDMLAndVMLDrawingOpen
;
165 /// List of TextBoxes in this document: they are exported as part of their shape, never alone.
166 std::list
<SwFrmFmt
*> m_aTextBoxes
;
168 Impl(DocxSdrExport
& rSdrExport
, DocxExport
& rExport
, sax_fastparser::FSHelperPtr pSerializer
, oox::drawingml::DrawingML
* pDrawingML
)
169 : m_rSdrExport(rSdrExport
),
171 m_pSerializer(pSerializer
),
172 m_pDrawingML(pDrawingML
),
174 m_bTextFrameSyntax(false),
175 m_bDMLTextFrameSyntax(false),
177 m_pTextboxAttrList(0),
179 m_bDrawingOpen(false),
180 m_bParagraphHasDrawing(false),
181 m_bFlyFrameGraphic(false),
182 m_pFlyFillAttrList(0),
183 m_pFlyWrapAttrList(0),
184 m_pBodyPrAttrList(0),
185 m_pDashLineStyleAttr(0),
188 m_bDMLAndVMLDrawingOpen(false),
189 m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport
.pDoc
))
195 delete m_pFlyAttrList
, m_pFlyAttrList
= NULL
;
196 delete m_pTextboxAttrList
, m_pTextboxAttrList
= NULL
;
199 /// Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax.
201 void textFrameShadow(const SwFrmFmt
& rFrmFmt
);
202 bool isSupportedDMLShape(com::sun::star::uno::Reference
<com::sun::star::drawing::XShape
> xShape
);
205 DocxSdrExport::DocxSdrExport(DocxExport
& rExport
, sax_fastparser::FSHelperPtr pSerializer
, oox::drawingml::DrawingML
* pDrawingML
)
206 : m_pImpl(new Impl(*this, rExport
, pSerializer
, pDrawingML
))
210 DocxSdrExport::~DocxSdrExport()
214 void DocxSdrExport::setSerializer(sax_fastparser::FSHelperPtr pSerializer
)
216 m_pImpl
->m_pSerializer
= pSerializer
;
219 const Size
* DocxSdrExport::getFlyFrameSize()
221 return m_pImpl
->m_pFlyFrameSize
;
224 bool DocxSdrExport::getTextFrameSyntax()
226 return m_pImpl
->m_bTextFrameSyntax
;
229 bool DocxSdrExport::getDMLTextFrameSyntax()
231 return m_pImpl
->m_bDMLTextFrameSyntax
;
234 sax_fastparser::FastAttributeList
*& DocxSdrExport::getFlyAttrList()
236 return m_pImpl
->m_pFlyAttrList
;
239 void DocxSdrExport::setFlyAttrList(sax_fastparser::FastAttributeList
* pAttrList
)
241 m_pImpl
->m_pFlyAttrList
= pAttrList
;
244 sax_fastparser::FastAttributeList
* DocxSdrExport::getTextboxAttrList()
246 return m_pImpl
->m_pTextboxAttrList
;
249 OStringBuffer
& DocxSdrExport::getTextFrameStyle()
251 return m_pImpl
->m_aTextFrameStyle
;
254 bool DocxSdrExport::getFrameBtLr()
256 return m_pImpl
->m_bFrameBtLr
;
259 bool DocxSdrExport::IsDrawingOpen()
261 return m_pImpl
->m_bDrawingOpen
;
264 bool DocxSdrExport::IsDMLAndVMLDrawingOpen()
266 return m_pImpl
->m_bDMLAndVMLDrawingOpen
;
269 bool DocxSdrExport::IsParagraphHasDrawing()
271 return m_pImpl
->m_bParagraphHasDrawing
;
274 void DocxSdrExport::setParagraphHasDrawing(bool bParagraphHasDrawing
)
276 m_pImpl
->m_bParagraphHasDrawing
= bParagraphHasDrawing
;
279 sax_fastparser::FastAttributeList
*& DocxSdrExport::getFlyFillAttrList()
281 return m_pImpl
->m_pFlyFillAttrList
;
284 sax_fastparser::FastAttributeList
* DocxSdrExport::getFlyWrapAttrList()
286 return m_pImpl
->m_pFlyWrapAttrList
;
289 sax_fastparser::FastAttributeList
* DocxSdrExport::getBodyPrAttrList()
291 return m_pImpl
->m_pBodyPrAttrList
;
294 sax_fastparser::FastAttributeList
*& DocxSdrExport::getDashLineStyle()
296 return m_pImpl
->m_pDashLineStyleAttr
;
299 void DocxSdrExport::setFlyWrapAttrList(sax_fastparser::FastAttributeList
* pAttrList
)
301 m_pImpl
->m_pFlyWrapAttrList
= pAttrList
;
304 void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt
* pFrmFmt
, const Size
& rSize
)
306 m_pImpl
->m_bDrawingOpen
= true;
307 m_pImpl
->m_bParagraphHasDrawing
= true;
308 m_pImpl
->m_pSerializer
->startElementNS(XML_w
, XML_drawing
, FSEND
);
310 const SvxLRSpaceItem pLRSpaceItem
= pFrmFmt
->GetLRSpace(false);
311 const SvxULSpaceItem pULSpaceItem
= pFrmFmt
->GetULSpace(false);
315 if (m_pImpl
->m_bFlyFrameGraphic
)
317 isAnchor
= false; // make Graphic object inside DMLTextFrame & VMLTextFrame as Inline
321 isAnchor
= pFrmFmt
->GetAnchor().GetAnchorId() != FLY_AS_CHAR
;
325 sax_fastparser::FastAttributeList
* attrList
= m_pImpl
->m_pSerializer
->createAttrList();
326 bool bOpaque
= pFrmFmt
->GetOpaque().GetValue();
327 awt::Point
aPos(pFrmFmt
->GetHoriOrient().GetPos(), pFrmFmt
->GetVertOrient().GetPos());
328 const SdrObject
* pObj
= pFrmFmt
->FindRealSdrObject();
331 // SdrObjects know their layer, consider that instead of the frame format.
332 bOpaque
= pObj
->GetLayer() != pFrmFmt
->GetDoc()->getIDocumentDrawModelAccess().GetHellId() && pObj
->GetLayer() != pFrmFmt
->GetDoc()->getIDocumentDrawModelAccess().GetInvisibleHellId();
334 lclMovePositionWithRotation(aPos
, rSize
, pObj
->GetRotateAngle());
336 attrList
->add(XML_behindDoc
, bOpaque
? "0" : "1");
337 attrList
->add(XML_distT
, OString::number(TwipsToEMU(pULSpaceItem
.GetUpper())).getStr());
338 attrList
->add(XML_distB
, OString::number(TwipsToEMU(pULSpaceItem
.GetLower())).getStr());
339 attrList
->add(XML_distL
, OString::number(TwipsToEMU(pLRSpaceItem
.GetLeft())).getStr());
340 attrList
->add(XML_distR
, OString::number(TwipsToEMU(pLRSpaceItem
.GetRight())).getStr());
341 attrList
->add(XML_simplePos
, "0");
342 attrList
->add(XML_locked
, "0");
343 attrList
->add(XML_layoutInCell
, "1");
344 attrList
->add(XML_allowOverlap
, "1"); // TODO
346 // It seems 0 and 1 have special meaning: just start counting from 2 to avoid issues with that.
347 attrList
->add(XML_relativeHeight
, OString::number(pObj
->GetOrdNum() + 2));
349 // relativeHeight is mandatory attribute, if value is not present, we must write default value
350 attrList
->add(XML_relativeHeight
, "0");
353 OUString sAnchorId
= lclGetAnchorIdFromGrabBag(pObj
);
354 if (!sAnchorId
.isEmpty())
355 attrList
->addNS(XML_wp14
, XML_anchorId
, OUStringToOString(sAnchorId
, RTL_TEXTENCODING_UTF8
));
357 sax_fastparser::XFastAttributeListRef
xAttrList(attrList
);
358 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_anchor
, xAttrList
);
359 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_simplePos
, XML_x
, "0", XML_y
, "0", FSEND
); // required, unused
360 const char* relativeFromH
;
361 const char* relativeFromV
;
362 const char* alignH
= NULL
;
363 const char* alignV
= NULL
;
364 switch (pFrmFmt
->GetVertOrient().GetRelationOrient())
366 case text::RelOrientation::PAGE_PRINT_AREA
:
367 relativeFromV
= "margin";
369 case text::RelOrientation::PAGE_FRAME
:
370 relativeFromV
= "page";
372 case text::RelOrientation::FRAME
:
373 relativeFromV
= "paragraph";
375 case text::RelOrientation::TEXT_LINE
:
377 relativeFromV
= "line";
380 switch (pFrmFmt
->GetVertOrient().GetVertOrient())
382 case text::VertOrientation::TOP
:
383 case text::VertOrientation::CHAR_TOP
:
384 case text::VertOrientation::LINE_TOP
:
385 if (pFrmFmt
->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE
)
390 case text::VertOrientation::BOTTOM
:
391 case text::VertOrientation::CHAR_BOTTOM
:
392 case text::VertOrientation::LINE_BOTTOM
:
393 if (pFrmFmt
->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE
)
398 case text::VertOrientation::CENTER
:
399 case text::VertOrientation::CHAR_CENTER
:
400 case text::VertOrientation::LINE_CENTER
:
406 switch (pFrmFmt
->GetHoriOrient().GetRelationOrient())
408 case text::RelOrientation::PAGE_PRINT_AREA
:
409 relativeFromH
= "margin";
411 case text::RelOrientation::PAGE_FRAME
:
412 relativeFromH
= "page";
414 case text::RelOrientation::CHAR
:
415 relativeFromH
= "character";
417 case text::RelOrientation::PAGE_RIGHT
:
418 relativeFromH
= "page";
421 case text::RelOrientation::FRAME
:
423 relativeFromH
= "column";
426 switch (pFrmFmt
->GetHoriOrient().GetHoriOrient())
428 case text::HoriOrientation::LEFT
:
431 case text::HoriOrientation::RIGHT
:
434 case text::HoriOrientation::CENTER
:
437 case text::HoriOrientation::INSIDE
:
440 case text::HoriOrientation::OUTSIDE
:
446 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_positionH
, XML_relativeFrom
, relativeFromH
, FSEND
);
448 * Sizes of integral types
449 * climits header defines constants with the limits of integral types for the specific system and compiler implemetation used.
450 * Use of this might cause platform dependent problem like posOffset exceed the limit.
452 const sal_Int64 MAX_INTEGER_VALUE
= SAL_MAX_INT32
;
453 const sal_Int64 MIN_INTEGER_VALUE
= SAL_MIN_INT32
;
456 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_align
, FSEND
);
457 m_pImpl
->m_pSerializer
->write(alignH
);
458 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_align
);
462 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_posOffset
, FSEND
);
463 sal_Int64 nTwipstoEMU
= TwipsToEMU(aPos
.X
);
465 /* Absolute Position Offset Value is of type Int. Hence it should not be greater than
466 * Maximum value for Int OR Less than the Minimum value for Int.
467 * - Maximum value for Int = 2147483647
468 * - Minimum value for Int = -2147483648
470 * As per ECMA Specification : ECMA-376, Second Edition,
471 * Part 1 - Fundamentals And Markup Language Reference[20.4.3.3 ST_PositionOffset (Absolute Position Offset Value)]
473 * Please refer : http://www.schemacentral.com/sc/xsd/t-xsd_int.html
476 if (nTwipstoEMU
> MAX_INTEGER_VALUE
)
478 nTwipstoEMU
= MAX_INTEGER_VALUE
;
480 else if (nTwipstoEMU
< MIN_INTEGER_VALUE
)
482 nTwipstoEMU
= MIN_INTEGER_VALUE
;
484 m_pImpl
->m_pSerializer
->write(nTwipstoEMU
);
485 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_posOffset
);
487 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_positionH
);
488 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_positionV
, XML_relativeFrom
, relativeFromV
, FSEND
);
491 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_align
, FSEND
);
492 m_pImpl
->m_pSerializer
->write(alignV
);
493 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_align
);
497 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_posOffset
, FSEND
);
498 sal_Int64 nTwipstoEMU
= TwipsToEMU(aPos
.Y
);
499 if (nTwipstoEMU
> MAX_INTEGER_VALUE
)
501 nTwipstoEMU
= MAX_INTEGER_VALUE
;
503 else if (nTwipstoEMU
< MIN_INTEGER_VALUE
)
505 nTwipstoEMU
= MIN_INTEGER_VALUE
;
507 m_pImpl
->m_pSerializer
->write(nTwipstoEMU
);
508 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_posOffset
);
510 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, XML_positionV
);
514 sax_fastparser::FastAttributeList
* aAttrList
= m_pImpl
->m_pSerializer
->createAttrList();
515 aAttrList
->add(XML_distT
, OString::number(TwipsToEMU(pULSpaceItem
.GetUpper())).getStr());
516 aAttrList
->add(XML_distB
, OString::number(TwipsToEMU(pULSpaceItem
.GetLower())).getStr());
517 aAttrList
->add(XML_distL
, OString::number(TwipsToEMU(pLRSpaceItem
.GetLeft())).getStr());
518 aAttrList
->add(XML_distR
, OString::number(TwipsToEMU(pLRSpaceItem
.GetRight())).getStr());
519 const SdrObject
* pObj
= pFrmFmt
->FindRealSdrObject();
522 OUString sAnchorId
= lclGetAnchorIdFromGrabBag(pObj
);
523 if (!sAnchorId
.isEmpty())
524 aAttrList
->addNS(XML_wp14
, XML_anchorId
, OUStringToOString(sAnchorId
, RTL_TEXTENCODING_UTF8
));
526 m_pImpl
->m_pSerializer
->startElementNS(XML_wp
, XML_inline
, aAttrList
);
529 // now the common parts
530 // extent of the image
532 * Extent width is of type long ( i.e cx & cy ) as
534 * per ECMA-376, Second Edition, Part 1 - Fundamentals And Markup Language Reference
535 * [ 20.4.2.7 extent (Drawing Object Size)]
537 * cy is of type a:ST_PositiveCoordinate.
538 * Minimum inclusive: 0
539 * Maximum inclusive: 27273042316900
541 * reference : http://www.schemacentral.com/sc/ooxml/e-wp_extent-1.html
543 * Though ECMA mentions the max value as aforementioned. It appears that MSO does not
544 * handle for the same, infact it acutally can handles a max value of int32 i.e
545 * 2147483647( MAX_INTEGER_VALUE ).
546 * Therefore changing the following accordingly so that LO sync's up with MSO.
550 const sal_Int64 MAX_INTEGER_VALUE
= SAL_MAX_INT32
;
552 // the 'Size' type uses 'long' for width and height, so on
553 // platforms where 'long' is 32 bits they can obviously never be
554 // larger than the max signed 32-bit integer.
555 #if SAL_TYPES_SIZEOFLONG > 4
556 if (rSize
.Width() > MAX_INTEGER_VALUE
)
557 cx
= MAX_INTEGER_VALUE
;
561 if (0 > rSize
.Width())
567 #if SAL_TYPES_SIZEOFLONG > 4
568 if (rSize
.Height() > MAX_INTEGER_VALUE
)
569 cy
= MAX_INTEGER_VALUE
;
573 if (0 > rSize
.Height())
579 OString
aWidth(OString::number(TwipsToEMU(cx
)));
580 //we explicitly check the converted EMU value for the range as mentioned in above comment.
581 aWidth
= (aWidth
.toInt64() > 0 ? (aWidth
.toInt64() > MAX_INTEGER_VALUE
? I64S(MAX_INTEGER_VALUE
) : aWidth
.getStr()): "0");
582 OString
aHeight(OString::number(TwipsToEMU(cy
)));
583 aHeight
= (aHeight
.toInt64() > 0 ? (aHeight
.toInt64() > MAX_INTEGER_VALUE
? I64S(MAX_INTEGER_VALUE
) : aHeight
.getStr()): "0");
585 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_extent
,
590 // effectExtent, extent including the effect (shadow only for now)
591 SvxShadowItem aShadowItem
= pFrmFmt
->GetShadow();
592 OString
aLeftExt("0"), aRightExt("0"), aTopExt("0"), aBottomExt("0");
593 if (aShadowItem
.GetLocation() != SVX_SHADOW_NONE
)
595 OString
aShadowWidth(OString::number(TwipsToEMU(aShadowItem
.GetWidth())));
596 switch (aShadowItem
.GetLocation())
598 case SVX_SHADOW_TOPLEFT
:
599 aTopExt
= aLeftExt
= aShadowWidth
;
601 case SVX_SHADOW_TOPRIGHT
:
602 aTopExt
= aRightExt
= aShadowWidth
;
604 case SVX_SHADOW_BOTTOMLEFT
:
605 aBottomExt
= aLeftExt
= aShadowWidth
;
607 case SVX_SHADOW_BOTTOMRIGHT
:
608 aBottomExt
= aRightExt
= aShadowWidth
;
610 case SVX_SHADOW_NONE
:
616 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_effectExtent
,
625 switch (pFrmFmt
->GetSurround().GetValue())
628 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_wrapTopAndBottom
, FSEND
);
630 case SURROUND_THROUGHT
:
631 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_wrapNone
, FSEND
);
633 case SURROUND_PARALLEL
:
634 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_wrapSquare
,
635 XML_wrapText
, "bothSides", FSEND
);
639 m_pImpl
->m_pSerializer
->singleElementNS(XML_wp
, XML_wrapSquare
,
640 XML_wrapText
, "largest", FSEND
);
646 void DocxSdrExport::endDMLAnchorInline(const SwFrmFmt
* pFrmFmt
)
649 if (m_pImpl
->m_bFlyFrameGraphic
)
651 isAnchor
= false; // end Inline Graphic object inside DMLTextFrame
655 isAnchor
= pFrmFmt
->GetAnchor().GetAnchorId() != FLY_AS_CHAR
;
657 m_pImpl
->m_pSerializer
->endElementNS(XML_wp
, isAnchor
? XML_anchor
: XML_inline
);
659 m_pImpl
->m_pSerializer
->endElementNS(XML_w
, XML_drawing
);
660 m_pImpl
->m_bDrawingOpen
= false;
663 void DocxSdrExport::writeVMLDrawing(const SdrObject
* sdrObj
, const SwFrmFmt
& rFrmFmt
,const Point
& rNdTopLeft
)
665 bool bSwapInPage
= false;
666 if (!(sdrObj
)->GetPage())
668 if (SdrModel
* pModel
= m_pImpl
->m_rExport
.pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
670 if (SdrPage
* pPage
= pModel
->GetPage(0))
673 const_cast< SdrObject
* >(sdrObj
)->SetPage(pPage
);
678 m_pImpl
->m_pSerializer
->startElementNS(XML_w
, XML_pict
, FSEND
);
679 m_pImpl
->m_pDrawingML
->SetFS(m_pImpl
->m_pSerializer
);
680 // See WinwordAnchoring::SetAnchoring(), these are not part of the SdrObject, have to be passed around manually.
682 SwFmtHoriOrient rHoriOri
= (rFrmFmt
).GetHoriOrient();
683 SwFmtVertOrient rVertOri
= (rFrmFmt
).GetVertOrient();
684 m_pImpl
->m_rExport
.VMLExporter().AddSdrObject(*(sdrObj
),
685 rHoriOri
.GetHoriOrient(), rVertOri
.GetVertOrient(),
686 rHoriOri
.GetRelationOrient(),
687 rVertOri
.GetRelationOrient(), (&rNdTopLeft
), true);
688 m_pImpl
->m_pSerializer
->endElementNS(XML_w
, XML_pict
);
691 const_cast< SdrObject
* >(sdrObj
)->SetPage(0);
694 bool lcl_isLockedCanvas(uno::Reference
<drawing::XShape
> xShape
)
697 uno::Sequence
< beans::PropertyValue
> propList
=
698 lclGetProperty(xShape
, "InteropGrabBag");
699 for (sal_Int32 nProp
=0; nProp
< propList
.getLength(); ++nProp
)
701 OUString propName
= propList
[nProp
].Name
;
702 if (propName
== "LockedCanvas")
705 * Export as Locked Canvas only if the property
706 * is in the PropertySet
715 void DocxSdrExport::writeDMLDrawing(const SdrObject
* pSdrObject
, const SwFrmFmt
* pFrmFmt
, int nAnchorId
)
717 uno::Reference
<drawing::XShape
> xShape(const_cast<SdrObject
*>(pSdrObject
)->getUnoShape(), uno::UNO_QUERY_THROW
);
718 if (!m_pImpl
->isSupportedDMLShape(xShape
))
721 sax_fastparser::FSHelperPtr pFS
= m_pImpl
->m_pSerializer
;
722 Size
aSize(pSdrObject
->GetLogicRect().GetWidth(), pSdrObject
->GetLogicRect().GetHeight());
723 startDMLAnchorInline(pFrmFmt
, aSize
);
725 sax_fastparser::FastAttributeList
* pDocPrAttrList
= pFS
->createAttrList();
726 pDocPrAttrList
->add(XML_id
, OString::number(nAnchorId
).getStr());
727 pDocPrAttrList
->add(XML_name
, OUStringToOString(pSdrObject
->GetName(), RTL_TEXTENCODING_UTF8
));
728 if (!pSdrObject
->GetTitle().isEmpty())
729 pDocPrAttrList
->add(XML_title
, OUStringToOString(pSdrObject
->GetTitle(), RTL_TEXTENCODING_UTF8
));
730 if (!pSdrObject
->GetDescription().isEmpty())
731 pDocPrAttrList
->add(XML_descr
, OUStringToOString(pSdrObject
->GetDescription(), RTL_TEXTENCODING_UTF8
));
732 sax_fastparser::XFastAttributeListRef
xDocPrAttrListRef(pDocPrAttrList
);
733 pFS
->singleElementNS(XML_wp
, XML_docPr
, xDocPrAttrListRef
);
735 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xShape
, uno::UNO_QUERY_THROW
);
736 const char* pNamespace
= "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
737 if (xServiceInfo
->supportsService("com.sun.star.drawing.GroupShape"))
738 pNamespace
= "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
739 else if (xServiceInfo
->supportsService("com.sun.star.drawing.GraphicObjectShape"))
740 pNamespace
= "http://schemas.openxmlformats.org/drawingml/2006/picture";
741 pFS
->startElementNS(XML_a
, XML_graphic
,
742 FSNS(XML_xmlns
, XML_a
), "http://schemas.openxmlformats.org/drawingml/2006/main",
744 pFS
->startElementNS(XML_a
, XML_graphicData
,
748 bool bLockedCanvas
= lcl_isLockedCanvas(xShape
);
750 pFS
->startElementNS(XML_lc
, XML_lockedCanvas
,
751 FSNS(XML_xmlns
, XML_lc
), "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas",
754 m_pImpl
->m_rExport
.OutputDML(xShape
);
757 pFS
->endElementNS(XML_lc
, XML_lockedCanvas
);
758 pFS
->endElementNS(XML_a
, XML_graphicData
);
759 pFS
->endElementNS(XML_a
, XML_graphic
);
761 // Relative size of the drawing.
762 if (pSdrObject
->GetRelativeWidth())
764 // At the moment drawinglayer objects are always relative from page.
765 pFS
->startElementNS(XML_wp14
, XML_sizeRelH
,
766 XML_relativeFrom
, (pSdrObject
->GetRelativeWidthRelation() == text::RelOrientation::FRAME
? "margin" : "page"),
768 pFS
->startElementNS(XML_wp14
, XML_pctWidth
, FSEND
);
769 pFS
->writeEscaped(OUString::number(*pSdrObject
->GetRelativeWidth() * 100 * oox::drawingml::PER_PERCENT
));
770 pFS
->endElementNS(XML_wp14
, XML_pctWidth
);
771 pFS
->endElementNS(XML_wp14
, XML_sizeRelH
);
773 if (pSdrObject
->GetRelativeHeight())
775 pFS
->startElementNS(XML_wp14
, XML_sizeRelV
,
776 XML_relativeFrom
, (pSdrObject
->GetRelativeHeightRelation() == text::RelOrientation::FRAME
? "margin" : "page"),
778 pFS
->startElementNS(XML_wp14
, XML_pctHeight
, FSEND
);
779 pFS
->writeEscaped(OUString::number(*pSdrObject
->GetRelativeHeight() * 100 * oox::drawingml::PER_PERCENT
));
780 pFS
->endElementNS(XML_wp14
, XML_pctHeight
);
781 pFS
->endElementNS(XML_wp14
, XML_sizeRelV
);
784 endDMLAnchorInline(pFrmFmt
);
787 void DocxSdrExport::Impl::textFrameShadow(const SwFrmFmt
& rFrmFmt
)
789 SvxShadowItem aShadowItem
= rFrmFmt
.GetShadow();
790 if (aShadowItem
.GetLocation() == SVX_SHADOW_NONE
)
793 OString
aShadowWidth(OString::number(double(aShadowItem
.GetWidth()) / 20) + "pt");
795 switch (aShadowItem
.GetLocation())
797 case SVX_SHADOW_TOPLEFT
:
798 aOffset
= "-" + aShadowWidth
+ ",-" + aShadowWidth
;
800 case SVX_SHADOW_TOPRIGHT
:
801 aOffset
= aShadowWidth
+ ",-" + aShadowWidth
;
803 case SVX_SHADOW_BOTTOMLEFT
:
804 aOffset
= "-" + aShadowWidth
+ "," + aShadowWidth
;
806 case SVX_SHADOW_BOTTOMRIGHT
:
807 aOffset
= aShadowWidth
+ "," + aShadowWidth
;
809 case SVX_SHADOW_NONE
:
813 if (aOffset
.isEmpty())
816 OString aShadowColor
= msfilter::util::ConvertColor(aShadowItem
.GetColor());
817 m_pSerializer
->singleElementNS(XML_v
, XML_shadow
,
819 XML_color
, "#" + aShadowColor
,
824 bool DocxSdrExport::Impl::isSupportedDMLShape(uno::Reference
<drawing::XShape
> xShape
)
826 bool supported
= true;
828 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xShape
, uno::UNO_QUERY_THROW
);
829 if (xServiceInfo
->supportsService("com.sun.star.drawing.PolyPolygonShape") || xServiceInfo
->supportsService("com.sun.star.drawing.PolyLineShape"))
835 void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject
* sdrObj
, const SwFrmFmt
& rFrmFmt
,const Point
& rNdTopLeft
, int nAnchorId
)
837 bool bDMLAndVMLDrawingOpen
= m_pImpl
->m_bDMLAndVMLDrawingOpen
;
838 m_pImpl
->m_bDMLAndVMLDrawingOpen
= true;
840 // Depending on the shape type, we actually don't write the shape as DML.
842 sal_uInt32 nMirrorFlags
= 0;
843 uno::Reference
<drawing::XShape
> xShape(const_cast<SdrObject
*>(sdrObj
)->getUnoShape(), uno::UNO_QUERY_THROW
);
845 // Locked canvas is OK inside DML.
846 if (lcl_isLockedCanvas(xShape
))
847 bDMLAndVMLDrawingOpen
= false;
849 MSO_SPT eShapeType
= EscherPropertyContainer::GetCustomShapeType(xShape
, nMirrorFlags
, sShapeType
);
851 // In case we are already inside a DML block, then write the shape only as VML, turn out that's allowed to do.
852 if (eShapeType
!= ESCHER_ShpInst_TextPlainText
&& m_pImpl
->isSupportedDMLShape(xShape
) && !bDMLAndVMLDrawingOpen
)
854 m_pImpl
->m_pSerializer
->startElementNS(XML_mc
, XML_AlternateContent
, FSEND
);
856 const SdrObjGroup
* pObjGroup
= dynamic_cast<const SdrObjGroup
*>(sdrObj
);
857 m_pImpl
->m_pSerializer
->startElementNS(XML_mc
, XML_Choice
,
858 XML_Requires
, (pObjGroup
? "wpg" : "wps"),
860 writeDMLDrawing(sdrObj
, &rFrmFmt
, nAnchorId
);
861 m_pImpl
->m_pSerializer
->endElementNS(XML_mc
, XML_Choice
);
863 m_pImpl
->m_pSerializer
->startElementNS(XML_mc
, XML_Fallback
, FSEND
);
864 writeVMLDrawing(sdrObj
, rFrmFmt
, rNdTopLeft
);
865 m_pImpl
->m_pSerializer
->endElementNS(XML_mc
, XML_Fallback
);
867 m_pImpl
->m_pSerializer
->endElementNS(XML_mc
, XML_AlternateContent
);
870 writeVMLDrawing(sdrObj
, rFrmFmt
, rNdTopLeft
);
872 m_pImpl
->m_bDMLAndVMLDrawingOpen
= false;
875 // Converts ARGB transparency (0..255) to drawingml alpha (opposite, and 0..100000)
876 OString
lcl_ConvertTransparency(const Color
& rColor
)
878 if (rColor
.GetTransparency() > 0)
880 sal_Int32 nTransparencyPercent
= 100 - float(rColor
.GetTransparency()) / 2.55;
881 return OString::number(nTransparencyPercent
* oox::drawingml::PER_PERCENT
);
887 void DocxSdrExport::writeDMLEffectLst(const SwFrmFmt
& rFrmFmt
)
889 SvxShadowItem aShadowItem
= rFrmFmt
.GetShadow();
892 if (aShadowItem
.GetLocation() != SVX_SHADOW_NONE
)
894 // Distance is measured diagonally from corner
895 double nShadowDist
= sqrt((double)aShadowItem
.GetWidth()*aShadowItem
.GetWidth()*2.0);
896 OString
aShadowDist(OString::number(TwipsToEMU(nShadowDist
)));
897 OString aShadowColor
= msfilter::util::ConvertColor(aShadowItem
.GetColor());
898 OString aShadowAlpha
= lcl_ConvertTransparency(aShadowItem
.GetColor());
899 sal_uInt32 nShadowDir
= 0;
900 switch (aShadowItem
.GetLocation())
902 case SVX_SHADOW_TOPLEFT
:
903 nShadowDir
= 13500000;
905 case SVX_SHADOW_TOPRIGHT
:
906 nShadowDir
= 18900000;
908 case SVX_SHADOW_BOTTOMLEFT
:
909 nShadowDir
= 8100000;
911 case SVX_SHADOW_BOTTOMRIGHT
:
912 nShadowDir
= 2700000;
914 case SVX_SHADOW_NONE
:
918 OString
aShadowDir(OString::number(nShadowDir
));
920 m_pImpl
->m_pSerializer
->startElementNS(XML_a
, XML_effectLst
, FSEND
);
921 m_pImpl
->m_pSerializer
->startElementNS(XML_a
, XML_outerShdw
,
922 XML_dist
, aShadowDist
.getStr(),
923 XML_dir
, aShadowDir
.getStr(), FSEND
);
924 if (aShadowAlpha
.isEmpty())
925 m_pImpl
->m_pSerializer
->singleElementNS(XML_a
, XML_srgbClr
,
926 XML_val
, aShadowColor
.getStr(), FSEND
);
929 m_pImpl
->m_pSerializer
->startElementNS(XML_a
, XML_srgbClr
, XML_val
, aShadowColor
.getStr(), FSEND
);
930 m_pImpl
->m_pSerializer
->singleElementNS(XML_a
, XML_alpha
, XML_val
, aShadowAlpha
.getStr(), FSEND
);
931 m_pImpl
->m_pSerializer
->endElementNS(XML_a
, XML_srgbClr
);
933 m_pImpl
->m_pSerializer
->endElementNS(XML_a
, XML_outerShdw
);
934 m_pImpl
->m_pSerializer
->endElementNS(XML_a
, XML_effectLst
);
939 void DocxSdrExport::writeDiagramRels(uno::Reference
<xml::dom::XDocument
> xDom
,
940 const uno::Sequence
< uno::Sequence
< uno::Any
> >& xRelSeq
,
941 uno::Reference
< io::XOutputStream
> xOutStream
, const OUString
& sGrabBagProperyName
,
944 // add image relationships of OOXData, OOXDiagram
945 OUString
sType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
946 uno::Reference
< xml::sax::XSAXSerializable
> xSerializer(xDom
, uno::UNO_QUERY
);
947 uno::Reference
< xml::sax::XWriter
> xWriter
= xml::sax::Writer::create(comphelper::getProcessComponentContext());
948 xWriter
->setOutputStream(xOutStream
);
950 // retrieve the relationships from Sequence
951 for (sal_Int32 j
= 0; j
< xRelSeq
.getLength(); j
++)
953 // diagramDataRelTuple[0] => RID,
954 // diagramDataRelTuple[1] => xInputStream
955 // diagramDataRelTuple[2] => extension
956 uno::Sequence
< uno::Any
> diagramDataRelTuple
= xRelSeq
[j
];
958 OUString sRelId
, sExtension
;
959 diagramDataRelTuple
[0] >>= sRelId
;
960 diagramDataRelTuple
[2] >>= sExtension
;
961 OUString sContentType
;
962 if (sExtension
.equalsIgnoreAsciiCase(".WMF"))
963 sContentType
= "image/x-wmf";
965 sContentType
= OUString("image/") + sExtension
.copy(1);
966 sRelId
= sRelId
.copy(3);
968 StreamDataSequence dataSeq
;
969 diagramDataRelTuple
[1] >>= dataSeq
;
970 uno::Reference
<io::XInputStream
> dataImagebin(new ::comphelper::SequenceInputStream(dataSeq
));
972 OUString
sFragment("../media/");
973 //nAnchorId is used to make the name unique irrespective of the number of smart arts.
974 sFragment
+= sGrabBagProperyName
+ OUString::number(nAnchorId
) + "_" + OUString::number(j
) + sExtension
;
976 PropertySet
aProps(xOutStream
);
977 aProps
.setAnyProperty(PROP_RelId
, uno::makeAny(sal_Int32(sRelId
.toInt32())));
979 m_pImpl
->m_rExport
.GetFilter().addRelation(xOutStream
, sType
, sFragment
);
981 sFragment
= sFragment
.replaceFirst("..","word");
982 uno::Reference
< io::XOutputStream
> xBinOutStream
= m_pImpl
->m_rExport
.GetFilter().openFragmentStream(sFragment
, sContentType
);
986 sal_Int32 nBufferSize
= 512;
987 uno::Sequence
< sal_Int8
> aDataBuffer(nBufferSize
);
991 nRead
= dataImagebin
->readBytes(aDataBuffer
, nBufferSize
);
994 if (nRead
< nBufferSize
)
997 aDataBuffer
.realloc(nRead
);
999 xBinOutStream
->writeBytes(aDataBuffer
);
1003 xBinOutStream
->flush();
1005 catch (const uno::Exception
& rException
)
1007 SAL_WARN("sw.ww8", "DocxSdrExport::writeDiagramRels Failed to copy grabbaged Image: " << rException
.Message
);
1009 dataImagebin
->closeInput();
1013 void DocxSdrExport::writeDiagram(const SdrObject
* sdrObject
, const SwFrmFmt
& rFrmFmt
, int nAnchorId
)
1015 sax_fastparser::FSHelperPtr pFS
= m_pImpl
->m_pSerializer
;
1016 uno::Reference
< drawing::XShape
> xShape(((SdrObject
*)sdrObject
)->getUnoShape(), uno::UNO_QUERY
);
1017 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1019 uno::Reference
<xml::dom::XDocument
> dataDom
;
1020 uno::Reference
<xml::dom::XDocument
> layoutDom
;
1021 uno::Reference
<xml::dom::XDocument
> styleDom
;
1022 uno::Reference
<xml::dom::XDocument
> colorDom
;
1023 uno::Reference
<xml::dom::XDocument
> drawingDom
;
1024 uno::Sequence
< uno::Sequence
< uno::Any
> > xDataRelSeq
;
1025 uno::Sequence
< uno::Any
> diagramDrawing
;
1027 // retrieve the doms from the GrabBag
1028 OUString pName
= UNO_NAME_MISC_OBJ_INTEROPGRABBAG
;
1029 uno::Sequence
< beans::PropertyValue
> propList
;
1030 xPropSet
->getPropertyValue(pName
) >>= propList
;
1031 for (sal_Int32 nProp
=0; nProp
< propList
.getLength(); ++nProp
)
1033 OUString propName
= propList
[nProp
].Name
;
1034 if (propName
== "OOXData")
1035 propList
[nProp
].Value
>>= dataDom
;
1036 else if (propName
== "OOXLayout")
1037 propList
[nProp
].Value
>>= layoutDom
;
1038 else if (propName
== "OOXStyle")
1039 propList
[nProp
].Value
>>= styleDom
;
1040 else if (propName
== "OOXColor")
1041 propList
[nProp
].Value
>>= colorDom
;
1042 else if (propName
== "OOXDrawing")
1044 propList
[nProp
].Value
>>= diagramDrawing
;
1045 diagramDrawing
[0] >>= drawingDom
; // if there is OOXDrawing property then set drawingDom here only.
1047 else if (propName
== "OOXDiagramDataRels")
1048 propList
[nProp
].Value
>>= xDataRelSeq
;
1051 // check that we have the 4 mandatory XDocuments
1052 // if not, there was an error importing and we won't output anything
1053 if (!dataDom
.is() || !layoutDom
.is() || !styleDom
.is() || !colorDom
.is())
1056 // write necessary tags to document.xml
1057 Size
aSize(sdrObject
->GetSnapRect().GetWidth(), sdrObject
->GetSnapRect().GetHeight());
1058 startDMLAnchorInline(&rFrmFmt
, aSize
);
1060 // generate an unique id
1061 sax_fastparser::FastAttributeList
* pDocPrAttrList
= pFS
->createAttrList();
1062 pDocPrAttrList
->add(XML_id
, OString::number(nAnchorId
).getStr());
1063 OUString sName
= "Diagram" + OUString::number(nAnchorId
);
1064 pDocPrAttrList
->add(XML_name
, OUStringToOString(sName
, RTL_TEXTENCODING_UTF8
).getStr());
1065 sax_fastparser::XFastAttributeListRef
xDocPrAttrListRef(pDocPrAttrList
);
1066 pFS
->singleElementNS(XML_wp
, XML_docPr
, xDocPrAttrListRef
);
1068 sal_Int32 diagramCount
;
1069 diagramCount
= nAnchorId
;
1071 pFS
->singleElementNS(XML_wp
, XML_cNvGraphicFramePr
,
1074 pFS
->startElementNS(XML_a
, XML_graphic
,
1075 FSNS(XML_xmlns
, XML_a
), "http://schemas.openxmlformats.org/drawingml/2006/main",
1078 pFS
->startElementNS(XML_a
, XML_graphicData
,
1079 XML_uri
, "http://schemas.openxmlformats.org/drawingml/2006/diagram",
1082 // add data relation
1083 OUString dataFileName
= "diagrams/data" + OUString::number(diagramCount
) + ".xml";
1084 OString dataRelId
= OUStringToOString(m_pImpl
->m_rExport
.GetFilter().addRelation(pFS
->getOutputStream(),
1085 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData",
1086 dataFileName
, false), RTL_TEXTENCODING_UTF8
);
1089 // add layout relation
1090 OUString layoutFileName
= "diagrams/layout" + OUString::number(diagramCount
) + ".xml";
1091 OString layoutRelId
= OUStringToOString(m_pImpl
->m_rExport
.GetFilter().addRelation(pFS
->getOutputStream(),
1092 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout",
1093 layoutFileName
, false), RTL_TEXTENCODING_UTF8
);
1095 // add style relation
1096 OUString styleFileName
= "diagrams/quickStyle" + OUString::number(diagramCount
) + ".xml";
1097 OString styleRelId
= OUStringToOString(m_pImpl
->m_rExport
.GetFilter().addRelation(pFS
->getOutputStream(),
1098 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle",
1099 styleFileName
, false), RTL_TEXTENCODING_UTF8
);
1101 // add color relation
1102 OUString colorFileName
= "diagrams/colors" + OUString::number(diagramCount
) + ".xml";
1103 OString colorRelId
= OUStringToOString(m_pImpl
->m_rExport
.GetFilter().addRelation(pFS
->getOutputStream(),
1104 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors",
1105 colorFileName
, false), RTL_TEXTENCODING_UTF8
);
1107 OUString drawingFileName
;
1108 if (drawingDom
.is())
1110 // add drawing relation
1111 drawingFileName
= "diagrams/drawing" + OUString::number(diagramCount
) + ".xml";
1112 OUString drawingRelId
= m_pImpl
->m_rExport
.GetFilter().addRelation(pFS
->getOutputStream(),
1113 "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing",
1114 drawingFileName
, false);
1116 // the data dom contains a reference to the drawing relation. We need to update it with the new generated
1117 // relation value before writing the dom to a file
1119 // Get the dsp:damaModelExt node from the dom
1120 uno::Reference
< xml::dom::XNodeList
> nodeList
=
1121 dataDom
->getElementsByTagNameNS("http://schemas.microsoft.com/office/drawing/2008/diagram", "dataModelExt");
1123 // There must be one element only so get it
1124 uno::Reference
< xml::dom::XNode
> node
= nodeList
->item(0);
1126 // Get the list of attributes of the node
1127 uno::Reference
< xml::dom::XNamedNodeMap
> nodeMap
= node
->getAttributes();
1129 // Get the node with the relId attribute and set its new value
1130 uno::Reference
< xml::dom::XNode
> relIdNode
= nodeMap
->getNamedItem("relId");
1131 relIdNode
->setNodeValue(drawingRelId
);
1134 pFS
->singleElementNS(XML_dgm
, XML_relIds
,
1135 FSNS(XML_xmlns
, XML_dgm
), "http://schemas.openxmlformats.org/drawingml/2006/diagram",
1136 FSNS(XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1137 FSNS(XML_r
, XML_dm
), dataRelId
.getStr(),
1138 FSNS(XML_r
, XML_lo
), layoutRelId
.getStr(),
1139 FSNS(XML_r
, XML_qs
), styleRelId
.getStr(),
1140 FSNS(XML_r
, XML_cs
), colorRelId
.getStr(),
1143 pFS
->endElementNS(XML_a
, XML_graphicData
);
1144 pFS
->endElementNS(XML_a
, XML_graphic
);
1145 endDMLAnchorInline(&rFrmFmt
);
1147 uno::Reference
< xml::sax::XSAXSerializable
> serializer
;
1148 uno::Reference
< xml::sax::XWriter
> writer
= xml::sax::Writer::create(comphelper::getProcessComponentContext());
1151 serializer
.set(dataDom
, uno::UNO_QUERY
);
1152 uno::Reference
< io::XOutputStream
> xDataOutputStream
= m_pImpl
->m_rExport
.GetFilter().openFragmentStream(
1153 "word/" + dataFileName
, "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml");
1154 writer
->setOutputStream(xDataOutputStream
);
1155 serializer
->serialize(uno::Reference
< xml::sax::XDocumentHandler
>(writer
, uno::UNO_QUERY_THROW
),
1156 uno::Sequence
< beans::StringPair
>());
1158 // write the associated Images and rels for data file
1159 writeDiagramRels(dataDom
, xDataRelSeq
, xDataOutputStream
, OUString("OOXDiagramDataRels"), nAnchorId
);
1161 // write layout file
1162 serializer
.set(layoutDom
, uno::UNO_QUERY
);
1163 writer
->setOutputStream(m_pImpl
->m_rExport
.GetFilter().openFragmentStream("word/" + layoutFileName
,
1164 "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"));
1165 serializer
->serialize(uno::Reference
< xml::sax::XDocumentHandler
>(writer
, uno::UNO_QUERY_THROW
),
1166 uno::Sequence
< beans::StringPair
>());
1169 serializer
.set(styleDom
, uno::UNO_QUERY
);
1170 writer
->setOutputStream(m_pImpl
->m_rExport
.GetFilter().openFragmentStream("word/" + styleFileName
,
1171 "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"));
1172 serializer
->serialize(uno::Reference
< xml::sax::XDocumentHandler
>(writer
, uno::UNO_QUERY_THROW
),
1173 uno::Sequence
< beans::StringPair
>());
1176 serializer
.set(colorDom
, uno::UNO_QUERY
);
1177 writer
->setOutputStream(m_pImpl
->m_rExport
.GetFilter().openFragmentStream("word/" + colorFileName
,
1178 "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"));
1179 serializer
->serialize(uno::Reference
< xml::sax::XDocumentHandler
>(writer
, uno::UNO_QUERY_THROW
),
1180 uno::Sequence
< beans::StringPair
>());
1182 // write drawing file
1184 if (drawingDom
.is())
1186 serializer
.set(drawingDom
, uno::UNO_QUERY
);
1187 uno::Reference
< io::XOutputStream
> xDrawingOutputStream
= m_pImpl
->m_rExport
.GetFilter().openFragmentStream("word/" + drawingFileName
,
1188 "application/vnd.openxmlformats-officedocument.drawingml.diagramDrawing+xml");
1189 writer
->setOutputStream(xDrawingOutputStream
);
1190 serializer
->serialize(uno::Reference
< xml::sax::XDocumentHandler
>(writer
, uno::UNO_QUERY_THROW
),
1191 uno::Sequence
< beans::StringPair
>());
1193 // write the associated Images and rels for drawing file
1194 uno::Sequence
< uno::Sequence
< uno::Any
> > xDrawingRelSeq
;
1195 diagramDrawing
[1] >>= xDrawingRelSeq
;
1196 writeDiagramRels(drawingDom
, xDrawingRelSeq
, xDrawingOutputStream
, OUString("OOXDiagramDrawingRels"), nAnchorId
);
1200 void DocxSdrExport::writeOnlyTextOfFrame(sw::Frame
* pParentFrame
)
1202 const SwFrmFmt
& rFrmFmt
= pParentFrame
->GetFrmFmt();
1203 const SwNodeIndex
* pNodeIndex
= rFrmFmt
.GetCntnt().GetCntntIdx();
1204 sax_fastparser::FSHelperPtr pFS
= m_pImpl
->m_pSerializer
;
1206 sal_uLong nStt
= pNodeIndex
? pNodeIndex
->GetIndex()+1 : 0;
1207 sal_uLong nEnd
= pNodeIndex
? pNodeIndex
->GetNode().EndOfSectionIndex() : 0;
1209 //Save data here and restore when out of scope
1210 ExportDataSaveRestore
aDataGuard(m_pImpl
->m_rExport
, nStt
, nEnd
, pParentFrame
);
1212 m_pImpl
->m_pBodyPrAttrList
= pFS
->createAttrList();
1213 m_pImpl
->m_bFrameBtLr
= checkFrameBtlr(m_pImpl
->m_rExport
.pDoc
->GetNodes()[nStt
], 0);
1214 m_pImpl
->m_bFlyFrameGraphic
= true;
1215 m_pImpl
->m_rExport
.WriteText();
1216 m_pImpl
->m_bFlyFrameGraphic
= false;
1217 m_pImpl
->m_bFrameBtLr
= false;
1220 void DocxSdrExport::writeDMLTextFrame(sw::Frame
* pParentFrame
, int nAnchorId
, bool bTextBoxOnly
)
1222 sax_fastparser::FSHelperPtr pFS
= m_pImpl
->m_pSerializer
;
1223 const SwFrmFmt
& rFrmFmt
= pParentFrame
->GetFrmFmt();
1224 const SwNodeIndex
* pNodeIndex
= rFrmFmt
.GetCntnt().GetCntntIdx();
1226 sal_uLong nStt
= pNodeIndex
? pNodeIndex
->GetIndex()+1 : 0;
1227 sal_uLong nEnd
= pNodeIndex
? pNodeIndex
->GetNode().EndOfSectionIndex() : 0;
1229 //Save data here and restore when out of scope
1230 ExportDataSaveRestore
aDataGuard(m_pImpl
->m_rExport
, nStt
, nEnd
, pParentFrame
);
1232 // When a frame has some low height, but automatically expanded due
1233 // to lots of contents, this size contains the real size.
1234 const Size aSize
= pParentFrame
->GetSize();
1236 uno::Reference
< drawing::XShape
> xShape
;
1237 const SdrObject
* pSdrObj
= rFrmFmt
.FindRealSdrObject();
1239 xShape
= uno::Reference
< drawing::XShape
>(const_cast<SdrObject
*>(pSdrObj
)->getUnoShape(), uno::UNO_QUERY
);
1240 uno::Reference
< beans::XPropertySet
> xPropertySet(xShape
, uno::UNO_QUERY
);
1241 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
;
1242 if (xPropertySet
.is())
1243 xPropSetInfo
= xPropertySet
->getPropertySetInfo();
1245 m_pImpl
->m_pBodyPrAttrList
= pFS
->createAttrList();
1247 drawing::TextVerticalAdjust eAdjust
= drawing::TextVerticalAdjust_TOP
;
1248 if (xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("TextVerticalAdjust"))
1249 xPropertySet
->getPropertyValue("TextVerticalAdjust") >>= eAdjust
;
1250 m_pImpl
->m_pBodyPrAttrList
->add(XML_anchor
, oox::drawingml::GetTextVerticalAdjust(eAdjust
));
1255 startDMLAnchorInline(&rFrmFmt
, aSize
);
1257 sax_fastparser::FastAttributeList
* pDocPrAttrList
= pFS
->createAttrList();
1258 pDocPrAttrList
->add(XML_id
, OString::number(nAnchorId
).getStr());
1259 pDocPrAttrList
->add(XML_name
, OUStringToOString(rFrmFmt
.GetName(), RTL_TEXTENCODING_UTF8
).getStr());
1260 sax_fastparser::XFastAttributeListRef
xDocPrAttrListRef(pDocPrAttrList
);
1261 pFS
->singleElementNS(XML_wp
, XML_docPr
, xDocPrAttrListRef
);
1263 pFS
->startElementNS(XML_a
, XML_graphic
,
1264 FSNS(XML_xmlns
, XML_a
), "http://schemas.openxmlformats.org/drawingml/2006/main",
1266 pFS
->startElementNS(XML_a
, XML_graphicData
,
1267 XML_uri
, "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
1269 pFS
->startElementNS(XML_wps
, XML_wsp
, FSEND
);
1270 pFS
->singleElementNS(XML_wps
, XML_cNvSpPr
,
1274 uno::Any aRotation
;
1275 sal_Int32 nRotation
= 0;
1276 if (xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("FrameInteropGrabBag"))
1278 uno::Sequence
< beans::PropertyValue
> propList
;
1279 xPropertySet
->getPropertyValue("FrameInteropGrabBag") >>= propList
;
1280 for (sal_Int32 nProp
=0; nProp
< propList
.getLength(); ++nProp
)
1282 OUString propName
= propList
[nProp
].Name
;
1283 if (propName
== "mso-rotation-angle")
1285 aRotation
= propList
[nProp
].Value
;
1290 aRotation
>>= nRotation
;
1291 OString
sRotation(OString::number(nRotation
));
1293 pFS
->startElementNS(XML_wps
, XML_spPr
, FSEND
);
1296 pFS
->startElementNS(XML_a
, XML_xfrm
,
1297 XML_rot
, sRotation
.getStr(),
1302 pFS
->startElementNS(XML_a
, XML_xfrm
, FSEND
);
1304 pFS
->singleElementNS(XML_a
, XML_off
,
1308 OString
aWidth(OString::number(TwipsToEMU(aSize
.Width())));
1309 OString
aHeight(OString::number(TwipsToEMU(aSize
.Height())));
1310 pFS
->singleElementNS(XML_a
, XML_ext
,
1311 XML_cx
, aWidth
.getStr(),
1312 XML_cy
, aHeight
.getStr(),
1314 pFS
->endElementNS(XML_a
, XML_xfrm
);
1315 OUString shapeType
= "rect";
1316 if (xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("FrameInteropGrabBag"))
1318 uno::Sequence
< beans::PropertyValue
> propList
;
1319 xPropertySet
->getPropertyValue("FrameInteropGrabBag") >>= propList
;
1320 for (sal_Int32 nProp
=0; nProp
< propList
.getLength(); ++nProp
)
1322 OUString propName
= propList
[nProp
].Name
;
1323 if (propName
== "mso-orig-shape-type")
1325 propList
[nProp
].Value
>>= shapeType
;
1330 //Empty shapeType will lead to corruption so to avoid that shapeType is set to default i.e. "rect"
1331 if (shapeType
.isEmpty())
1334 pFS
->singleElementNS(XML_a
, XML_prstGeom
,
1335 XML_prst
, OUStringToOString(shapeType
, RTL_TEXTENCODING_UTF8
).getStr(),
1337 m_pImpl
->m_bDMLTextFrameSyntax
= true;
1338 m_pImpl
->m_rExport
.OutputFormat(pParentFrame
->GetFrmFmt(), false, false, true);
1339 m_pImpl
->m_bDMLTextFrameSyntax
= false;
1340 writeDMLEffectLst(rFrmFmt
);
1341 pFS
->endElementNS(XML_wps
, XML_spPr
);
1344 m_pImpl
->m_rExport
.mpParentFrame
= NULL
;
1345 bool skipTxBxContent
= false ;
1346 bool isTxbxLinked
= false ;
1348 /* Check if the text box is linked and then decides whether
1349 to write the tag txbx or linkedTxbx
1351 if (xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("ChainPrevName") &&
1352 xPropSetInfo
->hasPropertyByName("ChainNextName"))
1354 OUString sChainPrevName
;
1355 OUString sChainNextName
;
1357 xPropertySet
->getPropertyValue("ChainPrevName") >>= sChainPrevName
;
1358 xPropertySet
->getPropertyValue("ChainNextName") >>= sChainNextName
;
1360 if (!sChainPrevName
.isEmpty())
1362 /* no text content should be added to this tag,
1363 since the textbox is linked, the entire content
1364 is written in txbx block
1367 pFS
->singleElementNS(XML_wps
, XML_linkedTxbx
,
1368 XML_id
, I32S(m_pImpl
->m_nId
),
1369 XML_seq
, I32S(m_pImpl
->m_nSeq
),
1371 skipTxBxContent
= true ;
1373 //Text box chaining for a group of textboxes ends here,
1374 //therefore reset the seq.
1375 if (sChainNextName
.isEmpty())
1376 m_pImpl
->m_nSeq
= 0 ;
1378 else if (sChainPrevName
.isEmpty() && !sChainNextName
.isEmpty())
1380 /* this is the first textbox in the chaining, we add the text content
1383 //since the text box is linked, it needs an id.
1384 pFS
->startElementNS(XML_wps
, XML_txbx
,
1385 XML_id
, I32S(m_pImpl
->m_nId
),
1387 isTxbxLinked
= true ;
1391 if (!skipTxBxContent
)
1394 pFS
->startElementNS(XML_wps
, XML_txbx
, FSEND
);//text box is not linked, therefore no id.
1396 pFS
->startElementNS(XML_w
, XML_txbxContent
, FSEND
);
1398 m_pImpl
->m_bFrameBtLr
= checkFrameBtlr(m_pImpl
->m_rExport
.pDoc
->GetNodes()[nStt
], 0);
1399 m_pImpl
->m_bFlyFrameGraphic
= true;
1400 m_pImpl
->m_rExport
.WriteText();
1401 m_pImpl
->m_bFlyFrameGraphic
= false;
1402 m_pImpl
->m_bFrameBtLr
= false;
1404 pFS
->endElementNS(XML_w
, XML_txbxContent
);
1405 pFS
->endElementNS(XML_wps
, XML_txbx
);
1407 sax_fastparser::XFastAttributeListRef
xBodyPrAttrList(m_pImpl
->m_pBodyPrAttrList
);
1408 m_pImpl
->m_pBodyPrAttrList
= NULL
;
1411 pFS
->startElementNS(XML_wps
, XML_bodyPr
, xBodyPrAttrList
);
1412 // AutoSize of the Text Frame.
1413 const SwFmtFrmSize
& rSize
= rFrmFmt
.GetFrmSize();
1414 pFS
->singleElementNS(XML_a
, (rSize
.GetHeightSizeType() == ATT_VAR_SIZE
? XML_spAutoFit
: XML_noAutofit
), FSEND
);
1415 pFS
->endElementNS(XML_wps
, XML_bodyPr
);
1417 pFS
->endElementNS(XML_wps
, XML_wsp
);
1418 pFS
->endElementNS(XML_a
, XML_graphicData
);
1419 pFS
->endElementNS(XML_a
, XML_graphic
);
1421 // Relative size of the Text Frame.
1422 if (rSize
.GetWidthPercent())
1424 pFS
->startElementNS(XML_wp14
, XML_sizeRelH
,
1425 XML_relativeFrom
, (rSize
.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME
? "page" : "margin"),
1427 pFS
->startElementNS(XML_wp14
, XML_pctWidth
, FSEND
);
1428 pFS
->writeEscaped(OUString::number(rSize
.GetWidthPercent() * oox::drawingml::PER_PERCENT
));
1429 pFS
->endElementNS(XML_wp14
, XML_pctWidth
);
1430 pFS
->endElementNS(XML_wp14
, XML_sizeRelH
);
1432 if (rSize
.GetHeightPercent())
1434 pFS
->startElementNS(XML_wp14
, XML_sizeRelV
,
1435 XML_relativeFrom
, (rSize
.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME
? "page" : "margin"),
1437 pFS
->startElementNS(XML_wp14
, XML_pctHeight
, FSEND
);
1438 pFS
->writeEscaped(OUString::number(rSize
.GetHeightPercent() * oox::drawingml::PER_PERCENT
));
1439 pFS
->endElementNS(XML_wp14
, XML_pctHeight
);
1440 pFS
->endElementNS(XML_wp14
, XML_sizeRelV
);
1443 endDMLAnchorInline(&rFrmFmt
);
1447 void DocxSdrExport::writeVMLTextFrame(sw::Frame
* pParentFrame
, bool bTextBoxOnly
)
1449 sax_fastparser::FSHelperPtr pFS
= m_pImpl
->m_pSerializer
;
1450 const SwFrmFmt
& rFrmFmt
= pParentFrame
->GetFrmFmt();
1451 const SwNodeIndex
* pNodeIndex
= rFrmFmt
.GetCntnt().GetCntntIdx();
1453 sal_uLong nStt
= pNodeIndex
? pNodeIndex
->GetIndex()+1 : 0;
1454 sal_uLong nEnd
= pNodeIndex
? pNodeIndex
->GetNode().EndOfSectionIndex() : 0;
1456 //Save data here and restore when out of scope
1457 ExportDataSaveRestore
aDataGuard(m_pImpl
->m_rExport
, nStt
, nEnd
, pParentFrame
);
1459 // When a frame has some low height, but automatically expanded due
1460 // to lots of contents, this size contains the real size.
1461 const Size aSize
= pParentFrame
->GetSize();
1462 m_pImpl
->m_pFlyFrameSize
= &aSize
;
1464 m_pImpl
->m_bTextFrameSyntax
= true;
1465 m_pImpl
->m_pFlyAttrList
= pFS
->createAttrList();
1466 m_pImpl
->m_pTextboxAttrList
= pFS
->createAttrList();
1467 m_pImpl
->m_aTextFrameStyle
= "position:absolute";
1468 m_pImpl
->m_rExport
.OutputFormat(pParentFrame
->GetFrmFmt(), false, false, true);
1469 m_pImpl
->m_pFlyAttrList
->add(XML_style
, m_pImpl
->m_aTextFrameStyle
.makeStringAndClear());
1471 const SdrObject
* pObject
= pParentFrame
->GetFrmFmt().FindRealSdrObject();
1472 if (pObject
!= NULL
)
1474 OUString sAnchorId
= lclGetAnchorIdFromGrabBag(pObject
);
1475 if (!sAnchorId
.isEmpty())
1476 m_pImpl
->m_pFlyAttrList
->addNS(XML_w14
, XML_anchorId
, OUStringToOString(sAnchorId
, RTL_TEXTENCODING_UTF8
));
1479 sax_fastparser::XFastAttributeListRef
xFlyAttrList(m_pImpl
->m_pFlyAttrList
);
1480 m_pImpl
->m_pFlyAttrList
= NULL
;
1481 m_pImpl
->m_bFrameBtLr
= checkFrameBtlr(m_pImpl
->m_rExport
.pDoc
->GetNodes()[nStt
], m_pImpl
->m_pTextboxAttrList
);
1482 sax_fastparser::XFastAttributeListRef
xTextboxAttrList(m_pImpl
->m_pTextboxAttrList
);
1483 m_pImpl
->m_pTextboxAttrList
= NULL
;
1484 m_pImpl
->m_bTextFrameSyntax
= false;
1485 m_pImpl
->m_pFlyFrameSize
= 0;
1486 m_pImpl
->m_rExport
.mpParentFrame
= NULL
;
1490 pFS
->startElementNS(XML_w
, XML_pict
, FSEND
);
1491 pFS
->startElementNS(XML_v
, XML_rect
, xFlyAttrList
);
1492 m_pImpl
->textFrameShadow(rFrmFmt
);
1493 if (m_pImpl
->m_pFlyFillAttrList
)
1495 sax_fastparser::XFastAttributeListRef
xFlyFillAttrList(m_pImpl
->m_pFlyFillAttrList
);
1496 m_pImpl
->m_pFlyFillAttrList
= NULL
;
1497 pFS
->singleElementNS(XML_v
, XML_fill
, xFlyFillAttrList
);
1499 if (m_pImpl
->m_pDashLineStyleAttr
)
1501 sax_fastparser::XFastAttributeListRef
xDashLineStyleAttr(m_pImpl
->m_pDashLineStyleAttr
);
1502 m_pImpl
->m_pDashLineStyleAttr
= NULL
;
1503 pFS
->singleElementNS(XML_v
, XML_stroke
, xDashLineStyleAttr
);
1505 pFS
->startElementNS(XML_v
, XML_textbox
, xTextboxAttrList
);
1507 pFS
->startElementNS(XML_w
, XML_txbxContent
, FSEND
);
1508 m_pImpl
->m_bFlyFrameGraphic
= true;
1509 m_pImpl
->m_rExport
.WriteText();
1510 m_pImpl
->m_bFlyFrameGraphic
= false;
1511 pFS
->endElementNS(XML_w
, XML_txbxContent
);
1514 pFS
->endElementNS(XML_v
, XML_textbox
);
1516 if (m_pImpl
->m_pFlyWrapAttrList
)
1518 sax_fastparser::XFastAttributeListRef
xFlyWrapAttrList(m_pImpl
->m_pFlyWrapAttrList
);
1519 m_pImpl
->m_pFlyWrapAttrList
= NULL
;
1520 pFS
->singleElementNS(XML_w10
, XML_wrap
, xFlyWrapAttrList
);
1523 pFS
->endElementNS(XML_v
, XML_rect
);
1524 pFS
->endElementNS(XML_w
, XML_pict
);
1526 m_pImpl
->m_bFrameBtLr
= false;
1529 bool DocxSdrExport::checkFrameBtlr(SwNode
* pStartNode
, sax_fastparser::FastAttributeList
* pTextboxAttrList
)
1531 // The intended usage is to pass either a valid VML or DML attribute list.
1532 assert(pTextboxAttrList
|| m_pImpl
->m_pBodyPrAttrList
);
1534 if (!pStartNode
->IsTxtNode())
1537 SwTxtNode
* pTxtNode
= static_cast<SwTxtNode
*>(pStartNode
);
1539 const SfxPoolItem
* pItem
= 0; // explicitly init to avoid warnings
1540 bool bItemSet
= false;
1541 if (pTxtNode
->HasSwAttrSet())
1543 const SwAttrSet
& rAttrSet
= pTxtNode
->GetSwAttrSet();
1544 bItemSet
= rAttrSet
.GetItemState(RES_CHRATR_ROTATE
, true, &pItem
) == SFX_ITEM_SET
;
1549 if (!pTxtNode
->HasHints())
1552 SwTxtAttr
* pTxtAttr
= pTxtNode
->GetTxtAttrAt(0, RES_TXTATR_AUTOFMT
);
1554 if (!pTxtAttr
|| pTxtAttr
->Which() != RES_TXTATR_AUTOFMT
)
1557 boost::shared_ptr
<SfxItemSet
> pItemSet
= pTxtAttr
->GetAutoFmt().GetStyleHandle();
1558 bItemSet
= pItemSet
->GetItemState(RES_CHRATR_ROTATE
, true, &pItem
) == SFX_ITEM_SET
;
1563 const SvxCharRotateItem
& rCharRotate
= static_cast<const SvxCharRotateItem
&>(*pItem
);
1564 if (rCharRotate
.GetValue() == 900)
1566 if (pTextboxAttrList
)
1567 pTextboxAttrList
->add(XML_style
, "mso-layout-flow-alt:bottom-to-top");
1569 m_pImpl
->m_pBodyPrAttrList
->add(XML_vert
, "vert270");
1576 bool DocxSdrExport::isTextBox(const SwFrmFmt
& rFrmFmt
)
1578 return std::find(m_pImpl
->m_aTextBoxes
.begin(), m_pImpl
->m_aTextBoxes
.end(), &rFrmFmt
) != m_pImpl
->m_aTextBoxes
.end();
1581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */