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