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