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