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  SAL_WARN_IF( nColor & 0xFF000000 , "oox.vml" , "TODO: this is not a RGB value!");
290 
291  if ( !pAttrList || ( nColor & 0xFF000000 ) )
292  return;
293 
294  nColor = ( ( nColor & 0xFF ) << 16 ) + ( nColor & 0xFF00 ) + ( ( nColor & 0xFF0000 ) >> 16 );
295 
296  const char *pColor = nullptr;
297  char pRgbColor[10];
298  switch ( nColor )
299  {
300  case 0x000000: pColor = "black"; break;
301  case 0xC0C0C0: pColor = "silver"; break;
302  case 0x808080: pColor = "gray"; break;
303  case 0xFFFFFF: pColor = "white"; break;
304  case 0x800000: pColor = "maroon"; break;
305  case 0xFF0000: pColor = "red"; break;
306  case 0x800080: pColor = "purple"; break;
307  case 0xFF00FF: pColor = "fuchsia"; break;
308  case 0x008000: pColor = "green"; break;
309  case 0x00FF00: pColor = "lime"; break;
310  case 0x808000: pColor = "olive"; break;
311  case 0xFFFF00: pColor = "yellow"; break;
312  case 0x000080: pColor = "navy"; break;
313  case 0x0000FF: pColor = "blue"; break;
314  case 0x008080: pColor = "teal"; break;
315  case 0x00FFFF: pColor = "aqua"; break;
316  default:
317  {
318  snprintf( pRgbColor, sizeof( pRgbColor ), "#%06x", static_cast< unsigned int >( nColor ) ); // not too handy to use OString::valueOf() here :-(
319  pColor = pRgbColor;
320  }
321  break;
322  }
323 
324  pAttrList->add( nElement, pColor );
325 }
326 
327 static void impl_AddInt( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue )
328 {
329  if ( !pAttrList )
330  return;
331 
332  pAttrList->add( nElement, OString::number( nValue ).getStr() );
333 }
334 
335 static sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal )
336 {
337  sal_uInt16 nRet = *pVal++;
338  nRet += ( *pVal++ ) << 8;
339  return nRet;
340 }
341 
342 static sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize )
343 {
344  sal_Int32 nRet = 0;
345  if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) )
346  {
347  sal_uInt16 nUnsigned = *pVal++;
348  nUnsigned += ( *pVal++ ) << 8;
349 
350  nRet = sal_Int16( nUnsigned );
351  }
352  else if ( nPointSize == 8 )
353  {
354  sal_uInt32 nUnsigned = *pVal++;
355  nUnsigned += ( *pVal++ ) << 8;
356  nUnsigned += ( *pVal++ ) << 16;
357  nUnsigned += ( *pVal++ ) << 24;
358 
359  nRet = nUnsigned;
360  }
361 
362  return nRet;
363 }
364 
366 {
367  m_pSdrObject = &rObj;
368 }
370 {
372  return;
373 
374  // postpone the output of the embedded elements so that they are written
375  // inside the shapes
376  m_pSerializer->mark(Tag_Commit);
377 
378  // dimensions
380  AddLineDimensions( rRect );
381  else
382  {
384  {
385  // Watermark need some padding to be compatible with MSO
386  tools::Long nPaddingY = 0;
387  const SfxItemSet& rSet = m_pSdrObject->GetMergedItemSet();
388  if ( const SdrMetricItem* pItem = rSet.GetItem( SDRATTR_TEXT_UPPERDIST ) )
389  nPaddingY += pItem->GetValue();
390 
391  tools::Rectangle aRect( rRect );
392  aRect.setHeight( aRect.getHeight() + nPaddingY );
394  }
395  else
397  }
398 
399  // properties
400  bool bAlreadyWritten[ 0xFFF ] = {};
401  const EscherProperties &rOpts = rProps.GetOpts();
402  for (auto const& opt : rOpts)
403  {
404  sal_uInt16 nId = ( opt.nPropId & 0x0FFF );
405 
406  if ( bAlreadyWritten[ nId ] )
407  continue;
408 
409  switch ( nId )
410  {
411  case ESCHER_Prop_WrapText: // 133
412  {
413  const char *pWrapType = nullptr;
414  switch ( opt.nPropValue )
415  {
416  case ESCHER_WrapSquare:
417  case ESCHER_WrapByPoints: pWrapType = "square"; break; // these two are equivalent according to the docu
418  case ESCHER_WrapNone: pWrapType = "none"; break;
420  case ESCHER_WrapThrough:
421  break; // last two are *undefined* in MS-ODRAW, don't exist in VML
422  }
423  if ( pWrapType )
424  {
425  m_ShapeStyle.append(";mso-wrap-style:");
426  m_ShapeStyle.append(pWrapType);
427  }
428  }
429  bAlreadyWritten[ ESCHER_Prop_WrapText ] = true;
430  break;
431 
432  case ESCHER_Prop_AnchorText: // 135
433  {
434  char const* pValue(nullptr);
435  switch (opt.nPropValue)
436  {
437  case ESCHER_AnchorTop:
438  pValue = "top";
439  break;
440  case ESCHER_AnchorMiddle:
441  pValue = "middle";
442  break;
443  case ESCHER_AnchorBottom:
444  pValue = "bottom";
445  break;
447  pValue = "top-center";
448  break;
450  pValue = "middle-center";
451  break;
453  pValue = "bottom-center";
454  break;
456  pValue = "top-baseline";
457  break;
459  pValue = "bottom-baseline";
460  break;
462  pValue = "top-center-baseline";
463  break;
465  pValue = "bottom-center-baseline";
466  break;
467  }
468  m_ShapeStyle.append(";v-text-anchor:");
469  m_ShapeStyle.append(pValue);
470  }
471  break;
472 
473  case ESCHER_Prop_txflTextFlow: // 136
474  {
475  // at least "bottom-to-top" only has an effect when it's on the v:textbox element, not on v:shape
476  assert(m_TextboxStyle.isEmpty());
477  switch (opt.nPropValue)
478  {
479  case ESCHER_txflHorzN:
480  m_TextboxStyle.append("layout-flow:horizontal");
481  break;
482  case ESCHER_txflTtoBA:
483  m_TextboxStyle.append("layout-flow:vertical");
484  break;
485  case ESCHER_txflBtoT:
486  m_TextboxStyle.append("mso-layout-flow-alt:bottom-to-top");
487  break;
488  default:
489  assert(false); // unimplemented in escher export
490  break;
491  }
492  }
493  break;
494 
495  // coordorigin
496  case ESCHER_Prop_geoLeft: // 320
497  case ESCHER_Prop_geoTop: // 321
498  {
499  sal_uInt32 nLeft = 0, nTop = 0;
500 
501  if ( nId == ESCHER_Prop_geoLeft )
502  {
503  nLeft = opt.nPropValue;
504  rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
505  }
506  else
507  {
508  nTop = opt.nPropValue;
509  rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
510  }
511  if(nTop!=0 && nLeft!=0)
512  m_pShapeAttrList->add( XML_coordorigin,
513  OString::number( nLeft ) + "," + OString::number( nTop ) );
514  }
515  bAlreadyWritten[ ESCHER_Prop_geoLeft ] = true;
516  bAlreadyWritten[ ESCHER_Prop_geoTop ] = true;
517  break;
518 
519  // coordsize
520  case ESCHER_Prop_geoRight: // 322
521  case ESCHER_Prop_geoBottom: // 323
522  {
523  sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0;
524  rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
525  rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
526 
527  if ( nId == ESCHER_Prop_geoRight )
528  {
529  nRight = opt.nPropValue;
530  rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom );
531  }
532  else
533  {
534  nBottom = opt.nPropValue;
535  rProps.GetOpt( ESCHER_Prop_geoRight, nRight );
536  }
537 
538  if(nBottom!=0 && nRight!=0 )
539  m_pShapeAttrList->add( XML_coordsize,
540  OString::number( nRight - nLeft ) + "," + OString::number( nBottom - nTop ) );
541  }
542  bAlreadyWritten[ ESCHER_Prop_geoRight ] = true;
543  bAlreadyWritten[ ESCHER_Prop_geoBottom ] = true;
544  break;
545 
546  case ESCHER_Prop_pVertices: // 325
547  case ESCHER_Prop_pSegmentInfo: // 326
548  {
549  EscherPropSortStruct aVertices;
551 
552  if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
553  rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
554  {
555  const sal_uInt8 *pVerticesIt = aVertices.nProp.data() + 6;
556  const sal_uInt8 *pSegmentIt = aSegments.nProp.data();
557  OStringBuffer aPath( 512 );
558 
559  sal_uInt16 nPointSize = aVertices.nProp[4] + ( aVertices.nProp[5] << 8 );
560 
561  // number of segments
562  sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
563  pSegmentIt += 4;
564 
565  for ( ; nSegments; --nSegments )
566  {
567  sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt );
568 
569  // The segment type is stored in the upper 3 bits
570  // and segment count is stored in the lower 13
571  // bits.
572  unsigned char nSegmentType = (nSeg & 0xE000) >> 13;
573  unsigned short nSegmentCount = nSeg & 0x03FF;
574 
575  switch (nSegmentType)
576  {
577  case msopathMoveTo:
578  {
579  sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
580  sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
581  if (nX >= 0 && nY >= 0 )
582  aPath.append( "m" + OString::number( nX ) + "," + OString::number( nY ) );
583  break;
584  }
585  case msopathClientEscape:
586  break;
587  case msopathEscape:
588  {
589  // If the segment type is msopathEscape, the lower 13 bits are
590  // divided in a 5 bit escape code and 8 bit
591  // vertex count (not segment count!)
592  unsigned char nEscapeCode = (nSegmentCount & 0x1F00) >> 8;
593  unsigned char nVertexCount = nSegmentCount & 0x00FF;
594  pVerticesIt += nVertexCount;
595 
596  switch (nEscapeCode)
597  {
598  case 0xa: // nofill
599  aPath.append( "nf" );
600  break;
601  case 0xb: // nostroke
602  aPath.append( "ns" );
603  break;
604  }
605 
606  break;
607  }
608  case msopathLineTo:
609  for (unsigned short i = 0; i < nSegmentCount; ++i)
610  {
611  sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
612  sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
613  aPath.append( "l" + OString::number( nX ) + "," + OString::number( nY ) );
614  }
615  break;
616  case msopathCurveTo:
617  for (unsigned short i = 0; i < nSegmentCount; ++i)
618  {
619  sal_Int32 nX1 = impl_GetPointComponent( pVerticesIt, nPointSize );
620  sal_Int32 nY1 = impl_GetPointComponent( pVerticesIt, nPointSize );
621  sal_Int32 nX2 = impl_GetPointComponent( pVerticesIt, nPointSize );
622  sal_Int32 nY2 = impl_GetPointComponent( pVerticesIt, nPointSize );
623  sal_Int32 nX3 = impl_GetPointComponent( pVerticesIt, nPointSize );
624  sal_Int32 nY3 = impl_GetPointComponent( pVerticesIt, nPointSize );
625  aPath.append( "c" + OString::number( nX1 ) + "," + OString::number( nY1 ) + "," +
626  OString::number( nX2 ) + "," + OString::number( nY2 ) + "," +
627  OString::number( nX3 ) + "," + OString::number( nY3 ) );
628  }
629  break;
630  case msopathClose:
631  aPath.append( "x" );
632  break;
633  case msopathEnd:
634  aPath.append( "e" );
635  break;
636  default:
637  SAL_WARN("oox", "Totally b0rked");
638  break;
639  case msopathInvalid:
640  SAL_WARN("oox", "Invalid - should never be found");
641  break;
642  }
643  }
644  OString pathString = aPath.makeStringAndClear();
645  if ( !pathString.isEmpty() && pathString != "xe" )
646  m_pShapeAttrList->add( XML_path, pathString );
647  }
648  else
649  SAL_WARN("oox.vml", "unhandled shape path, missing either pVertices or pSegmentInfo.");
650  }
651  bAlreadyWritten[ ESCHER_Prop_pVertices ] = true;
652  bAlreadyWritten[ ESCHER_Prop_pSegmentInfo ] = true;
653  break;
654 
655  case ESCHER_Prop_fillType: // 384
656  case ESCHER_Prop_fillColor: // 385
657  case ESCHER_Prop_fillBackColor: // 387
658  case ESCHER_Prop_fillBlip: // 390
659  case ESCHER_Prop_fNoFillHitTest: // 447
660  case ESCHER_Prop_fillOpacity: // 386
661  {
662  sal_uInt32 nValue;
664  = FastSerializerHelper::createAttrList();
665 
666  bool imageData = false;
667  EscherPropSortStruct aStruct;
668  const SdrGrafObj* pSdrGrafObj = dynamic_cast<const SdrGrafObj*>(m_pSdrObject);
669 
670  if (pSdrGrafObj && pSdrGrafObj->isSignatureLine() && m_pTextExport)
671  {
673  = FastSerializerHelper::createAttrList();
674  pAttrListSignatureLine->add(XML_issignatureline, "t");
675  if (!pSdrGrafObj->getSignatureLineId().isEmpty())
676  {
677  pAttrListSignatureLine->add(
678  XML_id, OUStringToOString(pSdrGrafObj->getSignatureLineId(),
679  RTL_TEXTENCODING_UTF8));
680  }
681  if (!pSdrGrafObj->getSignatureLineSuggestedSignerName().isEmpty())
682  {
683  pAttrListSignatureLine->add(
684  FSNS(XML_o, XML_suggestedsigner),
687  RTL_TEXTENCODING_UTF8));
688  }
689  if (!pSdrGrafObj->getSignatureLineSuggestedSignerTitle().isEmpty())
690  {
691  pAttrListSignatureLine->add(
692  FSNS(XML_o, XML_suggestedsigner2),
695  RTL_TEXTENCODING_UTF8));
696  }
697  if (!pSdrGrafObj->getSignatureLineSuggestedSignerEmail().isEmpty())
698  {
699  pAttrListSignatureLine->add(
700  FSNS(XML_o, XML_suggestedsigneremail),
703  RTL_TEXTENCODING_UTF8));
704  }
705  if (!pSdrGrafObj->getSignatureLineSigningInstructions().isEmpty())
706  {
707  pAttrListSignatureLine->add(XML_signinginstructionsset, "t");
708  pAttrListSignatureLine->add(
709  FSNS(XML_o, XML_signinginstructions),
712  RTL_TEXTENCODING_UTF8));
713  }
714  pAttrListSignatureLine->add(
715  XML_showsigndate,
716  pSdrGrafObj->isSignatureLineShowSignDate() ? "t" : "f");
717  pAttrListSignatureLine->add(
718  XML_allowcomments,
719  pSdrGrafObj->isSignatureLineCanAddComment() ? "t" : "f");
720 
721  m_pSerializer->singleElementNS(
722  XML_o, XML_signatureline,
723  pAttrListSignatureLine);
724 
725  // Get signature line graphic
726  const uno::Reference<graphic::XGraphic>& xGraphic
727  = pSdrGrafObj->getSignatureLineUnsignedGraphic();
728  Graphic aGraphic(xGraphic);
729 
730  BitmapChecksum nChecksum = aGraphic.GetChecksum();
731  OUString aImageId = m_pTextExport->FindRelId(nChecksum);
732  if (aImageId.isEmpty())
733  {
734  OUString aFileName;
735  aImageId = m_pTextExport->GetDrawingML().WriteImage(aGraphic, false, &aFileName);
736  m_pTextExport->CacheRelId(nChecksum, aImageId, aFileName);
737  }
738  pAttrList->add(FSNS(XML_r, XML_id),
739  OUStringToOString(aImageId, RTL_TEXTENCODING_UTF8));
740  imageData = true;
741  }
742  else if (rProps.GetOpt(ESCHER_Prop_fillBlip, aStruct) && m_pTextExport)
743  {
744  SvMemoryStream aStream;
745  // The first bytes are WW8-specific, we're only interested in the PNG
746  int nHeaderSize = 25;
747  aStream.WriteBytes(aStruct.nProp.data() + nHeaderSize,
748  aStruct.nProp.size() - nHeaderSize);
749  aStream.Seek(0);
750  Graphic aGraphic;
751  GraphicConverter::Import(aStream, aGraphic);
752 
753  BitmapChecksum nChecksum = aGraphic.GetChecksum();
754  OUString aImageId = m_pTextExport->FindRelId(nChecksum);
755  if (aImageId.isEmpty())
756  {
757  OUString aFileName;
758  aImageId = m_pTextExport->GetDrawingML().WriteImage(aGraphic, false, &aFileName);
759  m_pTextExport->CacheRelId(nChecksum, aImageId, aFileName);
760  }
761  pAttrList->add(FSNS(XML_r, XML_id),
762  OUStringToOString(aImageId, RTL_TEXTENCODING_UTF8));
763  imageData = true;
764  }
765 
766  if (rProps.GetOpt(ESCHER_Prop_fNoFillHitTest, nValue))
767  impl_AddBool(pAttrList.get(), FSNS(XML_o, XML_detectmouseclick), nValue != 0);
768 
769  if (imageData)
770  m_pSerializer->singleElementNS( XML_v, XML_imagedata, pAttrList );
771  else
772  {
773  if ( rProps.GetOpt( ESCHER_Prop_fillType, nValue ) )
774  {
775  const char *pFillType = nullptr;
776  switch ( nValue )
777  {
778  case ESCHER_FillSolid: pFillType = "solid"; break;
779  // TODO case ESCHER_FillPattern: pFillType = ""; break;
780  case ESCHER_FillTexture: pFillType = "tile"; break;
781  // TODO case ESCHER_FillPicture: pFillType = ""; break;
782  // TODO case ESCHER_FillShade: pFillType = ""; break;
783  // TODO case ESCHER_FillShadeCenter: pFillType = ""; break;
784  // TODO case ESCHER_FillShadeShape: pFillType = ""; break;
785  // TODO case ESCHER_FillShadeScale: pFillType = ""; break;
786  // TODO case ESCHER_FillShadeTitle: pFillType = ""; break;
787  // TODO case ESCHER_FillBackground: pFillType = ""; break;
788  default:
789  SAL_INFO("oox.vml", "Unhandled fill type: " << nValue);
790  break;
791  }
792  if ( pFillType )
793  pAttrList->add( XML_type, pFillType );
794  }
795  else if (!rProps.GetOpt(ESCHER_Prop_fillColor, nValue))
796  pAttrList->add( XML_on, "false" );
797 
798  if ( rProps.GetOpt( ESCHER_Prop_fillColor, nValue ) )
799  impl_AddColor( m_pShapeAttrList.get(), XML_fillcolor, nValue );
800 
801  if ( rProps.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
802  impl_AddColor( pAttrList.get(), XML_color2, nValue );
803 
804 
805  if (rProps.GetOpt(ESCHER_Prop_fillOpacity, nValue))
806  // Partly undo the transformation at the end of EscherPropertyContainer::CreateFillProperties(): VML opacity is 0..1.
807  pAttrList->add(XML_opacity, OString::number(double((nValue * 100) >> 16) / 100));
808  m_pSerializer->singleElementNS( XML_v, XML_fill, pAttrList );
809 
810  }
811  }
812  bAlreadyWritten[ ESCHER_Prop_fillType ] = true;
813  bAlreadyWritten[ ESCHER_Prop_fillColor ] = true;
814  bAlreadyWritten[ ESCHER_Prop_fillBackColor ] = true;
815  bAlreadyWritten[ ESCHER_Prop_fillBlip ] = true;
816  bAlreadyWritten[ ESCHER_Prop_fNoFillHitTest ] = true;
817  bAlreadyWritten[ ESCHER_Prop_fillOpacity ] = true;
818  break;
819 
820  case ESCHER_Prop_lineColor: // 448
821  case ESCHER_Prop_lineWidth: // 459
822  case ESCHER_Prop_lineDashing: // 462
823  case ESCHER_Prop_lineStartArrowhead: // 464
824  case ESCHER_Prop_lineEndArrowhead: // 465
827  case ESCHER_Prop_lineEndArrowWidth: // 468
828  case ESCHER_Prop_lineEndArrowLength: // 469
829  case ESCHER_Prop_lineJoinStyle: // 470
830  case ESCHER_Prop_lineEndCapStyle: // 471
831  {
832  sal_uInt32 nValue;
833  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
834 
835  if ( rProps.GetOpt( ESCHER_Prop_lineColor, nValue ) )
836  impl_AddColor( pAttrList.get(), XML_color, nValue );
837 
838  if ( rProps.GetOpt( ESCHER_Prop_lineWidth, nValue ) )
839  impl_AddInt( pAttrList.get(), XML_weight, nValue );
840 
841  if ( rProps.GetOpt( ESCHER_Prop_lineDashing, nValue ) )
842  {
843  const char *pDashStyle = nullptr;
844  switch ( nValue )
845  {
846  case ESCHER_LineSolid: pDashStyle = "solid"; break;
847  case ESCHER_LineDashSys: pDashStyle = "shortdash"; break;
848  case ESCHER_LineDotSys: pDashStyle = "shortdot"; break;
849  case ESCHER_LineDashDotSys: pDashStyle = "shortdashdot"; break;
850  case ESCHER_LineDashDotDotSys: pDashStyle = "shortdashdotdot"; break;
851  case ESCHER_LineDotGEL: pDashStyle = "dot"; break;
852  case ESCHER_LineDashGEL: pDashStyle = "dash"; break;
853  case ESCHER_LineLongDashGEL: pDashStyle = "longdash"; break;
854  case ESCHER_LineDashDotGEL: pDashStyle = "dashdot"; break;
855  case ESCHER_LineLongDashDotGEL: pDashStyle = "longdashdot"; break;
856  case ESCHER_LineLongDashDotDotGEL: pDashStyle = "longdashdotdot"; break;
857  }
858  if ( pDashStyle )
859  pAttrList->add( XML_dashstyle, pDashStyle );
860  }
861 
862  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowhead, nValue ) )
863  impl_AddArrowHead( pAttrList.get(), XML_startarrow, nValue );
864 
865  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowhead, nValue ) )
866  impl_AddArrowHead( pAttrList.get(), XML_endarrow, nValue );
867 
868  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowWidth, nValue ) )
869  impl_AddArrowWidth( pAttrList.get(), XML_startarrowwidth, nValue );
870 
871  if ( rProps.GetOpt( ESCHER_Prop_lineStartArrowLength, nValue ) )
872  impl_AddArrowLength( pAttrList.get(), XML_startarrowlength, nValue );
873 
874  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowWidth, nValue ) )
875  impl_AddArrowWidth( pAttrList.get(), XML_endarrowwidth, nValue );
876 
877  if ( rProps.GetOpt( ESCHER_Prop_lineEndArrowLength, nValue ) )
878  impl_AddArrowLength( pAttrList.get(), XML_endarrowlength, nValue );
879 
880  if ( rProps.GetOpt( ESCHER_Prop_lineJoinStyle, nValue ) )
881  {
882  const char *pJoinStyle = nullptr;
883  switch ( nValue )
884  {
885  case ESCHER_LineJoinBevel: pJoinStyle = "bevel"; break;
886  case ESCHER_LineJoinMiter: pJoinStyle = "miter"; break;
887  case ESCHER_LineJoinRound: pJoinStyle = "round"; break;
888  }
889  if ( pJoinStyle )
890  pAttrList->add( XML_joinstyle, pJoinStyle );
891  }
892 
893  if ( rProps.GetOpt( ESCHER_Prop_lineEndCapStyle, nValue ) )
894  {
895  const char *pEndCap = nullptr;
896  switch ( nValue )
897  {
898  case ESCHER_LineEndCapRound: pEndCap = "round"; break;
899  case ESCHER_LineEndCapSquare: pEndCap = "square"; break;
900  case ESCHER_LineEndCapFlat: pEndCap = "flat"; break;
901  }
902  if ( pEndCap )
903  pAttrList->add( XML_endcap, pEndCap );
904  }
905 
906  m_pSerializer->singleElementNS( XML_v, XML_stroke, pAttrList );
907  }
908  bAlreadyWritten[ ESCHER_Prop_lineColor ] = true;
909  bAlreadyWritten[ ESCHER_Prop_lineWidth ] = true;
910  bAlreadyWritten[ ESCHER_Prop_lineDashing ] = true;
911  bAlreadyWritten[ ESCHER_Prop_lineStartArrowhead ] = true;
912  bAlreadyWritten[ ESCHER_Prop_lineEndArrowhead ] = true;
913  bAlreadyWritten[ ESCHER_Prop_lineStartArrowWidth ] = true;
914  bAlreadyWritten[ ESCHER_Prop_lineStartArrowLength ] = true;
915  bAlreadyWritten[ ESCHER_Prop_lineEndArrowWidth ] = true;
916  bAlreadyWritten[ ESCHER_Prop_lineEndArrowLength ] = true;
917  bAlreadyWritten[ ESCHER_Prop_lineJoinStyle ] = true;
918  bAlreadyWritten[ ESCHER_Prop_lineEndCapStyle ] = true;
919  break;
920 
921  case ESCHER_Prop_fHidden:
922  if ( !opt.nPropValue )
923  m_ShapeStyle.append( ";visibility:hidden" );
924  break;
927  {
928  sal_uInt32 nValue = 0;
929  bool bShadow = false;
930  bool bObscured = false;
931  if ( rProps.GetOpt( ESCHER_Prop_fshadowObscured, nValue ) )
932  {
933  bShadow = (( nValue & 0x20002 ) == 0x20002 );
934  bObscured = (( nValue & 0x10001 ) == 0x10001 );
935  }
936  if ( bShadow )
937  {
938  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
939  impl_AddBool( pAttrList.get(), XML_on, bShadow );
940  impl_AddBool( pAttrList.get(), XML_obscured, bObscured );
941 
942  if ( rProps.GetOpt( ESCHER_Prop_shadowColor, nValue ) )
943  impl_AddColor( pAttrList.get(), XML_color, nValue );
944 
945  m_pSerializer->singleElementNS( XML_v, XML_shadow, pAttrList );
946  bAlreadyWritten[ ESCHER_Prop_fshadowObscured ] = true;
947  bAlreadyWritten[ ESCHER_Prop_shadowColor ] = true;
948  }
949  }
950  break;
953  {
954  EscherPropSortStruct aUnicode;
955  if (rProps.GetOpt(ESCHER_Prop_gtextUNICODE, aUnicode))
956  {
957  SvMemoryStream aStream;
958 
959  if(!opt.nProp.empty())
960  {
961  aStream.WriteBytes(opt.nProp.data(), opt.nProp.size());
962  }
963 
964  aStream.Seek(0);
965  OUString aTextPathString = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
966  aStream.Seek(0);
967 
968  m_pSerializer->singleElementNS(XML_v, XML_path, XML_textpathok, "t");
969 
970  rtl::Reference<sax_fastparser::FastAttributeList> pAttrList = FastSerializerHelper::createAttrList();
971  pAttrList->add(XML_on, "t");
972  pAttrList->add(XML_fitshape, "t");
973  pAttrList->add(XML_string, OUStringToOString(aTextPathString, RTL_TEXTENCODING_UTF8));
974  EscherPropSortStruct aFont;
975  OUString aStyle;
976  if (rProps.GetOpt(ESCHER_Prop_gtextFont, aFont))
977  {
978  aStream.WriteBytes(aFont.nProp.data(), aFont.nProp.size());
979  aStream.Seek(0);
980  OUString aTextPathFont = SvxMSDffManager::MSDFFReadZString(aStream, aFont.nProp.size(), true);
981  aStyle += "font-family:\"" + aTextPathFont + "\"";
982  }
983  sal_uInt32 nSize;
984  if (rProps.GetOpt(ESCHER_Prop_gtextSize, nSize))
985  {
986  float nSizeF = static_cast<sal_Int32>(nSize) / 65536.0;
987  OUString aSize = OUString::number(nSizeF);
988  aStyle += ";font-size:" + aSize + "pt";
989  }
991  pAttrList->add(XML_trim, "t");
992 
993  if (!aStyle.isEmpty())
994  pAttrList->add(XML_style, OUStringToOString(aStyle, RTL_TEXTENCODING_UTF8));
995  m_pSerializer->singleElementNS(XML_v, XML_textpath, pAttrList);
996  }
997 
998  bAlreadyWritten[ESCHER_Prop_gtextUNICODE] = true;
999  bAlreadyWritten[ESCHER_Prop_gtextFont] = true;
1000  }
1001  break;
1002  case ESCHER_Prop_Rotation:
1003  {
1004  // The higher half of the variable contains the angle.
1005  m_ShapeStyle.append(";rotation:" + OString::number(double(opt.nPropValue >> 16)));
1006  bAlreadyWritten[ESCHER_Prop_Rotation] = true;
1007  }
1008  break;
1010  {
1011  // See DffPropertyReader::ApplyLineAttributes().
1012  impl_AddBool( m_pShapeAttrList.get(), XML_stroked, (opt.nPropValue & 8) != 0 );
1013  bAlreadyWritten[ESCHER_Prop_fNoLineDrawDash] = true;
1014  }
1015  break;
1016  case ESCHER_Prop_wzName:
1017  {
1018  SvMemoryStream aStream;
1019 
1020  if(!opt.nProp.empty())
1021  {
1022  aStream.WriteBytes(opt.nProp.data(), opt.nProp.size());
1023  }
1024 
1025  aStream.Seek(0);
1026  OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, opt.nProp.size(), true);
1027  aStream.Seek(0);
1029  m_pShapeAttrList->add(XML_ID, OUStringToOString(idStr, RTL_TEXTENCODING_UTF8));
1030 
1031  bAlreadyWritten[ESCHER_Prop_wzName] = true;
1032  }
1033  break;
1034  default:
1035 #if OSL_DEBUG_LEVEL > 0
1036  const size_t opt_nProp_size(opt.nProp.size());
1037  const sal_uInt8 opt_nProp_empty(0);
1038  fprintf( stderr, "TODO VMLExport::Commit(), unimplemented id: %d, value: %" SAL_PRIuUINT32 ", data: [%zu, %p]\n",
1039  nId,
1040  opt.nPropValue,
1041  opt_nProp_size,
1042  0 == opt_nProp_size ? &opt_nProp_empty : opt.nProp.data());
1043  if ( opt.nProp.size() )
1044  {
1045  const sal_uInt8 *pIt = opt.nProp.data();
1046  fprintf( stderr, " ( " );
1047  for ( int nCount = opt.nProp.size(); nCount; --nCount )
1048  {
1049  fprintf( stderr, "%02x ", *pIt );
1050  ++pIt;
1051  }
1052  fprintf( stderr, ")\n" );
1053  }
1054 #endif
1055  break;
1056  }
1057  }
1058 
1060 }
1061 
1062 OString VMLExport::ShapeIdString( sal_uInt32 nId )
1063 {
1065  return m_sShapeIDPrefix + OString::number( nId );
1066  else
1067  return "shape_" + OString::number( nId );
1068 }
1069 
1071 {
1072  if (m_nShapeFlags & (ShapeFlag::FlipH | ShapeFlag::FlipV))
1073  {
1074  m_ShapeStyle.append( ";flip:" );
1075 
1076  if (m_nShapeFlags & ShapeFlag::FlipH)
1077  m_ShapeStyle.append( "x" );
1078 
1079  if (m_nShapeFlags & ShapeFlag::FlipV)
1080  m_ShapeStyle.append( "y" );
1081  }
1082 }
1083 
1085 {
1086  // style
1087  if (!m_ShapeStyle.isEmpty())
1088  m_ShapeStyle.append( ";" );
1089 
1090  m_ShapeStyle.append( "position:absolute" );
1091 
1092  AddFlipXY();
1093 
1094  // the actual dimensions
1095  OString aLeft, aTop, aRight, aBottom;
1096 
1097  if ( mnGroupLevel == 1 )
1098  {
1099  const OString aPt( "pt" );
1100  aLeft = OString::number( double( rRectangle.Left() ) / 20 ) + aPt;
1101  aTop = OString::number( double( rRectangle.Top() ) / 20 ) + aPt;
1102  aRight = OString::number( double( rRectangle.Right() ) / 20 ) + aPt;
1103  aBottom = OString::number( double( rRectangle.Bottom() ) / 20 ) + aPt;
1104  }
1105  else
1106  {
1107  aLeft = OString::number( rRectangle.Left() );
1108  aTop = OString::number( rRectangle.Top() );
1109  aRight = OString::number( rRectangle.Right() );
1110  aBottom = OString::number( rRectangle.Bottom() );
1111  }
1112 
1113  m_pShapeAttrList->add( XML_from, aLeft + "," + aTop );
1114 
1115  m_pShapeAttrList->add( XML_to, aRight + "," + aBottom );
1116 }
1117 
1118 void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const tools::Rectangle& rRectangle, bool rbAbsolutePos)
1119 {
1120  if ( !rBuffer.isEmpty() )
1121  rBuffer.append( ";" );
1122 
1123  if (rbAbsolutePos && !m_bInline)
1124  {
1125  rBuffer.append( "position:absolute;" );
1126  }
1127 
1128  if(m_bInline)
1129  {
1130  rBuffer.append( "width:" + OString::number( double( rRectangle.Right() - rRectangle.Left() ) / 20 ) +
1131  "pt;height:" + OString::number( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 ) +
1132  "pt" );
1133  }
1134  else if ( mnGroupLevel == 1 )
1135  {
1136  rBuffer.append( "margin-left:" + OString::number( double( rRectangle.Left() ) / 20 ) +
1137  "pt;margin-top:" + OString::number( double( rRectangle.Top() ) / 20 ) +
1138  "pt;width:" + OString::number( double( rRectangle.Right() - rRectangle.Left() ) / 20 ) +
1139  "pt;height:" + OString::number( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 ) +
1140  "pt" );
1141  }
1142  else
1143  {
1144  rBuffer.append( "left:" + OString::number( rRectangle.Left() ) +
1145  ";top:" + OString::number( rRectangle.Top() ) +
1146  ";width:" + OString::number( rRectangle.Right() - rRectangle.Left() ) +
1147  ";height:" + OString::number( rRectangle.Bottom() - rRectangle.Top() ) );
1148  }
1149 
1150  AddFlipXY();
1151 }
1152 
1153 void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const OString& rValue )
1154 {
1155  m_pShapeAttrList->add( nAttribute, rValue );
1156 }
1157 
1158 static std::vector<OString> lcl_getShapeTypes()
1159 {
1160  std::vector<OString> aRet;
1161 
1162  OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/vml-shape-types");
1163  rtl::Bootstrap::expandMacros(aPath);
1164  SvFileStream aStream(aPath, StreamMode::READ);
1165  if (aStream.GetError() != ERRCODE_NONE)
1166  SAL_WARN("oox", "failed to open vml-shape-types");
1167  OString aLine;
1168  bool bNotDone = aStream.ReadLine(aLine);
1169  while (bNotDone)
1170  {
1171  // Filter out comments.
1172  if (!aLine.startsWith("/"))
1173  aRet.push_back(aLine);
1174  bNotDone = aStream.ReadLine(aLine);
1175  }
1176  return aRet;
1177 }
1178 
1179 static bool lcl_isTextBox(const SdrObject* pSdrObject)
1180 {
1181  uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY);
1182  if (xPropertySet.is())
1183  {
1184  uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
1185  return xPropertySetInfo->hasPropertyByName("TextBox") && xPropertySet->getPropertyValue("TextBox").get<bool>();
1186  }
1187  return false;
1188 }
1189 
1190 static OUString lcl_getAnchorIdFromGrabBag(const SdrObject* pSdrObject)
1191 {
1192  OUString aResult;
1193 
1194  uno::Reference<beans::XPropertySet> xShape(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY);
1195  if (xShape->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"))
1196  {
1197  comphelper::SequenceAsHashMap aInteropGrabBag(xShape->getPropertyValue("InteropGrabBag"));
1198  if (aInteropGrabBag.find("AnchorId") != aInteropGrabBag.end())
1199  aInteropGrabBag["AnchorId"] >>= aResult;
1200  }
1201 
1202  return aResult;
1203 }
1204 
1206 {
1208  return EscherEx::GenerateShapeId();
1209  else
1210  return m_nShapeIDCounter++;
1211 }
1212 
1214  std::string_view sShapeID, const bool bIsPictureFrame )
1215 {
1216  OString sShapeType;
1217  if ( !bIsPictureFrame )
1218  // We don't have a shape definition for host control in presetShapeDefinitions.xml
1219  // So use a definition copied from DOCX file created with MSO
1220  sShapeType = OString::Concat("<v:shapetype id=\"_x0000_t") + sShapeID +
1221  "\" coordsize=\"21600,21600\" o:spt=\"" + sShapeID +
1222  "\" path=\"m,l,21600l21600,21600l21600,xe\">\n"
1223  "<v:stroke joinstyle=\"miter\"/>\n"
1224  "<v:path shadowok=\"f\" o:extrusionok=\"f\" strokeok=\"f\" fillok=\"f\" o:connecttype=\"rect\"/>\n"
1225  "<o:lock v:ext=\"edit\" shapetype=\"t\"/>\n"
1226  "</v:shapetype>";
1227  else
1228  // We don't have a shape definition for picture frame in presetShapeDefinitions.xml
1229  // So use a definition copied from DOCX file created with MSO
1230  sShapeType = OString::Concat("<v:shapetype id=\"_x0000_t") + sShapeID +
1231  "\" coordsize=\"21600,21600\" o:spt=\"" + sShapeID +
1232  "\" o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\n"
1233  "<v:stroke joinstyle=\"miter\"/>\n"
1234  "<v:formulas>\n"
1235  "<v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\n"
1236  "<v:f eqn=\"sum @0 1 0\"/>\n"
1237  "<v:f eqn=\"sum 0 0 @1\"/>\n"
1238  "<v:f eqn=\"prod @2 1 2\"/>\n"
1239  "<v:f eqn=\"prod @3 21600 pixelWidth\"/>\n"
1240  "<v:f eqn=\"prod @3 21600 pixelHeight\"/>\n"
1241  "<v:f eqn=\"sum @0 0 1\"/>\n"
1242  "<v:f eqn=\"prod @6 1 2\"/>\n"
1243  "<v:f eqn=\"prod @7 21600 pixelWidth\"/>\n"
1244  "<v:f eqn=\"sum @8 21600 0\"/>\n"
1245  "<v:f eqn=\"prod @7 21600 pixelHeight\"/>\n"
1246  "<v:f eqn=\"sum @10 21600 0\"/>\n"
1247  "</v:formulas>\n"
1248  "<v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n"
1249  "<o:lock v:ext=\"edit\" aspectratio=\"t\"/>\n"
1250  "</v:shapetype>";
1251  return sShapeType;
1252 }
1253 
1255 {
1257  return -1;
1258 
1259  // some of the shapes have their own name ;-)
1260  sal_Int32 nShapeElement = -1;
1261  bool bReferToShapeType = false;
1262  switch ( m_nShapeType )
1263  {
1264  case ESCHER_ShpInst_NotPrimitive: nShapeElement = XML_shape; break;
1265  case ESCHER_ShpInst_Rectangle: nShapeElement = XML_rect; break;
1266  case ESCHER_ShpInst_RoundRectangle: nShapeElement = XML_roundrect; break;
1267  case ESCHER_ShpInst_Ellipse: nShapeElement = XML_oval; break;
1268  case ESCHER_ShpInst_Arc: nShapeElement = XML_arc; break;
1269  case ESCHER_ShpInst_Line: nShapeElement = XML_line; break;
1271  {
1272  bReferToShapeType = true;
1273  nShapeElement = XML_shape;
1275  {
1276  m_pSerializer->write(GetVMLShapeTypeDefinition(OString::number(m_nShapeType), false));
1278  }
1279  break;
1280  }
1282  {
1283  bReferToShapeType = true;
1284  nShapeElement = XML_shape;
1286  {
1287  m_pSerializer->write(GetVMLShapeTypeDefinition(OString::number(m_nShapeType), true));
1289  }
1290  break;
1291  }
1292  default:
1294  {
1295  nShapeElement = XML_shape;
1296 
1297  // a predefined shape?
1298  static std::vector<OString> aShapeTypes = lcl_getShapeTypes();
1299  SAL_WARN_IF(m_nShapeType >= aShapeTypes.size(), "oox.vml", "Unknown shape type!");
1300  if (m_nShapeType < aShapeTypes.size() && aShapeTypes[m_nShapeType] != "NULL")
1301  {
1302  bReferToShapeType = true;
1304  {
1305  m_pSerializer->write(aShapeTypes[m_nShapeType]);
1307  }
1308  }
1309  else
1310  {
1311  // rectangle is probably the best fallback...
1312  nShapeElement = XML_rect;
1313  }
1314  }
1315  break;
1316  }
1317 
1318  // anchoring
1319  switch (m_eHOri)
1320  {
1321  case text::HoriOrientation::LEFT:
1322  m_ShapeStyle.append(";mso-position-horizontal:left");
1323  break;
1324  case text::HoriOrientation::CENTER:
1325  m_ShapeStyle.append(";mso-position-horizontal:center");
1326  break;
1327  case text::HoriOrientation::RIGHT:
1328  m_ShapeStyle.append(";mso-position-horizontal:right");
1329  break;
1330  case text::HoriOrientation::INSIDE:
1331  m_ShapeStyle.append(";mso-position-horizontal:inside");
1332  break;
1333  case text::HoriOrientation::OUTSIDE:
1334  m_ShapeStyle.append(";mso-position-horizontal:outside");
1335  break;
1336  default:
1337  case text::HoriOrientation::NONE:
1338  break;
1339  }
1340  switch (m_eHRel)
1341  {
1342  case text::RelOrientation::PAGE_PRINT_AREA:
1343  m_ShapeStyle.append(";mso-position-horizontal-relative:margin");
1344  break;
1345  case text::RelOrientation::PAGE_FRAME:
1346  case text::RelOrientation::PAGE_LEFT:
1347  case text::RelOrientation::PAGE_RIGHT:
1348  m_ShapeStyle.append(";mso-position-horizontal-relative:page");
1349  break;
1350  case text::RelOrientation::CHAR:
1351  m_ShapeStyle.append(";mso-position-horizontal-relative:char");
1352  break;
1353  default:
1354  break;
1355  }
1356 
1357  switch (m_eVOri)
1358  {
1359  case text::VertOrientation::TOP:
1360  case text::VertOrientation::LINE_TOP:
1361  case text::VertOrientation::CHAR_TOP:
1362  m_ShapeStyle.append(";mso-position-vertical:top");
1363  break;
1364  case text::VertOrientation::CENTER:
1365  case text::VertOrientation::LINE_CENTER:
1366  m_ShapeStyle.append(";mso-position-vertical:center");
1367  break;
1368  case text::VertOrientation::BOTTOM:
1369  case text::VertOrientation::LINE_BOTTOM:
1370  case text::VertOrientation::CHAR_BOTTOM:
1371  m_ShapeStyle.append(";mso-position-vertical:bottom");
1372  break;
1373  default:
1374  case text::VertOrientation::NONE:
1375  break;
1376  }
1377  switch (m_eVRel)
1378  {
1379  case text::RelOrientation::PAGE_PRINT_AREA:
1380  m_ShapeStyle.append(";mso-position-vertical-relative:margin");
1381  break;
1382  case text::RelOrientation::PAGE_FRAME:
1383  m_ShapeStyle.append(";mso-position-vertical-relative:page");
1384  break;
1385  default:
1386  break;
1387  }
1388 
1389  if (!m_pSdrObject->getHyperlink().isEmpty())
1390  m_pShapeAttrList->add(
1391  XML_href, OUStringToOString(m_pSdrObject->getHyperlink(), RTL_TEXTENCODING_UTF8));
1392 
1393  m_pShapeAttrList->addNS(XML_o, XML_allowincell, m_IsFollowingTextFlow ? "t" : "f");
1394 
1395  // add style
1396  m_pShapeAttrList->add( XML_style, m_ShapeStyle.makeStringAndClear() );
1397 
1398  OUString sAnchorId = lcl_getAnchorIdFromGrabBag(m_pSdrObject);
1399  if (!sAnchorId.isEmpty())
1400  m_pShapeAttrList->addNS(XML_wp14, XML_anchorId, OUStringToOString(sAnchorId, RTL_TEXTENCODING_UTF8));
1401 
1402  if ( nShapeElement >= 0 && !m_pShapeAttrList->hasAttribute( XML_type ) && bReferToShapeType )
1403  {
1404  OString sType;
1406  sType = "#";
1407  m_pShapeAttrList->add( XML_type, sType +
1408  "_x0000_t" + OString::number( m_nShapeType ) );
1409  }
1410 
1411  // start of the shape
1412  m_pSerializer->startElementNS( XML_v, nShapeElement, m_pShapeAttrList );
1413 
1414  OString const textboxStyle(m_TextboxStyle.makeStringAndClear());
1415 
1416  // now check if we have some editeng text (not associated textbox) and we have a text exporter registered
1417  const SdrTextObj* pTxtObj = dynamic_cast<const SdrTextObj*>( m_pSdrObject );
1419  {
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();
1430  }
1431  else if (pTxtObj->GetOutlinerParaObject())
1432  {
1433  pParaObj = *pTxtObj->GetOutlinerParaObject();
1434  }
1435 
1436  if( pParaObj )
1437  {
1438  rtl::Reference<sax_fastparser::FastAttributeList> pTextboxAttrList = FastSerializerHelper::createAttrList();
1439  if (!textboxStyle.isEmpty())
1440  {
1441  pTextboxAttrList->add(XML_style, textboxStyle);
1442  }
1443 
1444  // this is reached only in case some text is attached to the shape
1445  m_pSerializer->startElementNS(XML_v, XML_textbox, pTextboxAttrList);
1446  m_pTextExport->WriteOutliner(*pParaObj);
1447  m_pSerializer->endElementNS(XML_v, XML_textbox);
1448  }
1449  }
1450 
1451  return nShapeElement;
1452 }
1453 
1454 void VMLExport::EndShape( sal_Int32 nShapeElement )
1455 {
1456  if ( nShapeElement < 0 )
1457  return;
1458 
1460  {
1461  uno::Reference<drawing::XShape> xShape {const_cast<SdrObject*>(m_pSdrObject)->getUnoShape(), uno::UNO_QUERY};
1462  uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
1463  uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
1464  bool bBottomToTop = false;
1465  if (xPropertySetInfo->hasPropertyByName("CustomShapeGeometry"))
1466  {
1467  // In this case a DrawingML DOCX was imported.
1468  comphelper::SequenceAsHashMap aCustomShapeProperties(
1469  xPropertySet->getPropertyValue("CustomShapeGeometry"));
1470  if (aCustomShapeProperties.find("TextPreRotateAngle") != aCustomShapeProperties.end())
1471  {
1472  sal_Int32 nTextRotateAngle = aCustomShapeProperties["TextPreRotateAngle"].get<sal_Int32>();
1473  if (nTextRotateAngle == -270)
1474  bBottomToTop = true;
1475  }
1476  }
1477  else
1478  {
1479  // In this case a pure VML DOCX was imported, so there is no CustomShapeGeometry.
1480  auto pTextExport = m_pTextExport->GetDrawingML().GetTextExport();
1481  // FIXME: somewhy pTextExport is always nullptr, we should find its reason
1482  if (pTextExport)
1483  {
1484  auto xTextFrame = pTextExport->GetUnoTextFrame(xShape);
1485  uno::Reference<beans::XPropertySet> xPropSet(xTextFrame, uno::UNO_QUERY);
1486  auto aAny = xPropSet->getPropertyValue("WritingMode");
1487  sal_Int16 nWritingMode;
1488  if (aAny >>= nWritingMode)
1489  {
1490  switch (nWritingMode)
1491  {
1492  case text::WritingMode2::BT_LR:
1493  bBottomToTop = true;
1494  break;
1495  default:
1496  break;
1497  }
1498  }
1499  }
1500  }
1501  rtl::Reference<sax_fastparser::FastAttributeList> pTextboxAttrList = FastSerializerHelper::createAttrList();
1502  if (bBottomToTop)
1503  pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
1504  m_pSerializer->startElementNS(XML_v, XML_textbox, pTextboxAttrList);
1505 
1506  m_pTextExport->WriteVMLTextBox(uno::Reference<drawing::XShape>(xPropertySet, uno::UNO_QUERY_THROW));
1507 
1508  m_pSerializer->endElementNS(XML_v, XML_textbox);
1509  }
1510 
1511  if (m_pWrapAttrList)
1512  {
1513  m_pSerializer->singleElementNS(XML_w10, XML_wrap, m_pWrapAttrList);
1514  }
1515 
1516  // end of the shape
1517  m_pSerializer->endElementNS( XML_v, nShapeElement );
1518 }
1519 
1520 OString const & VMLExport::AddSdrObject( const SdrObject& rObj,
1521  bool const bIsFollowingTextFlow,
1522  sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel,
1523  FastAttributeList* pWrapAttrList,
1524  const bool bOOxmlExport )
1525 {
1526  m_pSdrObject = &rObj;
1527  m_eHOri = eHOri;
1528  m_eVOri = eVOri;
1529  m_eHRel = eHRel;
1530  m_eVRel = eVRel;
1531  m_pWrapAttrList = pWrapAttrList;
1532  m_bInline = false;
1533  m_IsFollowingTextFlow = bIsFollowingTextFlow;
1534  EscherEx::AddSdrObject(rObj, bOOxmlExport);
1535  return m_sShapeId;
1536 }
1537 
1538 OString const & VMLExport::AddInlineSdrObject( const SdrObject& rObj, const bool bOOxmlExport )
1539 {
1540  m_pSdrObject = &rObj;
1541  m_eHOri = -1;
1542  m_eVOri = -1;
1543  m_eHRel = -1;
1544  m_eVRel = -1;
1545  m_pWrapAttrList.clear();
1546  m_bInline = true;
1547  m_IsFollowingTextFlow = true;
1548  EscherEx::AddSdrObject(rObj, bOOxmlExport);
1549  return m_sShapeId;
1550 }
1551 
1552 /* 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:1153
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:365
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:1538
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:1084
#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
msopathEnd
void OverrideShapeIDGen(bool bOverrideShapeIdGeneration, const OString &sShapeIDPrefix=OString())
Definition: vmlexport.cxx:213
SvStream * mpOutStrm
ESCHER_LineEndCapFlat
msopathLineTo
ESCHER_WrapThrough
constexpr tools::Long Left() const
#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
const OUString & getHyperlink() const
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:1158
#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
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:1205
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
#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:1179
#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:1454
#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:335
constexpr tools::Long Top() const
#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
OStringBuffer m_TextboxStyle
style for textbox
Definition: vmlexport.hxx:107
void AddFlipXY()
Add flip X and flip Y.
Definition: vmlexport.cxx:1070
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:327
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:369
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:1118
void add(const FastAttributeList &)
constexpr tools::Long Bottom() const
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()
XML_ID
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:1254
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:1213
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:1226
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:1520
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:342
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:1190
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:1062
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