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