LibreOffice Module oox (master)  1
vmlexport.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <config_folders.h>
21 #include <rtl/bootstrap.hxx>
22 #include <svl/itemset.hxx>
23 #include <oox/export/drawingml.hxx>
24 #include <oox/export/vmlexport.hxx>
25 #include <sax/fastattribs.hxx>
26 
27 #include <oox/token/tokens.hxx>
28 
29 #include <rtl/strbuf.hxx>
30 #include <rtl/ustring.hxx>
31 #include <sal/log.hxx>
32 
33 #include <tools/stream.hxx>
35 #include <svx/svdotext.hxx>
36 #include <svx/svdograf.hxx>
37 #include <svx/sdmetitm.hxx>
38 #include <vcl/cvtgrf.hxx>
40 #include <filter/msfilter/util.hxx>
42 #include <o3tl/string_view.hxx>
43 
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/beans/XPropertySetInfo.hpp>
46 #include <com/sun/star/drawing/XShape.hpp>
47 #include <com/sun/star/text/HoriOrientation.hpp>
48 #include <com/sun/star/text/VertOrientation.hpp>
49 #include <com/sun/star/text/RelOrientation.hpp>
50 #include <com/sun/star/text/WritingMode2.hpp>
51 #include <com/sun/star/text/XTextFrame.hpp>
52 
53 #include <cstdio>
54 
55 using namespace sax_fastparser;
56 using namespace oox::vml;
57 using namespace com::sun::star;
58 
59 const sal_Int32 Tag_Container = 44444;
60 const sal_Int32 Tag_Commit = 44445;
61 
62 VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr const & pSerializer, VMLTextExport* pTextExport )
63  : EscherEx( std::make_shared<EscherExGlobal>(), nullptr, /*bOOXML=*/true )
64  , m_pSerializer( pSerializer )
65  , m_pTextExport( pTextExport )
66  , m_eHOri( 0 )
67  , m_eVOri( 0 )
68  , m_eHRel( 0 )
69  , m_eVRel( 0 )
70  , m_bInline( false )
71  , m_pSdrObject( nullptr )
72  , m_nShapeType( ESCHER_ShpInst_Nil )
73  , m_nShapeFlags(ShapeFlag::NONE)
74  , m_ShapeStyle( 200 )
75  , m_aShapeTypeWritten( ESCHER_ShpInst_COUNT )
76  , m_bSkipwzName( false )
77  , m_bUseHashMarkForType( false )
78  , m_bOverrideShapeIdGeneration( false )
79  , m_nShapeIDCounter( 0 )
80 {
81  mnGroupLevel = 1;
82 }
83 
84 void VMLExport::SetFS( const ::sax_fastparser::FSHelperPtr& pSerializer )
85 {
86  m_pSerializer = pSerializer;
87 }
88 
90 {
91  delete mpOutStrm;
92  mpOutStrm = nullptr;
93 }
94 
95 void VMLExport::OpenContainer( sal_uInt16 nEscherContainer, int nRecInstance )
96 {
97  EscherEx::OpenContainer( nEscherContainer, nRecInstance );
98 
99  if ( nEscherContainer != ESCHER_SpContainer )
100  return;
101 
102  // opening a shape container
103  SAL_WARN_IF(m_nShapeType != ESCHER_ShpInst_Nil, "oox.vml", "opening shape inside of a shape!");
105  m_pShapeAttrList = FastSerializerHelper::createAttrList();
106 
107  m_ShapeStyle.setLength(0);
108  m_ShapeStyle.ensureCapacity(200);
109 
110  // postpone the output so that we are able to write even the elements
111  // that we learn inside Commit()
113 }
114 
116 {
117  if ( mRecTypes.back() == ESCHER_SpContainer )
118  {
119  // write the shape now when we have all the info
120  sal_Int32 nShapeElement = StartShape();
121 
122  m_pSerializer->mergeTopMarks(Tag_Container);
123 
124  EndShape( nShapeElement );
125 
126  // cleanup
128  m_pShapeAttrList = nullptr;
129  }
130 
132 }
133 
134 sal_uInt32 VMLExport::EnterGroup( const OUString& rShapeName, const tools::Rectangle* pRect )
135 {
136  sal_uInt32 nShapeId = GenerateShapeId();
137 
138  OStringBuffer aStyle( 200 );
139  rtl::Reference<FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
140 
141  pAttrList->add( XML_id, ShapeIdString( nShapeId ) );
142 
143  if ( rShapeName.getLength() )
144  pAttrList->add( XML_alt, rShapeName );
145 
146  bool rbAbsolutePos = true;
147  //editAs
148  OUString rEditAs = EscherEx::GetEditAs();
149  if (!rEditAs.isEmpty())
150  {
151  pAttrList->add(XML_editas, rEditAs);
152  rbAbsolutePos = false;
153  }
154 
155  // style
156  if ( pRect )
157  AddRectangleDimensions( aStyle, *pRect, rbAbsolutePos );
158 
159  if ( !aStyle.isEmpty() )
160  pAttrList->add( XML_style, aStyle.makeStringAndClear() );
161 
162  // coordorigin/coordsize
163  if ( pRect && ( mnGroupLevel == 1 ) )
164  {
165  pAttrList->add( XML_coordorigin,
166  OString::number( pRect->Left() ) + "," + OString::number( pRect->Top() ) );
167 
168  pAttrList->add( XML_coordsize,
169  OString::number( pRect->Right() - pRect->Left() ) + "," +
170  OString::number( pRect->Bottom() - pRect->Top() ) );
171  }
172 
173  m_pSerializer->startElementNS( XML_v, XML_group, pAttrList );
174 
175  mnGroupLevel++;
176  return nShapeId;
177 }
178 
180 {
181  --mnGroupLevel;
182  m_pSerializer->endElementNS( XML_v, XML_group );
183 }
184 
185 void VMLExport::AddShape( sal_uInt32 nShapeType, ShapeFlag nShapeFlags, sal_uInt32 nShapeId )
186 {
187  m_nShapeType = nShapeType;
188  m_nShapeFlags = nShapeFlags;
189 
190  m_sShapeId = ShapeIdString( nShapeId );
191  // If shape is a watermark object - should keep the original shape's name
192  // because Microsoft detects if it is a watermark by the actual name
194  {
195  // Not a watermark object
196  m_pShapeAttrList->add( XML_id, m_sShapeId );
197  }
198  else
199  {
200  // A watermark object - store the optional shape ID
201  m_pShapeAttrList->add( XML_id, m_pSdrObject->GetName() );
202  // also ('o:spid')
203  m_pShapeAttrList->addNS( XML_o, XML_spid, m_sShapeId );
204  }
205 }
206 
207 bool VMLExport::IsWaterMarkShape(std::u16string_view rStr)
208 {
209  if (rStr.empty() ) return false;
210 
211  return o3tl::starts_with(rStr, u"PowerPlusWaterMarkObject") || o3tl::starts_with(rStr, u"WordPictureWatermark");
212 }
213 
214 void VMLExport::OverrideShapeIDGen(bool bOverrideShapeIdGen, const OString& sShapeIDPrefix)
215 {
216  m_bOverrideShapeIdGeneration = bOverrideShapeIdGen;
217  if(bOverrideShapeIdGen)
218  {
219  assert(!sShapeIDPrefix.isEmpty());
220  m_sShapeIDPrefix = sShapeIDPrefix;
221  }
222  else
223  m_sShapeIDPrefix.clear();
224 }
225 
226 static void impl_AddArrowHead( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
227 {
228  if ( !pAttrList )
229  return;
230 
231  const char *pArrowHead = nullptr;
232  switch ( nValue )
233  {
234  case ESCHER_LineNoEnd: pArrowHead = "none"; break;
235  case ESCHER_LineArrowEnd: pArrowHead = "block"; break;
236  case ESCHER_LineArrowStealthEnd: pArrowHead = "classic"; break;
237  case ESCHER_LineArrowDiamondEnd: pArrowHead = "diamond"; break;
238  case ESCHER_LineArrowOvalEnd: pArrowHead = "oval"; break;
239  case ESCHER_LineArrowOpenEnd: pArrowHead = "open"; break;
240  }
241 
242  if ( pArrowHead )
243  pAttrList->add( nElement, pArrowHead );
244 }
245 
246 static void impl_AddArrowLength( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
247 {
248  if ( !pAttrList )
249  return;
250 
251  const char *pArrowLength = nullptr;
252  switch ( nValue )
253  {
254  case ESCHER_LineShortArrow: pArrowLength = "short"; break;
255  case ESCHER_LineMediumLenArrow: pArrowLength = "medium"; break;
256  case ESCHER_LineLongArrow: pArrowLength = "long"; break;
257  }
258 
259  if ( pArrowLength )
260  pAttrList->add( nElement, pArrowLength );
261 }
262 
263 static void impl_AddArrowWidth( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
264 {
265  if ( !pAttrList )
266  return;
267 
268  const char *pArrowWidth = nullptr;
269  switch ( nValue )
270  {
271  case ESCHER_LineNarrowArrow: pArrowWidth = "narrow"; break;
272  case ESCHER_LineMediumWidthArrow: pArrowWidth = "medium"; break;
273  case ESCHER_LineWideArrow: pArrowWidth = "wide"; break;
274  }
275 
276  if ( pArrowWidth )
277  pAttrList->add( nElement, pArrowWidth );
278 }
279 
280 static void impl_AddBool( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, bool bValue )
281 {
282  if ( !pAttrList )
283  return;
284 
285  pAttrList->add( nElement, bValue? "t": "f" );
286 }
287 
288 static void impl_AddColor( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nColor )
289 {
290  SAL_WARN_IF( nColor & 0xFF000000 , "oox.vml" , "TODO: this is not a RGB value!");
291 
292  if ( !pAttrList || ( nColor & 0xFF000000 ) )
293  return;
294 
295  nColor = ( ( nColor & 0xFF ) << 16 ) + ( nColor & 0xFF00 ) + ( ( nColor & 0xFF0000 ) >> 16 );
296 
297  const char *pColor = nullptr;
298  char pRgbColor[10];
299  switch ( nColor )
300  {
301  case 0x000000: pColor = "black"; break;
302  case 0xC0C0C0: pColor = "silver"; break;
303  case 0x808080: pColor = "gray"; break;
304  case 0xFFFFFF: pColor = "white"; break;
305  case 0x800000: pColor = "maroon"; break;
306  case 0xFF0000: pColor = "red"; break;
307  case 0x800080: pColor = "purple"; break;
308  case 0xFF00FF: pColor = "fuchsia"; break;
309  case 0x008000: pColor = "green"; break;
310  case 0x00FF00: pColor = "lime"; break;
311  case 0x808000: pColor = "olive"; break;
312  case 0xFFFF00: pColor = "yellow"; break;
313  case 0x000080: pColor = "navy"; break;
314  case 0x0000FF: pColor = "blue"; break;
315  case 0x008080: pColor = "teal"; break;
316  case 0x00FFFF: pColor = "aqua"; break;
317  default:
318  {
319  snprintf( pRgbColor, sizeof( pRgbColor ), "#%06x", static_cast< unsigned int >( nColor ) ); // not too handy to use OString::valueOf() here :-(
320  pColor = pRgbColor;
321  }
322  break;
323  }
324 
325  pAttrList->add( nElement, pColor );
326 }
327 
328 static void impl_AddInt( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
329 {
330  if ( !pAttrList )
331  return;
332 
333  pAttrList->add( nElement, OString::number( nValue ).getStr() );
334 }
335 
336 static sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal )
337 {
338  sal_uInt16 nRet = *pVal++;
339  nRet += ( *pVal++ ) << 8;
340  return nRet;
341 }
342 
343 static sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize )
344 {
345  sal_Int32 nRet = 0;
346  if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) )
347  {
348  sal_uInt16 nUnsigned = *pVal++;
349  nUnsigned += ( *pVal++ ) << 8;
350 
351  nRet = sal_Int16( nUnsigned );
352  }
353  else if ( nPointSize == 8 )
354  {
355  sal_uInt32 nUnsigned = *pVal++;
356  nUnsigned += ( *pVal++ ) << 8;
357  nUnsigned += ( *pVal++ ) << 16;
358  nUnsigned += ( *pVal++ ) << 24;
359 
360  nRet = nUnsigned;
361  }
362 
363  return nRet;
364 }
365 
367 {
368  m_pSdrObject = &rObj;
369 }
371 {
373  return;
374 
375  // postpone the output of the embedded elements so that they are written
376  // inside the shapes
377  m_pSerializer->mark(Tag_Commit);
378 
379  // dimensions
381  AddLineDimensions( rRect );
382  else
383  {
385  {
386  // Watermark need some padding to be compatible with MSO
387  tools::Long nPaddingY = 0;
388  const SfxItemSet& rSet = m_pSdrObject->GetMergedItemSet();
389  if ( const SdrMetricItem* pItem = rSet.GetItem( SDRATTR_TEXT_UPPERDIST ) )
390  nPaddingY += pItem->GetValue();
391 
392  tools::Rectangle aRect( rRect );
393  aRect.setHeight( aRect.getHeight() + nPaddingY );
395  }
396  else
398  }
399 
400  // properties
401  bool bAlreadyWritten[ 0xFFF ] = {};
402  const EscherProperties &rOpts = rProps.GetOpts();
403  for (auto const& opt : rOpts)
404  {
405  sal_uInt16 nId = ( opt.nPropId & 0x0FFF );
406 
407  if ( bAlreadyWritten[ nId ] )
408  continue;
409 
410  switch ( nId )
411  {
412  case ESCHER_Prop_WrapText: // 133
413  {
414  const char *pWrapType = nullptr;
415  switch ( opt.nPropValue )
416  {
417  case ESCHER_WrapSquare:
418  case ESCHER_WrapByPoints: pWrapType = "square"; break; // these two are equivalent according to the docu
419  case ESCHER_WrapNone: pWrapType = "none"; break;
421  case ESCHER_WrapThrough:
422  break; // last two are *undefined* in MS-ODRAW, don't exist in VML
423  }
424  if ( pWrapType )
425  {
426  m_ShapeStyle.append(";mso-wrap-style:");
427  m_ShapeStyle.append(pWrapType);
428  }
429  }
430  bAlreadyWritten[ ESCHER_Prop_WrapText ] = true;
431  break;
432 
433  case ESCHER_Prop_AnchorText: // 135
434  {
435  char const* pValue(nullptr);
436  switch (opt.nPropValue)
437  {
438  case ESCHER_AnchorTop:
439  pValue = "top";
440  break;
441  case ESCHER_AnchorMiddle:
442  pValue = "middle";
443  break;
444  case ESCHER_AnchorBottom:
445  pValue = "bottom";
446  break;
448  pValue = "top-center";
449  break;
451  pValue = "middle-center";
452  break;
454  pValue = "bottom-center";
455  break;
457  pValue = "top-baseline";
458  break;
460  pValue = "bottom-baseline";
461  break;
463  pValue = "top-center-baseline";
464  break;
466  pValue = "bottom-center-baseline";
467  break;
468  }
469  m_ShapeStyle.append(";v-text-anchor:");
470  m_ShapeStyle.append(pValue);
471  }
472  break;
473 
474  case ESCHER_Prop_txflTextFlow: // 136
475  {
476  // at least "bottom-to-top" only has an effect when it's on the v:textbox element, not on v:shape
477  assert(m_TextboxStyle.isEmpty());
478  switch (opt.nPropValue)
479  {
480  case ESCHER_txflHorzN:
481  m_TextboxStyle.append("layout-flow:horizontal");
482  break;
483  case ESCHER_txflTtoBA:
484  m_TextboxStyle.append("layout-flow:vertical");
485  break;
486  case ESCHER_txflBtoT:
487  m_TextboxStyle.append("mso-layout-flow-alt:bottom-to-top");
488  break;
489  default:
490  assert(false); // unimplemented in escher export
491  break;
492  }
493  }
494  break;
495 
496  // coordorigin
497  case ESCHER_Prop_geoLeft: // 320
498  case ESCHER_Prop_geoTop: // 321
499  {
500  sal_uInt32 nLeft = 0, nTop = 0;
501 
502  if ( nId == ESCHER_Prop_geoLeft )
503  {
504  nLeft = opt.nPropValue;
505  rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
506  }
507  else
508  {
509  nTop = opt.nPropValue;
510  rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
511  }
512  if(nTop!=0 && nLeft!=0)
513  m_pShapeAttrList->add( XML_coordorigin,
514  OString::number( nLeft ) + "," + OString::number( nTop ) );
515  }
516  bAlreadyWritten[ ESCHER_Prop_geoLeft ] = true;
517  bAlreadyWritten[ ESCHER_Prop_geoTop ] = true;
518  break;
519 
520  // coordsize
521  case ESCHER_Prop_geoRight: // 322
522  case ESCHER_Prop_geoBottom: // 323
523  {
524  sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0;
525  rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
526  rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
527 
528  if ( nId == ESCHER_Prop_geoRight )
529  {
530  nRight = opt.nPropValue;
531  rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom );
532  }
533  else
534  {
535  nBottom = opt.nPropValue;
536  rProps.GetOpt( ESCHER_Prop_geoRight, nRight );
537  }
538 
539  if(nBottom!=0 && nRight!=0 )
540  m_pShapeAttrList->add( XML_coordsize,
541  OString::number( nRight - nLeft ) + "," + OString::number( nBottom - nTop ) );
542  }
543  bAlreadyWritten[ ESCHER_Prop_geoRight ] = true;
544  bAlreadyWritten[ ESCHER_Prop_geoBottom ] = true;
545  break;
546 
547  case ESCHER_Prop_pVertices: // 325
548  case ESCHER_Prop_pSegmentInfo: // 326
549  {
550  EscherPropSortStruct aVertices;
552 
553  if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
554  rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
555  {
556  const sal_uInt8 *pVerticesIt = aVertices.nProp.data() + 6;
557  const sal_uInt8 *pSegmentIt = aSegments.nProp.data();
558  OStringBuffer aPath( 512 );
559 
560  sal_uInt16 nPointSize = aVertices.nProp[4] + ( aVertices.nProp[5] << 8 );
561 
562  // number of segments
563  sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
564  pSegmentIt += 4;
565 
566  for ( ; nSegments; --nSegments )
567  {
568  sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt );
569 
570  // The segment type is stored in the upper 3 bits
571  // and segment count is stored in the lower 13
572  // bits.
573  unsigned char nSegmentType = (nSeg & 0xE000) >> 13;
574  unsigned short nSegmentCount = nSeg & 0x03FF;
575 
576  switch (nSegmentType)
577  {
578  case msopathMoveTo:
579  {
580  sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
581  sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
582  if (nX >= 0 && nY >= 0 )
583  aPath.append( "m" + OString::number( nX ) + "," + OString::number( nY ) );
584  break;
585  }
586  case msopathClientEscape:
587  break;
588  case msopathEscape:
589  {
590  // If the segment type is msopathEscape, the lower 13 bits are
591  // divided in a 5 bit escape code and 8 bit
592  // vertex count (not segment count!)
593  unsigned char nEscapeCode = (nSegmentCount & 0x1F00) >> 8;
594  unsigned char nVertexCount = nSegmentCount & 0x00FF;
595  pVerticesIt += nVertexCount;
596 
597  switch (nEscapeCode)
598  {
599  case 0xa: // nofill
600  aPath.append( "nf" );
601  break;
602  case 0xb: // nostroke
603  aPath.append( "ns" );
604  break;
605  }
606 
607  break;
608  }
609  case msopathLineTo:
610  for (unsigned short i = 0; i < nSegmentCount; ++i)
611  {
612  sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
613  sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
614  aPath.append( "l" + OString::number( nX ) + "," + OString::number( nY ) );
615  }
616  break;
617  case msopathCurveTo:
618  for (unsigned short i = 0; i < nSegmentCount; ++i)
619  {
620  sal_Int32 nX1 = impl_GetPointComponent( pVerticesIt, nPointSize );
621  sal_Int32 nY1 = impl_GetPointComponent( pVerticesIt, nPointSize );
622  sal_Int32 nX2 = impl_GetPointComponent( pVerticesIt, nPointSize );
623  sal_Int32 nY2 = impl_GetPointComponent( pVerticesIt, nPointSize );
624  sal_Int32 nX3 = impl_GetPointComponent( pVerticesIt, nPointSize );
625  sal_Int32 nY3 = impl_GetPointComponent( pVerticesIt, nPointSize );
626  aPath.append( "c" + OString::number( nX1 ) + "," + OString::number( nY1 ) + "," +
627  OString::number( nX2 ) + "," + OString::number( nY2 ) + "," +
628  OString::number( nX3 ) + "," + OString::number( nY3 ) );
629  }
630  break;
631  case msopathClose:
632  aPath.append( "x" );
633  break;
634  case msopathEnd:
635  aPath.append( "e" );
636  break;
637  default:
638  SAL_WARN("oox", "Totally b0rked");
639  break;
640  case msopathInvalid:
641  SAL_WARN("oox", "Invalid - should never be found");
642  break;
643  }
644  }
645  OString pathString = aPath.makeStringAndClear();
646  if ( !pathString.isEmpty() && pathString != "xe" )
647  m_pShapeAttrList->add( XML_path, pathString );
648  }
649  else
650  SAL_WARN("oox.vml", "unhandled shape path, missing either pVertices or pSegmentInfo.");
651  }
652  bAlreadyWritten[ ESCHER_Prop_pVertices ] = true;
653  bAlreadyWritten[ ESCHER_Prop_pSegmentInfo ] = true;
654  break;
655 
656  case ESCHER_Prop_fillType: // 384
657  case ESCHER_Prop_fillColor: // 385
658  case ESCHER_Prop_fillBackColor: // 387
659  case ESCHER_Prop_fillBlip: // 390
660  case ESCHER_Prop_fNoFillHitTest: // 447
661  case ESCHER_Prop_fillOpacity: // 386
662  {
663  sal_uInt32 nValue;
665  = FastSerializerHelper::createAttrList();
666 
667  bool imageData = false;
668  EscherPropSortStruct aStruct;
669  const SdrGrafObj* pSdrGrafObj = dynamic_cast<const SdrGrafObj*>(m_pSdrObject);
670 
671  if (pSdrGrafObj && pSdrGrafObj->isSignatureLine() && m_pTextExport)
672  {
674  = FastSerializerHelper::createAttrList();
675  pAttrListSignatureLine->add(XML_issignatureline, "t");
676  if (!pSdrGrafObj->getSignatureLineId().isEmpty())
677  {
678  pAttrListSignatureLine->add(
679  XML_id, pSdrGrafObj->getSignatureLineId());
680  }
681  if (!pSdrGrafObj->getSignatureLineSuggestedSignerName().isEmpty())
682  {
683  pAttrListSignatureLine->add(
684  FSNS(XML_o, XML_suggestedsigner),
685  pSdrGrafObj->getSignatureLineSuggestedSignerName());
686  }
687  if (!pSdrGrafObj->getSignatureLineSuggestedSignerTitle().isEmpty())
688  {
689  pAttrListSignatureLine->add(
690  FSNS(XML_o, XML_suggestedsigner2),
691  pSdrGrafObj->getSignatureLineSuggestedSignerTitle());
692  }
693  if (!pSdrGrafObj->getSignatureLineSuggestedSignerEmail().isEmpty())
694  {
695  pAttrListSignatureLine->add(
696  FSNS(XML_o, XML_suggestedsigneremail),
697  pSdrGrafObj->getSignatureLineSuggestedSignerEmail());
698  }
699  if (!pSdrGrafObj->getSignatureLineSigningInstructions().isEmpty())
700  {
701  pAttrListSignatureLine->add(XML_signinginstructionsset, "t");
702  pAttrListSignatureLine->add(
703  FSNS(XML_o, XML_signinginstructions),
704  pSdrGrafObj->getSignatureLineSigningInstructions());
705  }
706  pAttrListSignatureLine->add(
707  XML_showsigndate,
708  pSdrGrafObj->isSignatureLineShowSignDate() ? "t" : "f");
709  pAttrListSignatureLine->add(
710  XML_allowcomments,
711  pSdrGrafObj->isSignatureLineCanAddComment() ? "t" : "f");
712 
713  m_pSerializer->singleElementNS(
714  XML_o, XML_signatureline,
715  pAttrListSignatureLine);
716 
717  // Get signature line graphic
718  const uno::Reference<graphic::XGraphic>& xGraphic
719  = pSdrGrafObj->getSignatureLineUnsignedGraphic();
720  Graphic aGraphic(xGraphic);
721  OUString aImageId = m_pTextExport->GetDrawingML().WriteImage(aGraphic, false);
722  pAttrList->add(FSNS(XML_r, XML_id), aImageId);
723  imageData = true;
724  }
725  else if (rProps.GetOpt(ESCHER_Prop_fillBlip, aStruct) && m_pTextExport)
726  {
727  SvMemoryStream aStream;
728  // The first bytes are WW8-specific, we're only interested in the PNG
729  int nHeaderSize = 25;
730  aStream.WriteBytes(aStruct.nProp.data() + nHeaderSize,
731  aStruct.nProp.size() - nHeaderSize);
732  aStream.Seek(0);
733  Graphic aGraphic;
734  GraphicConverter::Import(aStream, aGraphic);
735  OUString aImageId = m_pTextExport->GetDrawingML().WriteImage(aGraphic, false);
736  pAttrList->add(FSNS(XML_r, XML_id), aImageId);
737  imageData = true;
738  }
739 
740  if (rProps.GetOpt(ESCHER_Prop_fNoFillHitTest, nValue))
741  impl_AddBool(pAttrList.get(), FSNS(XML_o, XML_detectmouseclick), nValue != 0);
742 
743  if (imageData)
744  m_pSerializer->singleElementNS( XML_v, XML_imagedata, pAttrList );
745  else
746  {
747  if ( rProps.GetOpt( ESCHER_Prop_fillType, nValue ) )
748  {
749  const char *pFillType = nullptr;
750  switch ( nValue )
751  {
752  case ESCHER_FillSolid: pFillType = "solid"; break;
753  // TODO case ESCHER_FillPattern: pFillType = ""; break;
754  case ESCHER_FillTexture: pFillType = "tile"; break;
755  // TODO case ESCHER_FillPicture: pFillType = ""; break;
756  // TODO case ESCHER_FillShade: pFillType = ""; break;
757  // TODO case ESCHER_FillShadeCenter: pFillType = ""; break;
758  // TODO case ESCHER_FillShadeShape: pFillType = ""; break;
759  // TODO case ESCHER_FillShadeScale: pFillType = ""; break;
760  // TODO case ESCHER_FillShadeTitle: pFillType = ""; break;
761  // TODO case ESCHER_FillBackground: pFillType = ""; break;
762  default:
763  SAL_INFO("oox.vml", "Unhandled fill type: " << nValue);
764  break;
765  }
766  if ( pFillType )
767  pAttrList->add( XML_type, pFillType );
768  }
769  else if (!rProps.GetOpt(ESCHER_Prop_fillColor, nValue))
770  pAttrList->add( XML_on, "false" );
771 
772  if ( rProps.GetOpt( ESCHER_Prop_fillColor, nValue ) )
773  impl_AddColor( m_pShapeAttrList.get(), XML_fillcolor, nValue );
774 
775  if ( rProps.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
776  impl_AddColor( pAttrList.get(), XML_color2, nValue );
777 
778 
779  if (rProps.GetOpt(ESCHER_Prop_fillOpacity, nValue))
780  // Partly undo the transformation at the end of EscherPropertyContainer::CreateFillProperties(): VML opacity is 0..1.
781  pAttrList->add(XML_opacity, OString::number(double((nValue * 100) >> 16) / 100));
782  m_pSerializer->singleElementNS( XML_v, XML_fill, pAttrList );
783 
784  }
785  }
786  bAlreadyWritten[ ESCHER_Prop_fillType ] = true;
787  bAlreadyWritten[ ESCHER_Prop_fillColor ] = true;
788  bAlreadyWritten[ ESCHER_Prop_fillBackColor ] = true;
789  bAlreadyWritten[ ESCHER_Prop_fillBlip ] = true;
790  bAlreadyWritten[ ESCHER_Prop_fNoFillHitTest ] = true;
791  bAlreadyWritten[ ESCHER_Prop_fillOpacity ] = true;
792  break;
793 
794  case ESCHER_Prop_lineColor: // 448
795  case ESCHER_Prop_lineWidth: // 459
796  case ESCHER_Prop_lineDashing: // 462
797  case ESCHER_Prop_lineStartArrowhead: // 464
798  case ESCHER_Prop_lineEndArrowhead: // 465
801  case ESCHER_Prop_lineEndArrowWidth: // 468
802  case ESCHER_Prop_lineEndArrowLength: // 469
803  case ESCHER_Prop_lineJoinStyle: // 470
804  case ESCHER_Prop_lineEndCapStyle: // 471
805  {
806  sal_uInt32 nValue;
807  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
808 
809  if ( rProps.GetOpt( ESCHER_Prop_lineColor, nValue ) )
810  impl_AddColor( pAttrList.get(), XML_color, nValue );
811 
812  if ( rProps.GetOpt( ESCHER_Prop_lineWidth, nValue ) )
813  impl_AddInt( pAttrList.get(), XML_weight, nValue );
814 
815  if ( rProps.GetOpt( ESCHER_Prop_lineDashing, nValue ) )
816  {
817  const char *pDashStyle = nullptr;
818  switch ( nValue )
819  {
820  case ESCHER_LineSolid: pDashStyle = "solid"; break;
821  case ESCHER_LineDashSys: pDashStyle = "shortdash"; break;
822  case ESCHER_LineDotSys: pDashStyle = "shortdot"; break;
823  case ESCHER_LineDashDotSys: pDashStyle = "shortdashdot"; break;
824  case ESCHER_LineDashDotDotSys: pDashStyle = "shortdashdotdot"; break;
825  case ESCHER_LineDotGEL: pDashStyle = "dot"; break;
826  case ESCHER_LineDashGEL: pDashStyle = "dash"; break;
827  case ESCHER_LineLongDashGEL: pDashStyle = "longdash"; break;
828  case ESCHER_LineDashDotGEL: pDashStyle = "dashdot"; break;
829  case ESCHER_LineLongDashDotGEL: pDashStyle = "longdashdot"; break;
830  case ESCHER_LineLongDashDotDotGEL: pDashStyle = "longdashdotdot"; break;
831  }
832  if ( pDashStyle )
833  pAttrList->add( XML_dashstyle, pDashStyle );
834  }
835 
836  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowhead, nValue ) )
837  impl_AddArrowHead( pAttrList.get(), XML_startarrow, nValue );
838 
839  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowhead, nValue ) )
840  impl_AddArrowHead( pAttrList.get(), XML_endarrow, nValue );
841 
842  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowWidth, nValue ) )
843  impl_AddArrowWidth( pAttrList.get(), XML_startarrowwidth, nValue );
844 
845  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowLength, nValue ) )
846  impl_AddArrowLength( pAttrList.get(), XML_startarrowlength, nValue );
847 
848  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowWidth, nValue ) )
849  impl_AddArrowWidth( pAttrList.get(), XML_endarrowwidth, nValue );
850 
851  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowLength, nValue ) )
852  impl_AddArrowLength( pAttrList.get(), XML_endarrowlength, nValue );
853 
854  if ( rProps.GetOpt( ESCHER_Prop_lineJoinStyle, nValue ) )
855  {
856  const char *pJoinStyle = nullptr;
857  switch ( nValue )
858  {
859  case ESCHER_LineJoinBevel: pJoinStyle = "bevel"; break;
860  case ESCHER_LineJoinMiter: pJoinStyle = "miter"; break;
861  case ESCHER_LineJoinRound: pJoinStyle = "round"; break;
862  }
863  if ( pJoinStyle )
864  pAttrList->add( XML_joinstyle, pJoinStyle );
865  }
866 
867  if ( rProps.GetOpt( ESCHER_Prop_lineEndCapStyle, nValue ) )
868  {
869  const char *pEndCap = nullptr;
870  switch ( nValue )
871  {
872  case ESCHER_LineEndCapRound: pEndCap = "round"; break;
873  case ESCHER_LineEndCapSquare: pEndCap = "square"; break;
874  case ESCHER_LineEndCapFlat: pEndCap = "flat"; break;
875  }
876  if ( pEndCap )
877  pAttrList->add( XML_endcap, pEndCap );
878  }
879 
880  m_pSerializer->singleElementNS( XML_v, XML_stroke, pAttrList );
881  }
882  bAlreadyWritten[ ESCHER_Prop_lineColor ] = true;
883  bAlreadyWritten[ ESCHER_Prop_lineWidth ] = true;
884  bAlreadyWritten[ ESCHER_Prop_lineDashing ] = true;
885  bAlreadyWritten[ ESCHER_Prop_lineStartArrowhead ] = true;
886  bAlreadyWritten[ ESCHER_Prop_lineEndArrowhead ] = true;
887  bAlreadyWritten[ ESCHER_Prop_lineStartArrowWidth ] = true;
888  bAlreadyWritten[ ESCHER_Prop_lineStartArrowLength ] = true;
889  bAlreadyWritten[ ESCHER_Prop_lineEndArrowWidth ] = true;
890  bAlreadyWritten[ ESCHER_Prop_lineEndArrowLength ] = true;
891  bAlreadyWritten[ ESCHER_Prop_lineJoinStyle ] = true;
892  bAlreadyWritten[ ESCHER_Prop_lineEndCapStyle ] = true;
893  break;
894 
895  case ESCHER_Prop_fHidden:
896  if ( !opt.nPropValue )
897  m_ShapeStyle.append( ";visibility:hidden" );
898  break;
901  {
902  sal_uInt32 nValue = 0;
903  bool bShadow = false;
904  bool bObscured = false;
905  if ( rProps.GetOpt( ESCHER_Prop_fshadowObscured, nValue ) )
906  {
907  bShadow = (( nValue & 0x20002 ) == 0x20002 );
908  bObscured = (( nValue & 0x10001 ) == 0x10001 );
909  }
910  if ( bShadow )
911  {
912  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
913  impl_AddBool( pAttrList.get(), XML_on, bShadow );
914  impl_AddBool( pAttrList.get(), XML_obscured, bObscured );
915 
916  if ( rProps.GetOpt( ESCHER_Prop_shadowColor, nValue ) )
917  impl_AddColor( pAttrList.get(), XML_color, nValue );
918 
919  m_pSerializer->singleElementNS( XML_v, XML_shadow, pAttrList );
920  bAlreadyWritten[ ESCHER_Prop_fshadowObscured ] = true;
921  bAlreadyWritten[ ESCHER_Prop_shadowColor ] = true;
922  }
923  }
924  break;
927  {
928  EscherPropSortStruct aUnicode;
929  if (rProps.GetOpt(ESCHER_Prop_gtextUNICODE, aUnicode))
930  {
931  SvMemoryStream aStream;
932 
933  if(!opt.nProp.empty())
934  {
935  aStream.WriteBytes(opt.nProp.data(), opt.nProp.size());
936  }
937 
938  aStream.Seek(0);
939  OUString aTextPathString = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
940  aStream.Seek(0);
941 
942  m_pSerializer->singleElementNS(XML_v, XML_path, XML_textpathok, "t");
943 
944  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
945  pAttrList->add(XML_on, "t");
946  pAttrList->add(XML_fitshape, "t");
947  pAttrList->add(XML_string, aTextPathString);
948  EscherPropSortStruct aFont;
949  OUString aStyle;
950  if (rProps.GetOpt(ESCHER_Prop_gtextFont, aFont))
951  {
952  aStream.WriteBytes(aFont.nProp.data(), aFont.nProp.size());
953  aStream.Seek(0);
954  OUString aTextPathFont = SvxMSDffManager::MSDFFReadZString(aStream, aFont.nProp.size(), true);
955  aStyle += "font-family:\"" + aTextPathFont + "\"";
956  }
957  sal_uInt32 nSize;
958  if (rProps.GetOpt(ESCHER_Prop_gtextSize, nSize))
959  {
960  float nSizeF = static_cast<sal_Int32>(nSize) / 65536.0;
961  OUString aSize = OUString::number(nSizeF);
962  aStyle += ";font-size:" + aSize + "pt";
963  }
965  pAttrList->add(XML_trim, "t");
966 
967  if (!aStyle.isEmpty())
968  pAttrList->add(XML_style, aStyle);
969  m_pSerializer->singleElementNS(XML_v, XML_textpath, pAttrList);
970  }
971 
972  bAlreadyWritten[ESCHER_Prop_gtextUNICODE] = true;
973  bAlreadyWritten[ESCHER_Prop_gtextFont] = true;
974  }
975  break;
977  {
978  // The higher half of the variable contains the angle.
979  m_ShapeStyle.append(";rotation:" + OString::number(double(opt.nPropValue >> 16)));
980  bAlreadyWritten[ESCHER_Prop_Rotation] = true;
981  }
982  break;
984  {
985  // See DffPropertyReader::ApplyLineAttributes().
986  impl_AddBool( m_pShapeAttrList.get(), XML_stroked, (opt.nPropValue & 8) != 0 );
987  bAlreadyWritten[ESCHER_Prop_fNoLineDrawDash] = true;
988  }
989  break;
990  case ESCHER_Prop_wzName:
991  {
992  SvMemoryStream aStream;
993 
994  if(!opt.nProp.empty())
995  {
996  aStream.WriteBytes(opt.nProp.data(), opt.nProp.size());
997  }
998 
999  aStream.Seek(0);
1000  OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
1001  aStream.Seek(0);
1003  m_pShapeAttrList->add(XML_ID, idStr);
1004 
1005  bAlreadyWritten[ESCHER_Prop_wzName] = true;
1006  }
1007  break;
1008  default:
1009 #if OSL_DEBUG_LEVEL > 0
1010  const size_t opt_nProp_size(opt.nProp.size());
1011  const sal_uInt8 opt_nProp_empty(0);
1012  fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %" SAL_PRIuUINT32 ", data: [%zu, %p]\n",
1013  nId,
1014  opt.nPropValue,
1015  opt_nProp_size,
1016  0 == opt_nProp_size ? &opt_nProp_empty : opt.nProp.data());
1017  if ( opt.nProp.size() )
1018  {
1019  const sal_uInt8 *pIt = opt.nProp.data();
1020  fprintf( stderr, " ( " );
1021  for ( int nCount = opt.nProp.size(); nCount; --nCount )
1022  {
1023  fprintf( stderr, "%02x ", *pIt );
1024  ++pIt;
1025  }
1026  fprintf( stderr, ")\n" );
1027  }
1028 #endif
1029  break;
1030  }
1031  }
1032 
1034 }
1035 
1036 OString VMLExport::ShapeIdString( sal_uInt32 nId )
1037 {
1039  return m_sShapeIDPrefix + OString::number( nId );
1040  else
1041  return "shape_" + OString::number( nId );
1042 }
1043 
1045 {
1046  if (m_nShapeFlags & (ShapeFlag::FlipH | ShapeFlag::FlipV))
1047  {
1048  m_ShapeStyle.append( ";flip:" );
1049 
1050  if (m_nShapeFlags & ShapeFlag::FlipH)
1051  m_ShapeStyle.append( "x" );
1052 
1053  if (m_nShapeFlags & ShapeFlag::FlipV)
1054  m_ShapeStyle.append( "y" );
1055  }
1056 }
1057 
1059 {
1060  // style
1061  if (!m_ShapeStyle.isEmpty())
1062  m_ShapeStyle.append( ";" );
1063 
1064  m_ShapeStyle.append( "position:absolute" );
1065 
1066  AddFlipXY();
1067 
1068  // the actual dimensions
1069  OString aLeft, aTop, aRight, aBottom;
1070 
1071  if ( mnGroupLevel == 1 )
1072  {
1073  const OString aPt( "pt" );
1074  aLeft = OString::number( double( rRectangle.Left() ) / 20 ) + aPt;
1075  aTop = OString::number( double( rRectangle.Top() ) / 20 ) + aPt;
1076  aRight = OString::number( double( rRectangle.Right() ) / 20 ) + aPt;
1077  aBottom = OString::number( double( rRectangle.Bottom() ) / 20 ) + aPt;
1078  }
1079  else
1080  {
1081  aLeft = OString::number( rRectangle.Left() );
1082  aTop = OString::number( rRectangle.Top() );
1083  aRight = OString::number( rRectangle.Right() );
1084  aBottom = OString::number( rRectangle.Bottom() );
1085  }
1086 
1087  m_pShapeAttrList->add( XML_from, aLeft + "," + aTop );
1088 
1089  m_pShapeAttrList->add( XML_to, aRight + "," + aBottom );
1090 }
1091 
1092 void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const tools::Rectangle& rRectangle, bool rbAbsolutePos)
1093 {
1094  if ( !rBuffer.isEmpty() )
1095  rBuffer.append( ";" );
1096 
1097  if (rbAbsolutePos && !m_bInline)
1098  {
1099  rBuffer.append( "position:absolute;" );
1100  }
1101 
1102  if(m_bInline)
1103  {
1104  rBuffer.append( "width:" + OString::number( double( rRectangle.Right() - rRectangle.Left() ) / 20 ) +
1105  "pt;height:" + OString::number( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 ) +
1106  "pt" );
1107  }
1108  else if ( mnGroupLevel == 1 )
1109  {
1110  rBuffer.append( "margin-left:" + OString::number( double( rRectangle.Left() ) / 20 ) +
1111  "pt;margin-top:" + OString::number( double( rRectangle.Top() ) / 20 ) +
1112  "pt;width:" + OString::number( double( rRectangle.Right() - rRectangle.Left() ) / 20 ) +
1113  "pt;height:" + OString::number( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 ) +
1114  "pt" );
1115  }
1116  else
1117  {
1118  rBuffer.append( "left:" + OString::number( rRectangle.Left() ) +
1119  ";top:" + OString::number( rRectangle.Top() ) +
1120  ";width:" + OString::number( rRectangle.Right() - rRectangle.Left() ) +
1121  ";height:" + OString::number( rRectangle.Bottom() - rRectangle.Top() ) );
1122  }
1123 
1124  AddFlipXY();
1125 }
1126 
1127 void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const OString& rValue )
1128 {
1129  m_pShapeAttrList->add( nAttribute, rValue );
1130 }
1131 
1132 static std::vector<OString> lcl_getShapeTypes()
1133 {
1134  std::vector<OString> aRet;
1135 
1136  OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/vml-shape-types");
1137  rtl::Bootstrap::expandMacros(aPath);
1138  SvFileStream aStream(aPath, StreamMode::READ);
1139  if (aStream.GetError() != ERRCODE_NONE)
1140  SAL_WARN("oox", "failed to open vml-shape-types");
1141  OStringBuffer aLine;
1142  bool bNotDone = aStream.ReadLine(aLine);
1143  while (bNotDone)
1144  {
1145  // Filter out comments.
1146  if (!o3tl::starts_with(aLine, "/"))
1147  aRet.push_back(OString(aLine));
1148  bNotDone = aStream.ReadLine(aLine);
1149  }
1150  return aRet;
1151 }
1152 
1153 static bool lcl_isTextBox(const SdrObject* pSdrObject)
1154 {
1155  uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY);
1156  if (xPropertySet.is())
1157  {
1158  uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
1159  return xPropertySetInfo->hasPropertyByName("TextBox") && xPropertySet->getPropertyValue("TextBox").get<bool>();
1160  }
1161  return false;
1162 }
1163 
1164 static OUString lcl_getAnchorIdFromGrabBag(const SdrObject* pSdrObject)
1165 {
1166  OUString aResult;
1167 
1168  uno::Reference<beans::XPropertySet> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY);
1169  if (xShape->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
1170  {
1171  comphelper::SequenceAsHashMap aInteropGrabBag(xShape->getPropertyValue("InteropGrabBag"));
1172  if (aInteropGrabBag.find("AnchorId") != aInteropGrabBag.end())
1173  aInteropGrabBag["AnchorId"] >>= aResult;
1174  }
1175 
1176  return aResult;
1177 }
1178 
1180 {
1182  return EscherEx::GenerateShapeId();
1183  else
1184  return m_nShapeIDCounter++;
1185 }
1186 
1188  std::string_view sShapeID, const bool bIsPictureFrame )
1189 {
1190  OString sShapeType;
1191  if ( !bIsPictureFrame )
1192  // We don't have a shape definition for host control in presetShapeDefinitions.xml
1193  // So use a definition copied from DOCX file created with MSO
1194  sShapeType = OString::Concat("<v:shapetype id=\"_x0000_t") + sShapeID +
1195  "\" coordsize=\"21600,21600\" o:spt=\"" + sShapeID +
1196  "\" path=\"m,l,21600l21600,21600l21600,xe\">\n"
1197  "<v:stroke joinstyle=\"miter\"/>\n"
1198  "<v:path shadowok=\"f\" o:extrusionok=\"f\" strokeok=\"f\" fillok=\"f\" o:connecttype=\"rect\"/>\n"
1199  "<o:lock v:ext=\"edit\" shapetype=\"t\"/>\n"
1200  "</v:shapetype>";
1201  else
1202  // We don't have a shape definition for picture frame in presetShapeDefinitions.xml
1203  // So use a definition copied from DOCX file created with MSO
1204  sShapeType = OString::Concat("<v:shapetype id=\"_x0000_t") + sShapeID +
1205  "\" coordsize=\"21600,21600\" o:spt=\"" + sShapeID +
1206  "\" o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\n"
1207  "<v:stroke joinstyle=\"miter\"/>\n"
1208  "<v:formulas>\n"
1209  "<v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\n"
1210  "<v:f eqn=\"sum @0 1 0\"/>\n"
1211  "<v:f eqn=\"sum 0 0 @1\"/>\n"
1212  "<v:f eqn=\"prod @2 1 2\"/>\n"
1213  "<v:f eqn=\"prod @3 21600 pixelWidth\"/>\n"
1214  "<v:f eqn=\"prod @3 21600 pixelHeight\"/>\n"
1215  "<v:f eqn=\"sum @0 0 1\"/>\n"
1216  "<v:f eqn=\"prod @6 1 2\"/>\n"
1217  "<v:f eqn=\"prod @7 21600 pixelWidth\"/>\n"
1218  "<v:f eqn=\"sum @8 21600 0\"/>\n"
1219  "<v:f eqn=\"prod @7 21600 pixelHeight\"/>\n"
1220  "<v:f eqn=\"sum @10 21600 0\"/>\n"
1221  "</v:formulas>\n"
1222  "<v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n"
1223  "<o:lock v:ext=\"edit\" aspectratio=\"t\"/>\n"
1224  "</v:shapetype>";
1225  return sShapeType;
1226 }
1227 
1229 {
1231  return -1;
1232 
1233  // some of the shapes have their own name ;-)
1234  sal_Int32 nShapeElement = -1;
1235  bool bReferToShapeType = false;
1236  switch ( m_nShapeType )
1237  {
1238  case ESCHER_ShpInst_NotPrimitive: nShapeElement = XML_shape; break;
1239  case ESCHER_ShpInst_Rectangle: nShapeElement = XML_rect; break;
1240  case ESCHER_ShpInst_RoundRectangle: nShapeElement = XML_roundrect; break;
1241  case ESCHER_ShpInst_Ellipse: nShapeElement = XML_oval; break;
1242  case ESCHER_ShpInst_Arc: nShapeElement = XML_arc; break;
1243  case ESCHER_ShpInst_Line: nShapeElement = XML_line; break;
1245  {
1246  bReferToShapeType = true;
1247  nShapeElement = XML_shape;
1249  {
1250  m_pSerializer->write(GetVMLShapeTypeDefinition(OString::number(m_nShapeType), false));
1252  }
1253  break;
1254  }
1256  {
1257  bReferToShapeType = true;
1258  nShapeElement = XML_shape;
1260  {
1261  m_pSerializer->write(GetVMLShapeTypeDefinition(OString::number(m_nShapeType), true));
1263  }
1264  break;
1265  }
1266  default:
1268  {
1269  nShapeElement = XML_shape;
1270 
1271  // a predefined shape?
1272  static std::vector<OString> aShapeTypes = lcl_getShapeTypes();
1273  SAL_WARN_IF(m_nShapeType >= aShapeTypes.size(), "oox.vml", "Unknown shape type!");
1274  if (m_nShapeType < aShapeTypes.size() && aShapeTypes[m_nShapeType] != "NULL")
1275  {
1276  bReferToShapeType = true;
1278  {
1279  m_pSerializer->write(aShapeTypes[m_nShapeType]);
1281  }
1282  }
1283  else
1284  {
1285  // rectangle is probably the best fallback...
1286  nShapeElement = XML_rect;
1287  }
1288  }
1289  break;
1290  }
1291 
1292  // anchoring
1293  switch (m_eHOri)
1294  {
1295  case text::HoriOrientation::LEFT:
1296  m_ShapeStyle.append(";mso-position-horizontal:left");
1297  break;
1298  case text::HoriOrientation::CENTER:
1299  m_ShapeStyle.append(";mso-position-horizontal:center");
1300  break;
1301  case text::HoriOrientation::RIGHT:
1302  m_ShapeStyle.append(";mso-position-horizontal:right");
1303  break;
1304  case text::HoriOrientation::INSIDE:
1305  m_ShapeStyle.append(";mso-position-horizontal:inside");
1306  break;
1307  case text::HoriOrientation::OUTSIDE:
1308  m_ShapeStyle.append(";mso-position-horizontal:outside");
1309  break;
1310  default:
1311  case text::HoriOrientation::NONE:
1312  break;
1313  }
1314  switch (m_eHRel)
1315  {
1316  case text::RelOrientation::PAGE_PRINT_AREA:
1317  m_ShapeStyle.append(";mso-position-horizontal-relative:margin");
1318  break;
1319  case text::RelOrientation::PAGE_FRAME:
1320  case text::RelOrientation::PAGE_LEFT:
1321  case text::RelOrientation::PAGE_RIGHT:
1322  m_ShapeStyle.append(";mso-position-horizontal-relative:page");
1323  break;
1324  case text::RelOrientation::CHAR:
1325  m_ShapeStyle.append(";mso-position-horizontal-relative:char");
1326  break;
1327  default:
1328  break;
1329  }
1330 
1331  switch (m_eVOri)
1332  {
1333  case text::VertOrientation::TOP:
1334  case text::VertOrientation::LINE_TOP:
1335  case text::VertOrientation::CHAR_TOP:
1336  m_ShapeStyle.append(";mso-position-vertical:top");
1337  break;
1338  case text::VertOrientation::CENTER:
1339  case text::VertOrientation::LINE_CENTER:
1340  m_ShapeStyle.append(";mso-position-vertical:center");
1341  break;
1342  case text::VertOrientation::BOTTOM:
1343  case text::VertOrientation::LINE_BOTTOM:
1344  case text::VertOrientation::CHAR_BOTTOM:
1345  m_ShapeStyle.append(";mso-position-vertical:bottom");
1346  break;
1347  default:
1348  case text::VertOrientation::NONE:
1349  break;
1350  }
1351  switch (m_eVRel)
1352  {
1353  case text::RelOrientation::PAGE_PRINT_AREA:
1354  m_ShapeStyle.append(";mso-position-vertical-relative:margin");
1355  break;
1356  case text::RelOrientation::PAGE_FRAME:
1357  m_ShapeStyle.append(";mso-position-vertical-relative:page");
1358  break;
1359  default:
1360  break;
1361  }
1362 
1363  if (!m_pSdrObject->getHyperlink().isEmpty())
1364  m_pShapeAttrList->add(
1365  XML_href, m_pSdrObject->getHyperlink());
1366 
1367  m_pShapeAttrList->addNS(XML_o, XML_allowincell, m_IsFollowingTextFlow ? "t" : "f");
1368 
1369  // add style
1370  m_pShapeAttrList->add( XML_style, m_ShapeStyle.makeStringAndClear() );
1371 
1372  OUString sAnchorId = lcl_getAnchorIdFromGrabBag(m_pSdrObject);
1373  if (!sAnchorId.isEmpty())
1374  m_pShapeAttrList->addNS(XML_wp14, XML_anchorId, sAnchorId);
1375 
1376  if ( nShapeElement >= 0 && !m_pShapeAttrList->hasAttribute( XML_type ) && bReferToShapeType )
1377  {
1378  OString sType;
1380  sType = "#";
1381  m_pShapeAttrList->add( XML_type, sType +
1382  "_x0000_t" + OString::number( m_nShapeType ) );
1383  }
1384 
1385  // start of the shape
1386  m_pSerializer->startElementNS( XML_v, nShapeElement, m_pShapeAttrList );
1387 
1388  OString const textboxStyle(m_TextboxStyle.makeStringAndClear());
1389 
1390  // now check if we have some editeng text (not associated textbox) and we have a text exporter registered
1391  const SdrTextObj* pTxtObj = dynamic_cast<const SdrTextObj*>( m_pSdrObject );
1393  {
1395 
1396  /*
1397  #i13885#
1398  When the object is actively being edited, that text is not set into
1399  the objects normal text object, but lives in a separate object.
1400  */
1401  if (pTxtObj->IsTextEditActive())
1402  {
1403  pParaObj = pTxtObj->CreateEditOutlinerParaObject();
1404  }
1405  else if (pTxtObj->GetOutlinerParaObject())
1406  {
1407  pParaObj = *pTxtObj->GetOutlinerParaObject();
1408  }
1409 
1410  if( pParaObj )
1411  {
1412  rtl::Reference<sax_fastparser::FastAttributeList> pTextboxAttrList = FastSerializerHelper::createAttrList();
1413  if (!textboxStyle.isEmpty())
1414  {
1415  pTextboxAttrList->add(XML_style, textboxStyle);
1416  }
1417 
1418  // this is reached only in case some text is attached to the shape
1419  m_pSerializer->startElementNS(XML_v, XML_textbox, pTextboxAttrList);
1420  m_pTextExport->WriteOutliner(*pParaObj);
1421  m_pSerializer->endElementNS(XML_v, XML_textbox);
1422  }
1423  }
1424 
1425  return nShapeElement;
1426 }
1427 
1428 void VMLExport::EndShape( sal_Int32 nShapeElement )
1429 {
1430  if ( nShapeElement < 0 )
1431  return;
1432 
1434  {
1435  uno::Reference<drawing::XShape> xShape {const_cast<SdrObject*>(m_pSdrObject)->getUnoShape(), uno::UNO_QUERY};
1436  uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
1437  uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
1438  bool bBottomToTop = false;
1439  if (xPropertySetInfo->hasPropertyByName("CustomShapeGeometry"))
1440  {
1441  // In this case a DrawingML DOCX was imported.
1442  comphelper::SequenceAsHashMap aCustomShapeProperties(
1443  xPropertySet->getPropertyValue("CustomShapeGeometry"));
1444  if (aCustomShapeProperties.find("TextPreRotateAngle") != aCustomShapeProperties.end())
1445  {
1446  sal_Int32 nTextRotateAngle = aCustomShapeProperties["TextPreRotateAngle"].get<sal_Int32>();
1447  if (nTextRotateAngle == -270)
1448  bBottomToTop = true;
1449  }
1450  }
1451  else
1452  {
1453  // In this case a pure VML DOCX was imported, so there is no CustomShapeGeometry.
1454  auto pTextExport = m_pTextExport->GetDrawingML().GetTextExport();
1455  // FIXME: somewhy pTextExport is always nullptr, we should find its reason
1456  if (pTextExport)
1457  {
1458  auto xTextFrame = pTextExport->GetUnoTextFrame(xShape);
1459  uno::Reference<beans::XPropertySet> xPropSet(xTextFrame, uno::UNO_QUERY);
1460  auto aAny = xPropSet->getPropertyValue("WritingMode");
1461  sal_Int16 nWritingMode;
1462  if (aAny >>= nWritingMode)
1463  {
1464  switch (nWritingMode)
1465  {
1466  case text::WritingMode2::BT_LR:
1467  bBottomToTop = true;
1468  break;
1469  default:
1470  break;
1471  }
1472  }
1473  }
1474  }
1475  rtl::Reference<sax_fastparser::FastAttributeList> pTextboxAttrList = FastSerializerHelper::createAttrList();
1476  if (bBottomToTop)
1477  pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
1478  m_pSerializer->startElementNS(XML_v, XML_textbox, pTextboxAttrList);
1479 
1480  m_pTextExport->WriteVMLTextBox(uno::Reference<drawing::XShape>(xPropertySet, uno::UNO_QUERY_THROW));
1481 
1482  m_pSerializer->endElementNS(XML_v, XML_textbox);
1483  }
1484 
1485  if (m_pWrapAttrList)
1486  {
1487  m_pSerializer->singleElementNS(XML_w10, XML_wrap, m_pWrapAttrList);
1488  }
1489 
1490  // end of the shape
1491  m_pSerializer->endElementNS( XML_v, nShapeElement );
1492 }
1493 
1494 OString const & VMLExport::AddSdrObject( const SdrObject& rObj,
1495  bool const bIsFollowingTextFlow,
1496  sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel,
1497  FastAttributeList* pWrapAttrList,
1498  const bool bOOxmlExport )
1499 {
1500  m_pSdrObject = &rObj;
1501  m_eHOri = eHOri;
1502  m_eVOri = eVOri;
1503  m_eHRel = eHRel;
1504  m_eVRel = eVRel;
1505  m_pWrapAttrList = pWrapAttrList;
1506  m_bInline = false;
1507  m_IsFollowingTextFlow = bIsFollowingTextFlow;
1508  EscherEx::AddSdrObject(rObj, bOOxmlExport);
1509  return m_sShapeId;
1510 }
1511 
1512 OString const & VMLExport::AddInlineSdrObject( const SdrObject& rObj, const bool bOOxmlExport )
1513 {
1514  m_pSdrObject = &rObj;
1515  m_eHOri = -1;
1516  m_eVOri = -1;
1517  m_eHRel = -1;
1518  m_eVRel = -1;
1519  m_pWrapAttrList.clear();
1520  m_bInline = true;
1521  m_IsFollowingTextFlow = true;
1522  EscherEx::AddSdrObject(rObj, bOOxmlExport);
1523  return m_sShapeId;
1524 }
1525 
1526 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void AddShapeAttribute(sal_Int32 nAttribute, const OString &sValue)
Add an attribute to the generated element.
Definition: vmlexport.cxx:1127
ESCHER_LineMediumLenArrow
rtl::Reference<::sax_fastparser::FastAttributeList > m_pShapeAttrList
Fill the shape attributes as they come.
Definition: vmlexport.hxx:91
ESCHER_LineEndCapSquare
#define ESCHER_ShpInst_Nil
virtual void LeaveGroup() override
Definition: vmlexport.cxx:179
virtual void AddSdrObjectVMLObject(const SdrObject &rObj) override
Definition: vmlexport.cxx:366
ESCHER_WrapSquare
sal_uInt32 m_nShapeType
Remember the shape type.
Definition: vmlexport.hxx:94
ESCHER_AnchorMiddleCentered
OString const & AddInlineSdrObject(const SdrObject &rObj, const bool bOOxmlExport)
Definition: vmlexport.cxx:1512
const SdrObject * m_pSdrObject
The object we're exporting.
Definition: vmlexport.hxx:88
void AddLineDimensions(const tools::Rectangle &rRectangle)
Add starting and ending point of a line to the m_pShapeAttrList.
Definition: vmlexport.cxx:1058
#define ESCHER_Prop_geoRight
#define ESCHER_Prop_geoLeft
bool m_bOverrideShapeIdGeneration
There is a shapeid generation mechanism in EscherEx, but it does not seem to work so override the exi...
Definition: vmlexport.hxx:120
msopathCurveTo
ESCHER_WrapTopBottom
#define ESCHER_Prop_fshadowObscured
ESCHER_AnchorBottomCenteredBaseline
ESCHER_LineNarrowArrow
msopathEnd
void OverrideShapeIDGen(bool bOverrideShapeIdGeneration, const OString &sShapeIDPrefix=OString())
Definition: vmlexport.cxx:214
SvStream * mpOutStrm
ESCHER_LineEndCapFlat
msopathLineTo
ESCHER_WrapThrough
constexpr tools::Long Left() const
#define ESCHER_Prop_lineEndArrowWidth
#define ESCHER_Prop_lineWidth
#define ESCHER_Prop_geoBottom
std::vector< sal_uInt8 > nProp
virtual oox::drawingml::DrawingML & GetDrawingML()=0
virtual void AddShape(sal_uInt32 nShapeType, ShapeFlag nShapeFlags, sal_uInt32 nShapeId=0) override
Definition: vmlexport.cxx:185
long Long
#define ESCHER_Prop_lineEndArrowLength
std::vector< sal_uInt16 > mRecTypes
#define ESCHER_Prop_pVertices
sal_uInt32 AddSdrObject(const SdrObject &rObj, bool ooxmlExport=false)
bool ReadLine(OStringBuffer &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
#define ESCHER_Prop_lineEndCapStyle
sal_Int16 nId
Definition: olehelper.cxx:97
#define ESCHER_ShpInst_Ellipse
sal_uInt64 Seek(sal_uInt64 nPos)
#define ESCHER_Prop_txflTextFlow
const OUString & getHyperlink() const
std::vector< bool > m_aShapeTypeWritten
Remember which shape types we had already written.
Definition: vmlexport.hxx:109
OString m_sShapeId
Remember the generated shape id.
Definition: vmlexport.hxx:106
std::shared_ptr< T > make_shared(Args &&...args)
ESCHER_WrapNone
VMLTextExport * m_pTextExport
Parent exporter, used for text callback.
Definition: vmlexport.hxx:79
ESCHER_LineArrowOvalEnd
ESCHER_LineLongDashDotDotGEL
const OUString & getSignatureLineSigningInstructions() const
static std::vector< OString > lcl_getShapeTypes()
Definition: vmlexport.cxx:1132
#define ESCHER_Prop_pSegmentInfo
ESCHER_FillTexture
bool isSignatureLineCanAddComment() const
const sal_Int32 Tag_Container
Definition: vmlexport.cxx:59
virtual sal_uInt32 GenerateShapeId()
NONE
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
tools::Long getHeight() const
virtual void OpenContainer(sal_uInt16 nEscherContainer, int nRecInstance=0) override
Definition: vmlexport.cxx:95
ESCHER_LineJoinMiter
ESCHER_LineShortArrow
static void impl_AddArrowWidth(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue)
Definition: vmlexport.cxx:263
#define ESCHER_Prop_wzName
ErrCode GetError() const
#define ESCHER_Prop_AnchorText
rtl::Reference< sax_fastparser::FastAttributeList > m_pWrapAttrList
Definition: vmlexport.hxx:83
virtual sal_uInt32 GenerateShapeId() override
Override shape ID generation when m_bOverrideShapeIdGeneration is set to true.
Definition: vmlexport.cxx:1179
ESCHER_LineJoinBevel
#define ESCHER_ShpInst_RoundRectangle
msopathClientEscape
int nCount
ESCHER_LineArrowDiamondEnd
virtual void CloseContainer() override
Definition: vmlexport.cxx:115
#define ESCHER_ShpInst_HostControl
ESCHER_LineDotGEL
static void impl_AddArrowHead(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue)
Definition: vmlexport.cxx:226
bool isSignatureLine() const
#define ESCHER_ShpInst_Line
ESCHER_LineLongDashGEL
bool HasTextBoxContent(sal_uInt32 nShapeType)
#define ESCHER_Prop_gtextUNICODE
ESCHER_LineNoEnd
static OUString MSDFFReadZString(SvStream &rIn, sal_uInt32 nMaxLen, bool bUniCode)
static void impl_AddArrowLength(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue)
Definition: vmlexport.cxx:246
#define ESCHER_Prop_fillOpacity
ESCHER_AnchorTopBaseline
ESCHER_LineJoinRound
#define ESCHER_Prop_fNoLineDrawDash
#define ESCHER_Prop_lineDashing
ESCHER_FillSolid
#define ESCHER_ShpInst_NotPrimitive
ShapeFlag
bool m_bUseHashMarkForType
Use '#' mark for type attribute (check Type Attribute of VML shape in OOXML documentation) ...
Definition: vmlexport.hxx:115
ESCHER_LineDashDotGEL
ESCHER_AnchorMiddle
sal_Int16 m_eHOri
Anchoring - Writer specific properties.
Definition: vmlexport.hxx:82
ESCHER_LineDashSys
ESCHER_LineDotSys
ESCHER_AnchorBottomBaseline
OptionalString sType
static bool lcl_isTextBox(const SdrObject *pSdrObject)
Definition: vmlexport.cxx:1153
#define ESCHER_Prop_WrapText
#define ESCHER_Prop_geoTop
ESCHER_LineLongArrow
#define ESCHER_Prop_fHidden
msopathClose
#define ESCHER_Prop_gtextSize
constexpr tools::Long Right() const
std::size_t WriteBytes(const void *pData, std::size_t nSize)
virtual void EndShape(sal_Int32 nShapeElement)
End the shape.
Definition: vmlexport.cxx:1428
float u
#define ESCHER_Prop_lineStartArrowhead
virtual void WriteVMLTextBox(css::uno::Reference< css::drawing::XShape > xShape)=0
Write the contents of the textbox that is associated to this shape in VML format. ...
static sal_uInt16 impl_GetUInt16(const sal_uInt8 *&pVal)
Definition: vmlexport.cxx:336
constexpr tools::Long Top() const
#define ESCHER_Prop_lineStartArrowWidth
ESCHER_LineSolid
ESCHER_txflHorzN
XML_type
#define ESCHER_Prop_lineStartArrowLength
ESCHER_AnchorTopCenteredBaseline
#define ESCHER_ShpInst_COUNT
ESCHER_LineEndCapRound
sal_uInt64 m_nShapeIDCounter
Counter for generating shape ids (used if m_bOverrideShapeIdGeneration is true)
Definition: vmlexport.hxx:126
OStringBuffer m_TextboxStyle
style for textbox
Definition: vmlexport.hxx:103
void AddFlipXY()
Add flip X and flip Y.
Definition: vmlexport.cxx:1044
std::shared_ptr< FastSerializerHelper > FSHelperPtr
static ErrCode Import(SvStream &rIStm, Graphic &rGraphic, ConvertDataFormat nFormat=ConvertDataFormat::Unknown)
#define ESCHER_Prop_lineEndArrowhead
static void impl_AddInt(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue)
Definition: vmlexport.cxx:328
ESCHER_LineDashGEL
const sal_Int32 Tag_Commit
Definition: vmlexport.cxx:60
#define ESCHER_Prop_lineJoinStyle
msopathEscape
#define ESCHER_Prop_fillBlip
bool m_bSkipwzName
It seems useless to write out an XML_ID attribute next to XML_id which defines the actual shape id...
Definition: vmlexport.hxx:112
virtual void Commit(EscherPropertyContainer &rProps, const tools::Rectangle &rRect) override
Definition: vmlexport.cxx:370
virtual sal_uInt32 EnterGroup(const OUString &rShapeName, const tools::Rectangle *pBoundRect) override
Definition: vmlexport.cxx:134
#define ESCHER_Prop_shadowColor
#define ESCHER_Prop_fillBackColor
const OUString & getSignatureLineSuggestedSignerName() const
std::vector< ISegmentProgressBarRef > aSegments
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXT_UPPERDIST(SDRATTR_MISC_FIRST+6)
virtual ~VMLExport() override
Definition: vmlexport.cxx:89
void AddRectangleDimensions(OStringBuffer &rBuffer, const tools::Rectangle &rRectangle, bool rbAbsolutePos=true)
Add position and size to the OStringBuffer.
Definition: vmlexport.cxx:1092
void add(const FastAttributeList &)
constexpr tools::Long Bottom() const
static bool IsWaterMarkShape(std::u16string_view rStr)
Definition: vmlexport.cxx:207
ESCHER_txflBtoT
#define ESCHER_Prop_fillColor
const OUString & getSignatureLineSuggestedSignerTitle() const
OUString WriteImage(const Graphic &rGraphic, bool bRelPathToMedia=false)
If bRelPathToMedia is true add "../" to image folder path while adding the image relationship.
Definition: drawingml.cxx:1292
ESCHER_txflTtoBA
ESCHER_LineLongDashDotGEL
ESCHER_LineArrowOpenEnd
#define ESCHER_SpContainer
virtual void WriteOutliner(const OutlinerParaObject &rParaObj)=0
virtual void CloseContainer()
XML_ID
ESCHER_LineMediumWidthArrow
#define ESCHER_ShpInst_PictureFrame
OStringBuffer m_ShapeStyle
Remember style, the most important shape attribute ;-)
Definition: vmlexport.hxx:100
virtual sal_Int32 StartShape()
Start the shape for which we just collected the information.
Definition: vmlexport.cxx:1228
static void impl_AddColor(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nColor)
Definition: vmlexport.cxx:288
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
#define ESCHER_ShpInst_Rectangle
unsigned char sal_uInt8
ESCHER_WrapByPoints
#define ESCHER_Prop_lineColor
#define ESCHER_Prop_fNoFillHitTest
::sax_fastparser::FSHelperPtr m_pSerializer
Fast serializer to output the data.
Definition: vmlexport.hxx:76
virtual void OpenContainer(sal_uInt16 nEscherContainer, int nRecInstance=0)
msopathMoveTo
#define SAL_INFO(area, stream)
const SfxItemSet & GetMergedItemSet() const
css::uno::Reference< css::graphic::XGraphic > const & getSignatureLineUnsignedGraphic() const
#define ESCHER_Prop_fillType
ESCHER_LineWideArrow
static OString GetVMLShapeTypeDefinition(std::string_view sShapeID, const bool bIsPictureFrame)
Definition: vmlexport.cxx:1187
DMLTextExport * GetTextExport()
The application-specific text exporter callback, if there is one.
Definition: drawingml.hxx:222
bool isSignatureLineShowSignDate() const
OString m_sShapeIDPrefix
Prefix for overridden shape id generation (used if m_bOverrideShapeIdGeneration is true) ...
Definition: vmlexport.hxx:123
Interface to be implemented by the parent exporter that knows how to handle shape text...
Definition: vmlexport.hxx:61
ESCHER_LineArrowEnd
sal_uInt32 mnGroupLevel
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
OString const & AddSdrObject(const SdrObject &rObj, bool const bIsFollowingTextFlow=false, sal_Int16 eHOri=-1, sal_Int16 eVOri=-1, sal_Int16 eHRel=-1, sal_Int16 eVRel=-1, sax_fastparser::FastAttributeList *pWrapAttrList=nullptr, const bool bOOxmlExport=false)
Export the sdr object as VML.
Definition: vmlexport.cxx:1494
const EscherProperties & GetOpts() const
ESCHER_AnchorTop
virtual css::uno::Reference< css::text::XTextFrame > GetUnoTextFrame(css::uno::Reference< css::drawing::XShape > xShape)=0
Get textbox which belongs to the shape.
#define SAL_WARN(area, stream)
ESCHER_LineArrowStealthEnd
static sal_Int32 impl_GetPointComponent(const sal_uInt8 *&pVal, sal_uInt16 nPointSize)
Definition: vmlexport.cxx:343
ESCHER_AnchorBottom
msopathInvalid
ESCHER_LineDashDotSys
#define ESCHER_ShpInst_Arc
bool GetOpt(sal_uInt16 nPropertyID, sal_uInt32 &rPropValue) const
const OUString & getSignatureLineId() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const OUString & GetEditAs() const
void SetFS(const ::sax_fastparser::FSHelperPtr &pSerializer)
Definition: vmlexport.cxx:84
static OUString lcl_getAnchorIdFromGrabBag(const SdrObject *pSdrObject)
Definition: vmlexport.cxx:1164
const OUString & GetName() const
ESCHER_LineDashDotDotSys
static void impl_AddBool(sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, bool bValue)
Definition: vmlexport.cxx:280
OString ShapeIdString(sal_uInt32 nId)
Create an OString representing the id from a numerical id.
Definition: vmlexport.cxx:1036
const OUString & getSignatureLineSuggestedSignerEmail() const
void setHeight(tools::Long n)
std::vector< EscherPropSortStruct > EscherProperties
sal_Int16 nValue
ESCHER_AnchorTopCentered
ESCHER_AnchorBottomCentered
#define ESCHER_Prop_Rotation
bool m_bDetectedRangeSegmentation false
ShapeFlag m_nShapeFlags
Remember the shape flags.
Definition: vmlexport.hxx:97
#define ESCHER_Prop_gtextFont