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/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>
29 :
30 : #include <frmatr.hxx>
31 : #include <frmfmt.hxx>
32 : #include <fmtanchr.hxx>
33 : #include <fmtornt.hxx>
34 : #include <fmtsrnd.hxx>
35 : #include <fmtcntnt.hxx>
36 : #include <ndtxt.hxx>
37 : #include <txatbase.hxx>
38 : #include <fmtautofmt.hxx>
39 : #include <fmtfsize.hxx>
40 :
41 : #include <docxsdrexport.hxx>
42 : #include <docxexport.hxx>
43 : #include <docxexportfilter.hxx>
44 : #include <writerhelper.hxx>
45 : #include <comphelper/seqstream.hxx>
46 :
47 : using namespace com::sun::star;
48 : using namespace oox;
49 :
50 : namespace
51 : {
52 :
53 0 : uno::Sequence<beans::PropertyValue> lclGetProperty(uno::Reference<drawing::XShape> rShape, const OUString& rPropName)
54 : {
55 0 : uno::Sequence<beans::PropertyValue> aResult;
56 0 : uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
57 0 : uno::Reference<beans::XPropertySetInfo> xPropSetInfo;
58 :
59 0 : if (!xPropertySet.is())
60 0 : return aResult;
61 :
62 0 : xPropSetInfo = xPropertySet->getPropertySetInfo();
63 0 : if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(rPropName))
64 : {
65 0 : xPropertySet->getPropertyValue(rPropName) >>= aResult;
66 : }
67 0 : return aResult;
68 : }
69 :
70 0 : OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj)
71 : {
72 0 : OUString aResult;
73 0 : uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObj)->getUnoShape(), uno::UNO_QUERY);
74 : uno::Sequence< beans::PropertyValue > propList =
75 0 : lclGetProperty(xShape, "FrameInteropGrabBag");
76 0 : for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp)
77 : {
78 0 : OUString aPropName = propList[nProp].Name;
79 0 : if (aPropName == "AnchorId")
80 : {
81 0 : propList[nProp].Value >>= aResult;
82 0 : break;
83 : }
84 0 : }
85 0 : return aResult;
86 : }
87 :
88 0 : void lclMovePositionWithRotation(awt::Point& aPos, sal_Int64 nRotation)
89 : {
90 : // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx)
91 : // TODO: refactor
92 :
93 0 : if (nRotation == 0)
94 0 : return;
95 :
96 0 : if (nRotation < 0)
97 0 : nRotation = (36000 + nRotation) % 36000;
98 0 : if (nRotation % 18000 == 0)
99 0 : nRotation = 0;
100 0 : while (nRotation > 9000)
101 0 : nRotation = (18000 - (nRotation % 18000));
102 :
103 0 : double fVal = (double) nRotation * F_PI18000;
104 0 : double fCos = cos(fVal);
105 0 : double fSin = sin(fVal);
106 :
107 0 : double nWidthHalf = (double) aPos.X / 2;
108 0 : double nHeightHalf = (double) aPos.Y / 2;
109 :
110 0 : double nXDiff = fSin * nHeightHalf + fCos * nWidthHalf - nWidthHalf;
111 0 : double nYDiff = fSin * nWidthHalf + fCos * nHeightHalf - nHeightHalf;
112 :
113 0 : aPos.X += nXDiff;
114 0 : aPos.Y += nYDiff;
115 : }
116 :
117 : }
118 :
119 0 : ExportDataSaveRestore::ExportDataSaveRestore(DocxExport& rExport, sal_uLong nStt, sal_uLong nEnd, sw::Frame* pParentFrame)
120 0 : : m_rExport(rExport)
121 : {
122 0 : m_rExport.SaveData(nStt, nEnd);
123 0 : m_rExport.mpParentFrame = pParentFrame;
124 0 : }
125 :
126 0 : ExportDataSaveRestore::~ExportDataSaveRestore()
127 : {
128 0 : m_rExport.RestoreData();
129 0 : }
130 :
131 : /// Holds data used by DocxSdrExport only.
132 : struct DocxSdrExport::Impl
133 : {
134 : DocxSdrExport& m_rSdrExport;
135 : DocxExport& m_rExport;
136 : sax_fastparser::FSHelperPtr m_pSerializer;
137 : oox::drawingml::DrawingML* m_pDrawingML;
138 : const Size* m_pFlyFrameSize;
139 : bool m_bTextFrameSyntax;
140 : bool m_bDMLTextFrameSyntax;
141 : sax_fastparser::FastAttributeList* m_pFlyAttrList;
142 : sax_fastparser::FastAttributeList* m_pTextboxAttrList;
143 : OStringBuffer m_aTextFrameStyle;
144 : bool m_bFrameBtLr;
145 : bool m_bFlyFrameGraphic;
146 : sax_fastparser::FastAttributeList* m_pFlyFillAttrList;
147 : sax_fastparser::FastAttributeList* m_pFlyWrapAttrList;
148 : sax_fastparser::FastAttributeList* m_pBodyPrAttrList;
149 : sax_fastparser::FastAttributeList* m_pDashLineStyleAttr;
150 : bool m_bIsInDMLTextFrame;
151 :
152 0 : Impl(DocxSdrExport& rSdrExport, DocxExport& rExport, sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML)
153 : : m_rSdrExport(rSdrExport),
154 : m_rExport(rExport),
155 : m_pSerializer(pSerializer),
156 : m_pDrawingML(pDrawingML),
157 : m_pFlyFrameSize(0),
158 : m_bTextFrameSyntax(false),
159 : m_bDMLTextFrameSyntax(false),
160 : m_pFlyAttrList(0),
161 : m_pTextboxAttrList(0),
162 : m_bFrameBtLr(false),
163 : m_bFlyFrameGraphic(false),
164 : m_pFlyFillAttrList(0),
165 : m_pFlyWrapAttrList(0),
166 : m_pBodyPrAttrList(0),
167 : m_pDashLineStyleAttr(0),
168 0 : m_bIsInDMLTextFrame(false)
169 : {
170 0 : }
171 :
172 0 : ~Impl()
173 0 : {
174 0 : delete m_pFlyAttrList, m_pFlyAttrList = NULL;
175 0 : delete m_pTextboxAttrList, m_pTextboxAttrList = NULL;
176 0 : }
177 :
178 : /// Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax.
179 :
180 : void textFrameShadow(const SwFrmFmt& rFrmFmt);
181 : bool isSupportedDMLShape(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xShape);
182 : };
183 :
184 0 : DocxSdrExport::DocxSdrExport(DocxExport& rExport, sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML)
185 0 : : m_pImpl(new Impl(*this, rExport, pSerializer, pDrawingML))
186 : {
187 0 : }
188 :
189 0 : DocxSdrExport::~DocxSdrExport()
190 : {
191 0 : }
192 :
193 0 : void DocxSdrExport::setSerializer(sax_fastparser::FSHelperPtr pSerializer)
194 : {
195 0 : m_pImpl->m_pSerializer = pSerializer;
196 0 : }
197 :
198 0 : const Size* DocxSdrExport::getFlyFrameSize()
199 : {
200 0 : return m_pImpl->m_pFlyFrameSize;
201 : }
202 :
203 0 : bool DocxSdrExport::getTextFrameSyntax()
204 : {
205 0 : return m_pImpl->m_bTextFrameSyntax;
206 : }
207 :
208 0 : bool DocxSdrExport::getDMLTextFrameSyntax()
209 : {
210 0 : return m_pImpl->m_bDMLTextFrameSyntax;
211 : }
212 :
213 0 : sax_fastparser::FastAttributeList*& DocxSdrExport::getFlyAttrList()
214 : {
215 0 : return m_pImpl->m_pFlyAttrList;
216 : }
217 :
218 0 : void DocxSdrExport::setFlyAttrList(sax_fastparser::FastAttributeList* pAttrList)
219 : {
220 0 : m_pImpl->m_pFlyAttrList = pAttrList;
221 0 : }
222 :
223 0 : sax_fastparser::FastAttributeList* DocxSdrExport::getTextboxAttrList()
224 : {
225 0 : return m_pImpl->m_pTextboxAttrList;
226 : }
227 :
228 0 : OStringBuffer& DocxSdrExport::getTextFrameStyle()
229 : {
230 0 : return m_pImpl->m_aTextFrameStyle;
231 : }
232 :
233 0 : bool DocxSdrExport::getFrameBtLr()
234 : {
235 0 : return m_pImpl->m_bFrameBtLr;
236 : }
237 :
238 0 : void DocxSdrExport::setFrameBtLr(bool bFrameBtLr)
239 : {
240 0 : m_pImpl->m_bFrameBtLr = bFrameBtLr;
241 0 : }
242 :
243 0 : bool DocxSdrExport::getFlyFrameGraphic()
244 : {
245 0 : return m_pImpl->m_bFlyFrameGraphic;
246 : }
247 :
248 0 : void DocxSdrExport::setFlyFrameGraphic(bool bFlyFrameGraphic)
249 : {
250 0 : m_pImpl->m_bFlyFrameGraphic = bFlyFrameGraphic;
251 0 : }
252 :
253 0 : sax_fastparser::FastAttributeList*& DocxSdrExport::getFlyFillAttrList()
254 : {
255 0 : return m_pImpl->m_pFlyFillAttrList;
256 : }
257 :
258 0 : sax_fastparser::FastAttributeList* DocxSdrExport::getFlyWrapAttrList()
259 : {
260 0 : return m_pImpl->m_pFlyWrapAttrList;
261 : }
262 :
263 0 : sax_fastparser::FastAttributeList* DocxSdrExport::getBodyPrAttrList()
264 : {
265 0 : return m_pImpl->m_pBodyPrAttrList;
266 : }
267 :
268 0 : sax_fastparser::FastAttributeList*& DocxSdrExport::getDashLineStyle()
269 : {
270 0 : return m_pImpl->m_pDashLineStyleAttr;
271 : }
272 :
273 0 : void DocxSdrExport::setFlyWrapAttrList(sax_fastparser::FastAttributeList* pAttrList)
274 : {
275 0 : m_pImpl->m_pFlyWrapAttrList = pAttrList;
276 0 : }
277 :
278 0 : void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rSize)
279 : {
280 0 : m_pImpl->m_pSerializer->startElementNS(XML_w, XML_drawing, FSEND);
281 :
282 0 : const SvxLRSpaceItem pLRSpaceItem = pFrmFmt->GetLRSpace(false);
283 0 : const SvxULSpaceItem pULSpaceItem = pFrmFmt->GetULSpace(false);
284 :
285 : bool isAnchor;
286 :
287 0 : if (m_pImpl->m_bFlyFrameGraphic)
288 : {
289 0 : isAnchor = false; // make Graphic object inside DMLTextFrame & VMLTextFrame as Inline
290 : }
291 : else
292 : {
293 0 : isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR;
294 : }
295 0 : if (isAnchor)
296 : {
297 0 : sax_fastparser::FastAttributeList* attrList = m_pImpl->m_pSerializer->createAttrList();
298 0 : bool bOpaque = pFrmFmt->GetOpaque().GetValue();
299 0 : awt::Point aPos(pFrmFmt->GetHoriOrient().GetPos(), pFrmFmt->GetVertOrient().GetPos());
300 0 : const SdrObject* pObj = pFrmFmt->FindRealSdrObject();
301 0 : if (pObj != NULL)
302 : {
303 : // SdrObjects know their layer, consider that instead of the frame format.
304 0 : bOpaque = pObj->GetLayer() != pFrmFmt->GetDoc()->GetHellId() && pObj->GetLayer() != pFrmFmt->GetDoc()->GetInvisibleHellId();
305 :
306 0 : lclMovePositionWithRotation(aPos, pObj->GetRotateAngle());
307 : }
308 0 : attrList->add(XML_behindDoc, bOpaque ? "0" : "1");
309 0 : attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr());
310 0 : attrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower())).getStr());
311 0 : attrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft())).getStr());
312 0 : attrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight())).getStr());
313 0 : attrList->add(XML_simplePos, "0");
314 0 : attrList->add(XML_locked, "0");
315 0 : attrList->add(XML_layoutInCell, "1");
316 0 : attrList->add(XML_allowOverlap, "1"); // TODO
317 0 : if (pObj != NULL)
318 : // It seems 0 and 1 have special meaning: just start counting from 2 to avoid issues with that.
319 0 : attrList->add(XML_relativeHeight, OString::number(pObj->GetOrdNum() + 2));
320 : else
321 : // relativeHeight is mandatory attribute, if value is not present, we must write default value
322 0 : attrList->add(XML_relativeHeight, "0");
323 0 : if (pObj != NULL)
324 : {
325 0 : OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
326 0 : if (!sAnchorId.isEmpty())
327 0 : attrList->addNS(XML_wp14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
328 : }
329 0 : sax_fastparser::XFastAttributeListRef xAttrList(attrList);
330 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_anchor, xAttrList);
331 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND); // required, unused
332 : const char* relativeFromH;
333 : const char* relativeFromV;
334 0 : const char* alignH = NULL;
335 0 : const char* alignV = NULL;
336 0 : switch (pFrmFmt->GetVertOrient().GetRelationOrient())
337 : {
338 : case text::RelOrientation::PAGE_PRINT_AREA:
339 0 : relativeFromV = "margin";
340 0 : break;
341 : case text::RelOrientation::PAGE_FRAME:
342 0 : relativeFromV = "page";
343 0 : break;
344 : case text::RelOrientation::FRAME:
345 0 : relativeFromV = "paragraph";
346 0 : break;
347 : case text::RelOrientation::TEXT_LINE:
348 : default:
349 0 : relativeFromV = "line";
350 0 : break;
351 : }
352 0 : switch (pFrmFmt->GetVertOrient().GetVertOrient())
353 : {
354 : case text::VertOrientation::TOP:
355 : case text::VertOrientation::CHAR_TOP:
356 : case text::VertOrientation::LINE_TOP:
357 0 : if (pFrmFmt->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE)
358 0 : alignV = "bottom";
359 : else
360 0 : alignV = "top";
361 0 : break;
362 : case text::VertOrientation::BOTTOM:
363 : case text::VertOrientation::CHAR_BOTTOM:
364 : case text::VertOrientation::LINE_BOTTOM:
365 0 : if (pFrmFmt->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE)
366 0 : alignV = "top";
367 : else
368 0 : alignV = "bottom";
369 0 : break;
370 : case text::VertOrientation::CENTER:
371 : case text::VertOrientation::CHAR_CENTER:
372 : case text::VertOrientation::LINE_CENTER:
373 0 : alignV = "center";
374 0 : break;
375 : default:
376 0 : break;
377 : }
378 0 : switch (pFrmFmt->GetHoriOrient().GetRelationOrient())
379 : {
380 : case text::RelOrientation::PAGE_PRINT_AREA:
381 0 : relativeFromH = "margin";
382 0 : break;
383 : case text::RelOrientation::PAGE_FRAME:
384 0 : relativeFromH = "page";
385 0 : break;
386 : case text::RelOrientation::CHAR:
387 0 : relativeFromH = "character";
388 0 : break;
389 : case text::RelOrientation::PAGE_RIGHT:
390 0 : relativeFromH = "page";
391 0 : alignH = "right";
392 0 : break;
393 : case text::RelOrientation::FRAME:
394 : default:
395 0 : relativeFromH = "column";
396 0 : break;
397 : }
398 0 : switch (pFrmFmt->GetHoriOrient().GetHoriOrient())
399 : {
400 : case text::HoriOrientation::LEFT:
401 0 : alignH = "left";
402 0 : break;
403 : case text::HoriOrientation::RIGHT:
404 0 : alignH = "right";
405 0 : break;
406 : case text::HoriOrientation::CENTER:
407 0 : alignH = "center";
408 0 : break;
409 : case text::HoriOrientation::INSIDE:
410 0 : alignH = "inside";
411 0 : break;
412 : case text::HoriOrientation::OUTSIDE:
413 0 : alignH = "outside";
414 0 : break;
415 : default:
416 0 : break;
417 : }
418 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionH, XML_relativeFrom, relativeFromH, FSEND);
419 0 : if (alignH != NULL)
420 : {
421 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND);
422 0 : m_pImpl->m_pSerializer->write(alignH);
423 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_align);
424 : }
425 : else
426 : {
427 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND);
428 0 : m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.X));
429 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
430 : }
431 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionH);
432 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND);
433 0 : if (alignV != NULL)
434 : {
435 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND);
436 0 : m_pImpl->m_pSerializer->write(alignV);
437 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_align);
438 : }
439 : else
440 : {
441 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND);
442 0 : m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.Y));
443 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset);
444 : }
445 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionV);
446 : }
447 : else
448 : {
449 0 : sax_fastparser::FastAttributeList* aAttrList = m_pImpl->m_pSerializer->createAttrList();
450 0 : aAttrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr());
451 0 : aAttrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower())).getStr());
452 0 : aAttrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft())).getStr());
453 0 : aAttrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight())).getStr());
454 0 : const SdrObject* pObj = pFrmFmt->FindRealSdrObject();
455 0 : if (pObj != NULL)
456 : {
457 0 : OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
458 0 : if (!sAnchorId.isEmpty())
459 0 : aAttrList->addNS(XML_wp14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
460 : }
461 0 : m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_inline, aAttrList);
462 : }
463 :
464 : // now the common parts
465 : // extent of the image
466 0 : OString aWidth(OString::number(TwipsToEMU(rSize.Width())));
467 0 : OString aHeight(OString::number(TwipsToEMU(rSize.Height())));
468 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_extent,
469 0 : XML_cx, (rSize.Width() > 0 ? aWidth.getStr() : "0"),
470 0 : XML_cy, (rSize.Height() > 0 ? aHeight.getStr() : "0"),
471 0 : FSEND);
472 :
473 : // effectExtent, extent including the effect (shadow only for now)
474 0 : SvxShadowItem aShadowItem = pFrmFmt->GetShadow();
475 0 : OString aLeftExt("0"), aRightExt("0"), aTopExt("0"), aBottomExt("0");
476 0 : if (aShadowItem.GetLocation() != SVX_SHADOW_NONE)
477 : {
478 0 : OString aShadowWidth(OString::number(TwipsToEMU(aShadowItem.GetWidth())));
479 0 : switch (aShadowItem.GetLocation())
480 : {
481 : case SVX_SHADOW_TOPLEFT:
482 0 : aTopExt = aLeftExt = aShadowWidth;
483 0 : break;
484 : case SVX_SHADOW_TOPRIGHT:
485 0 : aTopExt = aRightExt = aShadowWidth;
486 0 : break;
487 : case SVX_SHADOW_BOTTOMLEFT:
488 0 : aBottomExt = aLeftExt = aShadowWidth;
489 0 : break;
490 : case SVX_SHADOW_BOTTOMRIGHT:
491 0 : aBottomExt = aRightExt = aShadowWidth;
492 0 : break;
493 : case SVX_SHADOW_NONE:
494 : case SVX_SHADOW_END:
495 0 : break;
496 0 : }
497 : }
498 :
499 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_effectExtent,
500 : XML_l, aLeftExt,
501 : XML_t, aTopExt,
502 : XML_r, aRightExt,
503 : XML_b, aBottomExt,
504 0 : FSEND);
505 :
506 0 : if (isAnchor)
507 : {
508 0 : switch (pFrmFmt->GetSurround().GetValue())
509 : {
510 : case SURROUND_NONE:
511 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapTopAndBottom, FSEND);
512 0 : break;
513 : case SURROUND_THROUGHT:
514 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapNone, FSEND);
515 0 : break;
516 : case SURROUND_PARALLEL:
517 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapSquare,
518 0 : XML_wrapText, "bothSides", FSEND);
519 0 : break;
520 : case SURROUND_IDEAL:
521 : default:
522 0 : m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_wrapSquare,
523 0 : XML_wrapText, "largest", FSEND);
524 0 : break;
525 : }
526 0 : }
527 0 : }
528 :
529 0 : void DocxSdrExport::endDMLAnchorInline(const SwFrmFmt* pFrmFmt)
530 : {
531 : bool isAnchor;
532 0 : if (m_pImpl->m_bFlyFrameGraphic)
533 : {
534 0 : isAnchor = false; // end Inline Graphic object inside DMLTextFrame
535 : }
536 : else
537 : {
538 0 : isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR;
539 : }
540 0 : m_pImpl->m_pSerializer->endElementNS(XML_wp, isAnchor ? XML_anchor : XML_inline);
541 :
542 0 : m_pImpl->m_pSerializer->endElementNS(XML_w, XML_drawing);
543 0 : }
544 :
545 0 : void DocxSdrExport::writeVMLDrawing(const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft)
546 : {
547 0 : bool bSwapInPage = false;
548 0 : if (!(sdrObj)->GetPage())
549 : {
550 0 : if (SdrModel* pModel = m_pImpl->m_rExport.pDoc->GetDrawModel())
551 : {
552 0 : if (SdrPage* pPage = pModel->GetPage(0))
553 : {
554 0 : bSwapInPage = true;
555 0 : const_cast< SdrObject* >(sdrObj)->SetPage(pPage);
556 : }
557 : }
558 : }
559 :
560 0 : m_pImpl->m_pSerializer->startElementNS(XML_w, XML_pict, FSEND);
561 0 : m_pImpl->m_pDrawingML->SetFS(m_pImpl->m_pSerializer);
562 : // See WinwordAnchoring::SetAnchoring(), these are not part of the SdrObject, have to be passed around manually.
563 :
564 0 : SwFmtHoriOrient rHoriOri = (rFrmFmt).GetHoriOrient();
565 0 : SwFmtVertOrient rVertOri = (rFrmFmt).GetVertOrient();
566 0 : m_pImpl->m_rExport.VMLExporter().AddSdrObject(*(sdrObj),
567 0 : rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(),
568 0 : rHoriOri.GetRelationOrient(),
569 0 : rVertOri.GetRelationOrient(), (&rNdTopLeft), true);
570 0 : m_pImpl->m_pSerializer->endElementNS(XML_w, XML_pict);
571 :
572 0 : if (bSwapInPage)
573 0 : const_cast< SdrObject* >(sdrObj)->SetPage(0);
574 0 : }
575 :
576 0 : void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrmFmt* pFrmFmt, int nAnchorId)
577 : {
578 0 : uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY_THROW);
579 0 : if (!m_pImpl->isSupportedDMLShape(xShape))
580 0 : return;
581 :
582 0 : sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
583 0 : Size aSize(pSdrObject->GetLogicRect().GetWidth(), pSdrObject->GetLogicRect().GetHeight());
584 0 : startDMLAnchorInline(pFrmFmt, aSize);
585 :
586 0 : sax_fastparser::FastAttributeList* pDocPrAttrList = pFS->createAttrList();
587 0 : pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
588 0 : pDocPrAttrList->add(XML_name, OUStringToOString(pSdrObject->GetName(), RTL_TEXTENCODING_UTF8));
589 0 : if (!pSdrObject->GetTitle().isEmpty())
590 0 : pDocPrAttrList->add(XML_title, OUStringToOString(pSdrObject->GetTitle(), RTL_TEXTENCODING_UTF8));
591 0 : if (!pSdrObject->GetDescription().isEmpty())
592 0 : pDocPrAttrList->add(XML_descr, OUStringToOString(pSdrObject->GetDescription(), RTL_TEXTENCODING_UTF8));
593 0 : sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
594 0 : pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
595 :
596 0 : uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
597 0 : const char* pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
598 0 : if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
599 0 : pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
600 0 : else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
601 0 : pNamespace = "http://schemas.openxmlformats.org/drawingml/2006/picture";
602 : pFS->startElementNS(XML_a, XML_graphic,
603 : FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
604 0 : FSEND);
605 : pFS->startElementNS(XML_a, XML_graphicData,
606 : XML_uri, pNamespace,
607 0 : FSEND);
608 :
609 0 : bool bLockedCanvas = false;
610 : uno::Sequence< beans::PropertyValue > propList =
611 0 : lclGetProperty(xShape, "InteropGrabBag");
612 0 : for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
613 : {
614 0 : OUString propName = propList[nProp].Name;
615 0 : if (propName == "LockedCanvas")
616 : {
617 : /*
618 : * Export as Locked Canvas only if the drawing
619 : * was originally a Locked Canvas and is now inside a Text Frame.
620 : */
621 0 : bLockedCanvas = m_pImpl->m_bIsInDMLTextFrame;
622 0 : break;
623 : }
624 0 : }
625 0 : if (bLockedCanvas)
626 : pFS->startElementNS(XML_lc, XML_lockedCanvas,
627 : FSNS(XML_xmlns, XML_lc), "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas",
628 0 : FSEND);
629 :
630 0 : m_pImpl->m_rExport.OutputDML(xShape);
631 :
632 0 : if (bLockedCanvas)
633 0 : pFS->endElementNS(XML_lc, XML_lockedCanvas);
634 0 : pFS->endElementNS(XML_a, XML_graphicData);
635 0 : pFS->endElementNS(XML_a, XML_graphic);
636 :
637 : // Relative size of the drawing.
638 0 : if (pSdrObject->GetRelativeWidth())
639 : {
640 : // At the moment drawinglayer objects are always relative from page.
641 : pFS->startElementNS(XML_wp14, XML_sizeRelH,
642 0 : XML_relativeFrom, (pSdrObject->GetRelativeWidthRelation() == text::RelOrientation::FRAME ? "margin" : "page"),
643 0 : FSEND);
644 0 : pFS->startElementNS(XML_wp14, XML_pctWidth, FSEND);
645 0 : pFS->writeEscaped(OUString::number(*pSdrObject->GetRelativeWidth() * 100 * oox::drawingml::PER_PERCENT));
646 0 : pFS->endElementNS(XML_wp14, XML_pctWidth);
647 0 : pFS->endElementNS(XML_wp14, XML_sizeRelH);
648 : }
649 0 : if (pSdrObject->GetRelativeHeight())
650 : {
651 : pFS->startElementNS(XML_wp14, XML_sizeRelV,
652 0 : XML_relativeFrom, (pSdrObject->GetRelativeHeightRelation() == text::RelOrientation::FRAME ? "margin" : "page"),
653 0 : FSEND);
654 0 : pFS->startElementNS(XML_wp14, XML_pctHeight, FSEND);
655 0 : pFS->writeEscaped(OUString::number(*pSdrObject->GetRelativeHeight() * 100 * oox::drawingml::PER_PERCENT));
656 0 : pFS->endElementNS(XML_wp14, XML_pctHeight);
657 0 : pFS->endElementNS(XML_wp14, XML_sizeRelV);
658 : }
659 :
660 0 : endDMLAnchorInline(pFrmFmt);
661 : }
662 :
663 0 : void DocxSdrExport::Impl::textFrameShadow(const SwFrmFmt& rFrmFmt)
664 : {
665 0 : SvxShadowItem aShadowItem = rFrmFmt.GetShadow();
666 0 : if (aShadowItem.GetLocation() == SVX_SHADOW_NONE)
667 0 : return;
668 :
669 0 : OString aShadowWidth(OString::number(double(aShadowItem.GetWidth()) / 20) + "pt");
670 0 : OString aOffset;
671 0 : switch (aShadowItem.GetLocation())
672 : {
673 : case SVX_SHADOW_TOPLEFT:
674 0 : aOffset = "-" + aShadowWidth + ",-" + aShadowWidth;
675 0 : break;
676 : case SVX_SHADOW_TOPRIGHT:
677 0 : aOffset = aShadowWidth + ",-" + aShadowWidth;
678 0 : break;
679 : case SVX_SHADOW_BOTTOMLEFT:
680 0 : aOffset = "-" + aShadowWidth + "," + aShadowWidth;
681 0 : break;
682 : case SVX_SHADOW_BOTTOMRIGHT:
683 0 : aOffset = aShadowWidth + "," + aShadowWidth;
684 0 : break;
685 : case SVX_SHADOW_NONE:
686 : case SVX_SHADOW_END:
687 0 : break;
688 : }
689 0 : if (aOffset.isEmpty())
690 0 : return;
691 :
692 0 : OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
693 : m_pSerializer->singleElementNS(XML_v, XML_shadow,
694 : XML_on, "t",
695 0 : XML_color, "#" + aShadowColor,
696 : XML_offset, aOffset,
697 0 : FSEND);
698 : }
699 :
700 0 : bool DocxSdrExport::Impl::isSupportedDMLShape(uno::Reference<drawing::XShape> xShape)
701 : {
702 0 : bool supported = true;
703 :
704 0 : uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
705 0 : if (xServiceInfo->supportsService("com.sun.star.drawing.PolyPolygonShape") || xServiceInfo->supportsService("com.sun.star.drawing.PolyLineShape"))
706 0 : supported = false;
707 :
708 0 : return supported;
709 : }
710 :
711 0 : void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft, int nAnchorId)
712 : {
713 : // Depending on the shape type, we actually don't write the shape as DML.
714 0 : OUString sShapeType;
715 0 : sal_uInt32 nMirrorFlags = 0;
716 0 : uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(sdrObj)->getUnoShape(), uno::UNO_QUERY_THROW);
717 0 : MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType(xShape, nMirrorFlags, sShapeType);
718 :
719 0 : if (eShapeType != ESCHER_ShpInst_TextPlainText && m_pImpl->isSupportedDMLShape(xShape))
720 : {
721 0 : m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND);
722 :
723 0 : const SdrObjGroup* pObjGroup = PTR_CAST(SdrObjGroup, sdrObj);
724 0 : m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_Choice,
725 : XML_Requires, (pObjGroup ? "wpg" : "wps"),
726 0 : FSEND);
727 0 : writeDMLDrawing(sdrObj, &rFrmFmt, nAnchorId);
728 0 : m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_Choice);
729 :
730 0 : m_pImpl->m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND);
731 0 : writeVMLDrawing(sdrObj, rFrmFmt, rNdTopLeft);
732 0 : m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_Fallback);
733 :
734 0 : m_pImpl->m_pSerializer->endElementNS(XML_mc, XML_AlternateContent);
735 : }
736 : else
737 0 : writeVMLDrawing(sdrObj, rFrmFmt, rNdTopLeft);
738 0 : }
739 :
740 : // Converts ARGB transparency (0..255) to drawingml alpha (opposite, and 0..100000)
741 0 : OString lcl_ConvertTransparency(const Color& rColor)
742 : {
743 0 : if (rColor.GetTransparency() > 0)
744 : {
745 0 : sal_Int32 nTransparencyPercent = 100 - float(rColor.GetTransparency()) / 2.55;
746 0 : return OString::number(nTransparencyPercent * oox::drawingml::PER_PERCENT);
747 : }
748 : else
749 0 : return OString("");
750 : }
751 :
752 0 : void DocxSdrExport::writeDMLEffectLst(const SwFrmFmt& rFrmFmt)
753 : {
754 0 : SvxShadowItem aShadowItem = rFrmFmt.GetShadow();
755 :
756 : // Output effects
757 0 : if (aShadowItem.GetLocation() != SVX_SHADOW_NONE)
758 : {
759 : // Distance is measured diagonally from corner
760 0 : double nShadowDist = sqrt((double)aShadowItem.GetWidth()*aShadowItem.GetWidth()*2.0);
761 0 : OString aShadowDist(OString::number(TwipsToEMU(nShadowDist)));
762 0 : OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
763 0 : OString aShadowAlpha = lcl_ConvertTransparency(aShadowItem.GetColor());
764 0 : sal_uInt32 nShadowDir = 0;
765 0 : switch (aShadowItem.GetLocation())
766 : {
767 : case SVX_SHADOW_TOPLEFT:
768 0 : nShadowDir = 13500000;
769 0 : break;
770 : case SVX_SHADOW_TOPRIGHT:
771 0 : nShadowDir = 18900000;
772 0 : break;
773 : case SVX_SHADOW_BOTTOMLEFT:
774 0 : nShadowDir = 8100000;
775 0 : break;
776 : case SVX_SHADOW_BOTTOMRIGHT:
777 0 : nShadowDir = 2700000;
778 0 : break;
779 : case SVX_SHADOW_NONE:
780 : case SVX_SHADOW_END:
781 0 : break;
782 : }
783 0 : OString aShadowDir(OString::number(nShadowDir));
784 :
785 0 : m_pImpl->m_pSerializer->startElementNS(XML_a, XML_effectLst, FSEND);
786 0 : m_pImpl->m_pSerializer->startElementNS(XML_a, XML_outerShdw,
787 : XML_dist, aShadowDist.getStr(),
788 0 : XML_dir, aShadowDir.getStr(), FSEND);
789 0 : if (aShadowAlpha.isEmpty())
790 0 : m_pImpl->m_pSerializer->singleElementNS(XML_a, XML_srgbClr,
791 0 : XML_val, aShadowColor.getStr(), FSEND);
792 : else
793 : {
794 0 : m_pImpl->m_pSerializer->startElementNS(XML_a, XML_srgbClr, XML_val, aShadowColor.getStr(), FSEND);
795 0 : m_pImpl->m_pSerializer->singleElementNS(XML_a, XML_alpha, XML_val, aShadowAlpha.getStr(), FSEND);
796 0 : m_pImpl->m_pSerializer->endElementNS(XML_a, XML_srgbClr);
797 : }
798 0 : m_pImpl->m_pSerializer->endElementNS(XML_a, XML_outerShdw);
799 0 : m_pImpl->m_pSerializer->endElementNS(XML_a, XML_effectLst);
800 0 : }
801 :
802 0 : }
803 :
804 0 : void DocxSdrExport::writeDiagramRels(uno::Reference<xml::dom::XDocument> xDom,
805 : uno::Sequence< uno::Sequence< uno::Any > > xRelSeq,
806 : uno::Reference< io::XOutputStream > xOutStream, const OUString& sGrabBagProperyName)
807 : {
808 : // add image relationships of OOXData, OOXDiagram
809 0 : OUString sType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
810 0 : uno::Reference< xml::sax::XSAXSerializable > xSerializer(xDom, uno::UNO_QUERY);
811 0 : uno::Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(comphelper::getProcessComponentContext());
812 0 : xWriter->setOutputStream(xOutStream);
813 :
814 : // retrieve the relationships from Sequence
815 0 : for (sal_Int32 j = 0; j < xRelSeq.getLength(); j++)
816 : {
817 : // diagramDataRelTuple[0] => RID,
818 : // diagramDataRelTuple[1] => xInputStream
819 : // diagramDataRelTuple[2] => extension
820 0 : uno::Sequence< uno::Any > diagramDataRelTuple = xRelSeq[j];
821 :
822 0 : OUString sRelId, sExtension;
823 0 : diagramDataRelTuple[0] >>= sRelId;
824 0 : diagramDataRelTuple[2] >>= sExtension;
825 0 : OUString sContentType;
826 0 : if (sExtension == ".jpeg")
827 0 : sContentType = "image/jpeg";
828 0 : else if (sExtension == ".WMF")
829 0 : sContentType = "image/x-wmf";
830 0 : sRelId = sRelId.copy(3);
831 :
832 0 : StreamDataSequence dataSeq;
833 0 : diagramDataRelTuple[1] >>= dataSeq;
834 0 : uno::Reference<io::XInputStream> dataImagebin(new ::comphelper::SequenceInputStream(dataSeq));
835 :
836 0 : OUString sFragment("../media/");
837 0 : sFragment += sGrabBagProperyName + OUString::number(j) + sExtension;
838 :
839 0 : PropertySet aProps(xOutStream);
840 0 : aProps.setAnyProperty(PROP_RelId, uno::makeAny(sal_Int32(sRelId.toInt32())));
841 :
842 0 : m_pImpl->m_rExport.GetFilter().addRelation(xOutStream, sType, sFragment);
843 :
844 0 : sFragment = sFragment.replaceFirst("..","word");
845 0 : uno::Reference< io::XOutputStream > xBinOutStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(sFragment, sContentType);
846 :
847 : try
848 : {
849 0 : sal_Int32 nBufferSize = 512;
850 0 : uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
851 : sal_Int32 nRead;
852 0 : do
853 : {
854 0 : nRead = dataImagebin->readBytes(aDataBuffer, nBufferSize);
855 0 : if (nRead)
856 : {
857 0 : if (nRead < nBufferSize)
858 : {
859 0 : nBufferSize = nRead;
860 0 : aDataBuffer.realloc(nRead);
861 : }
862 0 : xBinOutStream->writeBytes(aDataBuffer);
863 : }
864 : }
865 : while (nRead);
866 0 : xBinOutStream->flush();
867 : }
868 0 : catch (const uno::Exception& rException)
869 : {
870 : SAL_WARN("sw.ww8", "DocxSdrExport::writeDiagramRels Failed to copy grabbaged Image: " << rException.Message);
871 : }
872 0 : dataImagebin->closeInput();
873 0 : }
874 0 : }
875 :
876 0 : void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFrmFmt, int nAnchorId)
877 : {
878 0 : sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
879 0 : uno::Reference< drawing::XShape > xShape(((SdrObject*)sdrObject)->getUnoShape(), uno::UNO_QUERY);
880 0 : uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
881 :
882 0 : uno::Reference<xml::dom::XDocument> dataDom;
883 0 : uno::Reference<xml::dom::XDocument> layoutDom;
884 0 : uno::Reference<xml::dom::XDocument> styleDom;
885 0 : uno::Reference<xml::dom::XDocument> colorDom;
886 0 : uno::Reference<xml::dom::XDocument> drawingDom;
887 0 : uno::Sequence< uno::Sequence< uno::Any > > xDataRelSeq;
888 0 : uno::Sequence< uno::Any > diagramDrawing;
889 :
890 : // retrieve the doms from the GrabBag
891 0 : OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
892 0 : uno::Sequence< beans::PropertyValue > propList;
893 0 : xPropSet->getPropertyValue(pName) >>= propList;
894 0 : for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
895 : {
896 0 : OUString propName = propList[nProp].Name;
897 0 : if (propName == "OOXData")
898 0 : propList[nProp].Value >>= dataDom;
899 0 : else if (propName == "OOXLayout")
900 0 : propList[nProp].Value >>= layoutDom;
901 0 : else if (propName == "OOXStyle")
902 0 : propList[nProp].Value >>= styleDom;
903 0 : else if (propName == "OOXColor")
904 0 : propList[nProp].Value >>= colorDom;
905 0 : else if (propName == "OOXDrawing")
906 0 : propList[nProp].Value >>= diagramDrawing;
907 0 : else if (propName == "OOXDiagramDataRels")
908 0 : propList[nProp].Value >>= xDataRelSeq;
909 0 : }
910 :
911 0 : diagramDrawing[0] >>= drawingDom;
912 : // check that we have the 4 mandatory XDocuments
913 : // if not, there was an error importing and we won't output anything
914 0 : if (!dataDom.is() || !layoutDom.is() || !styleDom.is() || !colorDom.is())
915 0 : return;
916 :
917 : // write necessary tags to document.xml
918 0 : Size aSize(sdrObject->GetSnapRect().GetWidth(), sdrObject->GetSnapRect().GetHeight());
919 0 : startDMLAnchorInline(&rFrmFmt, aSize);
920 :
921 : // generate an unique id
922 0 : sax_fastparser::FastAttributeList* pDocPrAttrList = pFS->createAttrList();
923 0 : pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
924 0 : OUString sName = "Diagram" + OUString::number(nAnchorId);
925 0 : pDocPrAttrList->add(XML_name, OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
926 0 : sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
927 0 : pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
928 :
929 : sal_Int32 diagramCount;
930 0 : diagramCount = nAnchorId;
931 :
932 : pFS->singleElementNS(XML_wp, XML_cNvGraphicFramePr,
933 0 : FSEND);
934 :
935 : pFS->startElementNS(XML_a, XML_graphic,
936 : FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
937 0 : FSEND);
938 :
939 : pFS->startElementNS(XML_a, XML_graphicData,
940 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/diagram",
941 0 : FSEND);
942 :
943 : // add data relation
944 0 : OUString dataFileName = "diagrams/data" + OUString::number(diagramCount) + ".xml";
945 0 : OString dataRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
946 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData",
947 0 : dataFileName, false), RTL_TEXTENCODING_UTF8);
948 :
949 :
950 : // add layout relation
951 0 : OUString layoutFileName = "diagrams/layout" + OUString::number(diagramCount) + ".xml";
952 0 : OString layoutRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
953 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout",
954 0 : layoutFileName, false), RTL_TEXTENCODING_UTF8);
955 :
956 : // add style relation
957 0 : OUString styleFileName = "diagrams/quickStyle" + OUString::number(diagramCount) + ".xml";
958 0 : OString styleRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
959 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle",
960 0 : styleFileName , false), RTL_TEXTENCODING_UTF8);
961 :
962 : // add color relation
963 0 : OUString colorFileName = "diagrams/colors" + OUString::number(diagramCount) + ".xml";
964 0 : OString colorRelId = OUStringToOString(m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
965 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors",
966 0 : colorFileName, false), RTL_TEXTENCODING_UTF8);
967 :
968 0 : OUString drawingFileName;
969 0 : if (drawingDom.is())
970 : {
971 : // add drawing relation
972 0 : drawingFileName = "diagrams/drawing" + OUString::number(diagramCount) + ".xml";
973 0 : OUString drawingRelId = m_pImpl->m_rExport.GetFilter().addRelation(pFS->getOutputStream(),
974 : "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing",
975 0 : drawingFileName , false);
976 :
977 : // the data dom contains a reference to the drawing relation. We need to update it with the new generated
978 : // relation value before writing the dom to a file
979 :
980 : // Get the dsp:damaModelExt node from the dom
981 : uno::Reference< xml::dom::XNodeList > nodeList =
982 0 : dataDom->getElementsByTagNameNS("http://schemas.microsoft.com/office/drawing/2008/diagram", "dataModelExt");
983 :
984 : // There must be one element only so get it
985 0 : uno::Reference< xml::dom::XNode > node = nodeList->item(0);
986 :
987 : // Get the list of attributes of the node
988 0 : uno::Reference< xml::dom::XNamedNodeMap > nodeMap = node->getAttributes();
989 :
990 : // Get the node with the relId attribute and set its new value
991 0 : uno::Reference< xml::dom::XNode > relIdNode = nodeMap->getNamedItem("relId");
992 0 : relIdNode->setNodeValue(drawingRelId);
993 : }
994 :
995 : pFS->singleElementNS(XML_dgm, XML_relIds,
996 : FSNS(XML_xmlns, XML_dgm), "http://schemas.openxmlformats.org/drawingml/2006/diagram",
997 : FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
998 : FSNS(XML_r, XML_dm), dataRelId.getStr(),
999 : FSNS(XML_r, XML_lo), layoutRelId.getStr(),
1000 : FSNS(XML_r, XML_qs), styleRelId.getStr(),
1001 : FSNS(XML_r, XML_cs), colorRelId.getStr(),
1002 0 : FSEND);
1003 :
1004 0 : pFS->endElementNS(XML_a, XML_graphicData);
1005 0 : pFS->endElementNS(XML_a, XML_graphic);
1006 0 : endDMLAnchorInline(&rFrmFmt);
1007 :
1008 0 : uno::Reference< xml::sax::XSAXSerializable > serializer;
1009 0 : uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
1010 :
1011 : // write data file
1012 0 : serializer.set(dataDom, uno::UNO_QUERY);
1013 0 : uno::Reference< io::XOutputStream > xDataOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream(
1014 0 : "word/" + dataFileName, "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml");
1015 0 : writer->setOutputStream(xDataOutputStream);
1016 0 : serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1017 0 : uno::Sequence< beans::StringPair >());
1018 :
1019 : // write the associated Images and rels for data file
1020 0 : writeDiagramRels(dataDom, xDataRelSeq, xDataOutputStream, OUString("OOXDiagramDataRels"));
1021 :
1022 : // write layout file
1023 0 : serializer.set(layoutDom, uno::UNO_QUERY);
1024 0 : writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + layoutFileName,
1025 0 : "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml"));
1026 0 : serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1027 0 : uno::Sequence< beans::StringPair >());
1028 :
1029 : // write style file
1030 0 : serializer.set(styleDom, uno::UNO_QUERY);
1031 0 : writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + styleFileName,
1032 0 : "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml"));
1033 0 : serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1034 0 : uno::Sequence< beans::StringPair >());
1035 :
1036 : // write color file
1037 0 : serializer.set(colorDom, uno::UNO_QUERY);
1038 0 : writer->setOutputStream(m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + colorFileName,
1039 0 : "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml"));
1040 0 : serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1041 0 : uno::Sequence< beans::StringPair >());
1042 :
1043 : // write drawing file
1044 :
1045 0 : if (drawingDom.is())
1046 : {
1047 0 : serializer.set(drawingDom, uno::UNO_QUERY);
1048 0 : uno::Reference< io::XOutputStream > xDrawingOutputStream = m_pImpl->m_rExport.GetFilter().openFragmentStream("word/" + drawingFileName,
1049 0 : "application/vnd.openxmlformats-officedocument.drawingml.diagramDrawing+xml");
1050 0 : writer->setOutputStream(xDrawingOutputStream);
1051 0 : serializer->serialize(uno::Reference< xml::sax::XDocumentHandler >(writer, uno::UNO_QUERY_THROW),
1052 0 : uno::Sequence< beans::StringPair >());
1053 :
1054 : // write the associated Images and rels for drawing file
1055 0 : uno::Sequence< uno::Sequence< uno::Any > > xDrawingRelSeq;
1056 0 : diagramDrawing[1] >>= xDrawingRelSeq;
1057 0 : writeDiagramRels(drawingDom, xDrawingRelSeq, xDrawingOutputStream, OUString("OOXDiagramDrawingRels"));
1058 0 : }
1059 : }
1060 :
1061 0 : void DocxSdrExport::writeDMLTextFrame(sw::Frame* pParentFrame, int nAnchorId)
1062 : {
1063 0 : m_pImpl->m_bIsInDMLTextFrame = true;
1064 0 : sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
1065 0 : const SwFrmFmt& rFrmFmt = pParentFrame->GetFrmFmt();
1066 0 : const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
1067 :
1068 0 : sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
1069 0 : sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1070 :
1071 : //Save data here and restore when out of scope
1072 0 : ExportDataSaveRestore aDataGuard(m_pImpl->m_rExport, nStt, nEnd, pParentFrame);
1073 :
1074 : // When a frame has some low height, but automatically expanded due
1075 : // to lots of contents, this size contains the real size.
1076 0 : const Size aSize = pParentFrame->GetSize();
1077 :
1078 0 : startDMLAnchorInline(&rFrmFmt, aSize);
1079 :
1080 0 : sax_fastparser::FastAttributeList* pDocPrAttrList = pFS->createAttrList();
1081 0 : pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
1082 0 : pDocPrAttrList->add(XML_name, OUStringToOString(rFrmFmt.GetName(), RTL_TEXTENCODING_UTF8).getStr());
1083 0 : sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
1084 0 : pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
1085 :
1086 : pFS->startElementNS(XML_a, XML_graphic,
1087 : FSNS(XML_xmlns, XML_a), "http://schemas.openxmlformats.org/drawingml/2006/main",
1088 0 : FSEND);
1089 : pFS->startElementNS(XML_a, XML_graphicData,
1090 : XML_uri, "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
1091 0 : FSEND);
1092 0 : pFS->startElementNS(XML_wps, XML_wsp, FSEND);
1093 : pFS->singleElementNS(XML_wps, XML_cNvSpPr,
1094 : XML_txBox, "1",
1095 0 : FSEND);
1096 :
1097 0 : uno::Any aRotation ;
1098 0 : uno::Reference< drawing::XShape > xShape;
1099 0 : const SdrObject* pSdrObj = rFrmFmt.FindRealSdrObject();
1100 0 : if (pSdrObj)
1101 0 : xShape = uno::Reference< drawing::XShape >(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
1102 0 : uno::Reference< beans::XPropertySet > xPropertySet(xShape, uno::UNO_QUERY);
1103 0 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
1104 0 : if (xPropertySet.is())
1105 0 : xPropSetInfo = xPropertySet->getPropertySetInfo();
1106 0 : sal_Int32 nRotation = 0;
1107 0 : if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
1108 : {
1109 0 : uno::Sequence< beans::PropertyValue > propList;
1110 0 : xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
1111 0 : for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
1112 : {
1113 0 : OUString propName = propList[nProp].Name;
1114 0 : if (propName == "mso-rotation-angle")
1115 : {
1116 0 : aRotation = propList[nProp].Value ;
1117 0 : break;
1118 : }
1119 0 : }
1120 : }
1121 0 : aRotation >>= nRotation ;
1122 0 : OString sRotation(OString::number(nRotation));
1123 : // Shape properties
1124 0 : pFS->startElementNS(XML_wps, XML_spPr, FSEND);
1125 0 : if (nRotation)
1126 : {
1127 : pFS->startElementNS(XML_a, XML_xfrm,
1128 : XML_rot, sRotation.getStr(),
1129 0 : FSEND);
1130 : }
1131 : else
1132 : {
1133 0 : pFS->startElementNS(XML_a, XML_xfrm, FSEND);
1134 : }
1135 : pFS->singleElementNS(XML_a, XML_off,
1136 : XML_x, "0",
1137 : XML_y, "0",
1138 0 : FSEND);
1139 0 : OString aWidth(OString::number(TwipsToEMU(aSize.Width())));
1140 0 : OString aHeight(OString::number(TwipsToEMU(aSize.Height())));
1141 : pFS->singleElementNS(XML_a, XML_ext,
1142 : XML_cx, aWidth.getStr(),
1143 : XML_cy, aHeight.getStr(),
1144 0 : FSEND);
1145 0 : pFS->endElementNS(XML_a, XML_xfrm);
1146 0 : OUString shapeType = "rect";
1147 0 : if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
1148 : {
1149 0 : uno::Sequence< beans::PropertyValue > propList;
1150 0 : xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
1151 0 : for (sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp)
1152 : {
1153 0 : OUString propName = propList[nProp].Name;
1154 0 : if (propName == "mso-orig-shape-type")
1155 : {
1156 0 : propList[nProp].Value >>= shapeType;
1157 0 : break;
1158 : }
1159 0 : }
1160 : }
1161 :
1162 : pFS->singleElementNS(XML_a, XML_prstGeom,
1163 : XML_prst, OUStringToOString(shapeType, RTL_TEXTENCODING_UTF8).getStr(),
1164 0 : FSEND);
1165 0 : m_pImpl->m_bDMLTextFrameSyntax = true;
1166 0 : m_pImpl->m_pBodyPrAttrList = pFS->createAttrList();
1167 : {
1168 0 : drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
1169 0 : if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("TextVerticalAdjust"))
1170 0 : xPropertySet->getPropertyValue("TextVerticalAdjust") >>= eAdjust;
1171 0 : m_pImpl->m_pBodyPrAttrList->add(XML_anchor, oox::drawingml::GetTextVerticalAdjust(eAdjust));
1172 : }
1173 0 : m_pImpl->m_rExport.OutputFormat(pParentFrame->GetFrmFmt(), false, false, true);
1174 0 : m_pImpl->m_bDMLTextFrameSyntax = false;
1175 0 : writeDMLEffectLst(rFrmFmt);
1176 0 : pFS->endElementNS(XML_wps, XML_spPr);
1177 :
1178 0 : m_pImpl->m_rExport.mpParentFrame = NULL;
1179 0 : pFS->startElementNS(XML_wps, XML_txbx, FSEND);
1180 0 : pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
1181 :
1182 0 : m_pImpl->m_bFrameBtLr = checkFrameBtlr(m_pImpl->m_rExport.pDoc->GetNodes()[nStt], 0);
1183 0 : m_pImpl->m_bFlyFrameGraphic = true;
1184 0 : m_pImpl->m_rExport.WriteText();
1185 0 : m_pImpl->m_bFlyFrameGraphic = false;
1186 0 : m_pImpl->m_bFrameBtLr = false;
1187 :
1188 0 : pFS->endElementNS(XML_w, XML_txbxContent);
1189 0 : pFS->endElementNS(XML_wps, XML_txbx);
1190 0 : sax_fastparser::XFastAttributeListRef xBodyPrAttrList(m_pImpl->m_pBodyPrAttrList);
1191 0 : m_pImpl->m_pBodyPrAttrList = NULL;
1192 0 : pFS->startElementNS(XML_wps, XML_bodyPr, xBodyPrAttrList);
1193 : // AutoSize of the Text Frame.
1194 0 : const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
1195 0 : pFS->singleElementNS(XML_a, (rSize.GetHeightSizeType() == ATT_VAR_SIZE ? XML_spAutoFit : XML_noAutofit), FSEND);
1196 0 : pFS->endElementNS(XML_wps, XML_bodyPr);
1197 :
1198 0 : pFS->endElementNS(XML_wps, XML_wsp);
1199 0 : pFS->endElementNS(XML_a, XML_graphicData);
1200 0 : pFS->endElementNS(XML_a, XML_graphic);
1201 :
1202 : // Relative size of the Text Frame.
1203 0 : if (rSize.GetWidthPercent())
1204 : {
1205 : pFS->startElementNS(XML_wp14, XML_sizeRelH,
1206 0 : XML_relativeFrom, (rSize.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME ? "page" : "margin"),
1207 0 : FSEND);
1208 0 : pFS->startElementNS(XML_wp14, XML_pctWidth, FSEND);
1209 0 : pFS->writeEscaped(OUString::number(rSize.GetWidthPercent() * oox::drawingml::PER_PERCENT));
1210 0 : pFS->endElementNS(XML_wp14, XML_pctWidth);
1211 0 : pFS->endElementNS(XML_wp14, XML_sizeRelH);
1212 : }
1213 0 : if (rSize.GetHeightPercent())
1214 : {
1215 : pFS->startElementNS(XML_wp14, XML_sizeRelV,
1216 0 : XML_relativeFrom, (rSize.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME ? "page" : "margin"),
1217 0 : FSEND);
1218 0 : pFS->startElementNS(XML_wp14, XML_pctHeight, FSEND);
1219 0 : pFS->writeEscaped(OUString::number(rSize.GetHeightPercent() * oox::drawingml::PER_PERCENT));
1220 0 : pFS->endElementNS(XML_wp14, XML_pctHeight);
1221 0 : pFS->endElementNS(XML_wp14, XML_sizeRelV);
1222 : }
1223 :
1224 0 : endDMLAnchorInline(&rFrmFmt);
1225 0 : m_pImpl->m_bIsInDMLTextFrame = false;
1226 0 : }
1227 :
1228 0 : void DocxSdrExport::writeVMLTextFrame(sw::Frame* pParentFrame)
1229 : {
1230 0 : sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
1231 0 : const SwFrmFmt& rFrmFmt = pParentFrame->GetFrmFmt();
1232 0 : const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
1233 :
1234 0 : sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
1235 0 : sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1236 :
1237 : //Save data here and restore when out of scope
1238 0 : ExportDataSaveRestore aDataGuard(m_pImpl->m_rExport, nStt, nEnd, pParentFrame);
1239 :
1240 : // When a frame has some low height, but automatically expanded due
1241 : // to lots of contents, this size contains the real size.
1242 0 : const Size aSize = pParentFrame->GetSize();
1243 0 : m_pImpl->m_pFlyFrameSize = &aSize;
1244 :
1245 0 : m_pImpl->m_bTextFrameSyntax = true;
1246 0 : m_pImpl->m_pFlyAttrList = pFS->createAttrList();
1247 0 : m_pImpl->m_pTextboxAttrList = pFS->createAttrList();
1248 0 : m_pImpl->m_aTextFrameStyle = "position:absolute";
1249 0 : m_pImpl->m_rExport.OutputFormat(pParentFrame->GetFrmFmt(), false, false, true);
1250 0 : m_pImpl->m_pFlyAttrList->add(XML_style, m_pImpl->m_aTextFrameStyle.makeStringAndClear());
1251 :
1252 0 : const SdrObject* pObject = pParentFrame->GetFrmFmt().FindRealSdrObject();
1253 0 : if (pObject != NULL)
1254 : {
1255 0 : OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObject);
1256 0 : if (!sAnchorId.isEmpty())
1257 0 : m_pImpl->m_pFlyAttrList->addNS(XML_w14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
1258 : }
1259 :
1260 0 : sax_fastparser::XFastAttributeListRef xFlyAttrList(m_pImpl->m_pFlyAttrList);
1261 0 : m_pImpl->m_pFlyAttrList = NULL;
1262 0 : m_pImpl->m_bFrameBtLr = checkFrameBtlr(m_pImpl->m_rExport.pDoc->GetNodes()[nStt], m_pImpl->m_pTextboxAttrList);
1263 0 : sax_fastparser::XFastAttributeListRef xTextboxAttrList(m_pImpl->m_pTextboxAttrList);
1264 0 : m_pImpl->m_pTextboxAttrList = NULL;
1265 0 : m_pImpl->m_bTextFrameSyntax = false;
1266 0 : m_pImpl->m_pFlyFrameSize = 0;
1267 0 : m_pImpl->m_rExport.mpParentFrame = NULL;
1268 :
1269 0 : pFS->startElementNS(XML_w, XML_pict, FSEND);
1270 0 : pFS->startElementNS(XML_v, XML_rect, xFlyAttrList);
1271 0 : m_pImpl->textFrameShadow(rFrmFmt);
1272 0 : if (m_pImpl->m_pFlyFillAttrList)
1273 : {
1274 0 : sax_fastparser::XFastAttributeListRef xFlyFillAttrList(m_pImpl->m_pFlyFillAttrList);
1275 0 : m_pImpl->m_pFlyFillAttrList = NULL;
1276 0 : pFS->singleElementNS(XML_v, XML_fill, xFlyFillAttrList);
1277 : }
1278 0 : if (m_pImpl->m_pDashLineStyleAttr)
1279 : {
1280 0 : sax_fastparser::XFastAttributeListRef xDashLineStyleAttr(m_pImpl->m_pDashLineStyleAttr);
1281 0 : m_pImpl->m_pDashLineStyleAttr = NULL;
1282 0 : pFS->singleElementNS(XML_v, XML_stroke, xDashLineStyleAttr);
1283 : }
1284 0 : pFS->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
1285 0 : pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
1286 0 : m_pImpl->m_bFlyFrameGraphic = true;
1287 0 : m_pImpl->m_rExport.WriteText();
1288 0 : m_pImpl->m_bFlyFrameGraphic = false;
1289 0 : pFS->endElementNS(XML_w, XML_txbxContent);
1290 0 : pFS->endElementNS(XML_v, XML_textbox);
1291 :
1292 0 : if (m_pImpl->m_pFlyWrapAttrList)
1293 : {
1294 0 : sax_fastparser::XFastAttributeListRef xFlyWrapAttrList(m_pImpl->m_pFlyWrapAttrList);
1295 0 : m_pImpl->m_pFlyWrapAttrList = NULL;
1296 0 : pFS->singleElementNS(XML_w10, XML_wrap, xFlyWrapAttrList);
1297 : }
1298 :
1299 0 : pFS->endElementNS(XML_v, XML_rect);
1300 0 : pFS->endElementNS(XML_w, XML_pict);
1301 0 : m_pImpl->m_bFrameBtLr = false;
1302 0 : }
1303 :
1304 0 : bool DocxSdrExport::checkFrameBtlr(SwNode* pStartNode, sax_fastparser::FastAttributeList* pTextboxAttrList)
1305 : {
1306 : // The intended usage is to pass either a valid VML or DML attribute list.
1307 : assert(pTextboxAttrList || m_pImpl->m_pBodyPrAttrList);
1308 :
1309 0 : if (!pStartNode->IsTxtNode())
1310 0 : return false;
1311 :
1312 0 : SwTxtNode* pTxtNode = static_cast<SwTxtNode*>(pStartNode);
1313 :
1314 0 : const SfxPoolItem* pItem = 0; // explicitly init to avoid warnings
1315 0 : bool bItemSet = false;
1316 0 : if (pTxtNode->HasSwAttrSet())
1317 : {
1318 0 : const SwAttrSet& rAttrSet = pTxtNode->GetSwAttrSet();
1319 0 : bItemSet = rAttrSet.GetItemState(RES_CHRATR_ROTATE, true, &pItem) == SFX_ITEM_SET;
1320 : }
1321 :
1322 0 : if (!bItemSet)
1323 : {
1324 0 : if (!pTxtNode->HasHints())
1325 0 : return false;
1326 :
1327 0 : SwTxtAttr* pTxtAttr = pTxtNode->GetTxtAttrAt(0, RES_TXTATR_AUTOFMT);
1328 :
1329 0 : if (!pTxtAttr || pTxtAttr->Which() != RES_TXTATR_AUTOFMT)
1330 0 : return false;
1331 :
1332 0 : boost::shared_ptr<SfxItemSet> pItemSet = pTxtAttr->GetAutoFmt().GetStyleHandle();
1333 0 : bItemSet = pItemSet->GetItemState(RES_CHRATR_ROTATE, true, &pItem) == SFX_ITEM_SET;
1334 : }
1335 :
1336 0 : if (bItemSet)
1337 : {
1338 0 : const SvxCharRotateItem& rCharRotate = static_cast<const SvxCharRotateItem&>(*pItem);
1339 0 : if (rCharRotate.GetValue() == 900)
1340 : {
1341 0 : if (pTextboxAttrList)
1342 0 : pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
1343 : else
1344 0 : m_pImpl->m_pBodyPrAttrList->add(XML_vert, "vert270");
1345 0 : return true;
1346 : }
1347 : }
1348 0 : return false;
1349 0 : }
1350 :
1351 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|