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