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