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