LibreOffice Module sw (master)  1
docxsdrexport.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "docxsdrexport.hxx"
11 #include <com/sun/star/beans/XPropertySet.hpp>
12 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
13 #include <editeng/lrspitem.hxx>
14 #include <editeng/ulspitem.hxx>
15 #include <editeng/shaditem.hxx>
16 #include <editeng/opaqitem.hxx>
17 #include <editeng/boxitem.hxx>
18 #include <svx/svdogrp.hxx>
19 #include <oox/token/namespaces.hxx>
20 #include <textboxhelper.hxx>
21 #include <fmtanchr.hxx>
22 #include <fmtsrnd.hxx>
23 #include <fmtcntnt.hxx>
24 #include <fmtornt.hxx>
25 #include <fmtfsize.hxx>
26 #include <frmatr.hxx>
28 #include "docxattributeoutput.hxx"
29 #include "docxexportfilter.hxx"
30 #include <comphelper/flagguard.hxx>
31 #include <comphelper/sequence.hxx>
33 #include <sal/log.hxx>
34 #include <frmfmt.hxx>
37 
38 using namespace com::sun::star;
39 using namespace oox;
40 
41 namespace
42 {
43 uno::Sequence<beans::PropertyValue> lclGetProperty(const uno::Reference<drawing::XShape>& rShape,
44  const OUString& rPropName)
45 {
46  uno::Sequence<beans::PropertyValue> aResult;
47  uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
48  uno::Reference<beans::XPropertySetInfo> xPropSetInfo;
49 
50  if (!xPropertySet.is())
51  return aResult;
52 
53  xPropSetInfo = xPropertySet->getPropertySetInfo();
54  if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(rPropName))
55  {
56  xPropertySet->getPropertyValue(rPropName) >>= aResult;
57  }
58  return aResult;
59 }
60 
61 OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj)
62 {
63  OUString aResult;
64  uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObj)->getUnoShape(),
65  uno::UNO_QUERY);
66  OUString aGrabBagName;
67  uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
68  if (xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
69  aGrabBagName = "FrameInteropGrabBag";
70  else
71  aGrabBagName = "InteropGrabBag";
72  uno::Sequence<beans::PropertyValue> propList = lclGetProperty(xShape, aGrabBagName);
73  auto pProp
74  = std::find_if(propList.begin(), propList.end(),
75  [](const beans::PropertyValue& rProp) { return rProp.Name == "AnchorId"; });
76  if (pProp != propList.end())
77  pProp->Value >>= aResult;
78  return aResult;
79 }
80 
81 void lclMovePositionWithRotation(awt::Point& aPos, const Size& rSize, sal_Int64 nRotation)
82 {
83  // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx)
84  // TODO: refactor
85 
86  if (nRotation == 0)
87  return;
88 
89  if (nRotation < 0)
90  nRotation = (36000 + nRotation) % 36000;
91  if (nRotation % 18000 == 0)
92  nRotation = 0;
93  while (nRotation > 9000)
94  nRotation = (18000 - (nRotation % 18000));
95 
96  double fVal = static_cast<double>(nRotation) * F_PI18000;
97  double fCos = cos(fVal);
98  double fSin = sin(fVal);
99 
100  double nWidthHalf = static_cast<double>(rSize.Width()) / 2;
101  double nHeightHalf = static_cast<double>(rSize.Height()) / 2;
102 
103  double nXDiff = fSin * nHeightHalf + fCos * nWidthHalf - nWidthHalf;
104  double nYDiff = fSin * nWidthHalf + fCos * nHeightHalf - nHeightHalf;
105 
106  aPos.X += nXDiff;
107  aPos.Y += nYDiff;
108 }
109 
111 bool IsAnchorTypeInsideParagraph(const ww8::Frame* pFrame)
112 {
113  const SwFormatAnchor& rAnchor = pFrame->GetFrameFormat().GetAttrSet().GetAnchor();
114  return rAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE;
115 }
116 }
117 
119  ww8::Frame const* pParentFrame)
120  : m_rExport(rExport)
121 {
122  m_rExport.SaveData(nStt, nEnd);
123  m_rExport.m_pParentFrame = pParentFrame;
124 }
125 
127 
130 {
131 private:
140  OStringBuffer m_aTextFrameStyle;
152 
153 public:
154  bool m_bFlyFrameGraphic = false;
155 
157  oox::drawingml::DrawingML* pDrawingML)
158  : m_rExport(rExport)
159  , m_pSerializer(std::move(pSerializer))
160  , m_pDrawingML(pDrawingML)
161  , m_pFlyFrameSize(nullptr)
162  , m_bTextFrameSyntax(false)
163  , m_bDMLTextFrameSyntax(false)
164  , m_bDrawingOpen(false)
165  , m_bParagraphSdtOpen(false)
166  , m_bParagraphHasDrawing(false)
167  , m_pFlyWrapAttrList(nullptr)
168  , m_pBodyPrAttrList(nullptr)
169  , m_bDMLAndVMLDrawingOpen(false)
170  , m_nDMLandVMLTextFrameRotation(0)
171  {
172  }
173 
175 
176  void textFrameShadow(const SwFrameFormat& rFrameFormat);
177  static bool isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape);
178 
180  {
181  m_pSerializer = pSerializer;
182  }
183 
185 
186  void setFlyFrameSize(const Size* pFlyFrameSize) { m_pFlyFrameSize = pFlyFrameSize; }
187 
188  const Size* getFlyFrameSize() const { return m_pFlyFrameSize; }
189 
190  void setTextFrameSyntax(bool bTextFrameSyntax) { m_bTextFrameSyntax = bTextFrameSyntax; }
191 
192  bool getTextFrameSyntax() const { return m_bTextFrameSyntax; }
193 
194  void setDMLTextFrameSyntax(bool bDMLTextFrameSyntax)
195  {
196  m_bDMLTextFrameSyntax = bDMLTextFrameSyntax;
197  }
198 
200 
202  {
203  m_pFlyAttrList = pFlyAttrList;
204  }
205 
207 
208  void
210  {
211  m_pTextboxAttrList = pTextboxAttrList;
212  }
213 
215  {
216  return m_pTextboxAttrList;
217  }
218 
219  OStringBuffer& getTextFrameStyle() { return m_aTextFrameStyle; }
220 
221  void setDrawingOpen(bool bDrawingOpen) { m_bDrawingOpen = bDrawingOpen; }
222 
223  bool getDrawingOpen() const { return m_bDrawingOpen; }
224 
225  void setParagraphSdtOpen(bool bParagraphSdtOpen) { m_bParagraphSdtOpen = bParagraphSdtOpen; }
226 
227  bool getParagraphSdtOpen() const { return m_bParagraphSdtOpen; }
228 
229  void setDMLAndVMLDrawingOpen(bool bDMLAndVMLDrawingOpen)
230  {
231  m_bDMLAndVMLDrawingOpen = bDMLAndVMLDrawingOpen;
232  }
233 
235 
236  void setParagraphHasDrawing(bool bParagraphHasDrawing)
237  {
238  m_bParagraphHasDrawing = bParagraphHasDrawing;
239  }
240 
242 
244  {
245  return m_pFlyFillAttrList;
246  }
247 
249  {
250  m_pFlyWrapAttrList = pFlyWrapAttrList;
251  }
252 
254 
256  {
257  m_pBodyPrAttrList = pBodyPrAttrList;
258  }
259 
261 
263  {
264  return m_pDashLineStyleAttr;
265  }
266 
267  bool getFlyFrameGraphic() const { return m_bFlyFrameGraphic; }
268 
270 
271  DocxExport& getExport() const { return m_rExport; }
272 
273  void setDMLandVMLTextFrameRotation(sal_Int32 nDMLandVMLTextFrameRotation)
274  {
275  m_nDMLandVMLTextFrameRotation = nDMLandVMLTextFrameRotation;
276  }
277 
279 };
280 
282  oox::drawingml::DrawingML* pDrawingML)
283  : m_pImpl(std::make_unique<Impl>(rExport, pSerializer, pDrawingML))
284 {
285 }
286 
288 
290 {
291  m_pImpl->setSerializer(pSerializer);
292 }
293 
294 const Size* DocxSdrExport::getFlyFrameSize() const { return m_pImpl->getFlyFrameSize(); }
295 
296 bool DocxSdrExport::getTextFrameSyntax() const { return m_pImpl->getTextFrameSyntax(); }
297 
298 bool DocxSdrExport::getDMLTextFrameSyntax() const { return m_pImpl->getDMLTextFrameSyntax(); }
299 
301 {
302  return m_pImpl->getFlyAttrList();
303 }
304 
306 {
307  return m_pImpl->getTextboxAttrList();
308 }
309 
310 OStringBuffer& DocxSdrExport::getTextFrameStyle() { return m_pImpl->getTextFrameStyle(); }
311 
312 bool DocxSdrExport::IsDrawingOpen() const { return m_pImpl->getDrawingOpen(); }
313 
314 void DocxSdrExport::setParagraphSdtOpen(bool bParagraphSdtOpen)
315 {
316  m_pImpl->setParagraphSdtOpen(bParagraphSdtOpen);
317 }
318 
319 bool DocxSdrExport::IsDMLAndVMLDrawingOpen() const { return m_pImpl->getDMLAndVMLDrawingOpen(); }
320 
321 bool DocxSdrExport::IsParagraphHasDrawing() const { return m_pImpl->getParagraphHasDrawing(); }
322 
323 void DocxSdrExport::setParagraphHasDrawing(bool bParagraphHasDrawing)
324 {
325  m_pImpl->setParagraphHasDrawing(bParagraphHasDrawing);
326 }
327 
329 {
330  return m_pImpl->getFlyFillAttrList();
331 }
332 
334 {
335  return m_pImpl->getFlyWrapAttrList();
336 }
337 
339 {
340  return m_pImpl->getBodyPrAttrList();
341 }
342 
344 {
345  return m_pImpl->getDashLineStyleAttr();
346 }
347 
349 {
350  m_pImpl->setFlyWrapAttrList(pAttrList);
351 }
352 
353 void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, const Size& rSize)
354 {
355  m_pImpl->setDrawingOpen(true);
356  m_pImpl->setParagraphHasDrawing(true);
357  m_pImpl->getSerializer()->startElementNS(XML_w, XML_drawing);
358 
359  const SvxLRSpaceItem aLRSpaceItem = pFrameFormat->GetLRSpace(false);
360  const SvxULSpaceItem aULSpaceItem = pFrameFormat->GetULSpace(false);
361 
362  bool isAnchor;
363 
364  if (m_pImpl->getFlyFrameGraphic())
365  {
366  isAnchor = false; // make Graphic object inside DMLTextFrame & VMLTextFrame as Inline
367  }
368  else
369  {
370  isAnchor = pFrameFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR;
371  }
372 
373  // Count effectExtent values, their value is needed before dist{T,B,L,R} is written.
374  SvxShadowItem aShadowItem = pFrameFormat->GetShadow();
375  sal_Int32 nLeftExt = 0;
376  sal_Int32 nRightExt = 0;
377  sal_Int32 nTopExt = 0;
378  sal_Int32 nBottomExt = 0;
379  if (aShadowItem.GetLocation() != SvxShadowLocation::NONE)
380  {
381  sal_Int32 nShadowWidth(TwipsToEMU(aShadowItem.GetWidth()));
382  switch (aShadowItem.GetLocation())
383  {
384  case SvxShadowLocation::TopLeft:
385  nTopExt = nLeftExt = nShadowWidth;
386  break;
387  case SvxShadowLocation::TopRight:
388  nTopExt = nRightExt = nShadowWidth;
389  break;
390  case SvxShadowLocation::BottomLeft:
391  nBottomExt = nLeftExt = nShadowWidth;
392  break;
393  case SvxShadowLocation::BottomRight:
394  nBottomExt = nRightExt = nShadowWidth;
395  break;
396  case SvxShadowLocation::NONE:
397  case SvxShadowLocation::End:
398  break;
399  }
400  }
401  else if (const SdrObject* pObject = pFrameFormat->FindRealSdrObject())
402  {
403  // No shadow, but we have an idea what was the original effectExtent.
404  uno::Any aAny;
405  pObject->GetGrabBagItem(aAny);
406  comphelper::SequenceAsHashMap aGrabBag(aAny);
407  auto it = aGrabBag.find("CT_EffectExtent");
408  if (it != aGrabBag.end())
409  {
410  comphelper::SequenceAsHashMap aEffectExtent(it->second);
411  for (const std::pair<const OUString, uno::Any>& rDirection : aEffectExtent)
412  {
413  if (rDirection.first == "l" && rDirection.second.has<sal_Int32>())
414  nLeftExt = rDirection.second.get<sal_Int32>();
415  else if (rDirection.first == "t" && rDirection.second.has<sal_Int32>())
416  nTopExt = rDirection.second.get<sal_Int32>();
417  else if (rDirection.first == "r" && rDirection.second.has<sal_Int32>())
418  nRightExt = rDirection.second.get<sal_Int32>();
419  else if (rDirection.first == "b" && rDirection.second.has<sal_Int32>())
420  nBottomExt = rDirection.second.get<sal_Int32>();
421  }
422  }
423  }
424 
425  if (isAnchor)
426  {
429  bool bOpaque = pFrameFormat->GetOpaque().GetValue();
430  awt::Point aPos(pFrameFormat->GetHoriOrient().GetPos(),
431  pFrameFormat->GetVertOrient().GetPos());
432  const SdrObject* pObj = pFrameFormat->FindRealSdrObject();
433  long nRotation = 0;
434  if (pObj != nullptr)
435  {
436  // SdrObjects know their layer, consider that instead of the frame format.
437  bOpaque = pObj->GetLayer()
438  != pFrameFormat->GetDoc()->getIDocumentDrawModelAccess().GetHellId()
439  && pObj->GetLayer()
440  != pFrameFormat->GetDoc()
443 
444  // Do not do this with lines.
445  if (pObj->GetObjIdentifier() != OBJ_LINE)
446  {
447  nRotation = pObj->GetRotateAngle();
448  lclMovePositionWithRotation(aPos, rSize, nRotation);
449  }
450  }
451  attrList->add(XML_behindDoc, bOpaque ? "0" : "1");
452  // Extend distance with the effect extent if the shape is not rotated, which is the opposite
453  // of the mapping done at import time.
454  // The type of dist* attributes is unsigned, so make sure no negative value is written.
455  sal_Int64 nTopExtDist = nRotation ? 0 : nTopExt;
456  sal_Int64 nDistT = std::max(static_cast<sal_Int64>(0),
457  TwipsToEMU(aULSpaceItem.GetUpper()) - nTopExtDist);
458  attrList->add(XML_distT, OString::number(nDistT).getStr());
459  sal_Int64 nBottomExtDist = nRotation ? 0 : nBottomExt;
460  sal_Int64 nDistB = std::max(static_cast<sal_Int64>(0),
461  TwipsToEMU(aULSpaceItem.GetLower()) - nBottomExtDist);
462  attrList->add(XML_distB, OString::number(nDistB).getStr());
463  sal_Int64 nLeftExtDist = nRotation ? 0 : nLeftExt;
464  sal_Int64 nDistL = std::max(static_cast<sal_Int64>(0),
465  TwipsToEMU(aLRSpaceItem.GetLeft()) - nLeftExtDist);
466  attrList->add(XML_distL, OString::number(nDistL).getStr());
467  sal_Int64 nRightExtDist = nRotation ? 0 : nRightExt;
468  sal_Int64 nDistR = std::max(static_cast<sal_Int64>(0),
469  TwipsToEMU(aLRSpaceItem.GetRight()) - nRightExtDist);
470  attrList->add(XML_distR, OString::number(nDistR).getStr());
471  attrList->add(XML_simplePos, "0");
472  attrList->add(XML_locked, "0");
473  bool bLclInTabCell = true;
474  if (pObj)
475  {
476  uno::Reference<drawing::XShape> xShape((const_cast<SdrObject*>(pObj)->getUnoShape()),
477  uno::UNO_QUERY);
478  uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
479  if (xShapeProps.is())
480  xShapeProps->getPropertyValue("IsFollowingTextFlow") >>= bLclInTabCell;
481  }
482  if (bLclInTabCell)
483  attrList->add(XML_layoutInCell, "1");
484  else
485  attrList->add(XML_layoutInCell, "0");
486  bool bAllowOverlap = pFrameFormat->GetWrapInfluenceOnObjPos().GetAllowOverlap();
487  attrList->add(XML_allowOverlap, bAllowOverlap ? "1" : "0");
488  if (pObj != nullptr)
489  // It seems 0 and 1 have special meaning: just start counting from 2 to avoid issues with that.
490  attrList->add(XML_relativeHeight, OString::number(pObj->GetOrdNum() + 2));
491  else
492  // relativeHeight is mandatory attribute, if value is not present, we must write default value
493  attrList->add(XML_relativeHeight, "0");
494  if (pObj != nullptr)
495  {
496  OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
497  if (!sAnchorId.isEmpty())
498  attrList->addNS(XML_wp14, XML_anchorId,
499  OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
500  }
501  sax_fastparser::XFastAttributeListRef xAttrList(attrList);
502  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_anchor, xAttrList);
503  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_simplePos, XML_x, "0", XML_y,
504  "0"); // required, unused
505  const char* relativeFromH;
506  const char* relativeFromV;
507  const char* alignH = nullptr;
508  const char* alignV = nullptr;
509  switch (pFrameFormat->GetVertOrient().GetRelationOrient())
510  {
511  case text::RelOrientation::PAGE_PRINT_AREA:
512  relativeFromV = "margin";
513  break;
514  case text::RelOrientation::PAGE_PRINT_AREA_BOTTOM:
515  relativeFromV = "bottomMargin";
516  break;
517  case text::RelOrientation::PAGE_FRAME:
518  relativeFromV = "page";
519  break;
520  case text::RelOrientation::FRAME:
521  relativeFromV = "paragraph";
522  break;
523  case text::RelOrientation::TEXT_LINE:
524  default:
525  relativeFromV = "line";
526  break;
527  }
528  switch (pFrameFormat->GetVertOrient().GetVertOrient())
529  {
530  case text::VertOrientation::TOP:
531  case text::VertOrientation::CHAR_TOP:
532  case text::VertOrientation::LINE_TOP:
533  if (pFrameFormat->GetVertOrient().GetRelationOrient()
534  == text::RelOrientation::TEXT_LINE)
535  alignV = "bottom";
536  else
537  alignV = "top";
538  break;
539  case text::VertOrientation::BOTTOM:
540  case text::VertOrientation::CHAR_BOTTOM:
541  case text::VertOrientation::LINE_BOTTOM:
542  if (pFrameFormat->GetVertOrient().GetRelationOrient()
543  == text::RelOrientation::TEXT_LINE)
544  alignV = "top";
545  else
546  alignV = "bottom";
547  break;
548  case text::VertOrientation::CENTER:
549  case text::VertOrientation::CHAR_CENTER:
550  case text::VertOrientation::LINE_CENTER:
551  alignV = "center";
552  break;
553  default:
554  break;
555  }
556  switch (pFrameFormat->GetHoriOrient().GetRelationOrient())
557  {
558  case text::RelOrientation::PAGE_PRINT_AREA:
559  relativeFromH = "margin";
560  break;
561  case text::RelOrientation::PAGE_FRAME:
562  relativeFromH = "page";
563  break;
564  case text::RelOrientation::CHAR:
565  relativeFromH = "character";
566  break;
567  case text::RelOrientation::PAGE_RIGHT:
568  relativeFromH = "rightMargin";
569  break;
570  case text::RelOrientation::PAGE_LEFT:
571  relativeFromH = "leftMargin";
572  break;
573  case text::RelOrientation::FRAME:
574  default:
575  relativeFromH = "column";
576  break;
577  }
578  switch (pFrameFormat->GetHoriOrient().GetHoriOrient())
579  {
580  case text::HoriOrientation::LEFT:
581  alignH = "left";
582  break;
583  case text::HoriOrientation::RIGHT:
584  alignH = "right";
585  break;
586  case text::HoriOrientation::CENTER:
587  alignH = "center";
588  break;
589  case text::HoriOrientation::INSIDE:
590  alignH = "inside";
591  break;
592  case text::HoriOrientation::OUTSIDE:
593  alignH = "outside";
594  break;
595  default:
596  break;
597  }
598  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_positionH, XML_relativeFrom,
599  relativeFromH);
605  const sal_Int64 MAX_INTEGER_VALUE = SAL_MAX_INT32;
606  const sal_Int64 MIN_INTEGER_VALUE = SAL_MIN_INT32;
607  if (alignH != nullptr)
608  {
609  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_align);
610  m_pImpl->getSerializer()->write(alignH);
611  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_align);
612  }
613  else
614  {
615  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_posOffset);
616  sal_Int64 nPosXEMU = TwipsToEMU(aPos.X);
617 
618  /* Absolute Position Offset Value is of type Int. Hence it should not be greater than
619  * Maximum value for Int OR Less than the Minimum value for Int.
620  * - Maximum value for Int = 2147483647
621  * - Minimum value for Int = -2147483648
622  *
623  * As per ECMA Specification : ECMA-376, Second Edition,
624  * Part 1 - Fundamentals And Markup Language Reference[20.4.3.3 ST_PositionOffset (Absolute Position Offset Value)]
625  *
626  * Please refer : http://www.schemacentral.com/sc/xsd/t-xsd_int.html
627  */
628 
629  if (nPosXEMU > MAX_INTEGER_VALUE)
630  {
631  nPosXEMU = MAX_INTEGER_VALUE;
632  }
633  else if (nPosXEMU < MIN_INTEGER_VALUE)
634  {
635  nPosXEMU = MIN_INTEGER_VALUE;
636  }
637  m_pImpl->getSerializer()->write(nPosXEMU);
638  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_posOffset);
639  }
640  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_positionH);
641  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_positionV, XML_relativeFrom,
642  relativeFromV);
643 
644  sal_Int64 nPosYEMU = TwipsToEMU(aPos.Y);
645 
646  // tdf#93675, 0 below line/paragraph and/or top line/paragraph with
647  // wrap top+bottom or other wraps is affecting the line directly
648  // above the anchor line, which seems odd, but a tiny adjustment
649  // here to bring the top down convinces msoffice to wrap like us
650  if (nPosYEMU == 0
651  && (strcmp(relativeFromV, "line") == 0 || strcmp(relativeFromV, "paragraph") == 0)
652  && (!alignV || strcmp(alignV, "top") == 0))
653  {
654  alignV = nullptr;
655  nPosYEMU = 635;
656  }
657 
658  if (alignV != nullptr)
659  {
660  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_align);
661  m_pImpl->getSerializer()->write(alignV);
662  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_align);
663  }
664  else
665  {
666  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_posOffset);
667  if (nPosYEMU > MAX_INTEGER_VALUE)
668  {
669  nPosYEMU = MAX_INTEGER_VALUE;
670  }
671  else if (nPosYEMU < MIN_INTEGER_VALUE)
672  {
673  nPosYEMU = MIN_INTEGER_VALUE;
674  }
675  m_pImpl->getSerializer()->write(nPosYEMU);
676  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_posOffset);
677  }
678  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_positionV);
679  }
680  else
681  {
684  aAttrList->add(XML_distT, OString::number(TwipsToEMU(aULSpaceItem.GetUpper())).getStr());
685  aAttrList->add(XML_distB, OString::number(TwipsToEMU(aULSpaceItem.GetLower())).getStr());
686  aAttrList->add(XML_distL, OString::number(TwipsToEMU(aLRSpaceItem.GetLeft())).getStr());
687  aAttrList->add(XML_distR, OString::number(TwipsToEMU(aLRSpaceItem.GetRight())).getStr());
688  const SdrObject* pObj = pFrameFormat->FindRealSdrObject();
689  if (pObj != nullptr)
690  {
691  OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObj);
692  if (!sAnchorId.isEmpty())
693  aAttrList->addNS(XML_wp14, XML_anchorId,
694  OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
695  }
696  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_inline, aAttrList);
697  }
698 
699  // now the common parts
700  // extent of the image
718  sal_uInt64 cx = TwipsToEMU(std::clamp(rSize.Width(), 0L, long(SAL_MAX_INT32)));
719  OString aWidth(OString::number(std::min(cx, sal_uInt64(SAL_MAX_INT32))));
720  sal_uInt64 cy = TwipsToEMU(std::clamp(rSize.Height(), 0L, long(SAL_MAX_INT32)));
721  OString aHeight(OString::number(std::min(cy, sal_uInt64(SAL_MAX_INT32))));
722 
723  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_extent, XML_cx, aWidth, XML_cy, aHeight);
724 
725  // effectExtent, extent including the effect (shadow only for now)
726  m_pImpl->getSerializer()->singleElementNS(
727  XML_wp, XML_effectExtent, XML_l, OString::number(nLeftExt), XML_t, OString::number(nTopExt),
728  XML_r, OString::number(nRightExt), XML_b, OString::number(nBottomExt));
729 
730  // See if we know the exact wrap type from grab-bag.
731  sal_Int32 nWrapToken = 0;
732  if (const SdrObject* pObject = pFrameFormat->FindRealSdrObject())
733  {
734  uno::Any aAny;
735  pObject->GetGrabBagItem(aAny);
736  comphelper::SequenceAsHashMap aGrabBag(aAny);
737  auto it = aGrabBag.find("EG_WrapType");
738  if (it != aGrabBag.end())
739  {
740  auto sType = it->second.get<OUString>();
741  if (sType == "wrapTight")
742  nWrapToken = XML_wrapTight;
743  else if (sType == "wrapThrough")
744  nWrapToken = XML_wrapThrough;
745  else
746  SAL_WARN("sw.ww8",
747  "DocxSdrExport::startDMLAnchorInline: unexpected EG_WrapType value");
748 
749  m_pImpl->getSerializer()->startElementNS(XML_wp, nWrapToken, XML_wrapText, "bothSides");
750 
751  it = aGrabBag.find("CT_WrapPath");
752  if (it != aGrabBag.end())
753  {
754  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_wrapPolygon, XML_edited, "0");
755  auto aSeqSeq = it->second.get<drawing::PointSequenceSequence>();
756  auto aPoints(comphelper::sequenceToContainer<std::vector<awt::Point>>(aSeqSeq[0]));
757  for (auto i = aPoints.begin(); i != aPoints.end(); ++i)
758  {
759  awt::Point& rPoint = *i;
760  m_pImpl->getSerializer()->singleElementNS(
761  XML_wp, (i == aPoints.begin() ? XML_start : XML_lineTo), XML_x,
762  OString::number(rPoint.X), XML_y, OString::number(rPoint.Y));
763  }
764  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_wrapPolygon);
765  }
766 
767  m_pImpl->getSerializer()->endElementNS(XML_wp, nWrapToken);
768  }
769  }
770 
771  // Or if we have a contour.
772  if (!nWrapToken && pFrameFormat->GetSurround().IsContour())
773  {
774  if (const SwNoTextNode* pNd = sw::util::GetNoTextNodeFromSwFrameFormat(*pFrameFormat))
775  {
776  const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
777  if (pPolyPoly && pPolyPoly->Count())
778  {
779  nWrapToken = XML_wrapTight;
780  m_pImpl->getSerializer()->startElementNS(XML_wp, nWrapToken, XML_wrapText,
781  "bothSides");
782 
783  m_pImpl->getSerializer()->startElementNS(XML_wp, XML_wrapPolygon, XML_edited, "0");
785  for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
786  m_pImpl->getSerializer()->singleElementNS(
787  XML_wp, (i == 0 ? XML_start : XML_lineTo), XML_x,
788  OString::number(aPoly[i].X()), XML_y, OString::number(aPoly[i].Y()));
789  m_pImpl->getSerializer()->endElementNS(XML_wp, XML_wrapPolygon);
790 
791  m_pImpl->getSerializer()->endElementNS(XML_wp, nWrapToken);
792  }
793  }
794  }
795 
796  // No? Then just approximate based on what we have.
797  if (isAnchor && !nWrapToken)
798  {
799  switch (pFrameFormat->GetSurround().GetValue())
800  {
801  case css::text::WrapTextMode_NONE:
802  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_wrapTopAndBottom);
803  break;
804  case css::text::WrapTextMode_THROUGH:
805  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_wrapNone);
806  break;
807  case css::text::WrapTextMode_PARALLEL:
808  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_wrapSquare, XML_wrapText,
809  "bothSides");
810  break;
811  case css::text::WrapTextMode_DYNAMIC:
812  default:
813  m_pImpl->getSerializer()->singleElementNS(XML_wp, XML_wrapSquare, XML_wrapText,
814  "largest");
815  break;
816  }
817  }
818 }
819 
821 {
822  bool isAnchor;
823  if (m_pImpl->getFlyFrameGraphic())
824  {
825  isAnchor = false; // end Inline Graphic object inside DMLTextFrame
826  }
827  else
828  {
829  isAnchor = pFrameFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR;
830  }
831  m_pImpl->getSerializer()->endElementNS(XML_wp, isAnchor ? XML_anchor : XML_inline);
832 
833  m_pImpl->getSerializer()->endElementNS(XML_w, XML_drawing);
834  m_pImpl->setDrawingOpen(false);
835 }
836 
837 void DocxSdrExport::writeVMLDrawing(const SdrObject* sdrObj, const SwFrameFormat& rFrameFormat)
838 {
839  m_pImpl->getSerializer()->startElementNS(XML_w, XML_pict);
840  m_pImpl->getDrawingML()->SetFS(m_pImpl->getSerializer());
841  // See WinwordAnchoring::SetAnchoring(), these are not part of the SdrObject, have to be passed around manually.
842 
843  const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
844  const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient();
845  m_pImpl->getExport().VMLExporter().AddSdrObject(
846  *sdrObj, rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(), rHoriOri.GetRelationOrient(),
847  rVertOri.GetRelationOrient(), true);
848  m_pImpl->getSerializer()->endElementNS(XML_w, XML_pict);
849 }
850 
851 static bool lcl_isLockedCanvas(const uno::Reference<drawing::XShape>& xShape)
852 {
853  uno::Sequence<beans::PropertyValue> propList = lclGetProperty(xShape, "InteropGrabBag");
854  /*
855  * Export as Locked Canvas only if the property
856  * is in the PropertySet
857  */
858  return std::any_of(propList.begin(), propList.end(), [](const beans::PropertyValue& rProp) {
859  return rProp.Name == "LockedCanvas";
860  });
861 }
862 
863 void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrameFormat* pFrameFormat,
864  int nAnchorId)
865 {
866  uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(),
867  uno::UNO_QUERY_THROW);
868  if (!Impl::isSupportedDMLShape(xShape))
869  return;
870 
871  m_pImpl->getExport().DocxAttrOutput().GetSdtEndBefore(pSdrObject);
872 
873  sax_fastparser::FSHelperPtr pFS = m_pImpl->getSerializer();
874  Size aSize(pSdrObject->GetLogicRect().GetWidth(), pSdrObject->GetLogicRect().GetHeight());
875  startDMLAnchorInline(pFrameFormat, aSize);
876 
877  sax_fastparser::FastAttributeList* pDocPrAttrList
879  pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
880  pDocPrAttrList->add(XML_name,
881  OUStringToOString(pSdrObject->GetName(), RTL_TEXTENCODING_UTF8).getStr());
882  if (!pSdrObject->GetTitle().isEmpty())
883  pDocPrAttrList->add(XML_title,
884  OUStringToOString(pSdrObject->GetTitle(), RTL_TEXTENCODING_UTF8));
885  if (!pSdrObject->GetDescription().isEmpty())
886  pDocPrAttrList->add(XML_descr,
887  OUStringToOString(pSdrObject->GetDescription(), RTL_TEXTENCODING_UTF8));
888  if (!pSdrObject->IsVisible()
889  && pFrameFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
890 
891  pDocPrAttrList->add(XML_hidden, OString::number(1).getStr());
892  sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
893  pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
894 
895  uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
896  const char* pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
897  if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
898  pNamespace = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
899  else if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
900  pNamespace = "http://schemas.openxmlformats.org/drawingml/2006/picture";
901  pFS->startElementNS(XML_a, XML_graphic, FSNS(XML_xmlns, XML_a),
902  m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dml)).toUtf8());
903  pFS->startElementNS(XML_a, XML_graphicData, XML_uri, pNamespace);
904 
905  bool bLockedCanvas = lcl_isLockedCanvas(xShape);
906  if (bLockedCanvas)
907  pFS->startElementNS(
908  XML_lc, XML_lockedCanvas, FSNS(XML_xmlns, XML_lc),
909  m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dmlLockedCanvas)).toUtf8());
910 
911  m_pImpl->getExport().OutputDML(xShape);
912 
913  if (bLockedCanvas)
914  pFS->endElementNS(XML_lc, XML_lockedCanvas);
915  pFS->endElementNS(XML_a, XML_graphicData);
916  pFS->endElementNS(XML_a, XML_graphic);
917 
918  // Relative size of the drawing.
919  if (pSdrObject->GetRelativeWidth())
920  {
921  // At the moment drawinglayer objects are always relative from page.
922  pFS->startElementNS(XML_wp14, XML_sizeRelH, XML_relativeFrom,
923  (pSdrObject->GetRelativeWidthRelation() == text::RelOrientation::FRAME
924  ? "margin"
925  : "page"));
926  pFS->startElementNS(XML_wp14, XML_pctWidth);
927  pFS->writeEscaped(
928  OUString::number(*pSdrObject->GetRelativeWidth() * 100 * oox::drawingml::PER_PERCENT));
929  pFS->endElementNS(XML_wp14, XML_pctWidth);
930  pFS->endElementNS(XML_wp14, XML_sizeRelH);
931  }
932  if (pSdrObject->GetRelativeHeight())
933  {
934  pFS->startElementNS(XML_wp14, XML_sizeRelV, XML_relativeFrom,
935  (pSdrObject->GetRelativeHeightRelation() == text::RelOrientation::FRAME
936  ? "margin"
937  : "page"));
938  pFS->startElementNS(XML_wp14, XML_pctHeight);
939  pFS->writeEscaped(
940  OUString::number(*pSdrObject->GetRelativeHeight() * 100 * oox::drawingml::PER_PERCENT));
941  pFS->endElementNS(XML_wp14, XML_pctHeight);
942  pFS->endElementNS(XML_wp14, XML_sizeRelV);
943  }
944 
945  endDMLAnchorInline(pFrameFormat);
946 }
947 
949 {
950  const SvxShadowItem& aShadowItem = rFrameFormat.GetShadow();
951  if (aShadowItem.GetLocation() == SvxShadowLocation::NONE)
952  return;
953 
954  OString aShadowWidth(OString::number(double(aShadowItem.GetWidth()) / 20) + "pt");
955  OString aOffset;
956  switch (aShadowItem.GetLocation())
957  {
958  case SvxShadowLocation::TopLeft:
959  aOffset = "-" + aShadowWidth + ",-" + aShadowWidth;
960  break;
961  case SvxShadowLocation::TopRight:
962  aOffset = aShadowWidth + ",-" + aShadowWidth;
963  break;
964  case SvxShadowLocation::BottomLeft:
965  aOffset = "-" + aShadowWidth + "," + aShadowWidth;
966  break;
967  case SvxShadowLocation::BottomRight:
968  aOffset = aShadowWidth + "," + aShadowWidth;
969  break;
970  case SvxShadowLocation::NONE:
971  case SvxShadowLocation::End:
972  break;
973  }
974  if (aOffset.isEmpty())
975  return;
976 
977  OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
978  m_pSerializer->singleElementNS(XML_v, XML_shadow, XML_on, "t", XML_color, "#" + aShadowColor,
979  XML_offset, aOffset);
980 }
981 
982 bool DocxSdrExport::Impl::isSupportedDMLShape(const uno::Reference<drawing::XShape>& xShape)
983 {
984  uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
985  if (xServiceInfo->supportsService("com.sun.star.drawing.PolyPolygonShape")
986  || xServiceInfo->supportsService("com.sun.star.drawing.PolyLineShape"))
987  return false;
988 
989  // For signature line shapes, we don't want DML, just the VML shape.
990  bool bIsSignatureLineShape = false;
991  if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
992  {
993  uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY);
994  xShapeProperties->getPropertyValue("IsSignatureLine") >>= bIsSignatureLineShape;
995  if (bIsSignatureLineShape)
996  return false;
997  }
998 
999  return true;
1000 }
1001 
1003  const SwFrameFormat& rFrameFormat, int nAnchorId)
1004 {
1005  bool bDMLAndVMLDrawingOpen = m_pImpl->getDMLAndVMLDrawingOpen();
1006  m_pImpl->setDMLAndVMLDrawingOpen(true);
1007 
1008  // Depending on the shape type, we actually don't write the shape as DML.
1009  OUString sShapeType;
1010  ShapeFlag nMirrorFlags = ShapeFlag::NONE;
1011  uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(sdrObj)->getUnoShape(),
1012  uno::UNO_QUERY_THROW);
1013 
1014  MSO_SPT eShapeType
1015  = EscherPropertyContainer::GetCustomShapeType(xShape, nMirrorFlags, sShapeType);
1016 
1017  // In case we are already inside a DML block, then write the shape only as VML, turn out that's allowed to do.
1018  // A common service created in util to check for VML shapes which are allowed to have textbox in content
1020  && (!bDMLAndVMLDrawingOpen || lcl_isLockedCanvas(xShape))) // Locked canvas is OK inside DML
1021  {
1022  m_pImpl->getSerializer()->startElementNS(XML_mc, XML_AlternateContent);
1023 
1024  auto pObjGroup = dynamic_cast<const SdrObjGroup*>(sdrObj);
1025  m_pImpl->getSerializer()->startElementNS(XML_mc, XML_Choice, XML_Requires,
1026  (pObjGroup ? "wpg" : "wps"));
1027  writeDMLDrawing(sdrObj, &rFrameFormat, nAnchorId);
1028  m_pImpl->getSerializer()->endElementNS(XML_mc, XML_Choice);
1029 
1030  m_pImpl->getSerializer()->startElementNS(XML_mc, XML_Fallback);
1031  writeVMLDrawing(sdrObj, rFrameFormat);
1032  m_pImpl->getSerializer()->endElementNS(XML_mc, XML_Fallback);
1033 
1034  m_pImpl->getSerializer()->endElementNS(XML_mc, XML_AlternateContent);
1035  }
1036  else
1037  writeVMLDrawing(sdrObj, rFrameFormat);
1038 
1039  m_pImpl->setDMLAndVMLDrawingOpen(bDMLAndVMLDrawingOpen);
1040 }
1041 
1042 // Converts ARGB transparency (0..255) to drawingml alpha (opposite, and 0..100000)
1043 static OString lcl_ConvertTransparency(const Color& rColor)
1044 {
1045  if (rColor.GetTransparency() > 0)
1046  {
1047  sal_Int32 nTransparencyPercent = 100 - float(rColor.GetTransparency()) / 2.55;
1048  return OString::number(nTransparencyPercent * oox::drawingml::PER_PERCENT);
1049  }
1050 
1051  return OString();
1052 }
1053 
1055 {
1056  const SvxShadowItem& aShadowItem = rFrameFormat.GetShadow();
1057 
1058  // Output effects
1059  if (aShadowItem.GetLocation() == SvxShadowLocation::NONE)
1060  return;
1061 
1062  // Distance is measured diagonally from corner
1063  double nShadowDist
1064  = sqrt(static_cast<double>(aShadowItem.GetWidth()) * aShadowItem.GetWidth() * 2.0);
1065  OString aShadowDist(OString::number(TwipsToEMU(nShadowDist)));
1066  OString aShadowColor = msfilter::util::ConvertColor(aShadowItem.GetColor());
1067  OString aShadowAlpha = lcl_ConvertTransparency(aShadowItem.GetColor());
1068  sal_uInt32 nShadowDir = 0;
1069  switch (aShadowItem.GetLocation())
1070  {
1071  case SvxShadowLocation::TopLeft:
1072  nShadowDir = 13500000;
1073  break;
1074  case SvxShadowLocation::TopRight:
1075  nShadowDir = 18900000;
1076  break;
1077  case SvxShadowLocation::BottomLeft:
1078  nShadowDir = 8100000;
1079  break;
1080  case SvxShadowLocation::BottomRight:
1081  nShadowDir = 2700000;
1082  break;
1083  case SvxShadowLocation::NONE:
1084  case SvxShadowLocation::End:
1085  break;
1086  }
1087  OString aShadowDir(OString::number(nShadowDir));
1088 
1089  m_pImpl->getSerializer()->startElementNS(XML_a, XML_effectLst);
1090  m_pImpl->getSerializer()->startElementNS(XML_a, XML_outerShdw, XML_dist, aShadowDist, XML_dir,
1091  aShadowDir);
1092  if (aShadowAlpha.isEmpty())
1093  m_pImpl->getSerializer()->singleElementNS(XML_a, XML_srgbClr, XML_val, aShadowColor);
1094  else
1095  {
1096  m_pImpl->getSerializer()->startElementNS(XML_a, XML_srgbClr, XML_val, aShadowColor);
1097  m_pImpl->getSerializer()->singleElementNS(XML_a, XML_alpha, XML_val, aShadowAlpha);
1098  m_pImpl->getSerializer()->endElementNS(XML_a, XML_srgbClr);
1099  }
1100  m_pImpl->getSerializer()->endElementNS(XML_a, XML_outerShdw);
1101  m_pImpl->getSerializer()->endElementNS(XML_a, XML_effectLst);
1102 }
1103 
1104 void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrameFormat& rFrameFormat,
1105  int nDiagramId)
1106 {
1107  uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(sdrObject)->getUnoShape(),
1108  uno::UNO_QUERY);
1109 
1110  // write necessary tags to document.xml
1111  Size aSize(sdrObject->GetSnapRect().GetWidth(), sdrObject->GetSnapRect().GetHeight());
1112  startDMLAnchorInline(&rFrameFormat, aSize);
1113 
1114  m_pImpl->getDrawingML()->WriteDiagram(xShape, nDiagramId);
1115 
1116  endDMLAnchorInline(&rFrameFormat);
1117 }
1118 
1120 {
1121  const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
1122  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
1123 
1124  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
1125  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1126 
1127  //Save data here and restore when out of scope
1128  ExportDataSaveRestore aDataGuard(m_pImpl->getExport(), nStt, nEnd, pParentFrame);
1129 
1131  ::comphelper::FlagRestorationGuard const g(m_pImpl->m_bFlyFrameGraphic, true);
1132  comphelper::ValueRestorationGuard vg(m_pImpl->getExport().m_nTextTyp, TXT_TXTBOX);
1133  m_pImpl->getExport().WriteText();
1134 }
1135 
1137 {
1138  const editeng::SvxBorderLine* pBorderLine = nullptr;
1139 
1140  if (rBox.GetTop())
1141  {
1142  pBorderLine = rBox.GetTop();
1143  }
1144  else if (rBox.GetLeft())
1145  {
1146  pBorderLine = rBox.GetLeft();
1147  }
1148  else if (rBox.GetBottom())
1149  {
1150  pBorderLine = rBox.GetBottom();
1151  }
1152  else if (rBox.GetRight())
1153  {
1154  pBorderLine = rBox.GetRight();
1155  }
1156 
1157  if (!pBorderLine)
1158  {
1159  return;
1160  }
1161 
1162  sax_fastparser::FSHelperPtr pFS = m_pImpl->getSerializer();
1163  double fConverted(editeng::ConvertBorderWidthToWord(pBorderLine->GetBorderLineStyle(),
1164  pBorderLine->GetWidth()));
1165  OString sWidth(OString::number(TwipsToEMU(fConverted)));
1166  pFS->startElementNS(XML_a, XML_ln, XML_w, sWidth);
1167 
1168  pFS->startElementNS(XML_a, XML_solidFill);
1169  OString sColor(msfilter::util::ConvertColor(pBorderLine->GetColor()));
1170  pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, sColor);
1171  pFS->endElementNS(XML_a, XML_solidFill);
1172 
1173  if (SvxBorderLineStyle::DASHED == pBorderLine->GetBorderLineStyle()) // Line Style is Dash type
1174  pFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dash");
1175 
1176  pFS->endElementNS(XML_a, XML_ln);
1177 }
1178 
1179 void DocxSdrExport::writeDMLTextFrame(ww8::Frame const* pParentFrame, int nAnchorId,
1180  bool bTextBoxOnly)
1181 {
1182  bool bDMLAndVMLDrawingOpen = m_pImpl->getDMLAndVMLDrawingOpen();
1183  m_pImpl->setDMLAndVMLDrawingOpen(IsAnchorTypeInsideParagraph(pParentFrame));
1184 
1185  sax_fastparser::FSHelperPtr pFS = m_pImpl->getSerializer();
1186  const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
1187  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
1188 
1189  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
1190  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1191 
1192  //Save data here and restore when out of scope
1193  ExportDataSaveRestore aDataGuard(m_pImpl->getExport(), nStt, nEnd, pParentFrame);
1194 
1195  // When a frame has some low height, but automatically expanded due
1196  // to lots of contents, this size contains the real size.
1197  const Size aSize = pParentFrame->GetSize();
1198 
1199  uno::Reference<drawing::XShape> xShape;
1200  const SdrObject* pSdrObj = rFrameFormat.FindRealSdrObject();
1201  if (pSdrObj)
1202  xShape.set(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
1203  uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
1204  uno::Reference<beans::XPropertySetInfo> xPropSetInfo;
1205  if (xPropertySet.is())
1206  xPropSetInfo = xPropertySet->getPropertySetInfo();
1207 
1209  {
1210  drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
1211  if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("TextVerticalAdjust"))
1212  xPropertySet->getPropertyValue("TextVerticalAdjust") >>= eAdjust;
1213  m_pImpl->getBodyPrAttrList()->add(XML_anchor,
1215  }
1216 
1217  if (!bTextBoxOnly)
1218  {
1219  startDMLAnchorInline(&rFrameFormat, aSize);
1220 
1221  sax_fastparser::FastAttributeList* pDocPrAttrList
1223  pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
1224  pDocPrAttrList->add(
1225  XML_name, OUStringToOString(rFrameFormat.GetName(), RTL_TEXTENCODING_UTF8).getStr());
1226  sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
1227  pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
1228 
1229  pFS->startElementNS(XML_a, XML_graphic, FSNS(XML_xmlns, XML_a),
1230  m_pImpl->getExport().GetFilter().getNamespaceURL(OOX_NS(dml)).toUtf8());
1231  pFS->startElementNS(XML_a, XML_graphicData, XML_uri,
1232  "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");
1233  pFS->startElementNS(XML_wps, XML_wsp);
1234  pFS->singleElementNS(XML_wps, XML_cNvSpPr, XML_txBox, "1");
1235 
1236  uno::Any aRotation;
1237  m_pImpl->setDMLandVMLTextFrameRotation(0);
1238  if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
1239  {
1240  uno::Sequence<beans::PropertyValue> propList;
1241  xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
1242  auto pProp = std::find_if(propList.begin(), propList.end(),
1243  [](const beans::PropertyValue& rProp) {
1244  return rProp.Name == "mso-rotation-angle";
1245  });
1246  if (pProp != propList.end())
1247  aRotation = pProp->Value;
1248  }
1249  aRotation >>= m_pImpl->getDMLandVMLTextFrameRotation();
1250  OString sRotation(OString::number(
1251  oox::drawingml::ExportRotateClockwisify(m_pImpl->getDMLandVMLTextFrameRotation())));
1252  // Shape properties
1253  pFS->startElementNS(XML_wps, XML_spPr);
1254  if (m_pImpl->getDMLandVMLTextFrameRotation())
1255  {
1256  pFS->startElementNS(XML_a, XML_xfrm, XML_rot, sRotation);
1257  }
1258  else
1259  {
1260  pFS->startElementNS(XML_a, XML_xfrm);
1261  }
1262  pFS->singleElementNS(XML_a, XML_off, XML_x, "0", XML_y, "0");
1263  OString aWidth(OString::number(TwipsToEMU(aSize.Width())));
1264  OString aHeight(OString::number(TwipsToEMU(aSize.Height())));
1265  pFS->singleElementNS(XML_a, XML_ext, XML_cx, aWidth, XML_cy, aHeight);
1266  pFS->endElementNS(XML_a, XML_xfrm);
1267  OUString shapeType = "rect";
1268  if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
1269  {
1270  uno::Sequence<beans::PropertyValue> propList;
1271  xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= propList;
1272  auto pProp = std::find_if(propList.begin(), propList.end(),
1273  [](const beans::PropertyValue& rProp) {
1274  return rProp.Name == "mso-orig-shape-type";
1275  });
1276  if (pProp != propList.end())
1277  pProp->Value >>= shapeType;
1278  }
1279  //Empty shapeType will lead to corruption so to avoid that shapeType is set to default i.e. "rect"
1280  if (shapeType.isEmpty())
1281  shapeType = "rect";
1282 
1283  pFS->singleElementNS(XML_a, XML_prstGeom, XML_prst, shapeType.toUtf8());
1284  m_pImpl->setDMLTextFrameSyntax(true);
1285  m_pImpl->getExport().OutputFormat(pParentFrame->GetFrameFormat(), false, false, true);
1286  m_pImpl->setDMLTextFrameSyntax(false);
1287  writeDMLEffectLst(rFrameFormat);
1288  pFS->endElementNS(XML_wps, XML_spPr);
1289  }
1290 
1291  //first, loop through ALL of the chained textboxes to identify a unique ID for each chain, and sequence number for each textbox in that chain.
1292  if (!m_pImpl->getExport().m_bLinkedTextboxesHelperInitialized)
1293  {
1294  sal_Int32 nSeq = 0;
1295  for (auto& rEntry : m_pImpl->getExport().m_aLinkedTextboxesHelper)
1296  {
1297  //find the start of a textbox chain: has no PREVIOUS link, but does have NEXT link
1298  if (rEntry.second.sPrevChain.isEmpty() && !rEntry.second.sNextChain.isEmpty())
1299  {
1300  //assign this chain a unique ID and start a new sequence
1301  nSeq = 0;
1302  rEntry.second.nId = ++m_pImpl->getExport().m_nLinkedTextboxesChainId;
1303  rEntry.second.nSeq = nSeq;
1304 
1305  OUString sCheckForBrokenChains = rEntry.first;
1306 
1307  //follow the chain and assign the same id, and incremental sequence numbers.
1308  auto followChainIter
1309  = m_pImpl->getExport().m_aLinkedTextboxesHelper.find(rEntry.second.sNextChain);
1310  while (followChainIter != m_pImpl->getExport().m_aLinkedTextboxesHelper.end())
1311  {
1312  //verify that the NEXT textbox also points to me as the PREVIOUS.
1313  // A broken link indicates a leftover remnant that can be ignored.
1314  if (followChainIter->second.sPrevChain != sCheckForBrokenChains)
1315  break;
1316 
1317  followChainIter->second.nId = m_pImpl->getExport().m_nLinkedTextboxesChainId;
1318  followChainIter->second.nSeq = ++nSeq;
1319 
1320  //empty next chain indicates the end of the linked chain.
1321  if (followChainIter->second.sNextChain.isEmpty())
1322  break;
1323 
1324  sCheckForBrokenChains = followChainIter->first;
1325  followChainIter = m_pImpl->getExport().m_aLinkedTextboxesHelper.find(
1326  followChainIter->second.sNextChain);
1327  }
1328  }
1329  }
1330  m_pImpl->getExport().m_bLinkedTextboxesHelperInitialized = true;
1331  }
1332 
1333  m_pImpl->getExport().m_pParentFrame = nullptr;
1334  bool skipTxBxContent = false;
1335  bool isTxbxLinked = false;
1336 
1337  OUString sLinkChainName;
1338  if (xPropSetInfo.is())
1339  {
1340  if (xPropSetInfo->hasPropertyByName("LinkDisplayName"))
1341  xPropertySet->getPropertyValue("LinkDisplayName") >>= sLinkChainName;
1342  else if (xPropSetInfo->hasPropertyByName("ChainName"))
1343  xPropertySet->getPropertyValue("ChainName") >>= sLinkChainName;
1344  }
1345 
1346  // second, check if THIS textbox is linked and then decide whether to write the tag txbx or linkedTxbx
1347  auto linkedTextboxesIter = m_pImpl->getExport().m_aLinkedTextboxesHelper.find(sLinkChainName);
1348  if (linkedTextboxesIter != m_pImpl->getExport().m_aLinkedTextboxesHelper.end())
1349  {
1350  if ((linkedTextboxesIter->second.nId != 0) && (linkedTextboxesIter->second.nSeq != 0))
1351  {
1352  //not the first in the chain, so write the tag as linkedTxbx
1353  pFS->singleElementNS(XML_wps, XML_linkedTxbx, XML_id,
1354  OString::number(linkedTextboxesIter->second.nId), XML_seq,
1355  OString::number(linkedTextboxesIter->second.nSeq));
1356  /* no text content should be added to this tag,
1357  since the textbox is linked, the entire content
1358  is written in txbx block
1359  */
1360  skipTxBxContent = true;
1361  }
1362  else if ((linkedTextboxesIter->second.nId != 0) && (linkedTextboxesIter->second.nSeq == 0))
1363  {
1364  /* this is the first textbox in the chaining, we add the text content
1365  to this block*/
1366  //since the text box is linked, it needs an id.
1367  pFS->startElementNS(XML_wps, XML_txbx, XML_id,
1368  OString::number(linkedTextboxesIter->second.nId));
1369  isTxbxLinked = true;
1370  }
1371  }
1372 
1373  if (!skipTxBxContent)
1374  {
1375  if (!isTxbxLinked)
1376  pFS->startElementNS(XML_wps, XML_txbx); //text box is not linked, therefore no id.
1377 
1378  pFS->startElementNS(XML_w, XML_txbxContent);
1379 
1380  const SvxFrameDirectionItem& rDirection = rFrameFormat.GetFrameDir();
1381  if (rDirection.GetValue() == SvxFrameDirection::Vertical_RL_TB)
1382  m_pImpl->getBodyPrAttrList()->add(XML_vert, "eaVert");
1383  else if (rDirection.GetValue() == SvxFrameDirection::Vertical_LR_BT)
1384  m_pImpl->getBodyPrAttrList()->add(XML_vert, "vert270");
1385 
1386  {
1387  ::comphelper::FlagRestorationGuard const g(m_pImpl->m_bFlyFrameGraphic, true);
1388  comphelper::ValueRestorationGuard vg(m_pImpl->getExport().m_nTextTyp, TXT_TXTBOX);
1389  m_pImpl->getExport().WriteText();
1390  if (m_pImpl->getParagraphSdtOpen())
1391  {
1392  m_pImpl->getExport().DocxAttrOutput().EndParaSdtBlock();
1393  m_pImpl->setParagraphSdtOpen(false);
1394  }
1395  }
1396 
1397  pFS->endElementNS(XML_w, XML_txbxContent);
1398  pFS->endElementNS(XML_wps, XML_txbx);
1399  }
1400 
1401  // We need to init padding to 0, if it's not set.
1402  // In LO the default is 0 and so ins attributes are not set when padding is 0
1403  // but in MSO the default is 254 / 127, so we need to set 0 padding explicitly
1404  if (m_pImpl->getBodyPrAttrList())
1405  {
1406  if (!m_pImpl->getBodyPrAttrList()->hasAttribute(XML_lIns))
1407  m_pImpl->getBodyPrAttrList()->add(XML_lIns, OString::number(0));
1408  if (!m_pImpl->getBodyPrAttrList()->hasAttribute(XML_tIns))
1409  m_pImpl->getBodyPrAttrList()->add(XML_tIns, OString::number(0));
1410  if (!m_pImpl->getBodyPrAttrList()->hasAttribute(XML_rIns))
1411  m_pImpl->getBodyPrAttrList()->add(XML_rIns, OString::number(0));
1412  if (!m_pImpl->getBodyPrAttrList()->hasAttribute(XML_bIns))
1413  m_pImpl->getBodyPrAttrList()->add(XML_bIns, OString::number(0));
1414  }
1415 
1416  sax_fastparser::XFastAttributeListRef xBodyPrAttrList(m_pImpl->getBodyPrAttrList());
1417  m_pImpl->setBodyPrAttrList(nullptr);
1418  if (!bTextBoxOnly)
1419  {
1420  pFS->startElementNS(XML_wps, XML_bodyPr, xBodyPrAttrList);
1421  // AutoSize of the Text Frame.
1422  const SwFormatFrameSize& rSize = rFrameFormat.GetFrameSize();
1423  pFS->singleElementNS(
1424  XML_a,
1425  (rSize.GetHeightSizeType() == SwFrameSize::Variable ? XML_spAutoFit : XML_noAutofit));
1426  pFS->endElementNS(XML_wps, XML_bodyPr);
1427 
1428  pFS->endElementNS(XML_wps, XML_wsp);
1429  pFS->endElementNS(XML_a, XML_graphicData);
1430  pFS->endElementNS(XML_a, XML_graphic);
1431 
1432  // Relative size of the Text Frame.
1433  const sal_uInt8 nWidthPercent = rSize.GetWidthPercent();
1434  if (nWidthPercent && nWidthPercent != SwFormatFrameSize::SYNCED)
1435  {
1436  pFS->startElementNS(XML_wp14, XML_sizeRelH, XML_relativeFrom,
1437  (rSize.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME
1438  ? "page"
1439  : "margin"));
1440  pFS->startElementNS(XML_wp14, XML_pctWidth);
1441  pFS->writeEscaped(OUString::number(nWidthPercent * oox::drawingml::PER_PERCENT));
1442  pFS->endElementNS(XML_wp14, XML_pctWidth);
1443  pFS->endElementNS(XML_wp14, XML_sizeRelH);
1444  }
1445  const sal_uInt8 nHeightPercent = rSize.GetHeightPercent();
1446  if (nHeightPercent && nHeightPercent != SwFormatFrameSize::SYNCED)
1447  {
1448  pFS->startElementNS(
1449  XML_wp14, XML_sizeRelV, XML_relativeFrom,
1450  (rSize.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME ? "page"
1451  : "margin"));
1452  pFS->startElementNS(XML_wp14, XML_pctHeight);
1453  pFS->writeEscaped(OUString::number(nHeightPercent * oox::drawingml::PER_PERCENT));
1454  pFS->endElementNS(XML_wp14, XML_pctHeight);
1455  pFS->endElementNS(XML_wp14, XML_sizeRelV);
1456  }
1457 
1458  endDMLAnchorInline(&rFrameFormat);
1459  }
1460  m_pImpl->setDMLAndVMLDrawingOpen(bDMLAndVMLDrawingOpen);
1461 }
1462 
1463 void DocxSdrExport::writeVMLTextFrame(ww8::Frame const* pParentFrame, bool bTextBoxOnly)
1464 {
1465  bool bDMLAndVMLDrawingOpen = m_pImpl->getDMLAndVMLDrawingOpen();
1466  m_pImpl->setDMLAndVMLDrawingOpen(IsAnchorTypeInsideParagraph(pParentFrame));
1467 
1468  sax_fastparser::FSHelperPtr pFS = m_pImpl->getSerializer();
1469  const SwFrameFormat& rFrameFormat = pParentFrame->GetFrameFormat();
1470  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
1471 
1472  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
1473  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1474 
1475  //Save data here and restore when out of scope
1476  ExportDataSaveRestore aDataGuard(m_pImpl->getExport(), nStt, nEnd, pParentFrame);
1477 
1478  // When a frame has some low height, but automatically expanded due
1479  // to lots of contents, this size contains the real size.
1480  const Size aSize = pParentFrame->GetSize();
1481  m_pImpl->setFlyFrameSize(&aSize);
1482 
1483  m_pImpl->setTextFrameSyntax(true);
1486  m_pImpl->getTextFrameStyle() = "position:absolute";
1487  if (!bTextBoxOnly)
1488  {
1489  OString sRotation(OString::number(m_pImpl->getDMLandVMLTextFrameRotation() / -100));
1490  m_pImpl->getExport()
1491  .SdrExporter()
1492  .getTextFrameStyle()
1493  .append(";rotation:")
1494  .append(sRotation);
1495  }
1496  m_pImpl->getExport().OutputFormat(pParentFrame->GetFrameFormat(), false, false, true);
1497  m_pImpl->getFlyAttrList()->add(XML_style, m_pImpl->getTextFrameStyle().makeStringAndClear());
1498 
1499  const SdrObject* pObject = pParentFrame->GetFrameFormat().FindRealSdrObject();
1500  if (pObject != nullptr)
1501  {
1502  OUString sAnchorId = lclGetAnchorIdFromGrabBag(pObject);
1503  if (!sAnchorId.isEmpty())
1504  m_pImpl->getFlyAttrList()->addNS(XML_w14, XML_anchorId,
1505  OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
1506  }
1507  sax_fastparser::XFastAttributeListRef xFlyAttrList(m_pImpl->getFlyAttrList().get());
1508  m_pImpl->getFlyAttrList().clear();
1509  sax_fastparser::XFastAttributeListRef xTextboxAttrList(m_pImpl->getTextboxAttrList().get());
1510  m_pImpl->getTextboxAttrList().clear();
1511  m_pImpl->setTextFrameSyntax(false);
1512  m_pImpl->setFlyFrameSize(nullptr);
1513  m_pImpl->getExport().m_pParentFrame = nullptr;
1514 
1515  if (!bTextBoxOnly)
1516  {
1517  pFS->startElementNS(XML_w, XML_pict);
1518  pFS->startElementNS(XML_v, XML_rect, xFlyAttrList);
1519  m_pImpl->textFrameShadow(rFrameFormat);
1520  if (m_pImpl->getFlyFillAttrList().is())
1521  {
1522  sax_fastparser::XFastAttributeListRef xFlyFillAttrList(
1523  m_pImpl->getFlyFillAttrList().get());
1524  m_pImpl->getFlyFillAttrList().clear();
1525  pFS->singleElementNS(XML_v, XML_fill, xFlyFillAttrList);
1526  }
1527  if (m_pImpl->getDashLineStyleAttr().is())
1528  {
1529  sax_fastparser::XFastAttributeListRef xDashLineStyleAttr(
1530  m_pImpl->getDashLineStyleAttr().get());
1531  m_pImpl->getDashLineStyleAttr().clear();
1532  pFS->singleElementNS(XML_v, XML_stroke, xDashLineStyleAttr);
1533  }
1534  pFS->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
1535  }
1536  pFS->startElementNS(XML_w, XML_txbxContent);
1537  {
1538  ::comphelper::FlagRestorationGuard const g(m_pImpl->m_bFlyFrameGraphic, true);
1539  comphelper::ValueRestorationGuard vg(m_pImpl->getExport().m_nTextTyp, TXT_TXTBOX);
1540  m_pImpl->getExport().WriteText();
1541  if (m_pImpl->getParagraphSdtOpen())
1542  {
1543  m_pImpl->getExport().DocxAttrOutput().EndParaSdtBlock();
1544  m_pImpl->setParagraphSdtOpen(false);
1545  }
1546  }
1547  pFS->endElementNS(XML_w, XML_txbxContent);
1548  if (!bTextBoxOnly)
1549  {
1550  pFS->endElementNS(XML_v, XML_textbox);
1551 
1552  if (m_pImpl->getFlyWrapAttrList())
1553  {
1554  sax_fastparser::XFastAttributeListRef xFlyWrapAttrList(m_pImpl->getFlyWrapAttrList());
1555  m_pImpl->setFlyWrapAttrList(nullptr);
1556  pFS->singleElementNS(XML_w10, XML_wrap, xFlyWrapAttrList);
1557  }
1558 
1559  pFS->endElementNS(XML_v, XML_rect);
1560  pFS->endElementNS(XML_w, XML_pict);
1561  }
1562 
1563  m_pImpl->setDMLAndVMLDrawingOpen(bDMLAndVMLDrawingOpen);
1564 }
1565 
1566 bool DocxSdrExport::isTextBox(const SwFrameFormat& rFrameFormat)
1567 {
1568  return SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT);
1569 }
1570 
1571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 Count() const
long GetLeft() const
long Width() const
bool getTextFrameSyntax() const
bool IsContour() const
Definition: fmtsrnd.hxx:53
void writeDMLAndVMLDrawing(const SdrObject *sdrObj, const SwFrameFormat &rFrameFormat, int nAnchorId)
Writes shape in both DML and VML format.
sax_fastparser::FastAttributeList * getFlyWrapAttrList() const
long GetWidth() const
Helper class, so that the DocxExport::RestoreData() call will always happen.
SwNoTextNode * GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
Get the SwNoTextNode associated with a SwFrameFormat if here is one.
static bool lcl_isLockedCanvas(const uno::Reference< drawing::XShape > &xShape)
sax_fastparser::FastAttributeList * m_pFlyWrapAttrList
bool getParagraphHasDrawing() const
bool IsDrawingOpen() const
long GetHeight() const
sal_uInt16 GetLower() const
sal_Int32 & getDMLandVMLTextFrameRotation()
const Size * m_pFlyFrameSize
static FastAttributeList * createAttrList()
double ConvertBorderWidthToWord(SvxBorderLineStyle, double)
std::unique_ptr< Impl > m_pImpl
TextVerticalAdjust GetTextVerticalAdjust(sal_Int32 nToken)
const sal_Int32 PER_PERCENT
void endDMLAnchorInline(const SwFrameFormat *pFrameFormat)
long Height() const
css::uno::Reference< css::xml::sax::XFastAttributeList > XFastAttributeListRef
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
oox::drawingml::DrawingML * m_pDrawingML
bool getDMLTextFrameSyntax() const
rtl::Reference< sax_fastparser::FastAttributeList > & getFlyAttrList()
sal_uInt8 GetTransparency() const
SwTwips GetPos() const
Definition: fmtornt.hxx:92
sal_uIntPtr sal_uLong
virtual void SaveData(sal_uLong nStt, sal_uLong nEnd)
Remember some of the members so that we can recurse in WriteText().
Definition: wrtww8.cxx:1909
void writeDMLEffectLst(const SwFrameFormat &rFrameFormat)
Write , the effect list.
OUString GetDescription() const
void addNS(sal_Int32 nNamespaceToken, sal_Int32 nToken, const OString &rValue)
const SvxFrameDirectionItem & GetFrameDir(bool=true) const
Definition: frmatr.hxx:94
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:78
Holds data used by DocxSdrExport only.
DocxExport & m_rExport
void setFlyAttrList(const rtl::Reference< sax_fastparser::FastAttributeList > &pFlyAttrList)
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool IsParagraphHasDrawing() const
tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon &rPolyPoly, const SwNoTextNode *pNd)
Undo all scaling / move tricks of the wrap polygon done during import.
const editeng::SvxBorderLine * GetRight() const
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
The class that does all the actual DOCX export-related work.
Definition: docxexport.hxx:66
sax_fastparser::FastAttributeList * getBodyPrAttrList()
Attributes of , used during DML export of text frames.
EmbeddedObjectRef * pObject
bool getParagraphSdtOpen() const
void startDMLAnchorInline(const SwFrameFormat *pFrameFormat, const Size &rSize)
rtl::Reference< sax_fastparser::FastAttributeList > & getFlyFillAttrList()
void writeDiagram(const SdrObject *sdrObject, const SwFrameFormat &rFrameFormat, int nDiagramId)
Writes a diagram (smartart).
void setDMLAndVMLDrawingOpen(bool bDMLAndVMLDrawingOpen)
sal_Int32 m_nDMLandVMLTextFrameRotation
List of TextBoxes in this document: they are exported as part of their shape, never alone...
static bool isTextBox(const SwFrameFormat &rFrameFormat)
Is this a standalone TextFrame, or used as a TextBox of a shape?
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:154
void writeDMLTextFrame(ww8::Frame const *pParentFrame, int nAnchorId, bool bTextBoxOnly=false)
Writes text frame in DML format.
virtual const tools::Rectangle & GetSnapRect() const
bool IsVisible() const
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
bool getDMLAndVMLDrawingOpen() const
SvxShadowLocation GetLocation() const
MSO_SPT
#define X
bool getDMLTextFrameSyntax() const
const OUString & GetName() const
Definition: format.hxx:111
oox::drawingml::DrawingML * getDrawingML() const
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType)
Is the frame format a text box?
const Size * getFlyFrameSize() const
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
bool HasTextBoxContent(sal_uInt32 nShapeType)
DocxSdrExport(DocxExport &rExport, const sax_fastparser::FSHelperPtr &pSerializer, oox::drawingml::DrawingML *pDrawingML)
void setParagraphSdtOpen(bool bParagraphSdtOpen)
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
Impl(DocxExport &rExport, sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML *pDrawingML)
virtual SdrLayerID GetInvisibleHellId() const =0
const sax_fastparser::FSHelperPtr & getSerializer() const
ShapeFlag
void setParagraphHasDrawing(bool bParagraphHasDrawing)
const Color & GetColor() const
rtl::Reference< sax_fastparser::FastAttributeList > & getTextboxAttrList()
Attributes of the next v:textbox element.
const editeng::SvxBorderLine * GetTop() const
OBJ_LINE
Style of a layout element.
Definition: frmfmt.hxx:57
#define SAL_MAX_INT32
rtl::Reference< sax_fastparser::FastAttributeList > m_pTextboxAttrList
void setFlyWrapAttrList(sax_fastparser::FastAttributeList *pFlyWrapAttrList)
OptionalString sType
virtual void RestoreData()
Restore what was saved in SaveData().
Definition: wrtww8.cxx:1941
const editeng::SvxBorderLine * GetLeft() const
rtl::Reference< sax_fastparser::FastAttributeList > & getFlyAttrList()
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
OStringBuffer & getTextFrameStyle()
void setFlyFrameSize(const Size *pFlyFrameSize)
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
const Color & GetColor() const
ExportDataSaveRestore(DocxExport &rExport, sal_uLong nStt, sal_uLong nEnd, ww8::Frame const *pParentFrame)
bool getDrawingOpen() const
FlyAnchors.
Definition: fmtanchr.hxx:34
void setSerializer(const sax_fastparser::FSHelperPtr &pSerializer)
sal_uInt8 GetHeightPercent() const
Definition: fmtfsize.hxx:88
const ww8::Frame * m_pParentFrame
Definition: wrtww8.hxx:523
#define SAL_MIN_INT32
OUString GetTitle() const
bool getTextFrameSyntax() const
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
Object Value
OStringBuffer & getTextFrameStyle()
OString ConvertColor(const Color &rColor)
sal_uInt16 GetSize() const
Marks a node in the document model.
Definition: ndindex.hxx:31
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
bool IsDMLAndVMLDrawingOpen() const
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
rtl::Reference< sax_fastparser::FastAttributeList > & getFlyFillAttrList()
std::shared_ptr< FastSerializerHelper > FSHelperPtr
void textFrameShadow(const SwFrameFormat &rFrameFormat)
Writes wp wrapper code around an SdrObject, which itself is written using drawingML syntax...
rtl::Reference< sax_fastparser::FastAttributeList > m_pFlyAttrList
void setFlyWrapAttrList(sax_fastparser::FastAttributeList *pAttrList)
const double * GetRelativeWidth() const
sax_fastparser::FSHelperPtr m_pSerializer
sal_Int16 GetRelativeWidthRelation() const
OUString GetName() const
#define Y
sax_fastparser::FastAttributeList * m_pBodyPrAttrList
virtual SdrLayerID GetHellId() const =0
virtual SdrLayerID GetLayer() const
sal_Int16 GetHeightPercentRelation() const
Definition: fmtfsize.hxx:89
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
void setParagraphSdtOpen(bool bParagraphSdtOpen)
Set if paragraph sdt open in the current drawing.
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
rtl::Reference< sax_fastparser::FastAttributeList > m_pDashLineStyleAttr
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
void writeVMLTextFrame(ww8::Frame const *pParentFrame, bool bTextBoxOnly=false)
Writes text frame in VML format.
rtl::Reference< sax_fastparser::FastAttributeList > & getDashLineStyle()
void setBodyPrAttrList(sax_fastparser::FastAttributeList *pBodyPrAttrList)
const SvxOpaqueItem & GetOpaque(bool=true) const
Definition: frmatr.hxx:80
iterator find(const OUString &rKey)
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
unsigned char sal_uInt8
void writeDMLDrawing(const SdrObject *pSdrObject, const SwFrameFormat *pFrameFormat, int nAnchorId)
Writes a drawing as DML.
Make exporting a Writer Frame easy.
rtl::Reference< sax_fastparser::FastAttributeList > m_pFlyFillAttrList
Flag for checking drawing in a paragraph.
SwTwips GetPos() const
Definition: fmtornt.hxx:59
T ExportRotateClockwisify(T input)
void writeOnlyTextOfFrame(ww8::Frame const *pParentFrame)
Writes text from Textbox for
void setTextFrameSyntax(bool bTextFrameSyntax)
void setTextboxAttrList(const rtl::Reference< sax_fastparser::FastAttributeList > &pTextboxAttrList)
const Size & GetSize() const
The Size of the contained element.
static OString lcl_ConvertTransparency(const Color &rColor)
void writeBoxItemLine(const SvxBoxItem &rBox)
Writes the drawingML markup of a box item.
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
sax_fastparser::FastAttributeList * getBodyPrAttrList() const
const SwFormatWrapInfluenceOnObjPos & GetWrapInfluenceOnObjPos(bool=true) const
void setDMLTextFrameSyntax(bool bDMLTextFrameSyntax)
sax_fastparser::FastAttributeList * getFlyWrapAttrList()
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(154)
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
long GetRight() const
void setSerializer(const sax_fastparser::FSHelperPtr &pSerializer)
void writeVMLDrawing(const SdrObject *sdrObj, const SwFrameFormat &rFrameFormat)
Writes a drawing as VML data.
SvxBorderLineStyle GetBorderLineStyle() const
static bool isSupportedDMLShape(const uno::Reference< drawing::XShape > &xShape)
rtl::Reference< sax_fastparser::FastAttributeList > & getTextboxAttrList()
long GetWidth() const
sal_Int16 GetRelativeHeightRelation() const
#define SAL_WARN(area, stream)
virtual const tools::Rectangle & GetLogicRect() const
bool getFlyFrameGraphic() const
OStringBuffer m_aTextFrameStyle
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
Frame is variable in Var-direction.
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
void setDrawingOpen(bool bDrawingOpen)
void setParagraphHasDrawing(bool bParagraphHasDrawing)
void setDMLandVMLTextFrameRotation(sal_Int32 nDMLandVMLTextFrameRotation)
const editeng::SvxBorderLine * GetBottom() const
sal_Int16 GetWidthPercentRelation() const
Definition: fmtfsize.hxx:92
const Size * getFlyFrameSize() const
When exporting fly frames, this holds the real size of the frame.
static MSO_SPT GetCustomShapeType(const css::uno::Reference< css::drawing::XShape > &rXShape, ShapeFlag &nMirrorFlags, OUString &rShapeType, bool bOOXML=false)
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2701
void add(sal_Int32 nToken, const char *pValue)
const double * GetRelativeHeight() const
rtl::Reference< sax_fastparser::FastAttributeList > & getDashLineStyleAttr()
sal_uInt16 GetUpper() const
DocxExport & getExport() const
SwFrameSize GetHeightSizeType() const
Definition: fmtfsize.hxx:80
sal_uInt16 GetWidth() const
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
EnumT GetValue() const
const SvxShadowItem & GetShadow(bool=true) const
Definition: frmatr.hxx:88