1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: escherex.cxx,v $
10 * $Revision: 1.77.64.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include "eschesdo.hxx"
35 #include <svx/escherex.hxx>
37 #include <svx/svdobj.hxx>
38 #include <svx/svdoashp.hxx>
39 #include <svx/svdoole2.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <vcl/gradient.hxx>
42 #include <vcl/graph.hxx>
43 #include <vcl/cvtgrf.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/wrkwin.hxx>
46 #include <tools/stream.hxx>
47 #include <tools/zcodec.hxx>
48 #include <svx/svdopath.hxx>
50 #include <svtools/filter.hxx>
51 #include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
52 #include "../customshapes/EnhancedCustomShapeGeometry.hxx"
53 #include <EnhancedCustomShapeFunctionParser.hxx>
54 #include "../customshapes/EnhancedCustomShape2d.hxx"
55 #include <com/sun/star/beans/PropertyValues.hpp>
56 #include <com/sun/star/beans/XPropertyState.hpp>
57 #include <com/sun/star/awt/GradientStyle.hpp>
58 #include <com/sun/star/awt/RasterOperation.hpp>
59 #include <com/sun/star/awt/Gradient.hpp>
60 #include <com/sun/star/drawing/LineStyle.hpp>
61 #include <com/sun/star/drawing/LineJoint.hpp>
62 #include <com/sun/star/drawing/FillStyle.hpp>
63 #include <com/sun/star/drawing/LineDash.hpp>
64 #include <com/sun/star/drawing/BezierPoint.hpp>
65 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
66 #include <com/sun/star/drawing/ConnectorType.hpp>
67 #include <com/sun/star/drawing/ConnectionType.hpp>
68 #include <com/sun/star/drawing/CircleKind.hpp>
69 #include <com/sun/star/drawing/PointSequence.hpp>
70 #include <com/sun/star/drawing/FlagSequence.hpp>
71 #include <com/sun/star/drawing/PolygonFlags.hpp>
72 #include <com/sun/star/text/WritingMode.hpp>
73 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
74 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
75 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
76 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
77 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
78 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
79 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
80 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
81 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
82 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
83 #include <com/sun/star/drawing/ProjectionMode.hpp>
84 #include <com/sun/star/text/XSimpleText.hpp>
85 #include <com/sun/star/drawing/ShadeMode.hpp>
86 #include <vcl/hatch.hxx>
87 #include <com/sun/star/awt/XGraphics.hpp>
88 #include <com/sun/star/awt/FontSlant.hpp>
89 #include <com/sun/star/awt/FontWeight.hpp>
90 #include <com/sun/star/drawing/ColorMode.hpp>
91 #include <com/sun/star/drawing/Position3D.hpp>
92 #include <com/sun/star/drawing/Direction3D.hpp>
93 #include <com/sun/star/text/GraphicCrop.hpp>
94 #include <unotools/ucbstreamhelper.hxx>
95 #include <unotools/localfilehelper.hxx>
96 #include <comphelper/extract.hxx>
97 #include <toolkit/unohlp.hxx>
98 #include <vcl/virdev.hxx>
100 #include <vos/xception.hxx>
101 #ifndef _VOS_NO_NAMESPACE
105 using namespace ::rtl
;
106 using namespace ::com::sun::star
;
109 // ---------------------------------------------------------------------------------------------
111 EscherExContainer::EscherExContainer( SvStream
& rSt
, const sal_uInt16 nRecType
, const sal_uInt16 nInstance
) :
114 rStrm
<< (sal_uInt32
)( ( 0xf | ( nInstance
<< 4 ) ) | ( nRecType
<< 16 ) ) << (sal_uInt32
)0;
115 nContPos
= rStrm
.Tell();
117 EscherExContainer::~EscherExContainer()
119 sal_uInt32 nPos
= rStrm
.Tell();
120 sal_uInt32 nSize
= nPos
- nContPos
;
123 rStrm
.Seek( nContPos
- 4 );
129 EscherExAtom::EscherExAtom( SvStream
& rSt
, const sal_uInt16 nRecType
, const sal_uInt16 nInstance
, const sal_uInt8 nVersion
) :
132 rStrm
<< (sal_uInt32
)( ( nVersion
| ( nInstance
<< 4 ) ) | ( nRecType
<< 16 ) ) << (sal_uInt32
)0;
133 nContPos
= rStrm
.Tell();
135 EscherExAtom::~EscherExAtom()
137 sal_uInt32 nPos
= rStrm
.Tell();
138 sal_uInt32 nSize
= nPos
- nContPos
;
141 rStrm
.Seek( nContPos
- 4 );
147 // ---------------------------------------------------------------------------------------------
149 EscherExClientRecord_Base::~EscherExClientRecord_Base()
153 EscherExClientAnchor_Base::~EscherExClientAnchor_Base()
157 // ---------------------------------------------------------------------------------------------
159 void EscherPropertyContainer::ImplInit()
165 bHasComplexData
= sal_False
;
166 bSuppressRotation
= sal_False
;
167 pSortStruct
= new EscherPropSortStruct
[ nSortBufSize
];
170 EscherPropertyContainer::EscherPropertyContainer() :
171 pGraphicProvider ( NULL
),
177 EscherPropertyContainer::EscherPropertyContainer(
178 EscherGraphicProvider
& rGraphProv
,
179 SvStream
* pPiOutStrm
,
180 Rectangle
& rBoundRect
) :
182 pGraphicProvider ( &rGraphProv
),
183 pPicOutStrm ( pPiOutStrm
),
184 pShapeBoundRect ( &rBoundRect
)
189 EscherPropertyContainer::~EscherPropertyContainer()
191 if ( bHasComplexData
)
193 while ( nSortCount
-- )
194 delete[] pSortStruct
[ nSortCount
].pBuf
;
196 delete[] pSortStruct
;
199 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID
, sal_uInt32 nPropValue
, sal_Bool bBlib
)
201 AddOpt( nPropID
, bBlib
, nPropValue
, NULL
, 0 );
204 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID
, const rtl::OUString
& rString
)
206 sal_Int32 j
, i
, nLen
= rString
.getLength() * 2 + 2;
207 sal_uInt8
* pBuf
= new sal_uInt8
[ nLen
];
208 for ( j
= i
= 0; i
< rString
.getLength(); i
++ )
210 sal_uInt16 nChar
= (sal_uInt16
)rString
[ i
];
211 pBuf
[ j
++ ] = (sal_uInt8
)nChar
;
212 pBuf
[ j
++ ] = (sal_uInt8
)( nChar
>> 8 );
216 AddOpt( nPropID
, sal_True
, nLen
, pBuf
, nLen
);
219 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID
, sal_Bool bBlib
, sal_uInt32 nPropValue
, sal_uInt8
* pProp
, sal_uInt32 nPropSize
)
221 if ( bBlib
) // bBlib is only valid when fComplex = 0
224 nPropID
|= 0x8000; // fComplex = TRUE;
227 for( i
= 0; i
< nSortCount
; i
++ )
229 if ( ( pSortStruct
[ i
].nPropId
&~0xc000 ) == ( nPropID
&~0xc000 ) ) // pruefen, ob Property nur ersetzt wird
231 pSortStruct
[ i
].nPropId
= nPropID
;
232 if ( pSortStruct
[ i
].pBuf
)
234 nCountSize
-= pSortStruct
[ i
].nPropSize
;
235 delete[] pSortStruct
[ i
].pBuf
;
237 pSortStruct
[ i
].pBuf
= pProp
;
238 pSortStruct
[ i
].nPropSize
= nPropSize
;
239 pSortStruct
[ i
].nPropValue
= nPropValue
;
241 nCountSize
+= nPropSize
;
247 if ( nSortCount
== nSortBufSize
) // buffer vergroessern
250 EscherPropSortStruct
* pTemp
= new EscherPropSortStruct
[ nSortBufSize
];
251 for( i
= 0; i
< nSortCount
; i
++ )
253 pTemp
[ i
] = pSortStruct
[ i
];
258 pSortStruct
[ nSortCount
].nPropId
= nPropID
; // property einfuegen
259 pSortStruct
[ nSortCount
].pBuf
= pProp
;
260 pSortStruct
[ nSortCount
].nPropSize
= nPropSize
;
261 pSortStruct
[ nSortCount
++ ].nPropValue
= nPropValue
;
265 nCountSize
+= nPropSize
;
266 bHasComplexData
= sal_True
;
270 sal_Bool
EscherPropertyContainer::GetOpt( sal_uInt16 nPropId
, sal_uInt32
& rPropValue
) const
272 EscherPropSortStruct aPropStruct
;
274 if ( GetOpt( nPropId
, aPropStruct
) )
276 rPropValue
= aPropStruct
.nPropValue
;
282 sal_Bool
EscherPropertyContainer::GetOpt( sal_uInt16 nPropId
, EscherPropSortStruct
& rPropValue
) const
284 for( sal_uInt32 i
= 0; i
< nSortCount
; i
++ )
286 if ( ( pSortStruct
[ i
].nPropId
&~0xc000 ) == ( nPropId
&~0xc000 ) )
288 rPropValue
= pSortStruct
[ i
];
295 EscherProperties
EscherPropertyContainer::GetOpts() const
297 EscherProperties aVector
;
299 for ( sal_uInt32 i
= 0; i
< nSortCount
; ++i
)
300 aVector
.push_back( pSortStruct
[ i
] );
305 extern "C" int __LOADONCALLAPI
EscherPropSortFunc( const void* p1
, const void* p2
)
307 INT16 nID1
= ((EscherPropSortStruct
*)p1
)->nPropId
&~0xc000;
308 INT16 nID2
= ((EscherPropSortStruct
*)p2
)->nPropId
&~0xc000;
312 else if( nID1
> nID2
)
318 void EscherPropertyContainer::Commit( SvStream
& rSt
, sal_uInt16 nVersion
, sal_uInt16 nRecType
)
320 rSt
<< (sal_uInt16
)( ( nCountCount
<< 4 ) | ( nVersion
& 0xf ) ) << nRecType
<< nCountSize
;
323 qsort( pSortStruct
, nSortCount
, sizeof( EscherPropSortStruct
), EscherPropSortFunc
);
326 for ( i
= 0; i
< nSortCount
; i
++ )
328 sal_uInt32 nPropValue
= pSortStruct
[ i
].nPropValue
;
329 sal_uInt16 nPropId
= pSortStruct
[ i
].nPropId
;
331 if ( bSuppressRotation
&& ( nPropId
== ESCHER_Prop_Rotation
) )
337 if ( bHasComplexData
)
339 for ( i
= 0; i
< nSortCount
; i
++ )
341 if ( pSortStruct
[ i
].pBuf
)
342 rSt
.Write( pSortStruct
[ i
].pBuf
, pSortStruct
[ i
].nPropSize
);
348 sal_Bool
EscherPropertyContainer::IsFontWork() const
350 sal_uInt32 nTextPathFlags
= 0;
351 GetOpt( DFF_Prop_gtextFStrikethrough
, nTextPathFlags
);
352 return ( nTextPathFlags
& 0x4000 ) != 0;
355 sal_uInt32
EscherPropertyContainer::ImplGetColor( const sal_uInt32 nSOColor
, sal_Bool bSwap
)
359 sal_uInt32 nColor
= nSOColor
& 0xff00; // GRUEN
360 nColor
|= (sal_uInt8
)( nSOColor
) << 16; // ROT
361 nColor
|= (sal_uInt8
)( nSOColor
>> 16 ); // BLAU
365 return nSOColor
& 0xffffff;
368 sal_uInt32
EscherPropertyContainer::GetGradientColor(
369 const ::com::sun::star::awt::Gradient
* pGradient
,
370 sal_uInt32 nStartColor
)
372 sal_uInt32 nIntensity
= 100;
377 if ( nStartColor
& 1 )
379 nIntensity
= pGradient
->StartIntensity
;
380 aColor
= pGradient
->StartColor
;
384 nIntensity
= pGradient
->EndIntensity
;
385 aColor
= pGradient
->EndColor
;
388 sal_uInt32 nRed
= ( ( aColor
.GetRed() * nIntensity
) / 100 );
389 sal_uInt32 nGreen
= ( ( aColor
.GetGreen() * nIntensity
) / 100 ) << 8;
390 sal_uInt32 nBlue
= ( ( aColor
.GetBlue() * nIntensity
) / 100 ) << 16;
391 return nRed
| nGreen
| nBlue
;
394 void EscherPropertyContainer::CreateGradientProperties(
395 const ::com::sun::star::awt::Gradient
& rGradient
)
397 sal_uInt32 nFillType
= ESCHER_FillShadeScale
;
398 sal_uInt32 nAngle
= 0;
399 sal_uInt32 nFillFocus
= 0;
400 sal_uInt32 nFillLR
= 0;
401 sal_uInt32 nFillTB
= 0;
402 sal_uInt32 nFirstColor
= 0;
403 bool bWriteFillTo
= false;
405 switch ( rGradient
.Style
)
407 case ::com::sun::star::awt::GradientStyle_LINEAR
:
408 case ::com::sun::star::awt::GradientStyle_AXIAL
:
410 nFillType
= ESCHER_FillShadeScale
;
411 nAngle
= (rGradient
.Angle
* 0x10000) / 10;
412 nFillFocus
= (sal::static_int_cast
<int>(rGradient
.Style
) ==
413 sal::static_int_cast
<int>(GradientStyle_LINEAR
)) ? 0 : 50;
416 case ::com::sun::star::awt::GradientStyle_RADIAL
:
417 case ::com::sun::star::awt::GradientStyle_ELLIPTICAL
:
418 case ::com::sun::star::awt::GradientStyle_SQUARE
:
419 case ::com::sun::star::awt::GradientStyle_RECT
:
421 nFillLR
= (rGradient
.XOffset
* 0x10000) / 100;
422 nFillTB
= (rGradient
.YOffset
* 0x10000) / 100;
423 if ( ((nFillLR
> 0) && (nFillLR
< 0x10000)) || ((nFillTB
> 0) && (nFillTB
< 0x10000)) )
424 nFillType
= ESCHER_FillShadeShape
;
426 nFillType
= ESCHER_FillShadeCenter
;
431 case ::com::sun::star::awt::GradientStyle_MAKE_FIXED_SIZE
: break;
433 AddOpt( ESCHER_Prop_fillType
, nFillType
);
434 AddOpt( ESCHER_Prop_fillAngle
, nAngle
);
435 AddOpt( ESCHER_Prop_fillColor
, GetGradientColor( &rGradient
, nFirstColor
) );
436 AddOpt( ESCHER_Prop_fillBackColor
, GetGradientColor( &rGradient
, nFirstColor
^ 1 ) );
437 AddOpt( ESCHER_Prop_fillFocus
, nFillFocus
);
440 AddOpt( ESCHER_Prop_fillToLeft
, nFillLR
);
441 AddOpt( ESCHER_Prop_fillToTop
, nFillTB
);
442 AddOpt( ESCHER_Prop_fillToRight
, nFillLR
);
443 AddOpt( ESCHER_Prop_fillToBottom
, nFillTB
);
447 void EscherPropertyContainer::CreateGradientProperties(
448 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
)
450 ::com::sun::star::uno::Any aAny
;
451 ::com::sun::star::awt::Gradient aGradient
;
452 if ( EscherPropertyValueHelper::GetPropertyValue(
453 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ), sal_False
) )
455 aGradient
= *static_cast< const ::com::sun::star::awt::Gradient
* >( aAny
.getValue() );
457 CreateGradientProperties( aGradient
);
460 void EscherPropertyContainer::CreateFillProperties(
461 const uno::Reference
< beans::XPropertySet
> & rXPropSet
,
464 ::com::sun::star::uno::Any aAny
;
465 AddOpt( ESCHER_Prop_WrapText
, ESCHER_WrapNone
);
466 AddOpt( ESCHER_Prop_AnchorText
, ESCHER_AnchorMiddle
);
468 sal_uInt32 nFillBackColor
= 0;
470 const rtl::OUString
aPropName( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) );
471 if ( EscherPropertyValueHelper::GetPropertyValue(
472 aAny
, rXPropSet
, aPropName
, sal_False
) )
474 ::com::sun::star::drawing::FillStyle eFS
;
475 if ( ! ( aAny
>>= eFS
) )
476 eFS
= ::com::sun::star::drawing::FillStyle_SOLID
;
479 case ::com::sun::star::drawing::FillStyle_GRADIENT
:
481 CreateGradientProperties( rXPropSet
);
482 AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x140014 );
486 case ::com::sun::star::drawing::FillStyle_BITMAP
:
488 CreateGraphicProperties( rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True
);
489 AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x140014 );
490 AddOpt( ESCHER_Prop_fillBackColor
, nFillBackColor
);
493 case ::com::sun::star::drawing::FillStyle_HATCH
:
495 CreateGraphicProperties( rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True
);
498 case ::com::sun::star::drawing::FillStyle_SOLID
:
501 ::com::sun::star::beans::PropertyState ePropState
= EscherPropertyValueHelper::GetPropertyState(
502 rXPropSet
, aPropName
);
503 if ( ePropState
== ::com::sun::star::beans::PropertyState_DIRECT_VALUE
)
504 AddOpt( ESCHER_Prop_fillType
, ESCHER_FillSolid
);
506 if ( EscherPropertyValueHelper::GetPropertyValue(
507 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False
) )
509 sal_uInt32 nFillColor
= ImplGetColor( *((sal_uInt32
*)aAny
.getValue()) );
510 nFillBackColor
= nFillColor
^ 0xffffff;
511 AddOpt( ESCHER_Prop_fillColor
, nFillColor
);
513 AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100010 );
514 AddOpt( ESCHER_Prop_fillBackColor
, nFillBackColor
);
517 case ::com::sun::star::drawing::FillStyle_NONE
:
518 AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100000 );
521 if ( eFS
!= ::com::sun::star::drawing::FillStyle_NONE
)
523 sal_uInt16 nTransparency
= ( EscherPropertyValueHelper::GetPropertyValue(
524 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparence" ) ), sal_True
) )
525 ? *((sal_Int16
*)aAny
.getValue() )
528 AddOpt( ESCHER_Prop_fillOpacity
, ( ( 100 - nTransparency
) << 16 ) / 100 );
531 CreateLineProperties( rXPropSet
, bEdge
);
534 void EscherPropertyContainer::CreateTextProperties(
535 const uno::Reference
< beans::XPropertySet
> & rXPropSet
, sal_uInt32 nTextId
,
536 const sal_Bool bIsCustomShape
, const sal_Bool bIsTextFrame
)
539 text::WritingMode
eWM( text::WritingMode_LR_TB
);
540 drawing::TextVerticalAdjust
eVA( drawing::TextVerticalAdjust_TOP
);
541 drawing::TextHorizontalAdjust
eHA( drawing::TextHorizontalAdjust_LEFT
);
543 sal_Int32
nLeft ( 0 );
544 sal_Int32
nTop ( 0 );
545 sal_Int32
nRight ( 0 );
546 sal_Int32
nBottom ( 0 );
548 // used with normal shapes:
549 sal_Bool
bAutoGrowWidth ( sal_False
);
550 sal_Bool
bAutoGrowHeight ( sal_False
);
551 // used with ashapes:
552 sal_Bool
bWordWrap ( sal_False
);
553 sal_Bool
bAutoGrowSize ( sal_False
);
555 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextWritingMode" ) ), sal_True
) )
557 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) ), sal_True
) )
559 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextHorizontalAdjust" ) ), sal_True
) )
561 if ( bIsCustomShape
)
563 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) ), sal_False
) )
565 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True
) )
566 aAny
>>= bAutoGrowSize
;
568 else if ( bIsTextFrame
)
570 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowWidth" ) ), sal_True
) )
571 aAny
>>= bAutoGrowWidth
;
573 // i63936 not setting autogrowheight, because otherwise
574 // the minframeheight of the text will be ignored
576 // if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) )
577 // aAny >>= bAutoGrowHeight;
579 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) ) ) )
581 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) ) ) )
583 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) ) ) )
585 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) ) ) )
589 if ( rObj.ImplGetPropertyValue(
590 ::rtl::OUString::createFromAscii("TextWritingMode") ) )
592 ::com::sun::star::text::WritingMode eMode;
593 rObj.GetUsrAny() >>= eMode;
596 case ::com::sun::star::text::WritingMode_TB_RL:
597 //Well if it so happens that we are fliped 180 we can use
599 if (rObj.GetAngle() == 18000)
600 eFlow = ESCHER_txflBtoT;
602 eFlow = ESCHER_txflTtoBA;
604 case ::com::sun::star::text::WritingMode_RL_TB:
605 eDir = ESCHER_txdirRTL;
611 ESCHER_AnchorText eAnchor
= ESCHER_AnchorTop
;
612 ESCHER_WrapMode eWrapMode
= ESCHER_WrapSquare
;
613 sal_uInt32 nTextAttr
= 0x40004; // rotate text with shape
615 if ( eWM
== text::WritingMode_TB_RL
)
619 case drawing::TextHorizontalAdjust_LEFT
:
620 eAnchor
= ESCHER_AnchorBottom
;
622 case drawing::TextHorizontalAdjust_CENTER
:
623 eAnchor
= ESCHER_AnchorMiddle
;
626 case drawing::TextHorizontalAdjust_BLOCK
:
627 case drawing::TextHorizontalAdjust_RIGHT
:
628 eAnchor
= ESCHER_AnchorTop
;
631 if ( eVA
== drawing::TextVerticalAdjust_CENTER
)
635 case ESCHER_AnchorMiddle
:
636 eAnchor
= ESCHER_AnchorMiddleCentered
;
638 case ESCHER_AnchorBottom
:
639 eAnchor
= ESCHER_AnchorBottomCentered
;
642 case ESCHER_AnchorTop
:
643 eAnchor
= ESCHER_AnchorTopCentered
;
647 if ( bIsCustomShape
)
650 eWrapMode
= ESCHER_WrapSquare
;
652 eWrapMode
= ESCHER_WrapNone
;
654 nTextAttr
|= 0x20002;
658 if ( bAutoGrowHeight
)
659 eWrapMode
= ESCHER_WrapNone
;
660 if ( bAutoGrowWidth
)
661 nTextAttr
|= 0x20002;
664 AddOpt( ESCHER_Prop_txflTextFlow
, ESCHER_txflTtoBA
); // rotate text within shape by 90
667 { // normal from left to right
670 case drawing::TextVerticalAdjust_CENTER
:
671 eAnchor
= ESCHER_AnchorMiddle
;
674 case drawing::TextVerticalAdjust_BOTTOM
:
675 eAnchor
= ESCHER_AnchorBottom
;
679 case drawing::TextVerticalAdjust_TOP
:
680 eAnchor
= ESCHER_AnchorTop
;
683 if ( eHA
== drawing::TextHorizontalAdjust_CENTER
)
687 case ESCHER_AnchorMiddle
:
688 eAnchor
= ESCHER_AnchorMiddleCentered
;
690 case ESCHER_AnchorBottom
:
691 eAnchor
= ESCHER_AnchorBottomCentered
;
693 case ESCHER_AnchorTop
:
694 eAnchor
= ESCHER_AnchorTopCentered
;
699 if ( bIsCustomShape
)
702 eWrapMode
= ESCHER_WrapSquare
;
704 eWrapMode
= ESCHER_WrapNone
;
706 nTextAttr
|= 0x20002;
710 if ( bAutoGrowWidth
)
711 eWrapMode
= ESCHER_WrapNone
;
712 if ( bAutoGrowHeight
)
713 nTextAttr
|= 0x20002;
716 AddOpt( ESCHER_Prop_dxTextLeft
, nLeft
* 360 );
717 AddOpt( ESCHER_Prop_dxTextRight
, nRight
* 360 );
718 AddOpt( ESCHER_Prop_dyTextTop
, nTop
* 360 );
719 AddOpt( ESCHER_Prop_dyTextBottom
, nBottom
* 360 );
721 AddOpt( ESCHER_Prop_WrapText
, eWrapMode
);
722 AddOpt( ESCHER_Prop_AnchorText
, eAnchor
);
723 AddOpt( ESCHER_Prop_FitTextToShape
, nTextAttr
);
726 AddOpt( ESCHER_Prop_lTxid
, nTextId
);
728 // n#404221: In case of rotation we need to write the txtflTextFlow
731 sal_uInt16 nAngle
= EscherPropertyValueHelper::GetPropertyValue(
734 String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ),
736 ? (sal_uInt16
)( ( *((sal_Int32
*)aAny
.getValue() ) ) + 5 ) / 10 : 0;
738 AddOpt( ESCHER_Prop_txflTextFlow
, 1 );
739 bSuppressRotation
=true;
742 AddOpt( ESCHER_Prop_txflTextFlow
, 2 );
743 bSuppressRotation
=true;
746 AddOpt( ESCHER_Prop_txflTextFlow
, 3 );
747 bSuppressRotation
=true;
752 sal_Bool
EscherPropertyContainer::GetLineArrow( const sal_Bool bLineStart
,
753 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
754 ESCHER_LineEnd
& reLineEnd
, sal_Int32
& rnArrowLength
, sal_Int32
& rnArrowWidth
)
756 static String
sLineStart ( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ) );
757 static String
sLineStartName( RTL_CONSTASCII_USTRINGPARAM( "LineStartName" ) );
758 static String
sLineEnd ( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ) );
759 static String
sLineEndName ( RTL_CONSTASCII_USTRINGPARAM( "LineEndName" ) );
761 const String
sLine ( bLineStart
? sLineStart
: sLineEnd
);
762 const String
sLineName ( bLineStart
? sLineStartName
: sLineEndName
);
764 sal_Bool bIsArrow
= sal_False
;
766 ::com::sun::star::uno::Any aAny
;
767 if ( EscherPropertyValueHelper::GetPropertyValue(
768 aAny
, rXPropSet
, sLine
, sal_False
) )
770 PolyPolygon
aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aAny
) );
771 if ( aPolyPoly
.Count() && aPolyPoly
[ 0 ].GetSize() )
775 reLineEnd
= ESCHER_LineArrowEnd
;
779 if ( EscherPropertyValueHelper::GetPropertyValue(
780 aAny
, rXPropSet
, sLineName
, sal_False
) )
782 String aArrowStartName
= *(::rtl::OUString
*)aAny
.getValue();
783 rtl::OUString aApiName
;
784 sal_Int16 nWhich
= bLineStart
? XATTR_LINESTART
: XATTR_LINEEND
;
786 SvxUnogetApiNameForItem( nWhich
, aArrowStartName
, aApiName
);
787 if ( aApiName
.getLength() )
791 calculate the best option for ArrowLenght and ArrowWidth
793 if ( aApiName
.equalsAscii( "Arrow concave" ) )
794 reLineEnd
= ESCHER_LineArrowStealthEnd
;
795 else if ( aApiName
.equalsAscii( "Square 45" ) )
796 reLineEnd
= ESCHER_LineArrowDiamondEnd
;
797 else if ( aApiName
.equalsAscii( "Small Arrow" ) )
798 reLineEnd
= ESCHER_LineArrowEnd
;
799 else if ( aApiName
.equalsAscii( "Dimension Lines" ) )
803 reLineEnd
= ESCHER_LineArrowOvalEnd
;
805 else if ( aApiName
.equalsAscii( "Double Arrow" ) )
806 reLineEnd
= ESCHER_LineArrowEnd
;
807 else if ( aApiName
.equalsAscii( "Rounded short Arrow" ) )
808 reLineEnd
= ESCHER_LineArrowEnd
;
809 else if ( aApiName
.equalsAscii( "Symmetric Arrow" ) )
810 reLineEnd
= ESCHER_LineArrowEnd
;
811 else if ( aApiName
.equalsAscii( "Line Arrow" ) )
812 reLineEnd
= ESCHER_LineArrowOpenEnd
;
813 else if ( aApiName
.equalsAscii( "Rounded large Arrow" ) )
814 reLineEnd
= ESCHER_LineArrowEnd
;
815 else if ( aApiName
.equalsAscii( "Circle" ) )
816 reLineEnd
= ESCHER_LineArrowOvalEnd
;
817 else if ( aApiName
.equalsAscii( "Square" ) )
818 reLineEnd
= ESCHER_LineArrowDiamondEnd
;
819 else if ( aApiName
.equalsAscii( "Arrow" ) )
820 reLineEnd
= ESCHER_LineArrowEnd
;
822 else if ( aArrowStartName
.GetTokenCount( ' ' ) == 2 )
824 sal_Bool b
= sal_True
;
825 String
aArrowName( aArrowStartName
.GetToken( 0, ' ' ) );
826 if ( aArrowName
.EqualsAscii( "msArrowEnd" ) )
827 reLineEnd
= ESCHER_LineArrowEnd
;
828 else if ( aArrowName
.EqualsAscii( "msArrowOpenEnd" ) )
829 reLineEnd
= ESCHER_LineArrowOpenEnd
;
830 else if ( aArrowName
.EqualsAscii( "msArrowStealthEnd" ) )
831 reLineEnd
= ESCHER_LineArrowStealthEnd
;
832 else if ( aArrowName
.EqualsAscii( "msArrowDiamondEnd" ) )
833 reLineEnd
= ESCHER_LineArrowDiamondEnd
;
834 else if ( aArrowName
.EqualsAscii( "msArrowOvalEnd" ) )
835 reLineEnd
= ESCHER_LineArrowOvalEnd
;
839 // now we have the arrow, and try to determine the arrow size;
842 String
aArrowSize( aArrowStartName
.GetToken( 1, ' ' ) );
843 sal_Int32 nArrowSize
= aArrowSize
.ToInt32();
844 rnArrowWidth
= ( nArrowSize
- 1 ) / 3;
845 rnArrowLength
= nArrowSize
- ( rnArrowWidth
* 3 ) - 1;
854 void EscherPropertyContainer::CreateLineProperties(
855 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
858 ::com::sun::star::uno::Any aAny
;
859 sal_uInt32 nLineFlags
= 0x80008;
861 ESCHER_LineEnd eLineEnd
;
862 sal_Int32 nArrowLength
;
863 sal_Int32 nArrowWidth
;
865 sal_Bool bSwapLineEnds
= sal_False
;
866 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ), sal_True
) )
868 ::com::sun::star::drawing::CircleKind eCircleKind
;
869 if ( aAny
>>= eCircleKind
)
871 if ( eCircleKind
== ::com::sun::star::drawing::CircleKind_ARC
)
872 bSwapLineEnds
= sal_True
;
875 if ( GetLineArrow( bSwapLineEnds
? sal_False
: sal_True
, rXPropSet
, eLineEnd
, nArrowLength
, nArrowWidth
) )
877 AddOpt( ESCHER_Prop_lineStartArrowLength
, nArrowLength
);
878 AddOpt( ESCHER_Prop_lineStartArrowWidth
, nArrowWidth
);
879 AddOpt( ESCHER_Prop_lineStartArrowhead
, eLineEnd
);
880 nLineFlags
|= 0x100010;
882 if ( GetLineArrow( bSwapLineEnds
? sal_True
: sal_False
, rXPropSet
, eLineEnd
, nArrowLength
, nArrowWidth
) )
884 AddOpt( ESCHER_Prop_lineEndArrowLength
, nArrowLength
);
885 AddOpt( ESCHER_Prop_lineEndArrowWidth
, nArrowWidth
);
886 AddOpt( ESCHER_Prop_lineEndArrowhead
, eLineEnd
);
887 nLineFlags
|= 0x100010;
889 if ( EscherPropertyValueHelper::GetPropertyValue(
890 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "LineStyle" ) ), sal_False
) )
892 ::com::sun::star::drawing::LineStyle eLS
;
897 case ::com::sun::star::drawing::LineStyle_NONE
:
898 AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x90000 ); // 80000
901 case ::com::sun::star::drawing::LineStyle_DASH
:
903 if ( EscherPropertyValueHelper::GetPropertyValue(
904 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "LineDash" ) ), sal_False
) )
906 ESCHER_LineDashing eDash
= ESCHER_LineSolid
;
907 ::com::sun::star::drawing::LineDash
* pLineDash
= (::com::sun::star::drawing::LineDash
*)aAny
.getValue();
908 sal_Int32 nDistance
= pLineDash
->Distance
<< 1;
909 switch ( pLineDash
->Style
)
911 case ::com::sun::star::drawing::DashStyle_ROUND
:
912 case ::com::sun::star::drawing::DashStyle_ROUNDRELATIVE
:
913 AddOpt( ESCHER_Prop_lineEndCapStyle
, 0 ); // Style Round setzen
917 if ( ((!(pLineDash
->Dots
)) || (!(pLineDash
->Dashes
)) ) || ( pLineDash
->DotLen
== pLineDash
->DashLen
) )
919 sal_Int32 nLen
= pLineDash
->DotLen
;
920 if ( pLineDash
->Dashes
)
921 nLen
= pLineDash
->DashLen
;
923 if ( nLen
>= nDistance
)
924 eDash
= ESCHER_LineLongDashGEL
;
925 else if ( pLineDash
->Dots
)
926 eDash
= ESCHER_LineDotSys
;
928 eDash
= ESCHER_LineDashGEL
;
932 if ( pLineDash
->Dots
!= pLineDash
->Dashes
)
934 if ( ( pLineDash
->DashLen
> nDistance
) || ( pLineDash
->DotLen
> nDistance
) )
935 eDash
= ESCHER_LineLongDashDotDotGEL
;
937 eDash
= ESCHER_LineDashDotDotSys
;
941 if ( ( pLineDash
->DashLen
> nDistance
) || ( pLineDash
->DotLen
> nDistance
) )
942 eDash
= ESCHER_LineLongDashDotGEL
;
944 eDash
= ESCHER_LineDashDotGEL
;
948 AddOpt( ESCHER_Prop_lineDashing
, eDash
);
951 case ::com::sun::star::drawing::LineStyle_SOLID
:
954 AddOpt( ESCHER_Prop_fNoLineDrawDash
, nLineFlags
);
959 if ( EscherPropertyValueHelper::GetPropertyValue(
960 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "LineColor" ) ), sal_False
) )
962 sal_uInt32 nLineColor
= ImplGetColor( *((sal_uInt32
*)aAny
.getValue()) );
963 AddOpt( ESCHER_Prop_lineColor
, nLineColor
);
964 AddOpt( ESCHER_Prop_lineBackColor
, nLineColor
^ 0xffffff );
968 sal_uInt32 nLineSize
= ( EscherPropertyValueHelper::GetPropertyValue(
969 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "LineWidth" ) ), sal_False
) )
970 ? *((sal_uInt32
*)aAny
.getValue())
973 AddOpt( ESCHER_Prop_lineWidth
, nLineSize
* 360 ); // 100TH MM -> PT , 1PT = 12700 EMU
975 ESCHER_LineJoin eLineJoin
= ESCHER_LineJoinMiter
;
976 if ( EscherPropertyValueHelper::GetPropertyValue(
977 aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "LineJoint" ) ), sal_True
) )
979 ::com::sun::star::drawing::LineJoint eLJ
;
984 case com::sun::star::drawing::LineJoint_NONE
:
985 case com::sun::star::drawing::LineJoint_MIDDLE
:
986 case com::sun::star::drawing::LineJoint_BEVEL
:
987 eLineJoin
= ESCHER_LineJoinBevel
;
990 case com::sun::star::drawing::LineJoint_MITER
:
991 eLineJoin
= ESCHER_LineJoinMiter
;
993 case com::sun::star::drawing::LineJoint_ROUND
:
994 eLineJoin
= ESCHER_LineJoinRound
;
999 AddOpt( ESCHER_Prop_lineJoinStyle
, eLineJoin
);
1001 if ( bEdge
== sal_False
)
1003 AddOpt( ESCHER_Prop_fFillOK
, 0x1001 );
1004 AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100000 );
1008 static Size
lcl_SizeToEmu(Size aPrefSize
, MapMode aPrefMapMode
)
1011 if (aPrefMapMode
== MAP_PIXEL
)
1012 aRetSize
= Application::GetDefaultDevice()->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
1014 aRetSize
= Application::GetDefaultDevice()->LogicToLogic( aPrefSize
, aPrefMapMode
, MAP_100TH_MM
);
1018 void EscherPropertyContainer::ImplCreateGraphicAttributes( const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
1019 sal_uInt32 nBlibId
, sal_Bool bCreateCroppingAttributes
)
1021 ::com::sun::star::uno::Any aAny
;
1023 sal_uInt32 nPicFlags
= 0;
1024 ::com::sun::star::drawing::ColorMode
eColorMode( ::com::sun::star::drawing::ColorMode_STANDARD
);
1025 sal_Int16 nLuminance
= 0;
1026 sal_Int32 nContrast
= 0;
1028 sal_Int16 nGreen
= 0;
1029 sal_Int16 nBlue
= 0;
1030 double fGamma
= 1.0;
1031 sal_Int16 nTransparency
= 0;
1033 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicColorMode" ) ) ) )
1034 aAny
>>= eColorMode
;
1035 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustLuminance" ) ) ) )
1036 aAny
>>= nLuminance
;
1037 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustContrast" ) ) ) )
1039 sal_Int16 nC
= sal_Int16();
1043 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustRed" ) ) ) )
1045 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustGreen" ) ) ) )
1047 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustBlue" ) ) ) )
1049 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "Gamma" ) ) ) )
1051 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "Transparency" ) ) ) )
1052 aAny
>>= nTransparency
;
1054 if ( eColorMode
== ::com::sun::star::drawing::ColorMode_WATERMARK
)
1056 eColorMode
= ::com::sun::star::drawing::ColorMode_STANDARD
;
1058 if ( nLuminance
> 100 )
1061 if ( nContrast
< -100 )
1064 if ( eColorMode
== ::com::sun::star::drawing::ColorMode_GREYS
)
1065 nPicFlags
|= 0x40004;
1066 else if ( eColorMode
== ::com::sun::star::drawing::ColorMode_MONO
)
1067 nPicFlags
|= 0x60006;
1072 if ( nContrast
== 100)
1073 nContrast
= 0x10000;
1074 else if ( nContrast
< 100 )
1076 nContrast
*= 0x10000;
1079 else if ( nContrast
< 200 )
1080 nContrast
= ( 100 * 0x10000 ) / ( 200 - nContrast
);
1082 nContrast
= 0x7fffffff;
1083 AddOpt( ESCHER_Prop_pictureContrast
, nContrast
);
1086 AddOpt( ESCHER_Prop_pictureBrightness
, nLuminance
* 327 );
1088 AddOpt( ESCHER_Prop_pictureActive
, nPicFlags
);
1090 if ( bCreateCroppingAttributes
&& pGraphicProvider
)
1093 MapMode aPrefMapMode
;
1094 if ( pGraphicProvider
->GetPrefSize( nBlibId
, aPrefSize
, aPrefMapMode
) )
1096 Size
aCropSize(lcl_SizeToEmu(aPrefSize
, aPrefMapMode
));
1097 if ( aCropSize
.Width() && aCropSize
.Height() )
1099 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicCrop" ) ) ) )
1101 ::com::sun::star::text::GraphicCrop aGraphCrop
;
1102 if ( aAny
>>= aGraphCrop
)
1104 if ( aGraphCrop
.Left
)
1106 sal_uInt32 nLeft
= ( aGraphCrop
.Left
* 65536 ) / aCropSize
.Width();
1107 AddOpt( ESCHER_Prop_cropFromLeft
, nLeft
);
1109 if ( aGraphCrop
.Top
)
1111 sal_uInt32 nTop
= ( aGraphCrop
.Top
* 65536 ) / aCropSize
.Height();
1112 AddOpt( ESCHER_Prop_cropFromTop
, nTop
);
1114 if ( aGraphCrop
.Right
)
1116 sal_uInt32 nRight
= ( aGraphCrop
.Right
* 65536 ) / aCropSize
.Width();
1117 AddOpt( ESCHER_Prop_cropFromRight
, nRight
);
1119 if ( aGraphCrop
.Bottom
)
1121 sal_uInt32 nBottom
= ( aGraphCrop
.Bottom
* 65536 ) / aCropSize
.Height();
1122 AddOpt( ESCHER_Prop_cropFromBottom
, nBottom
);
1131 sal_Bool
EscherPropertyContainer::CreateOLEGraphicProperties(
1132 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rXShape
)
1134 sal_Bool bRetValue
= sal_False
;
1138 SdrObject
* pSdrOLE2( GetSdrObjectFromXShape( rXShape
) ); // SJ: leaving unoapi, because currently there is
1139 if ( pSdrOLE2
&& pSdrOLE2
->ISA( SdrOle2Obj
) ) // no access to the native graphic object
1141 Graphic
* pGraphic
= ((SdrOle2Obj
*)pSdrOLE2
)->GetGraphic();
1144 GraphicObject
aGraphicObject( *pGraphic
);
1145 ByteString
aUniqueId( aGraphicObject
.GetUniqueID() );
1146 if ( aUniqueId
.Len() )
1148 AddOpt( ESCHER_Prop_fillType
, ESCHER_FillPicture
);
1149 uno::Reference
< beans::XPropertySet
> aXPropSet( rXShape
, uno::UNO_QUERY
);
1151 if ( pGraphicProvider
&& pPicOutStrm
&& pShapeBoundRect
&& aXPropSet
.is() )
1153 ::com::sun::star::uno::Any aAny
;
1154 ::com::sun::star::awt::Rectangle
* pVisArea
= NULL
;
1155 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ) ) )
1157 pVisArea
= new ::com::sun::star::awt::Rectangle
;
1158 aAny
>>= (*pVisArea
);
1160 Rectangle
aRect( Point( 0, 0 ), pShapeBoundRect
->GetSize() );
1161 sal_uInt32 nBlibId
= pGraphicProvider
->GetBlibID( *pPicOutStrm
, aUniqueId
, aRect
, pVisArea
, NULL
);
1164 AddOpt( ESCHER_Prop_pib
, nBlibId
, sal_True
);
1165 ImplCreateGraphicAttributes( aXPropSet
, nBlibId
, sal_False
);
1166 bRetValue
= sal_True
;
1178 sal_Bool
EscherPropertyContainer::ImplCreateEmbeddedBmp( const ByteString
& rUniqueId
)
1180 if( rUniqueId
.Len() > 0 )
1182 EscherGraphicProvider aProvider
;
1183 SvMemoryStream aMemStrm
;
1185 if ( aProvider
.GetBlibID( aMemStrm
, rUniqueId
, aRect
) )
1187 // grab BLIP from stream and insert directly as complex property
1188 // ownership of stream memory goes to complex property
1189 aMemStrm
.ObjectOwnsMemory( FALSE
);
1190 sal_uInt8
* pBuf
= (sal_uInt8
*) aMemStrm
.GetData();
1191 sal_uInt32 nSize
= aMemStrm
.Seek( STREAM_SEEK_TO_END
);
1192 AddOpt( ESCHER_Prop_fillBlip
, sal_True
, nSize
, pBuf
, nSize
);
1199 sal_Bool
EscherPropertyContainer::CreateEmbeddedBitmapProperties(
1200 const ::rtl::OUString
& rBitmapUrl
, ::com::sun::star::drawing::BitmapMode eBitmapMode
)
1202 sal_Bool bRetValue
= sal_False
;
1203 String
aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
1204 String
aBmpUrl( rBitmapUrl
);
1205 xub_StrLen nIndex
= aBmpUrl
.Search( aVndUrl
, 0 );
1206 if( nIndex
!= STRING_NOTFOUND
)
1208 // note: += ist not defined for xub_StrLen -> conversion to int and back to xub_StrLen
1209 nIndex
= nIndex
+ aVndUrl
.Len();
1210 if( aBmpUrl
.Len() > nIndex
)
1212 ByteString
aUniqueId( aBmpUrl
, nIndex
, aBmpUrl
.Len() - nIndex
, RTL_TEXTENCODING_UTF8
);
1213 bRetValue
= ImplCreateEmbeddedBmp( aUniqueId
);
1216 // bitmap mode property
1217 bool bRepeat
= eBitmapMode
== ::com::sun::star::drawing::BitmapMode_REPEAT
;
1218 AddOpt( ESCHER_Prop_fillType
, bRepeat
? ESCHER_FillTexture
: ESCHER_FillPicture
);
1228 GraphicObject
lclDrawHatch( const ::com::sun::star::drawing::Hatch
& rHatch
, const Color
& rBackColor
, bool bFillBackground
)
1230 const MapMode
aMap100( MAP_100TH_MM
);
1231 VirtualDevice
aVDev( *Application::GetDefaultDevice(), 0, 1 );
1232 aVDev
.SetMapMode( aMap100
);
1234 const Size aOutSize
= aVDev
.PixelToLogic( Size( 28, 28 ) );
1235 aVDev
.SetOutputSize( aOutSize
);
1237 Rectangle
aRectangle( Point( 0, 0 ), aOutSize
);
1238 const PolyPolygon
aPolyPoly( aRectangle
);
1240 aVDev
.SetLineColor();
1241 aVDev
.SetFillColor( bFillBackground
? rBackColor
: Color( COL_TRANSPARENT
) );
1242 aVDev
.DrawRect( Rectangle( Point(), aOutSize
) );
1244 Hatch
aVclHatch( (HatchStyle
) rHatch
.Style
, Color( rHatch
.Color
), rHatch
.Distance
, (sal_uInt16
)rHatch
.Angle
);
1245 aVDev
.DrawHatch( aPolyPoly
, aVclHatch
);
1247 return GraphicObject( Graphic( aVDev
.GetBitmapEx( Point(), aOutSize
) ) );
1253 sal_Bool
EscherPropertyContainer::CreateEmbeddedHatchProperties( const ::com::sun::star::drawing::Hatch
& rHatch
, const Color
& rBackColor
, bool bFillBackground
)
1255 GraphicObject aGraphicObject
= lclDrawHatch( rHatch
, rBackColor
, bFillBackground
);
1256 ByteString aUniqueId
= aGraphicObject
.GetUniqueID();
1257 sal_Bool bRetValue
= ImplCreateEmbeddedBmp( aUniqueId
);
1259 AddOpt( ESCHER_Prop_fillType
, ESCHER_FillTexture
);
1264 sal_Bool
EscherPropertyContainer::CreateGraphicProperties(
1265 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
1266 const String
& rSource
, const sal_Bool bCreateFillBitmap
, const sal_Bool bCreateCroppingAttributes
,
1267 const sal_Bool bFillBitmapModeAllowed
)
1269 sal_Bool bRetValue
= sal_False
;
1270 sal_Bool bCreateFillStyles
= sal_False
;
1272 sal_Bool bMirrored
= sal_False
;
1273 sal_Bool bRotate
= sal_True
;
1274 sal_uInt16 nAngle
= 0;
1275 GraphicAttr
* pGraphicAttr
= NULL
;
1276 GraphicObject aGraphicObject
;
1278 ByteString aUniqueId
;
1279 bool bIsGraphicMtf(false);
1281 ::com::sun::star::drawing::BitmapMode
eBitmapMode( ::com::sun::star::drawing::BitmapMode_NO_REPEAT
);
1282 ::com::sun::star::uno::Any aAny
;
1284 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, rSource
) )
1286 if ( rSource
== String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ) )
1288 ::com::sun::star::uno::Sequence
<sal_uInt8
> aSeq
= *(::com::sun::star::uno::Sequence
<sal_uInt8
>*)aAny
.getValue();
1289 const sal_uInt8
* pAry
= aSeq
.getArray();
1290 sal_uInt32 nAryLen
= aSeq
.getLength();
1292 // the metafile is already rotated
1293 bRotate
= sal_False
;
1295 if ( pAry
&& nAryLen
)
1298 SvMemoryStream
aTemp( (void*)pAry
, nAryLen
, STREAM_READ
);
1299 sal_uInt32 nErrCode
= GraphicConverter::Import( aTemp
, aGraphic
, CVT_WMF
);
1300 if ( nErrCode
== ERRCODE_NONE
)
1302 aGraphicObject
= aGraphic
;
1303 aUniqueId
= aGraphicObject
.GetUniqueID();
1304 bIsGraphicMtf
= aGraphicObject
.GetType() == GRAPHIC_GDIMETAFILE
;
1308 else if ( rSource
== String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) )
1310 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XBitmap
>xBitmap
;
1311 if ( ::cppu::extractInterface( xBitmap
, aAny
) )
1313 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XBitmap
> xBmp
;
1314 if ( aAny
>>= xBmp
)
1316 BitmapEx
aBitmapEx( VCLUnoHelper::GetBitmap( xBmp
) );
1317 Graphic
aGraphic( aBitmapEx
);
1318 aGraphicObject
= aGraphic
;
1319 aUniqueId
= aGraphicObject
.GetUniqueID();
1320 bIsGraphicMtf
= aGraphicObject
.GetType() == GRAPHIC_GDIMETAFILE
;
1324 else if ( rSource
== String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ) )
1326 aGraphicUrl
= *(::rtl::OUString
*)aAny
.getValue();
1328 else if ( rSource
== String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ) )
1330 aGraphicUrl
= *(::rtl::OUString
*)aAny
.getValue();
1331 bCreateFillStyles
= sal_True
;
1333 else if ( rSource
== String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ) )
1335 ::com::sun::star::drawing::Hatch aHatch
;
1336 if ( aAny
>>= aHatch
)
1339 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1340 String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False
) )
1342 aBackColor
= ImplGetColor( *((sal_uInt32
*)aAny
.getValue()), sal_False
);
1344 bool bFillBackground
= false;
1345 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1346 String( RTL_CONSTASCII_USTRINGPARAM( "FillBackground" ) ), sal_True
) )
1348 aAny
>>= bFillBackground
;
1350 aGraphicObject
= lclDrawHatch( aHatch
, aBackColor
, bFillBackground
);
1351 aUniqueId
= aGraphicObject
.GetUniqueID();
1352 eBitmapMode
= ::com::sun::star::drawing::BitmapMode_REPEAT
;
1353 bIsGraphicMtf
= aGraphicObject
.GetType() == GRAPHIC_GDIMETAFILE
;
1357 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "IsMirrored" ) ), sal_True
) )
1360 if ( bCreateFillBitmap
&& bFillBitmapModeAllowed
)
1362 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapMode" ) ), sal_True
) )
1363 aAny
>>= eBitmapMode
;
1367 nAngle
= bRotate
&& EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1368 String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True
)
1369 ? (sal_uInt16
)( ( *((sal_Int32
*)aAny
.getValue() ) ) + 5 ) / 10
1373 if ( aGraphicUrl
.Len() )
1375 String
aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
1376 xub_StrLen nIndex
= aGraphicUrl
.Search( aVndUrl
, 0 );
1377 if ( nIndex
!= STRING_NOTFOUND
)
1379 nIndex
= nIndex
+ aVndUrl
.Len();
1380 if ( aGraphicUrl
.Len() > nIndex
)
1381 aUniqueId
= ByteString( aGraphicUrl
, nIndex
, aGraphicUrl
.Len() - nIndex
, RTL_TEXTENCODING_UTF8
);
1385 // externally, linked graphic? convert to embedded
1386 // one, if transformations are needed. this is because
1387 // everything < msoxp cannot even handle rotated
1389 // And check whether the graphic link target is
1390 // actually supported by mso.
1391 INetURLObject
aTmp( aGraphicUrl
);
1392 GraphicDescriptor
aDescriptor(aTmp
);
1393 aDescriptor
.Detect();
1394 const USHORT nFormat
= aDescriptor
.GetFileFormat();
1396 // can MSO handle it?
1397 if ( bMirrored
|| nAngle
||
1398 (nFormat
!= GFF_BMP
&&
1399 nFormat
!= GFF_GIF
&&
1400 nFormat
!= GFF_JPG
&&
1401 nFormat
!= GFF_PNG
&&
1402 nFormat
!= GFF_TIF
&&
1403 nFormat
!= GFF_PCT
&&
1404 nFormat
!= GFF_WMF
&&
1405 nFormat
!= GFF_EMF
) )
1407 SvStream
* pIn
= ::utl::UcbStreamHelper::CreateStream(
1408 aTmp
.GetMainURL( INetURLObject::NO_DECODE
), STREAM_READ
);
1412 sal_uInt32 nErrCode
= GraphicConverter::Import( *pIn
, aGraphic
);
1414 if ( nErrCode
== ERRCODE_NONE
)
1417 aGraphicObject
= aGraphic
;
1418 aUniqueId
= aGraphicObject
.GetUniqueID();
1420 // else: simply keep the graphic link
1427 if ( aGraphicUrl
.Len() || aUniqueId
.Len() )
1429 if ( bMirrored
|| nAngle
)
1431 pGraphicAttr
= new GraphicAttr
;
1433 pGraphicAttr
->SetMirrorFlags( BMP_MIRROR_HORZ
);
1434 if ( bIsGraphicMtf
)
1435 AddOpt( ESCHER_Prop_Rotation
, ( ( ((sal_Int32
)nAngle
<< 16 ) / 10 ) + 0x8000 ) &~ 0xffff );
1438 pGraphicAttr
->SetRotation( nAngle
);
1439 if ( nAngle
&& pShapeBoundRect
) // up to xp ppoint does not rotate bitmaps !
1441 Polygon
aPoly( *pShapeBoundRect
);
1442 aPoly
.Rotate( pShapeBoundRect
->TopLeft(), nAngle
);
1443 *pShapeBoundRect
= aPoly
.GetBoundRect();
1444 bSuppressRotation
= sal_True
;
1449 if ( eBitmapMode
== ::com::sun::star::drawing::BitmapMode_REPEAT
)
1450 AddOpt( ESCHER_Prop_fillType
, ESCHER_FillTexture
);
1452 AddOpt( ESCHER_Prop_fillType
, ESCHER_FillPicture
);
1454 if ( aUniqueId
.Len() )
1456 // write out embedded graphic
1457 if ( pGraphicProvider
&& pPicOutStrm
&& pShapeBoundRect
)
1459 Rectangle
aRect( Point( 0, 0 ), pShapeBoundRect
->GetSize() );
1461 sal_uInt32 nBlibId
= 0;
1462 nBlibId
= pGraphicProvider
->GetBlibID( *pPicOutStrm
, aUniqueId
, aRect
, NULL
, pGraphicAttr
);
1465 if ( bCreateFillBitmap
)
1466 AddOpt( ESCHER_Prop_fillBlip
, nBlibId
, sal_True
);
1469 AddOpt( ESCHER_Prop_pib
, nBlibId
, sal_True
);
1470 ImplCreateGraphicAttributes( rXPropSet
, nBlibId
, bCreateCroppingAttributes
);
1472 bRetValue
= sal_True
;
1477 EscherGraphicProvider aProvider
;
1478 SvMemoryStream aMemStrm
;
1481 if ( aProvider
.GetBlibID( aMemStrm
, aUniqueId
, aRect
, NULL
, pGraphicAttr
) )
1483 // grab BLIP from stream and insert directly as complex property
1484 // ownership of stream memory goes to complex property
1485 aMemStrm
.ObjectOwnsMemory( FALSE
);
1486 sal_uInt8
* pBuf
= (sal_uInt8
*) aMemStrm
.GetData();
1487 sal_uInt32 nSize
= aMemStrm
.Seek( STREAM_SEEK_TO_END
);
1488 AddOpt( ESCHER_Prop_fillBlip
, sal_True
, nSize
, pBuf
, nSize
);
1489 bRetValue
= sal_True
;
1493 // write out link to graphic
1496 OSL_ASSERT(aGraphicUrl
.Len());
1498 AddOpt( ESCHER_Prop_pibName
, aGraphicUrl
);
1499 sal_uInt32 nPibFlags
=0;
1500 GetOpt( ESCHER_Prop_pibFlags
, nPibFlags
);
1501 AddOpt( ESCHER_Prop_pibFlags
,
1502 ESCHER_BlipFlagLinkToFile
|ESCHER_BlipFlagFile
|ESCHER_BlipFlagDoNotSave
| nPibFlags
);
1506 delete pGraphicAttr
;
1507 if ( bCreateFillStyles
)
1508 CreateFillProperties( rXPropSet
, sal_True
);
1513 PolyPolygon
EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rXShape
)
1515 PolyPolygon aRetPolyPoly
;
1516 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> aXPropSet
;
1517 ::com::sun::star::uno::Any
aAny( rXShape
->queryInterface(
1518 ::getCppuType( (const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>*) 0 ) ));
1520 String
sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
1521 String
sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
1522 String
sPolygon ( RTL_CONSTASCII_USTRINGPARAM( "Polygon" ) );
1524 if ( aAny
>>= aXPropSet
)
1526 sal_Bool bHasProperty
= EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sPolyPolygonBezier
, sal_True
);
1527 if ( !bHasProperty
)
1528 bHasProperty
= EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sPolyPolygon
, sal_True
);
1529 if ( !bHasProperty
)
1530 bHasProperty
= EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sPolygon
, sal_True
);
1532 aRetPolyPoly
= GetPolyPolygon( aAny
);
1534 return aRetPolyPoly
;
1537 PolyPolygon
EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Any
& rAny
)
1539 sal_Bool bNoError
= sal_True
;
1542 PolyPolygon aPolyPolygon
;
1544 if ( rAny
.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PolyPolygonBezierCoords
* ) 0 ) )
1546 ::com::sun::star::drawing::PolyPolygonBezierCoords
* pSourcePolyPolygon
1547 = (::com::sun::star::drawing::PolyPolygonBezierCoords
*)rAny
.getValue();
1548 sal_uInt16 nOuterSequenceCount
= (sal_uInt16
)pSourcePolyPolygon
->Coordinates
.getLength();
1550 // Zeiger auf innere sequences holen
1551 ::com::sun::star::drawing::PointSequence
* pOuterSequence
= pSourcePolyPolygon
->Coordinates
.getArray();
1552 ::com::sun::star::drawing::FlagSequence
* pOuterFlags
= pSourcePolyPolygon
->Flags
.getArray();
1554 bNoError
= pOuterSequence
&& pOuterFlags
;
1557 sal_uInt16 a
, b
, nInnerSequenceCount
;
1558 ::com::sun::star::awt::Point
* pArray
;
1560 // dies wird ein Polygon set
1561 for ( a
= 0; a
< nOuterSequenceCount
; a
++ )
1563 ::com::sun::star::drawing::PointSequence
* pInnerSequence
= pOuterSequence
++;
1564 ::com::sun::star::drawing::FlagSequence
* pInnerFlags
= pOuterFlags
++;
1566 bNoError
= pInnerSequence
&& pInnerFlags
;
1569 // Zeiger auf Arrays holen
1570 pArray
= pInnerSequence
->getArray();
1571 ::com::sun::star::drawing::PolygonFlags
* pFlags
= pInnerFlags
->getArray();
1573 if ( pArray
&& pFlags
)
1575 nInnerSequenceCount
= (sal_uInt16
)pInnerSequence
->getLength();
1576 aPolygon
= Polygon( nInnerSequenceCount
);
1577 for( b
= 0; b
< nInnerSequenceCount
; b
++)
1579 PolyFlags
ePolyFlags( *( (PolyFlags
*)pFlags
++ ) );
1580 ::com::sun::star::awt::Point
aPoint( (::com::sun::star::awt::Point
)*(pArray
++) );
1581 aPolygon
[ b
] = Point( aPoint
.X
, aPoint
.Y
);
1582 aPolygon
.SetFlags( b
, ePolyFlags
);
1584 if ( ePolyFlags
== POLY_CONTROL
)
1587 aPolyPolygon
.Insert( aPolygon
, POLYPOLY_APPEND
);
1593 else if ( rAny
.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequenceSequence
* ) 0 ) )
1595 ::com::sun::star::drawing::PointSequenceSequence
* pSourcePolyPolygon
1596 = (::com::sun::star::drawing::PointSequenceSequence
*)rAny
.getValue();
1597 sal_uInt16 nOuterSequenceCount
= (sal_uInt16
)pSourcePolyPolygon
->getLength();
1599 // Zeiger auf innere sequences holen
1600 ::com::sun::star::drawing::PointSequence
* pOuterSequence
= pSourcePolyPolygon
->getArray();
1601 bNoError
= pOuterSequence
!= NULL
;
1604 sal_uInt16 a
, b
, nInnerSequenceCount
;
1606 // dies wird ein Polygon set
1607 for( a
= 0; a
< nOuterSequenceCount
; a
++ )
1609 ::com::sun::star::drawing::PointSequence
* pInnerSequence
= pOuterSequence
++;
1610 bNoError
= pInnerSequence
!= NULL
;
1613 // Zeiger auf Arrays holen
1614 ::com::sun::star::awt::Point
* pArray
=
1615 pInnerSequence
->getArray();
1616 if ( pArray
!= NULL
)
1618 nInnerSequenceCount
= (sal_uInt16
)pInnerSequence
->getLength();
1619 aPolygon
= Polygon( nInnerSequenceCount
);
1620 for( b
= 0; b
< nInnerSequenceCount
; b
++)
1622 aPolygon
[ b
] = Point( pArray
->X
, pArray
->Y
);
1625 aPolyPolygon
.Insert( aPolygon
, POLYPOLY_APPEND
);
1631 else if ( rAny
.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequence
* ) 0 ) )
1633 ::com::sun::star::drawing::PointSequence
* pInnerSequence
=
1634 (::com::sun::star::drawing::PointSequence
*)rAny
.getValue();
1636 bNoError
= pInnerSequence
!= NULL
;
1639 sal_uInt16 a
, nInnerSequenceCount
;
1641 // Zeiger auf Arrays holen
1642 ::com::sun::star::awt::Point
* pArray
= pInnerSequence
->getArray();
1643 if ( pArray
!= NULL
)
1645 nInnerSequenceCount
= (sal_uInt16
)pInnerSequence
->getLength();
1646 aPolygon
= Polygon( nInnerSequenceCount
);
1647 for( a
= 0; a
< nInnerSequenceCount
; a
++)
1649 aPolygon
[ a
] = Point( pArray
->X
, pArray
->Y
);
1652 aPolyPolygon
.Insert( aPolygon
, POLYPOLY_APPEND
);
1656 return aPolyPolygon
;
1659 sal_Bool
EscherPropertyContainer::CreatePolygonProperties(
1660 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
1663 ::com::sun::star::awt::Rectangle
& rGeoRect
,
1666 static String
sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
1667 static String
sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
1669 sal_Bool bRetValue
= sal_True
;
1670 sal_Bool bLine
= ( nFlags
& ESCHER_CREATEPOLYGON_LINE
) != 0;
1672 PolyPolygon aPolyPolygon
;
1675 aPolyPolygon
.Insert( *pPolygon
, POLYPOLY_APPEND
);
1678 ::com::sun::star::uno::Any aAny
;
1679 bRetValue
= EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1680 ( bBezier
) ? sPolyPolygonBezier
: sPolyPolygon
, sal_True
);
1683 aPolyPolygon
= GetPolyPolygon( aAny
);
1684 bRetValue
= aPolyPolygon
.Count() != 0;
1691 if ( ( aPolyPolygon
.Count() == 1 ) && ( aPolyPolygon
[ 0 ].GetSize() == 2 ) )
1693 const Polygon
& rPoly
= aPolyPolygon
[ 0 ];
1694 rGeoRect
= ::com::sun::star::awt::Rectangle(
1697 rPoly
[ 1 ].X() - rPoly
[ 0 ].X(),
1698 rPoly
[ 1 ].Y() - rPoly
[ 0 ].Y() );
1701 bRetValue
= sal_False
;
1707 sal_uInt16 i
, j
, k
, nPoints
, nBezPoints
, nPolyCount
= aPolyPolygon
.Count();
1708 Rectangle
aRect( aPolyPolygon
.GetBoundRect() );
1709 rGeoRect
= ::com::sun::star::awt::Rectangle( aRect
.Left(), aRect
.Top(), aRect
.GetWidth(), aRect
.GetHeight() );
1711 for ( nBezPoints
= nPoints
= i
= 0; i
< nPolyCount
; i
++ )
1713 k
= aPolyPolygon
[ i
].GetSize();
1714 nPoints
= nPoints
+ k
;
1715 for ( j
= 0; j
< k
; j
++ )
1717 if ( aPolyPolygon
[ i
].GetFlags( j
) != POLY_CONTROL
)
1721 sal_uInt32 nVerticesBufSize
= ( nPoints
<< 2 ) + 6;
1722 sal_uInt8
* pVerticesBuf
= new sal_uInt8
[ nVerticesBufSize
];
1725 sal_uInt32 nSegmentBufSize
= ( ( nBezPoints
<< 2 ) + 8 );
1726 if ( nPolyCount
> 1 )
1727 nSegmentBufSize
+= ( nPolyCount
<< 1 );
1728 sal_uInt8
* pSegmentBuf
= new sal_uInt8
[ nSegmentBufSize
];
1730 sal_uInt8
* pPtr
= pVerticesBuf
;
1731 *pPtr
++ = (sal_uInt8
)( nPoints
); // Little endian
1732 *pPtr
++ = (sal_uInt8
)( nPoints
>> 8 );
1733 *pPtr
++ = (sal_uInt8
)( nPoints
);
1734 *pPtr
++ = (sal_uInt8
)( nPoints
>> 8 );
1735 *pPtr
++ = (sal_uInt8
)0xf0;
1736 *pPtr
++ = (sal_uInt8
)0xff;
1738 for ( j
= 0; j
< nPolyCount
; j
++ )
1740 aPolygon
= aPolyPolygon
[ j
];
1741 nPoints
= aPolygon
.GetSize();
1742 for ( i
= 0; i
< nPoints
; i
++ ) // Punkte aus Polygon in Buffer schreiben
1744 Point aPoint
= aPolygon
[ i
];
1745 aPoint
.X() -= rGeoRect
.X
;
1746 aPoint
.Y() -= rGeoRect
.Y
;
1748 *pPtr
++ = (sal_uInt8
)( aPoint
.X() );
1749 *pPtr
++ = (sal_uInt8
)( aPoint
.X() >> 8 );
1750 *pPtr
++ = (sal_uInt8
)( aPoint
.Y() );
1751 *pPtr
++ = (sal_uInt8
)( aPoint
.Y() >> 8 );
1756 *pPtr
++ = (sal_uInt8
)( ( nSegmentBufSize
- 6 ) >> 1 );
1757 *pPtr
++ = (sal_uInt8
)( ( nSegmentBufSize
- 6 ) >> 9 );
1758 *pPtr
++ = (sal_uInt8
)( ( nSegmentBufSize
- 6 ) >> 1 );
1759 *pPtr
++ = (sal_uInt8
)( ( nSegmentBufSize
- 6 ) >> 9 );
1760 *pPtr
++ = (sal_uInt8
)2;
1761 *pPtr
++ = (sal_uInt8
)0;
1763 for ( j
= 0; j
< nPolyCount
; j
++ )
1765 *pPtr
++ = 0x0; // Polygon start
1767 aPolygon
= aPolyPolygon
[ j
];
1768 nPoints
= aPolygon
.GetSize();
1769 for ( i
= 0; i
< nPoints
; i
++ ) // Polyflags in Buffer schreiben
1776 if ( ( i
+ 1 ) != nPoints
)
1779 if ( aPolygon
.GetFlags( i
+ 1 ) == POLY_CONTROL
)
1788 if ( nPolyCount
> 1 )
1790 *pPtr
++ = 1; // end of polygon
1797 AddOpt( ESCHER_Prop_geoRight
, rGeoRect
.Width
);
1798 AddOpt( ESCHER_Prop_geoBottom
, rGeoRect
.Height
);
1800 AddOpt( ESCHER_Prop_shapePath
, ESCHER_ShapeComplex
);
1801 AddOpt( ESCHER_Prop_pVertices
, TRUE
, nVerticesBufSize
- 6, (sal_uInt8
*)pVerticesBuf
, nVerticesBufSize
);
1802 AddOpt( ESCHER_Prop_pSegmentInfo
, TRUE
, nSegmentBufSize
, (sal_uInt8
*)pSegmentBuf
, nSegmentBufSize
);
1808 sal_Bool
EscherPropertyContainer::CreateConnectorProperties(
1809 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rXShape
,
1810 EscherSolverContainer
& rSolverContainer
, ::com::sun::star::awt::Rectangle
& rGeoRect
,
1811 sal_uInt16
& rShapeType
, sal_uInt16
& rShapeFlags
)
1813 static String
sEdgeKind ( RTL_CONSTASCII_USTRINGPARAM( "EdgeKind" ) );
1814 static String
sEdgeStartPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartPoint" ) );
1815 static String
sEdgeEndPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndPoint" ) );
1816 static String
sEdgeStartConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartConnection" ) );
1817 static String
sEdgeEndConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndConnection" ) );
1819 sal_Bool bRetValue
= sal_False
;
1820 rShapeType
= rShapeFlags
= 0;
1824 ::com::sun::star::awt::Point aStartPoint
, aEndPoint
;
1825 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> aXPropSet
;
1826 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> aShapeA
, aShapeB
;
1827 ::com::sun::star::uno::Any
aAny( rXShape
->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>*) 0 ) ));
1828 if ( aAny
>>= aXPropSet
)
1830 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sEdgeKind
, sal_True
) )
1832 ::com::sun::star::drawing::ConnectorType eCt
;
1834 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sEdgeStartPoint
) )
1836 aStartPoint
= *(::com::sun::star::awt::Point
*)aAny
.getValue();
1837 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sEdgeEndPoint
) )
1839 aEndPoint
= *(::com::sun::star::awt::Point
*)aAny
.getValue();
1841 rShapeFlags
= SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
| SHAPEFLAG_CONNECTOR
;
1842 rGeoRect
= ::com::sun::star::awt::Rectangle( aStartPoint
.X
, aStartPoint
.Y
,
1843 ( aEndPoint
.X
- aStartPoint
.X
) + 1, ( aEndPoint
.Y
- aStartPoint
.Y
) + 1 );
1844 if ( rGeoRect
.Height
< 0 ) // justify
1846 rShapeFlags
|= SHAPEFLAG_FLIPV
;
1847 rGeoRect
.Y
= aEndPoint
.Y
;
1848 rGeoRect
.Height
= -rGeoRect
.Height
;
1850 if ( rGeoRect
.Width
< 0 )
1852 rShapeFlags
|= SHAPEFLAG_FLIPH
;
1853 rGeoRect
.X
= aEndPoint
.X
;
1854 rGeoRect
.Width
= -rGeoRect
.Width
;
1856 sal_uInt32 nAdjustValue1
, nAdjustValue2
, nAdjustValue3
;
1857 nAdjustValue1
= nAdjustValue2
= nAdjustValue3
= 0x2a30;
1859 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sEdgeStartConnection
) )
1861 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, sEdgeEndConnection
) )
1864 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine1Delta" ) ) ) )
1867 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine2Delta" ) ) ) )
1870 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine3Delta" ) ) ) )
1873 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1HorzDist" ) ) ) )
1876 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1VertDist" ) ) ) )
1879 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2HorzDist" ) ) ) )
1882 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2VertDist" ) ) ) )
1886 rSolverContainer
.AddConnector( rXShape
, aStartPoint
, aShapeA
, aEndPoint
, aShapeB
);
1889 case ::com::sun::star::drawing::ConnectorType_CURVE
:
1891 rShapeType
= ESCHER_ShpInst_CurvedConnector3
;
1892 AddOpt( ESCHER_Prop_cxstyle
, ESCHER_cxstyleCurved
);
1893 AddOpt( ESCHER_Prop_adjustValue
, nAdjustValue1
);
1894 AddOpt( ESCHER_Prop_adjust2Value
, -(sal_Int32
)nAdjustValue2
);
1898 case ::com::sun::star::drawing::ConnectorType_STANDARD
:// Connector 2->5
1900 rShapeType
= ESCHER_ShpInst_BentConnector3
;
1901 AddOpt( ESCHER_Prop_cxstyle
, ESCHER_cxstyleBent
);
1906 case ::com::sun::star::drawing::ConnectorType_LINE
:
1907 case ::com::sun::star::drawing::ConnectorType_LINES
: // Connector 2->5
1909 rShapeType
= ESCHER_ShpInst_StraightConnector1
;
1910 AddOpt( ESCHER_Prop_cxstyle
, ESCHER_cxstyleStraight
);
1914 CreateLineProperties( aXPropSet
, sal_False
);
1915 bRetValue
= bSuppressRotation
= sal_True
;
1924 sal_Bool
EscherPropertyContainer::CreateShadowProperties(
1925 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
)
1927 ::com::sun::star::uno::Any aAny
;
1929 sal_Bool bHasShadow
= sal_False
; // shadow is possible only if at least a fillcolor, linecolor or graphic is set
1930 sal_uInt32 nLineFlags
= 0; // default : shape has no line
1931 sal_uInt32 nFillFlags
= 0x10; // shape is filled
1933 GetOpt( ESCHER_Prop_fNoLineDrawDash
, nLineFlags
);
1934 GetOpt( ESCHER_Prop_fNoFillHitTest
, nFillFlags
);
1937 sal_Bool bGraphic
= GetOpt( DFF_Prop_pib
, nDummy
) || GetOpt( DFF_Prop_pibName
, nDummy
) || GetOpt( DFF_Prop_pibFlags
, nDummy
);
1939 sal_uInt32 nShadowFlags
= 0x20000;
1940 if ( ( nLineFlags
& 8 ) || ( nFillFlags
& 0x10 ) || bGraphic
)
1942 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1943 String( RTL_CONSTASCII_USTRINGPARAM( "Shadow" ) ), sal_True
) )
1945 if ( aAny
>>= bHasShadow
)
1950 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1951 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowColor" ) ), sal_False
) )
1952 AddOpt( ESCHER_Prop_shadowColor
, ImplGetColor( *((sal_uInt32
*)aAny
.getValue()) ) );
1953 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1954 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowXDistance" ) ), sal_False
) )
1955 AddOpt( ESCHER_Prop_shadowOffsetX
, *((sal_Int32
*)aAny
.getValue()) * 360 );
1956 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1957 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowYDistance" ) ), sal_False
) )
1958 AddOpt( ESCHER_Prop_shadowOffsetY
, *((sal_Int32
*)aAny
.getValue()) * 360 );
1959 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, rXPropSet
,
1960 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowTransparence" ) ), sal_False
) )
1961 AddOpt( ESCHER_Prop_shadowOpacity
, 0x10000 - (((sal_uInt32
)*((sal_uInt16
*)aAny
.getValue())) * 655 ) );
1966 AddOpt( ESCHER_Prop_fshadowObscured
, nShadowFlags
);
1970 // ---------------------------------------------------------------------------------------------
1972 sal_Int32
GetValueForEnhancedCustomShapeParameter( const com::sun::star::drawing::EnhancedCustomShapeParameter
& rParameter
, const std::vector
< sal_Int32
>& rEquationOrder
)
1974 sal_Int32 nValue
= 0;
1975 if ( rParameter
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
1978 if ( rParameter
.Value
>>= fValue
)
1979 nValue
= (sal_Int32
)fValue
;
1982 rParameter
.Value
>>= nValue
;
1984 switch( rParameter
.Type
)
1986 case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION
:
1988 nValue
= (sal_uInt16
)rEquationOrder
[ nValue
];
1989 nValue
|= (sal_uInt32
)0x80000000;
1992 case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL
:
1997 /* not sure if it is allowed to set following values
1998 (but they are not yet used)
1999 case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
2000 case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
2001 case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
2002 case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
2003 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
2009 sal_Bool
GetValueForEnhancedCustomShapeHandleParameter( sal_Int32
& nRetValue
, const com::sun::star::drawing::EnhancedCustomShapeParameter
& rParameter
)
2011 sal_Bool bSpecial
= sal_False
;
2013 if ( rParameter
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
2016 if ( rParameter
.Value
>>= fValue
)
2017 nRetValue
= (sal_Int32
)fValue
;
2020 rParameter
.Value
>>= nRetValue
;
2022 switch( rParameter
.Type
)
2024 case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION
:
2027 bSpecial
= sal_True
;
2030 case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT
:
2033 bSpecial
= sal_True
;
2036 case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP
:
2037 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT
:
2040 bSpecial
= sal_True
;
2043 case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT
:
2044 case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM
:
2047 bSpecial
= sal_True
;
2050 case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL
:
2059 void ConvertEnhancedCustomShapeEquation( SdrObjCustomShape
* pCustoShape
,
2060 std::vector
< EnhancedCustomShapeEquation
>& rEquations
, std::vector
< sal_Int32
>& rEquationOrder
)
2064 uno::Sequence
< rtl::OUString
> sEquationSource
;
2065 const rtl::OUString
sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
2066 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)(const SdrCustomShapeGeometryItem
&)
2067 pCustoShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
2068 const uno::Any
* pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sEquations
);
2070 *pAny
>>= sEquationSource
;
2071 sal_Int32 nEquationSourceCount
= sEquationSource
.getLength();
2072 if ( nEquationSourceCount
)
2075 for ( i
= 0; i
< nEquationSourceCount
; i
++ )
2077 EnhancedCustomShape2d
aCustoShape2d( pCustoShape
);
2080 ::boost::shared_ptr
< EnhancedCustomShape::ExpressionNode
> aExpressNode(
2081 EnhancedCustomShape::FunctionParser::parseFunction( sEquationSource
[ i
], aCustoShape2d
) );
2082 com::sun::star::drawing::EnhancedCustomShapeParameter
aPara( aExpressNode
->fillNode( rEquations
, NULL
, 0 ) );
2083 if ( aPara
.Type
!= com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION
)
2085 EnhancedCustomShapeEquation aEquation
;
2086 aEquation
.nOperation
= 0;
2087 EnhancedCustomShape::FillEquationParameter( aPara
, 0, aEquation
);
2088 rEquations
.push_back( aEquation
);
2091 catch ( EnhancedCustomShape::ParseError
& )
2093 EnhancedCustomShapeEquation aEquation
; // ups, we should not be here,
2094 aEquation
.nOperation
= 0; // creating a default equation with value 1
2095 aEquation
.nPara
[ 0 ] = 1; // hoping that this will not break anything
2096 rEquations
.push_back( aEquation
);
2098 rEquationOrder
.push_back( rEquations
.size() - 1 );
2100 // now updating our old equation indices, they are marked with a bit in the hiword of nOperation
2101 std::vector
< EnhancedCustomShapeEquation
>::iterator
aIter( rEquations
.begin() );
2102 std::vector
< EnhancedCustomShapeEquation
>::iterator
aEnd ( rEquations
.end() );
2103 while( aIter
!= aEnd
)
2105 sal_Int32 nMask
= 0x20000000;
2106 for( i
= 0; i
< 3; i
++ )
2108 if ( aIter
->nOperation
& nMask
)
2110 aIter
->nOperation
^= nMask
;
2111 aIter
->nPara
[ i
] = rEquationOrder
[ aIter
->nPara
[ i
] & 0x3ff ] | 0x400;
2121 sal_Bool
EscherPropertyContainer::IsDefaultObject( SdrObjCustomShape
* pCustoShape
)
2123 sal_Bool bIsDefaultObject
= sal_False
;
2126 if ( pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_EQUATIONS
)
2127 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_VIEWBOX
)
2128 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_PATH
)
2129 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_GLUEPOINTS
)
2130 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_SEGMENTS
)
2131 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHX
)
2132 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHY
)
2133 // && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_HANDLES )
2134 && pCustoShape
->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_TEXTFRAMES
) )
2135 bIsDefaultObject
= sal_True
;
2138 return bIsDefaultObject
;
2141 void EscherPropertyContainer::LookForPolarHandles( const MSO_SPT eShapeType
, sal_Int32
& nAdjustmentsWhichNeedsToBeConverted
)
2143 const mso_CustomShape
* pDefCustomShape
= GetCustomShapeContent( eShapeType
);
2144 if ( pDefCustomShape
&& pDefCustomShape
->nHandles
&& pDefCustomShape
->pHandles
)
2146 sal_Int32 k
, nkCount
= pDefCustomShape
->nHandles
;
2147 const SvxMSDffHandle
* pData
= pDefCustomShape
->pHandles
;
2148 for ( k
= 0; k
< nkCount
; k
++, pData
++ )
2150 if ( pData
->nFlags
& MSDFF_HANDLE_FLAGS_POLAR
)
2152 if ( ( pData
->nPositionY
>= 0x256 ) || ( pData
->nPositionY
<= 0x107 ) )
2153 nAdjustmentsWhichNeedsToBeConverted
|= ( 1 << k
);
2159 sal_Bool
EscherPropertyContainer::GetAdjustmentValue( const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue
& rkProp
, sal_Int32 nIndex
, sal_Int32 nAdjustmentsWhichNeedsToBeConverted
, sal_Int32
& nValue
)
2161 if ( rkProp
.State
!= beans::PropertyState_DIRECT_VALUE
)
2164 sal_Bool bUseFixedFloat
= ( nAdjustmentsWhichNeedsToBeConverted
& ( 1 << nIndex
) ) != 0;
2165 if ( rkProp
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
2168 rkProp
.Value
>>= fValue
;
2169 if ( bUseFixedFloat
)
2171 nValue
= (sal_Int32
)fValue
;
2175 rkProp
.Value
>>= nValue
;
2176 if ( bUseFixedFloat
)
2183 void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType
, const uno::Reference
< drawing::XShape
> & rXShape
)
2185 uno::Reference
< beans::XPropertySet
> aXPropSet( rXShape
, uno::UNO_QUERY
);
2186 if ( aXPropSet
.is() )
2188 SdrObjCustomShape
* pCustoShape
= (SdrObjCustomShape
*)GetSdrObjectFromXShape( rXShape
);
2189 const rtl::OUString
sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
2190 uno::Any aGeoPropSet
= aXPropSet
->getPropertyValue( sCustomShapeGeometry
);
2191 uno::Sequence
< beans::PropertyValue
> aGeoPropSeq
;
2192 if ( aGeoPropSet
>>= aGeoPropSeq
)
2194 const rtl::OUString
sViewBox ( RTL_CONSTASCII_USTRINGPARAM( "ViewBox" ) );
2195 const rtl::OUString
sTextRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "TextRotateAngle" ) );
2196 const rtl::OUString
sExtrusion ( RTL_CONSTASCII_USTRINGPARAM( "Extrusion" ) );
2197 const rtl::OUString
sEquations ( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
2198 const rtl::OUString
sPath ( RTL_CONSTASCII_USTRINGPARAM( "Path" ) );
2199 const rtl::OUString
sTextPath ( RTL_CONSTASCII_USTRINGPARAM( "TextPath" ) );
2200 const rtl::OUString
sHandles ( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
2201 const rtl::OUString
sAdjustmentValues ( RTL_CONSTASCII_USTRINGPARAM( "AdjustmentValues" ) );
2203 const beans::PropertyValue
* pAdjustmentValuesProp
= NULL
;
2204 sal_Int32 nAdjustmentsWhichNeedsToBeConverted
= 0;
2205 uno::Sequence
< beans::PropertyValues
> aHandlesPropSeq
;
2206 sal_Bool bPredefinedHandlesUsed
= sal_True
;
2207 sal_Bool bIsDefaultObject
= IsDefaultObject( pCustoShape
);
2209 // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation >
2210 std::vector
< EnhancedCustomShapeEquation
> aEquations
;
2211 std::vector
< sal_Int32
> aEquationOrder
;
2212 ConvertEnhancedCustomShapeEquation( pCustoShape
, aEquations
, aEquationOrder
);
2214 sal_Int32 i
, nCount
= aGeoPropSeq
.getLength();
2215 for ( i
= 0; i
< nCount
; i
++ )
2217 const beans::PropertyValue
& rProp
= aGeoPropSeq
[ i
];
2218 if ( rProp
.Name
.equals( sViewBox
) )
2220 if ( !bIsDefaultObject
)
2222 awt::Rectangle aViewBox
;
2223 if ( rProp
.Value
>>= aViewBox
)
2225 AddOpt( DFF_Prop_geoLeft
, aViewBox
.X
);
2226 AddOpt( DFF_Prop_geoTop
, aViewBox
.Y
);
2227 AddOpt( DFF_Prop_geoRight
, aViewBox
.X
+ aViewBox
.Width
);
2228 AddOpt( DFF_Prop_geoBottom
,aViewBox
.Y
+ aViewBox
.Height
);
2232 else if ( rProp
.Name
.equals( sTextRotateAngle
) )
2234 double f
= 0, fTextRotateAngle
;
2235 if ( rProp
.Value
>>= f
)
2237 fTextRotateAngle
= fmod( f
, 360.0 );
2238 if ( fTextRotateAngle
< 0 )
2239 fTextRotateAngle
= 360 + fTextRotateAngle
;
2240 if ( ( fTextRotateAngle
< 271.0 ) && ( fTextRotateAngle
> 269.0 ) )
2241 AddOpt( DFF_Prop_cdirFont
, mso_cdir90
);
2242 else if ( ( fTextRotateAngle
< 181.0 ) && ( fTextRotateAngle
> 179.0 ) )
2243 AddOpt( DFF_Prop_cdirFont
, mso_cdir180
);
2244 else if ( ( fTextRotateAngle
< 91.0 ) && ( fTextRotateAngle
> 79.0 ) )
2245 AddOpt( DFF_Prop_cdirFont
, mso_cdir270
);
2248 else if ( rProp
.Name
.equals( sExtrusion
) )
2250 uno::Sequence
< beans::PropertyValue
> aExtrusionPropSeq
;
2251 if ( rProp
.Value
>>= aExtrusionPropSeq
)
2253 sal_uInt32 nLightFaceFlagsOrg
, nLightFaceFlags
;
2254 sal_uInt32 nFillHarshFlagsOrg
, nFillHarshFlags
;
2255 nLightFaceFlagsOrg
= nLightFaceFlags
= 0x000001;
2256 nFillHarshFlagsOrg
= nFillHarshFlags
= 0x00001e;
2257 if ( GetOpt( DFF_Prop_fc3DLightFace
, nLightFaceFlags
) )
2258 nLightFaceFlagsOrg
= nLightFaceFlags
;
2259 if ( GetOpt( DFF_Prop_fc3DFillHarsh
, nFillHarshFlags
) )
2260 nFillHarshFlagsOrg
= nFillHarshFlags
;
2262 sal_Int32 r
, nrCount
= aExtrusionPropSeq
.getLength();
2263 for ( r
= 0; r
< nrCount
; r
++ )
2265 const beans::PropertyValue
& rrProp
= aExtrusionPropSeq
[ r
];
2266 const rtl::OUString
sExtrusionBrightness ( RTL_CONSTASCII_USTRINGPARAM( "Brightness" ) );
2267 const rtl::OUString
sExtrusionDepth ( RTL_CONSTASCII_USTRINGPARAM( "Depth" ) );
2268 const rtl::OUString
sExtrusionDiffusion ( RTL_CONSTASCII_USTRINGPARAM( "Diffusion" ) );
2269 const rtl::OUString
sExtrusionNumberOfLineSegments ( RTL_CONSTASCII_USTRINGPARAM( "NumberOfLineSegments" ) );
2270 const rtl::OUString
sExtrusionLightFace ( RTL_CONSTASCII_USTRINGPARAM( "LightFace" ) );
2271 const rtl::OUString
sExtrusionFirstLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightHarsh" ) );
2272 const rtl::OUString
sExtrusionSecondLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightHarsh" ) );
2273 const rtl::OUString
sExtrusionFirstLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightLevel" ) );
2274 const rtl::OUString
sExtrusionSecondLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightLevel" ) );
2275 const rtl::OUString
sExtrusionFirstLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightDirection" ) );
2276 const rtl::OUString
sExtrusionSecondLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightDirection" ) );
2277 const rtl::OUString
sExtrusionMetal ( RTL_CONSTASCII_USTRINGPARAM( "Metal" ) );
2278 const rtl::OUString
sExtrusionShadeMode ( RTL_CONSTASCII_USTRINGPARAM( "ShadeMode" ) );
2279 const rtl::OUString
sExtrusionRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) );
2280 const rtl::OUString
sExtrusionRotationCenter ( RTL_CONSTASCII_USTRINGPARAM( "RotationCenter" ) );
2281 const rtl::OUString
sExtrusionShininess ( RTL_CONSTASCII_USTRINGPARAM( "Shininess" ) );
2282 const rtl::OUString
sExtrusionSkew ( RTL_CONSTASCII_USTRINGPARAM( "Skew" ) );
2283 const rtl::OUString
sExtrusionSpecularity ( RTL_CONSTASCII_USTRINGPARAM( "Specularity" ) );
2284 const rtl::OUString
sExtrusionProjectionMode ( RTL_CONSTASCII_USTRINGPARAM( "ProjectionMode" ) );
2285 const rtl::OUString
sExtrusionViewPoint ( RTL_CONSTASCII_USTRINGPARAM( "ViewPoint" ) );
2286 const rtl::OUString
sExtrusionOrigin ( RTL_CONSTASCII_USTRINGPARAM( "Origin" ) );
2287 const rtl::OUString
sExtrusionColor ( RTL_CONSTASCII_USTRINGPARAM( "Color" ) );
2289 if ( rrProp
.Name
.equals( sExtrusion
) )
2291 sal_Bool bExtrusionOn
= sal_Bool();
2292 if ( rrProp
.Value
>>= bExtrusionOn
)
2294 nLightFaceFlags
|= 0x80000;
2296 nLightFaceFlags
|= 8;
2298 nLightFaceFlags
&=~8;
2301 else if ( rrProp
.Name
.equals( sExtrusionBrightness
) )
2303 double fExtrusionBrightness
= 0;
2304 if ( rrProp
.Value
>>= fExtrusionBrightness
)
2305 AddOpt( DFF_Prop_c3DAmbientIntensity
, (sal_Int32
)( fExtrusionBrightness
* 655.36 ) );
2307 else if ( rrProp
.Name
.equals( sExtrusionDepth
) )
2310 double fFraction
= 0;
2311 com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair
;
2312 if ( ( rrProp
.Value
>>= aDepthParaPair
) && ( aDepthParaPair
.First
.Value
>>= fDepth
) && ( aDepthParaPair
.Second
.Value
>>= fFraction
) )
2314 double fForeDepth
= fDepth
* fFraction
;
2315 double fBackDepth
= fDepth
- fForeDepth
;
2317 fBackDepth
*= 360.0;
2318 AddOpt( DFF_Prop_c3DExtrudeBackward
, (sal_Int32
)fBackDepth
);
2320 if ( fForeDepth
!= 0.0 )
2322 fForeDepth
*= 360.0;
2323 AddOpt( DFF_Prop_c3DExtrudeForward
, (sal_Int32
)fForeDepth
);
2327 else if ( rrProp
.Name
.equals( sExtrusionDiffusion
) )
2329 double fExtrusionDiffusion
= 0;
2330 if ( rrProp
.Value
>>= fExtrusionDiffusion
)
2331 AddOpt( DFF_Prop_c3DDiffuseAmt
, (sal_Int32
)( fExtrusionDiffusion
* 655.36 ) );
2333 else if ( rrProp
.Name
.equals( sExtrusionNumberOfLineSegments
) )
2335 sal_Int32 nExtrusionNumberOfLineSegments
= 0;
2336 if ( rrProp
.Value
>>= nExtrusionNumberOfLineSegments
)
2337 AddOpt( DFF_Prop_c3DTolerance
, nExtrusionNumberOfLineSegments
);
2339 else if ( rrProp
.Name
.equals( sExtrusionLightFace
) )
2341 sal_Bool bExtrusionLightFace
= sal_Bool();
2342 if ( rrProp
.Value
>>= bExtrusionLightFace
)
2344 nLightFaceFlags
|= 0x10000;
2345 if ( bExtrusionLightFace
)
2346 nLightFaceFlags
|= 1;
2348 nLightFaceFlags
&=~1;
2351 else if ( rrProp
.Name
.equals( sExtrusionFirstLightHarsh
) )
2353 sal_Bool bExtrusionFirstLightHarsh
= sal_Bool();
2354 if ( rrProp
.Value
>>= bExtrusionFirstLightHarsh
)
2356 nFillHarshFlags
|= 0x20000;
2357 if ( bExtrusionFirstLightHarsh
)
2358 nFillHarshFlags
|= 2;
2360 nFillHarshFlags
&=~2;
2363 else if ( rrProp
.Name
.equals( sExtrusionSecondLightHarsh
) )
2365 sal_Bool bExtrusionSecondLightHarsh
= sal_Bool();
2366 if ( rrProp
.Value
>>= bExtrusionSecondLightHarsh
)
2368 nFillHarshFlags
|= 0x10000;
2369 if ( bExtrusionSecondLightHarsh
)
2370 nFillHarshFlags
|= 1;
2372 nFillHarshFlags
&=~1;
2375 else if ( rrProp
.Name
.equals( sExtrusionFirstLightLevel
) )
2377 double fExtrusionFirstLightLevel
= 0;
2378 if ( rrProp
.Value
>>= fExtrusionFirstLightLevel
)
2379 AddOpt( DFF_Prop_c3DKeyIntensity
, (sal_Int32
)( fExtrusionFirstLightLevel
* 655.36 ) );
2381 else if ( rrProp
.Name
.equals( sExtrusionSecondLightLevel
) )
2383 double fExtrusionSecondLightLevel
= 0;
2384 if ( rrProp
.Value
>>= fExtrusionSecondLightLevel
)
2385 AddOpt( DFF_Prop_c3DFillIntensity
, (sal_Int32
)( fExtrusionSecondLightLevel
* 655.36 ) );
2387 else if ( rrProp
.Name
.equals( sExtrusionFirstLightDirection
) )
2389 drawing::Direction3D aExtrusionFirstLightDirection
;
2390 if ( rrProp
.Value
>>= aExtrusionFirstLightDirection
)
2392 AddOpt( DFF_Prop_c3DKeyX
, (sal_Int32
)aExtrusionFirstLightDirection
.DirectionX
);
2393 AddOpt( DFF_Prop_c3DKeyY
, (sal_Int32
)aExtrusionFirstLightDirection
.DirectionY
);
2394 AddOpt( DFF_Prop_c3DKeyZ
, (sal_Int32
)aExtrusionFirstLightDirection
.DirectionZ
);
2397 else if ( rrProp
.Name
.equals( sExtrusionSecondLightDirection
) )
2399 drawing::Direction3D aExtrusionSecondLightPosition
;
2400 if ( rrProp
.Value
>>= aExtrusionSecondLightPosition
)
2402 AddOpt( DFF_Prop_c3DFillX
, (sal_Int32
)aExtrusionSecondLightPosition
.DirectionX
);
2403 AddOpt( DFF_Prop_c3DFillY
, (sal_Int32
)aExtrusionSecondLightPosition
.DirectionY
);
2404 AddOpt( DFF_Prop_c3DFillZ
, (sal_Int32
)aExtrusionSecondLightPosition
.DirectionZ
);
2407 else if ( rrProp
.Name
.equals( sExtrusionMetal
) )
2409 sal_Bool bExtrusionMetal
= sal_Bool();
2410 if ( rrProp
.Value
>>= bExtrusionMetal
)
2412 nLightFaceFlags
|= 0x40000;
2413 if ( bExtrusionMetal
)
2414 nLightFaceFlags
|= 4;
2416 nLightFaceFlags
&=~4;
2419 else if ( rrProp
.Name
.equals( sExtrusionShadeMode
) )
2421 drawing::ShadeMode eExtrusionShadeMode
;
2422 if ( rrProp
.Value
>>= eExtrusionShadeMode
)
2424 sal_uInt32 nRenderMode
;
2425 switch( eExtrusionShadeMode
)
2428 case drawing::ShadeMode_FLAT
:
2429 case drawing::ShadeMode_PHONG
:
2430 case drawing::ShadeMode_SMOOTH
:
2431 nRenderMode
= mso_FullRender
;
2433 case drawing::ShadeMode_DRAFT
:
2435 nRenderMode
= mso_Wireframe
;
2439 AddOpt( DFF_Prop_c3DRenderMode
, nRenderMode
);
2442 else if ( rrProp
.Name
.equals( sExtrusionRotateAngle
) )
2444 double fExtrusionAngleX
= 0;
2445 double fExtrusionAngleY
= 0;
2446 com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAnglePair
;
2447 if ( ( rrProp
.Value
>>= aRotateAnglePair
) && ( aRotateAnglePair
.First
.Value
>>= fExtrusionAngleX
) && ( aRotateAnglePair
.Second
.Value
>>= fExtrusionAngleY
) )
2449 fExtrusionAngleX
*= 65536;
2450 fExtrusionAngleY
*= 65536;
2451 AddOpt( DFF_Prop_c3DXRotationAngle
, (sal_Int32
)fExtrusionAngleX
);
2452 AddOpt( DFF_Prop_c3DYRotationAngle
, (sal_Int32
)fExtrusionAngleY
);
2455 else if ( rrProp
.Name
.equals( sExtrusionRotationCenter
) )
2457 drawing::Direction3D aExtrusionRotationCenter
;
2458 if ( rrProp
.Value
>>= aExtrusionRotationCenter
)
2460 AddOpt( DFF_Prop_c3DRotationCenterX
, (sal_Int32
)( aExtrusionRotationCenter
.DirectionX
* 360.0 ) );
2461 AddOpt( DFF_Prop_c3DRotationCenterY
, (sal_Int32
)( aExtrusionRotationCenter
.DirectionY
* 360.0 ) );
2462 AddOpt( DFF_Prop_c3DRotationCenterZ
, (sal_Int32
)( aExtrusionRotationCenter
.DirectionZ
* 360.0 ) );
2463 nFillHarshFlags
&=~8; // don't use AutoRotationCenter;
2466 else if ( rrProp
.Name
.equals( sExtrusionShininess
) )
2468 double fExtrusionShininess
= 0;
2469 if ( rrProp
.Value
>>= fExtrusionShininess
)
2470 AddOpt( DFF_Prop_c3DShininess
, (sal_Int32
)( fExtrusionShininess
* 655.36 ) );
2472 else if ( rrProp
.Name
.equals( sExtrusionSkew
) )
2474 double fSkewAmount
= 0;
2475 double fSkewAngle
= 0;
2476 com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair
;
2477 if ( ( rrProp
.Value
>>= aSkewParaPair
) && ( aSkewParaPair
.First
.Value
>>= fSkewAmount
) && ( aSkewParaPair
.Second
.Value
>>= fSkewAngle
) )
2479 AddOpt( DFF_Prop_c3DSkewAmount
, (sal_Int32
)fSkewAmount
);
2480 AddOpt( DFF_Prop_c3DSkewAngle
, (sal_Int32
)( fSkewAngle
* 65536 ) );
2483 else if ( rrProp
.Name
.equals( sExtrusionSpecularity
) )
2485 double fExtrusionSpecularity
= 0;
2486 if ( rrProp
.Value
>>= fExtrusionSpecularity
)
2487 AddOpt( DFF_Prop_c3DSpecularAmt
, (sal_Int32
)( fExtrusionSpecularity
* 1333 ) );
2489 else if ( rrProp
.Name
.equals( sExtrusionProjectionMode
) )
2491 drawing::ProjectionMode eExtrusionProjectionMode
;
2492 if ( rrProp
.Value
>>= eExtrusionProjectionMode
)
2494 nFillHarshFlags
|= 0x40000;
2495 if ( eExtrusionProjectionMode
== drawing::ProjectionMode_PARALLEL
)
2496 nFillHarshFlags
|= 4;
2498 nFillHarshFlags
&=~4;
2501 else if ( rrProp
.Name
.equals( sExtrusionViewPoint
) )
2503 drawing::Position3D aExtrusionViewPoint
;
2504 if ( rrProp
.Value
>>= aExtrusionViewPoint
)
2506 aExtrusionViewPoint
.PositionX
*= 360.0;
2507 aExtrusionViewPoint
.PositionY
*= 360.0;
2508 aExtrusionViewPoint
.PositionZ
*= 360.0;
2509 AddOpt( DFF_Prop_c3DXViewpoint
, (sal_Int32
)aExtrusionViewPoint
.PositionX
);
2510 AddOpt( DFF_Prop_c3DYViewpoint
, (sal_Int32
)aExtrusionViewPoint
.PositionY
);
2511 AddOpt( DFF_Prop_c3DZViewpoint
, (sal_Int32
)aExtrusionViewPoint
.PositionZ
);
2514 else if ( rrProp
.Name
.equals( sExtrusionOrigin
) )
2516 double fExtrusionOriginX
= 0;
2517 double fExtrusionOriginY
= 0;
2518 com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginPair
;
2519 if ( ( rrProp
.Value
>>= aOriginPair
) && ( aOriginPair
.First
.Value
>>= fExtrusionOriginX
) && ( aOriginPair
.Second
.Value
>>= fExtrusionOriginY
) )
2521 AddOpt( DFF_Prop_c3DOriginX
, (sal_Int32
)( fExtrusionOriginX
* 65536 ) );
2522 AddOpt( DFF_Prop_c3DOriginY
, (sal_Int32
)( fExtrusionOriginY
* 65536 ) );
2525 else if ( rrProp
.Name
.equals( sExtrusionColor
) )
2527 sal_Bool bExtrusionColor
= sal_Bool();
2528 if ( rrProp
.Value
>>= bExtrusionColor
)
2530 nLightFaceFlags
|= 0x20000;
2531 if ( bExtrusionColor
)
2533 nLightFaceFlags
|= 2;
2534 uno::Any aFillColor2
;
2535 if ( EscherPropertyValueHelper::GetPropertyValue( aFillColor2
, aXPropSet
,
2536 String( RTL_CONSTASCII_USTRINGPARAM( "FillColor2" ) ), sal_True
) )
2538 sal_uInt32 nFillColor
= ImplGetColor( *((sal_uInt32
*)aFillColor2
.getValue()) );
2539 AddOpt( DFF_Prop_c3DExtrusionColor
, nFillColor
);
2543 nLightFaceFlags
&=~2;
2547 if ( nLightFaceFlags
!= nLightFaceFlagsOrg
)
2548 AddOpt( DFF_Prop_fc3DLightFace
, nLightFaceFlags
);
2549 if ( nFillHarshFlags
!= nFillHarshFlagsOrg
)
2550 AddOpt( DFF_Prop_fc3DFillHarsh
, nFillHarshFlags
);
2553 else if ( rProp
.Name
.equals( sEquations
) )
2555 if ( !bIsDefaultObject
)
2557 sal_uInt16 nElements
= (sal_uInt16
)aEquations
.size();
2560 sal_uInt16 nElementSize
= 8;
2561 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
2562 SvMemoryStream
aOut( nStreamSize
);
2567 std::vector
< EnhancedCustomShapeEquation
>::const_iterator
aIter( aEquations
.begin() );
2568 std::vector
< EnhancedCustomShapeEquation
>::const_iterator
aEnd ( aEquations
.end() );
2569 while( aIter
!= aEnd
)
2571 aOut
<< (sal_uInt16
)aIter
->nOperation
2572 << (sal_Int16
)aIter
->nPara
[ 0 ]
2573 << (sal_Int16
)aIter
->nPara
[ 1 ]
2574 << (sal_Int16
)aIter
->nPara
[ 2 ];
2577 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
2578 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
2579 AddOpt( DFF_Prop_pFormulas
, sal_True
, nStreamSize
- 6, pBuf
, nStreamSize
);
2583 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
2584 AddOpt( DFF_Prop_pFormulas
, sal_True
, 0, pBuf
, 0 );
2588 else if ( rProp
.Name
.equals( sPath
) )
2590 uno::Sequence
< beans::PropertyValue
> aPathPropSeq
;
2591 if ( rProp
.Value
>>= aPathPropSeq
)
2593 sal_uInt32 nPathFlags
, nPathFlagsOrg
;
2594 nPathFlagsOrg
= nPathFlags
= 0x39;
2595 if ( GetOpt( DFF_Prop_fFillOK
, nPathFlags
) )
2596 nPathFlagsOrg
= nPathFlags
;
2598 sal_Int32 r
, nrCount
= aPathPropSeq
.getLength();
2599 for ( r
= 0; r
< nrCount
; r
++ )
2601 const beans::PropertyValue
& rrProp
= aPathPropSeq
[ r
];
2602 const rtl::OUString
sPathExtrusionAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ExtrusionAllowed" ) );
2603 const rtl::OUString
sPathConcentricGradientFillAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ConcentricGradientFillAllowed" ) );
2604 const rtl::OUString
sPathTextPathAllowed ( RTL_CONSTASCII_USTRINGPARAM( "TextPathAllowed" ) );
2605 const rtl::OUString
sPathCoordinates ( RTL_CONSTASCII_USTRINGPARAM( "Coordinates" ) );
2606 const rtl::OUString
sPathGluePoints ( RTL_CONSTASCII_USTRINGPARAM( "GluePoints" ) );
2607 const rtl::OUString
sPathGluePointType ( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) );
2608 const rtl::OUString
sPathSegments ( RTL_CONSTASCII_USTRINGPARAM( "Segments" ) );
2609 const rtl::OUString
sPathStretchX ( RTL_CONSTASCII_USTRINGPARAM( "StretchX" ) );
2610 const rtl::OUString
sPathStretchY ( RTL_CONSTASCII_USTRINGPARAM( "StretchY" ) );
2611 const rtl::OUString
sPathTextFrames ( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) );
2613 if ( rrProp
.Name
.equals( sPathExtrusionAllowed
) )
2615 sal_Bool bExtrusionAllowed
= sal_Bool();
2616 if ( rrProp
.Value
>>= bExtrusionAllowed
)
2618 nPathFlags
|= 0x100000;
2619 if ( bExtrusionAllowed
)
2625 else if ( rrProp
.Name
.equals( sPathConcentricGradientFillAllowed
) )
2627 sal_Bool bConcentricGradientFillAllowed
= sal_Bool();
2628 if ( rrProp
.Value
>>= bConcentricGradientFillAllowed
)
2630 nPathFlags
|= 0x20000;
2631 if ( bConcentricGradientFillAllowed
)
2637 else if ( rrProp
.Name
.equals( sPathTextPathAllowed
) )
2639 sal_Bool bTextPathAllowed
= sal_Bool();
2640 if ( rrProp
.Value
>>= bTextPathAllowed
)
2642 nPathFlags
|= 0x40000;
2643 if ( bTextPathAllowed
)
2649 else if ( rrProp
.Name
.equals( sPathCoordinates
) )
2651 if ( !bIsDefaultObject
)
2653 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> aCoordinates
;
2654 if ( rrProp
.Value
>>= aCoordinates
)
2656 // creating the vertices
2657 if ( (sal_uInt16
)aCoordinates
.getLength() )
2659 sal_uInt16 j
, nElements
= (sal_uInt16
)aCoordinates
.getLength();
2660 sal_uInt16 nElementSize
= 8;
2661 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
2662 SvMemoryStream
aOut( nStreamSize
);
2666 for( j
= 0; j
< nElements
; j
++ )
2668 sal_Int32 X
= GetValueForEnhancedCustomShapeParameter( aCoordinates
[ j
].First
, aEquationOrder
);
2669 sal_Int32 Y
= GetValueForEnhancedCustomShapeParameter( aCoordinates
[ j
].Second
, aEquationOrder
);
2673 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
2674 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
2675 AddOpt( DFF_Prop_pVertices
, sal_True
, nStreamSize
- 6, pBuf
, nStreamSize
); // -6
2679 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
2680 AddOpt( DFF_Prop_pVertices
, sal_True
, 0, pBuf
, 0 );
2685 else if ( rrProp
.Name
.equals( sPathGluePoints
) )
2687 if ( !bIsDefaultObject
)
2689 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> aGluePoints
;
2690 if ( rrProp
.Value
>>= aGluePoints
)
2692 // creating the vertices
2693 sal_uInt16 nElements
= (sal_uInt16
)aGluePoints
.getLength();
2696 sal_uInt16 j
, nElementSize
= 8;
2697 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
2698 SvMemoryStream
aOut( nStreamSize
);
2702 for( j
= 0; j
< nElements
; j
++ )
2704 sal_Int32 X
= GetValueForEnhancedCustomShapeParameter( aGluePoints
[ j
].First
, aEquationOrder
);
2705 sal_Int32 Y
= GetValueForEnhancedCustomShapeParameter( aGluePoints
[ j
].Second
, aEquationOrder
);
2709 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
2710 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
2711 AddOpt( DFF_Prop_connectorPoints
, sal_True
, nStreamSize
- 6, pBuf
, nStreamSize
); // -6
2715 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
2716 AddOpt( DFF_Prop_connectorPoints
, sal_True
, 0, pBuf
, 0 );
2721 else if ( rrProp
.Name
.equals( sPathGluePointType
) )
2723 sal_Int16 nGluePointType
= sal_Int16();
2724 if ( rrProp
.Value
>>= nGluePointType
)
2725 AddOpt( DFF_Prop_connectorType
, (sal_uInt16
)nGluePointType
);
2727 else if ( rrProp
.Name
.equals( sPathSegments
) )
2729 if ( !bIsDefaultObject
)
2731 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeSegment
> aSegments
;
2732 if ( rrProp
.Value
>>= aSegments
)
2735 if ( (sal_uInt16
)aSegments
.getLength() )
2737 sal_uInt16 j
, nElements
= (sal_uInt16
)aSegments
.getLength();
2738 sal_uInt16 nElementSize
= 2;
2739 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
2740 SvMemoryStream
aOut( nStreamSize
);
2744 for ( j
= 0; j
< nElements
; j
++ )
2746 sal_uInt16 nVal
= (sal_uInt16
)aSegments
[ j
].Count
;
2747 switch( aSegments
[ j
].Command
)
2749 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::UNKNOWN
:
2750 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO
: break;
2751 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO
:
2756 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO
:
2761 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
:
2766 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH
:
2771 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL
:
2776 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE
:
2781 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO
:
2787 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE
:
2793 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO
:
2799 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC
:
2805 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
:
2811 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
:
2817 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX
:
2822 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY
:
2830 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
2831 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
2832 AddOpt( DFF_Prop_pSegmentInfo
, sal_False
, nStreamSize
- 6, pBuf
, nStreamSize
);
2836 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
2837 AddOpt( DFF_Prop_pSegmentInfo
, sal_True
, 0, pBuf
, 0 );
2842 else if ( rrProp
.Name
.equals( sPathStretchX
) )
2844 if ( !bIsDefaultObject
)
2846 sal_Int32 nStretchX
= 0;
2847 if ( rrProp
.Value
>>= nStretchX
)
2848 AddOpt( DFF_Prop_stretchPointX
, nStretchX
);
2851 else if ( rrProp
.Name
.equals( sPathStretchY
) )
2853 if ( !bIsDefaultObject
)
2855 sal_Int32 nStretchY
= 0;
2856 if ( rrProp
.Value
>>= nStretchY
)
2857 AddOpt( DFF_Prop_stretchPointY
, nStretchY
);
2860 else if ( rrProp
.Name
.equals( sPathTextFrames
) )
2862 if ( !bIsDefaultObject
)
2864 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeTextFrame
> aPathTextFrames
;
2865 if ( rrProp
.Value
>>= aPathTextFrames
)
2867 if ( (sal_uInt16
)aPathTextFrames
.getLength() )
2869 sal_uInt16 j
, nElements
= (sal_uInt16
)aPathTextFrames
.getLength();
2870 sal_uInt16 nElementSize
= 16;
2871 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
2872 SvMemoryStream
aOut( nStreamSize
);
2876 for ( j
= 0; j
< nElements
; j
++ )
2878 sal_Int32 nLeft
= GetValueForEnhancedCustomShapeParameter( aPathTextFrames
[ j
].TopLeft
.First
, aEquationOrder
);
2879 sal_Int32 nTop
= GetValueForEnhancedCustomShapeParameter( aPathTextFrames
[ j
].TopLeft
.Second
, aEquationOrder
);
2880 sal_Int32 nRight
= GetValueForEnhancedCustomShapeParameter( aPathTextFrames
[ j
].BottomRight
.First
, aEquationOrder
);
2881 sal_Int32 nBottom
= GetValueForEnhancedCustomShapeParameter( aPathTextFrames
[ j
].BottomRight
.Second
, aEquationOrder
);
2888 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
2889 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
2890 AddOpt( DFF_Prop_textRectangles
, sal_True
, nStreamSize
- 6, pBuf
, nStreamSize
);
2894 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
2895 AddOpt( DFF_Prop_textRectangles
, sal_True
, 0, pBuf
, 0 );
2901 if ( nPathFlags
!= nPathFlagsOrg
)
2902 AddOpt( DFF_Prop_fFillOK
, nPathFlags
);
2905 else if ( rProp
.Name
.equals( sTextPath
) )
2907 uno::Sequence
< beans::PropertyValue
> aTextPathPropSeq
;
2908 if ( rProp
.Value
>>= aTextPathPropSeq
)
2910 sal_uInt32 nTextPathFlagsOrg
, nTextPathFlags
;
2911 nTextPathFlagsOrg
= nTextPathFlags
= 0xffff1000; // default
2912 if ( GetOpt( DFF_Prop_gtextFStrikethrough
, nTextPathFlags
) )
2913 nTextPathFlagsOrg
= nTextPathFlags
;
2915 sal_Int32 r
, nrCount
= aTextPathPropSeq
.getLength();
2916 for ( r
= 0; r
< nrCount
; r
++ )
2918 const beans::PropertyValue
& rrProp
= aTextPathPropSeq
[ r
];
2919 const rtl::OUString
sTextPathMode ( RTL_CONSTASCII_USTRINGPARAM( "TextPathMode" ) );
2920 const rtl::OUString
sTextPathScaleX ( RTL_CONSTASCII_USTRINGPARAM( "ScaleX" ) );
2921 const rtl::OUString
sSameLetterHeights ( RTL_CONSTASCII_USTRINGPARAM( "SameLetterHeights" ) );
2923 if ( rrProp
.Name
.equals( sTextPath
) )
2925 sal_Bool bTextPathOn
= sal_Bool();
2926 if ( rrProp
.Value
>>= bTextPathOn
)
2928 nTextPathFlags
|= 0x40000000;
2931 nTextPathFlags
|= 0x4000;
2933 sal_uInt32 nPathFlags
= 0x39;
2934 GetOpt( DFF_Prop_fFillOK
, nPathFlags
); // SJ: can be removed if we are supporting the TextPathAllowed property in XML
2935 nPathFlags
|= 0x40004;
2936 AddOpt( DFF_Prop_fFillOK
, nPathFlags
);
2939 nTextPathFlags
&=~0x4000;
2942 else if ( rrProp
.Name
.equals( sTextPathMode
) )
2944 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode
;
2945 if ( rrProp
.Value
>>= eTextPathMode
)
2947 nTextPathFlags
|= 0x05000000;
2948 nTextPathFlags
&=~0x500; // TextPathMode_NORMAL
2949 if ( eTextPathMode
== com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH
)
2950 nTextPathFlags
|= 0x100;
2951 else if ( eTextPathMode
== com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE
)
2952 nTextPathFlags
|= 0x500;
2955 else if ( rrProp
.Name
.equals( sTextPathScaleX
) )
2957 sal_Bool bTextPathScaleX
= sal_Bool();
2958 if ( rrProp
.Value
>>= bTextPathScaleX
)
2960 nTextPathFlags
|= 0x00400000;
2961 if ( bTextPathScaleX
)
2962 nTextPathFlags
|= 0x40;
2964 nTextPathFlags
&=~0x40;
2967 else if ( rrProp
.Name
.equals( sSameLetterHeights
) )
2969 sal_Bool bSameLetterHeights
= sal_Bool();
2970 if ( rrProp
.Value
>>= bSameLetterHeights
)
2972 nTextPathFlags
|= 0x00800000;
2973 if ( bSameLetterHeights
)
2974 nTextPathFlags
|= 0x80;
2976 nTextPathFlags
&=~0x80;
2980 if ( nTextPathFlags
& 0x4000 ) // Is FontWork ?
2983 rtl::OUString aText
;
2984 uno::Reference
< text::XSimpleText
> xText( rXShape
, uno::UNO_QUERY
);
2986 aText
= xText
->getString();
2987 if ( !aText
.getLength() )
2988 aText
= ::rtl::OUString::createFromAscii( "your text" ); // todo: moving into a resource
2989 AddOpt( DFF_Prop_gtextUNICODE
, aText
);
2992 rtl::OUString aFontName
;
2993 const rtl::OUString
sCharFontName ( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) );
2994 uno::Any aAny
= aXPropSet
->getPropertyValue( sCharFontName
);
2996 if ( !aFontName
.getLength() )
2997 aFontName
= ::rtl::OUString::createFromAscii( "Arial Black" );
2998 AddOpt( DFF_Prop_gtextFont
, aFontName
);
3000 sal_Int16 nCharScaleWidth
= 100;
3001 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "CharScaleWidth" ) ), sal_True
) )
3003 if ( aAny
>>= nCharScaleWidth
)
3005 if ( nCharScaleWidth
!= 100 )
3007 sal_Int32 nVal
= nCharScaleWidth
* 655;
3008 AddOpt( DFF_Prop_gtextSpacing
, nVal
);
3012 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "CharKerning" ) ), sal_True
) )
3014 sal_Int16 nCharKerning
= sal_Int16();
3015 if ( aAny
>>= nCharKerning
)
3017 nTextPathFlags
|= 0x10000000;
3019 nTextPathFlags
|= 0x1000;
3021 nTextPathFlags
&=~0x1000;
3024 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ), sal_True
) )
3026 awt::FontSlant eFontSlant
;
3027 if ( aAny
>>= eFontSlant
)
3029 nTextPathFlags
|= 0x100010;
3030 if ( eFontSlant
!= awt::FontSlant_NONE
)
3031 nTextPathFlags
|= 0x10;
3033 nTextPathFlags
&=~0x10;
3036 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
, aXPropSet
, String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ), sal_True
) )
3038 float fFontWidth
= 0;
3039 if ( aAny
>>= fFontWidth
)
3041 nTextPathFlags
|= 0x200020;
3042 if ( fFontWidth
> awt::FontWeight::NORMAL
)
3043 nTextPathFlags
|= 0x20;
3045 nTextPathFlags
&=~0x20;
3049 if ( nTextPathFlags
!= nTextPathFlagsOrg
)
3050 AddOpt( DFF_Prop_gtextFStrikethrough
, nTextPathFlags
);
3053 else if ( rProp
.Name
.equals( sHandles
) )
3055 if ( !bIsDefaultObject
)
3057 bPredefinedHandlesUsed
= sal_False
;
3058 if ( rProp
.Value
>>= aHandlesPropSeq
)
3060 sal_uInt16 nElements
= (sal_uInt16
)aHandlesPropSeq
.getLength();
3063 const rtl::OUString
sHandle ( RTL_CONSTASCII_USTRINGPARAM( "Handle" ) );
3065 sal_uInt16 k
, j
, nElementSize
= 36;
3066 sal_uInt32 nStreamSize
= nElementSize
* nElements
+ 6;
3067 SvMemoryStream
aOut( nStreamSize
);
3072 for ( k
= 0; k
< nElements
; k
++ )
3074 sal_uInt32 nFlags
= 0;
3075 sal_Int32 nXPosition
= 0;
3076 sal_Int32 nYPosition
= 0;
3077 sal_Int32 nXMap
= 0;
3078 sal_Int32 nYMap
= 0;
3079 sal_Int32 nXRangeMin
= 0x80000000;
3080 sal_Int32 nXRangeMax
= 0x7fffffff;
3081 sal_Int32 nYRangeMin
= 0x80000000;
3082 sal_Int32 nYRangeMax
= 0x7fffffff;
3084 const uno::Sequence
< beans::PropertyValue
>& rPropSeq
= aHandlesPropSeq
[ k
];
3085 for ( j
= 0; j
< rPropSeq
.getLength(); j
++ )
3087 const beans::PropertyValue
& rPropVal
= rPropSeq
[ j
];
3089 const rtl::OUString
sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) );
3090 const rtl::OUString
sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) );
3091 const rtl::OUString
sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) );
3092 const rtl::OUString
sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) );
3093 const rtl::OUString
sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) );
3094 // const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) );
3095 const rtl::OUString
sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) );
3096 const rtl::OUString
sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) );
3097 const rtl::OUString
sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) );
3098 const rtl::OUString
sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) );
3099 const rtl::OUString
sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) );
3100 const rtl::OUString
sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) );
3102 if ( rPropVal
.Name
.equals( sPosition
) )
3104 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition
;
3105 if ( rPropVal
.Value
>>= aPosition
)
3107 GetValueForEnhancedCustomShapeHandleParameter( nXPosition
, aPosition
.First
);
3108 GetValueForEnhancedCustomShapeHandleParameter( nYPosition
, aPosition
.Second
);
3111 else if ( rPropVal
.Name
.equals( sMirroredX
) )
3113 sal_Bool bMirroredX
= sal_Bool();
3114 if ( rPropVal
.Value
>>= bMirroredX
)
3120 else if ( rPropVal
.Name
.equals( sMirroredY
) )
3122 sal_Bool bMirroredY
= sal_Bool();
3123 if ( rPropVal
.Value
>>= bMirroredY
)
3129 else if ( rPropVal
.Name
.equals( sSwitched
) )
3131 sal_Bool bSwitched
= sal_Bool();
3132 if ( rPropVal
.Value
>>= bSwitched
)
3138 else if ( rPropVal
.Name
.equals( sPolar
) )
3140 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar
;
3141 if ( rPropVal
.Value
>>= aPolar
)
3143 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap
, aPolar
.First
) )
3145 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap
, aPolar
.Second
) )
3150 /* seems not to be used.
3151 else if ( rPropVal.Name.equals( sMap ) )
3153 com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap;
3154 if ( rPropVal.Value >>= aMap )
3156 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) )
3158 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) )
3164 else if ( rPropVal
.Name
.equals( sRadiusRangeMinimum
) )
3166 nYRangeMin
= (sal_Int32
)0xff4c0000; // the range of angles seems to be a not
3167 nYRangeMax
= (sal_Int32
)0x00b40000; // used feature, so we are defaulting this
3169 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum
;
3170 if ( rPropVal
.Value
>>= aRadiusRangeMinimum
)
3172 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin
, aRadiusRangeMinimum
) )
3177 else if ( rPropVal
.Name
.equals( sRadiusRangeMaximum
) )
3179 nYRangeMin
= (sal_Int32
)0xff4c0000; // the range of angles seems to be a not
3180 nYRangeMax
= (sal_Int32
)0x00b40000; // used feature, so we are defaulting this
3182 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum
;
3183 if ( rPropVal
.Value
>>= aRadiusRangeMaximum
)
3185 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax
, aRadiusRangeMaximum
) )
3190 else if ( rPropVal
.Name
.equals( sRangeXMinimum
) )
3192 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum
;
3193 if ( rPropVal
.Value
>>= aXRangeMinimum
)
3195 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin
, aXRangeMinimum
) )
3200 else if ( rPropVal
.Name
.equals( sRangeXMaximum
) )
3202 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum
;
3203 if ( rPropVal
.Value
>>= aXRangeMaximum
)
3205 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax
, aXRangeMaximum
) )
3210 else if ( rPropVal
.Name
.equals( sRangeYMinimum
) )
3212 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum
;
3213 if ( rPropVal
.Value
>>= aYRangeMinimum
)
3215 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMin
, aYRangeMinimum
) )
3220 else if ( rPropVal
.Name
.equals( sRangeYMaximum
) )
3222 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum
;
3223 if ( rPropVal
.Value
>>= aYRangeMaximum
)
3225 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMax
, aYRangeMaximum
) )
3242 nAdjustmentsWhichNeedsToBeConverted
|= ( 1 << ( nYPosition
- 0x100 ) );
3244 sal_uInt8
* pBuf
= new sal_uInt8
[ nStreamSize
];
3245 memcpy( pBuf
, aOut
.GetData(), nStreamSize
);
3246 AddOpt( DFF_Prop_Handles
, sal_True
, nStreamSize
- 6, pBuf
, nStreamSize
);
3250 sal_uInt8
* pBuf
= new sal_uInt8
[ 1 ];
3251 AddOpt( DFF_Prop_Handles
, sal_True
, 0, pBuf
, 0 );
3256 else if ( rProp
.Name
.equals( sAdjustmentValues
) )
3258 // it is required, that the information which handle is polar has already be read,
3259 // so we are able to change the polar value to a fixed float
3260 pAdjustmentValuesProp
= &rProp
;
3263 if ( pAdjustmentValuesProp
)
3265 uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue
> aAdjustmentSeq
;
3266 if ( pAdjustmentValuesProp
->Value
>>= aAdjustmentSeq
)
3268 if ( bPredefinedHandlesUsed
)
3269 LookForPolarHandles( eShapeType
, nAdjustmentsWhichNeedsToBeConverted
);
3271 sal_Int32 k
, nValue
= 0, nAdjustmentValues
= aAdjustmentSeq
.getLength();
3272 for ( k
= 0; k
< nAdjustmentValues
; k
++ )
3273 if( GetAdjustmentValue( aAdjustmentSeq
[ k
], k
, nAdjustmentsWhichNeedsToBeConverted
, nValue
) )
3274 AddOpt( (sal_uInt16
)( DFF_Prop_adjustValue
+ k
), (sal_uInt32
)nValue
);
3281 // ---------------------------------------------------------------------------------------------
3283 MSO_SPT
EscherPropertyContainer::GetCustomShapeType( const uno::Reference
< drawing::XShape
> & rXShape
, sal_uInt32
& nMirrorFlags
, rtl::OUString
& rShapeType
)
3285 MSO_SPT eShapeType
= mso_sptNil
;
3287 uno::Reference
< beans::XPropertySet
> aXPropSet( rXShape
, uno::UNO_QUERY
);
3288 if ( aXPropSet
.is() )
3292 const OUString
sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM ( "CustomShapeGeometry" ) );
3293 uno::Any aGeoPropSet
= aXPropSet
->getPropertyValue( sCustomShapeGeometry
);
3294 uno::Sequence
< beans::PropertyValue
> aGeoPropSeq
;
3295 if ( aGeoPropSet
>>= aGeoPropSeq
)
3297 sal_Int32 i
, nCount
= aGeoPropSeq
.getLength();
3298 for ( i
= 0; i
< nCount
; i
++ )
3300 const beans::PropertyValue
& rProp
= aGeoPropSeq
[ i
];
3301 if ( rProp
.Name
.equalsAscii( "Type" ) )
3303 if ( rProp
.Value
>>= rShapeType
)
3304 eShapeType
= EnhancedCustomShapeTypeNames::Get( rShapeType
);
3306 else if ( rProp
.Name
.equalsAscii( "MirroredX" ) )
3308 sal_Bool bMirroredX
= sal_Bool();
3309 if ( ( rProp
.Value
>>= bMirroredX
) && bMirroredX
)
3310 nMirrorFlags
|= SHAPEFLAG_FLIPH
;
3312 else if ( rProp
.Name
.equalsAscii( "MirroredY" ) )
3314 sal_Bool bMirroredY
= sal_Bool();
3315 if ( ( rProp
.Value
>>= bMirroredY
) && bMirroredY
)
3316 nMirrorFlags
|= SHAPEFLAG_FLIPV
;
3321 catch( ::com::sun::star::uno::Exception
& )
3328 MSO_SPT
EscherPropertyContainer::GetCustomShapeType( const uno::Reference
< drawing::XShape
> & rXShape
, sal_uInt32
& nMirrorFlags
)
3330 rtl::OUString aShapeType
;
3331 return GetCustomShapeType( rXShape
, nMirrorFlags
, aShapeType
);
3334 // ---------------------------------------------------------------------------------------------
3336 EscherPersistTable::EscherPersistTable()
3340 // ---------------------------------------------------------------------------------------------
3342 EscherPersistTable::~EscherPersistTable()
3344 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3345 delete (EscherPersistEntry
*)pPtr
;
3348 // ---------------------------------------------------------------------------------------------
3350 BOOL
EscherPersistTable::PtIsID( UINT32 nID
)
3352 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3354 if ( ((EscherPersistEntry
*)pPtr
)->mnID
== nID
)
3360 // ---------------------------------------------------------------------------------------------
3362 void EscherPersistTable::PtInsert( UINT32 nID
, UINT32 nOfs
)
3364 maPersistTable
.Insert( new EscherPersistEntry( nID
, nOfs
) );
3367 // ---------------------------------------------------------------------------------------------
3369 UINT32
EscherPersistTable::PtDelete( UINT32 nID
)
3371 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3373 if ( ((EscherPersistEntry
*)pPtr
)->mnID
== nID
)
3375 // UINT32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset;
3376 delete (EscherPersistEntry
*) maPersistTable
.Remove();
3382 // ---------------------------------------------------------------------------------------------
3384 UINT32
EscherPersistTable::PtGetOffsetByID( UINT32 nID
)
3386 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3388 if ( ((EscherPersistEntry
*)pPtr
)->mnID
== nID
)
3389 return ((EscherPersistEntry
*)pPtr
)->mnOffset
;
3394 // ---------------------------------------------------------------------------------------------
3396 UINT32
EscherPersistTable::PtReplace( UINT32 nID
, UINT32 nOfs
)
3398 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3400 if ( ((EscherPersistEntry
*)pPtr
)->mnID
== nID
)
3402 UINT32 nRetValue
= ((EscherPersistEntry
*)pPtr
)->mnOffset
;
3403 ((EscherPersistEntry
*)pPtr
)->mnOffset
= nOfs
;
3410 // ---------------------------------------------------------------------------------------------
3412 UINT32
EscherPersistTable::PtReplaceOrInsert( UINT32 nID
, UINT32 nOfs
)
3414 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
3416 if ( ((EscherPersistEntry
*)pPtr
)->mnID
== nID
)
3418 UINT32 nRetValue
= ((EscherPersistEntry
*)pPtr
)->mnOffset
;
3419 ((EscherPersistEntry
*)pPtr
)->mnOffset
= nOfs
;
3423 PtInsert( nID
, nOfs
);
3427 sal_Bool
EscherPropertyValueHelper::GetPropertyValue(
3428 ::com::sun::star::uno::Any
& rAny
,
3429 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
3430 const String
& rString
,
3431 sal_Bool bTestPropertyAvailability
)
3433 sal_Bool bRetValue
= sal_True
;
3434 if ( bTestPropertyAvailability
)
3436 bRetValue
= sal_False
;
3439 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySetInfo
>
3440 aXPropSetInfo( rXPropSet
->getPropertySetInfo() );
3441 if ( aXPropSetInfo
.is() )
3442 bRetValue
= aXPropSetInfo
->hasPropertyByName( rString
);
3444 catch( ::com::sun::star::uno::Exception
& )
3446 bRetValue
= sal_False
;
3453 rAny
= rXPropSet
->getPropertyValue( rString
);
3454 if ( !rAny
.hasValue() )
3455 bRetValue
= sal_False
;
3457 catch( ::com::sun::star::uno::Exception
& )
3459 bRetValue
= sal_False
;
3465 // ---------------------------------------------------------------------------------------------
3467 ::com::sun::star::beans::PropertyState
EscherPropertyValueHelper::GetPropertyState(
3468 const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
3469 const String
& rPropertyName
)
3471 ::com::sun::star::beans::PropertyState eRetValue
= ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE
;
3474 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyState
> aXPropState
3475 ( rXPropSet
, ::com::sun::star::uno::UNO_QUERY
);
3476 if ( aXPropState
.is() )
3477 eRetValue
= aXPropState
->getPropertyState( rPropertyName
);
3479 catch( ::com::sun::star::uno::Exception
& )
3486 // ---------------------------------------------------------------------------------------------
3487 // ---------------------------------------------------------------------------------------------
3488 // ---------------------------------------------------------------------------------------------
3490 EscherBlibEntry::EscherBlibEntry( sal_uInt32 nPictureOffset
, const GraphicObject
& rObject
, const ByteString
& rId
,
3491 const GraphicAttr
* pGraphicAttr
) :
3492 mnPictureOffset ( nPictureOffset
),
3495 maPrefSize ( rObject
.GetPrefSize() ),
3496 maPrefMapMode ( rObject
.GetPrefMapMode() ),
3499 mbIsNativeGraphicPossible
= ( pGraphicAttr
== NULL
);
3500 meBlibType
= UNKNOWN
;
3503 sal_uInt32 nLen
= rId
.Len();
3504 const sal_Char
* pData
= rId
.GetBuffer();
3505 GraphicType
eType( rObject
.GetType() );
3506 if ( nLen
&& pData
&& ( eType
!= GRAPHIC_NONE
) )
3508 mnIdentifier
[ 0 ] = rtl_crc32( 0,pData
, nLen
);
3509 mnIdentifier
[ 1 ] = 0;
3513 if ( pGraphicAttr
->IsSpecialDrawMode()
3514 || pGraphicAttr
->IsMirrored()
3515 || pGraphicAttr
->IsCropped()
3516 || pGraphicAttr
->IsRotated()
3517 || pGraphicAttr
->IsTransparent()
3518 || pGraphicAttr
->IsAdjusted() )
3520 SvMemoryStream
aSt( sizeof( GraphicAttr
) );
3521 aSt
<< static_cast<sal_uInt16
>(pGraphicAttr
->GetDrawMode())
3522 << static_cast<sal_uInt32
>(pGraphicAttr
->GetMirrorFlags())
3523 << pGraphicAttr
->GetLeftCrop()
3524 << pGraphicAttr
->GetTopCrop()
3525 << pGraphicAttr
->GetRightCrop()
3526 << pGraphicAttr
->GetBottomCrop()
3527 << pGraphicAttr
->GetRotation()
3528 << pGraphicAttr
->GetLuminance()
3529 << pGraphicAttr
->GetContrast()
3530 << pGraphicAttr
->GetChannelR()
3531 << pGraphicAttr
->GetChannelG()
3532 << pGraphicAttr
->GetChannelB()
3533 << pGraphicAttr
->GetGamma()
3534 << (BOOL
)( pGraphicAttr
->IsInvert() == TRUE
)
3535 << pGraphicAttr
->GetTransparency();
3536 mnIdentifier
[ 1 ] = rtl_crc32( 0, aSt
.GetData(), aSt
.Tell() );
3539 mbIsNativeGraphicPossible
= TRUE
;
3541 sal_uInt32 i
, nTmp
, n1
, n2
;
3543 for ( i
= 0; i
< nLen
; i
++ )
3545 nTmp
= n2
>> 28; // rotating 4 bit
3550 n1
^= *pData
++ - '0';
3552 mnIdentifier
[ 2 ] = n1
;
3553 mnIdentifier
[ 3 ] = n2
;
3558 // ---------------------------------------------------------------------------------------------
3560 void EscherBlibEntry::WriteBlibEntry( SvStream
& rSt
, sal_Bool bWritePictureOffset
, sal_uInt32 nResize
)
3562 sal_uInt32 nPictureOffset
= ( bWritePictureOffset
) ? mnPictureOffset
: 0;
3564 rSt
<< (sal_uInt32
)( ( ESCHER_BSE
<< 16 ) | ( ( (sal_uInt16
)meBlibType
<< 4 ) | 2 ) )
3565 << (sal_uInt32
)( 36 + nResize
)
3566 << (sal_uInt8
)meBlibType
;
3568 switch ( meBlibType
)
3571 case WMF
: // EMF/WMF auf OS2 zu Pict Konvertieren
3572 rSt
<< (sal_uInt8
)PICT
;
3575 rSt
<< (sal_uInt8
)meBlibType
;
3578 rSt
.Write( &mnIdentifier
[ 0 ], 16 );
3579 rSt
<< (sal_uInt16
)0
3580 << (sal_uInt32
)( mnSize
+ mnSizeExtra
)
3586 // ---------------------------------------------------------------------------------------------
3588 EscherBlibEntry::~EscherBlibEntry()
3592 // ---------------------------------------------------------------------------------------------
3594 BOOL
EscherBlibEntry::operator==( const EscherBlibEntry
& rEscherBlibEntry
) const
3596 for ( int i
= 0; i
< 3; i
++ )
3598 if ( mnIdentifier
[ i
] != rEscherBlibEntry
.mnIdentifier
[ i
] )
3604 // ---------------------------------------------------------------------------------------------
3605 // ---------------------------------------------------------------------------------------------
3606 // ---------------------------------------------------------------------------------------------
3608 EscherGraphicProvider::EscherGraphicProvider( sal_uInt32 nFlags
) :
3610 mpBlibEntrys ( NULL
),
3611 mnBlibBufSize ( 0 ),
3616 EscherGraphicProvider::~EscherGraphicProvider()
3618 for ( UINT32 i
= 0; i
< mnBlibEntrys
; delete mpBlibEntrys
[ i
++ ] ) ;
3619 delete[] mpBlibEntrys
;
3622 void EscherGraphicProvider::SetNewBlipStreamOffset( sal_Int32 nOffset
)
3624 for( sal_uInt32 i
= 0; i
< mnBlibEntrys
; i
++ )
3626 EscherBlibEntry
* pBlibEntry
= mpBlibEntrys
[ i
];
3627 pBlibEntry
->mnPictureOffset
+= nOffset
;
3631 UINT32
EscherGraphicProvider::ImplInsertBlib( EscherBlibEntry
* p_EscherBlibEntry
)
3633 if ( mnBlibBufSize
== mnBlibEntrys
)
3635 mnBlibBufSize
+= 64;
3636 EscherBlibEntry
** pTemp
= new EscherBlibEntry
*[ mnBlibBufSize
];
3637 for ( UINT32 i
= 0; i
< mnBlibEntrys
; i
++ )
3639 pTemp
[ i
] = mpBlibEntrys
[ i
];
3641 delete[] mpBlibEntrys
;
3642 mpBlibEntrys
= pTemp
;
3644 mpBlibEntrys
[ mnBlibEntrys
++ ] = p_EscherBlibEntry
;
3645 return mnBlibEntrys
;
3648 sal_uInt32
EscherGraphicProvider::GetBlibStoreContainerSize( SvStream
* pMergePicStreamBSE
) const
3650 sal_uInt32 nSize
= 44 * mnBlibEntrys
+ 8;
3651 if ( pMergePicStreamBSE
)
3653 for ( sal_uInt32 i
= 0; i
< mnBlibEntrys
; i
++ )
3654 nSize
+= mpBlibEntrys
[ i
]->mnSize
+ mpBlibEntrys
[ i
]->mnSizeExtra
;
3659 sal_Bool
EscherGraphicProvider::WriteBlibStoreEntry(SvStream
& rSt
,
3660 sal_uInt32 nBlipId
, sal_Bool bWritePictureOffSet
, sal_uInt32 nResize
)
3662 if (nBlipId
> mnBlibEntrys
|| nBlipId
== 0)
3664 mpBlibEntrys
[nBlipId
-1]->WriteBlibEntry(rSt
, bWritePictureOffSet
, nResize
);
3668 void EscherGraphicProvider::WriteBlibStoreContainer( SvStream
& rSt
, SvStream
* pMergePicStreamBSE
)
3670 sal_uInt32 nSize
= GetBlibStoreContainerSize( pMergePicStreamBSE
);
3673 rSt
<< (sal_uInt32
)( ( ESCHER_BstoreContainer
<< 16 ) | 0x1f )
3674 << (sal_uInt32
)( nSize
- 8 );
3676 if ( pMergePicStreamBSE
)
3678 sal_uInt32 i
, nBlipSize
, nOldPos
= pMergePicStreamBSE
->Tell();
3679 const sal_uInt32 nBuf
= 0x40000; // 256KB buffer
3680 sal_uInt8
* pBuf
= new sal_uInt8
[ nBuf
];
3682 for ( i
= 0; i
< mnBlibEntrys
; i
++ )
3684 EscherBlibEntry
* pBlibEntry
= mpBlibEntrys
[ i
];
3686 ESCHER_BlibType nBlibType
= pBlibEntry
->meBlibType
;
3687 nBlipSize
= pBlibEntry
->mnSize
+ pBlibEntry
->mnSizeExtra
;
3688 pBlibEntry
->WriteBlibEntry( rSt
, sal_False
, nBlipSize
);
3691 pMergePicStreamBSE
->Seek( pBlibEntry
->mnPictureOffset
);
3693 // record version and instance
3694 *pMergePicStreamBSE
>> n16
;
3697 *pMergePicStreamBSE
>> n16
;
3698 rSt
<< UINT16( ESCHER_BlipFirst
+ nBlibType
);
3699 DBG_ASSERT( n16
== ESCHER_BlipFirst
+ nBlibType
, "EscherEx::Flush: BLIP record types differ" );
3702 *pMergePicStreamBSE
>> n32
;
3705 DBG_ASSERT( nBlipSize
== n32
, "EscherEx::Flush: BLIP sizes differ" );
3709 UINT32 nBytes
= ( nBlipSize
> nBuf
? nBuf
: nBlipSize
);
3710 pMergePicStreamBSE
->Read( pBuf
, nBytes
);
3711 rSt
.Write( pBuf
, nBytes
);
3712 nBlipSize
-= nBytes
;
3716 pMergePicStreamBSE
->Seek( nOldPos
);
3720 for ( sal_uInt32 i
= 0; i
< mnBlibEntrys
; i
++ )
3721 mpBlibEntrys
[ i
]->WriteBlibEntry( rSt
, sal_True
);
3726 sal_Bool
EscherGraphicProvider::GetPrefSize( const sal_uInt32 nBlibId
, Size
& rPrefSize
, MapMode
& rPrefMapMode
)
3728 sal_Bool bInRange
= nBlibId
&& ( ( nBlibId
- 1 ) < mnBlibEntrys
);
3731 EscherBlibEntry
* pEntry
= mpBlibEntrys
[ nBlibId
- 1 ];
3732 rPrefSize
= pEntry
->maPrefSize
;
3733 rPrefMapMode
= pEntry
->maPrefMapMode
;
3738 sal_uInt32
EscherGraphicProvider::GetBlibID( SvStream
& rPicOutStrm
, const ByteString
& rId
,
3739 const Rectangle
& /* rBoundRect */, const com::sun::star::awt::Rectangle
* pVisArea
, const GraphicAttr
* pGraphicAttr
)
3741 sal_uInt32 nBlibId
= 0;
3742 GraphicObject
aGraphicObject( rId
);
3744 EscherBlibEntry
* p_EscherBlibEntry
= new EscherBlibEntry( rPicOutStrm
.Tell(), aGraphicObject
, rId
, pGraphicAttr
);
3745 if ( !p_EscherBlibEntry
->IsEmpty() )
3747 for ( UINT32 i
= 0; i
< mnBlibEntrys
; i
++ )
3749 if ( *( mpBlibEntrys
[ i
] ) == *p_EscherBlibEntry
)
3751 mpBlibEntrys
[ i
]->mnRefCount
++;
3752 delete p_EscherBlibEntry
;
3757 sal_Bool
bUseNativeGraphic( FALSE
);
3759 Graphic
aGraphic( aGraphicObject
.GetTransformedGraphic( pGraphicAttr
) );
3760 GfxLink aGraphicLink
;
3761 SvMemoryStream aStream
;
3763 const sal_uInt8
* pGraphicAry
= NULL
;
3765 if ( p_EscherBlibEntry
->mbIsNativeGraphicPossible
&& aGraphic
.IsLink() )
3767 aGraphicLink
= aGraphic
.GetLink();
3769 p_EscherBlibEntry
->mnSize
= aGraphicLink
.GetDataSize();
3770 pGraphicAry
= aGraphicLink
.GetData();
3772 if ( p_EscherBlibEntry
->mnSize
&& pGraphicAry
)
3774 switch ( aGraphicLink
.GetType() )
3776 case GFX_LINK_TYPE_NATIVE_JPG
: p_EscherBlibEntry
->meBlibType
= PEG
; break;
3777 case GFX_LINK_TYPE_NATIVE_PNG
: p_EscherBlibEntry
->meBlibType
= PNG
; break;
3778 case GFX_LINK_TYPE_NATIVE_WMF
:
3780 if ( pGraphicAry
&& ( p_EscherBlibEntry
->mnSize
> 0x2c ) )
3782 if ( ( pGraphicAry
[ 0x28 ] == 0x20 ) && ( pGraphicAry
[ 0x29 ] == 0x45 ) // check the magic
3783 && ( pGraphicAry
[ 0x2a ] == 0x4d ) && ( pGraphicAry
[ 0x2b ] == 0x46 ) ) // number ( emf detection )
3785 p_EscherBlibEntry
->meBlibType
= EMF
;
3789 p_EscherBlibEntry
->meBlibType
= WMF
;
3790 if ( ( pGraphicAry
[ 0 ] == 0xd7 ) && ( pGraphicAry
[ 1 ] == 0xcd )
3791 && ( pGraphicAry
[ 2 ] == 0xc6 ) && ( pGraphicAry
[ 3 ] == 0x9a ) )
3792 { // we have to get rid of the metafileheader
3794 p_EscherBlibEntry
->mnSize
-= 22;
3802 if ( p_EscherBlibEntry
->meBlibType
!= UNKNOWN
)
3803 bUseNativeGraphic
= TRUE
;
3806 if ( !bUseNativeGraphic
)
3808 GraphicType eGraphicType
= aGraphic
.GetType();
3809 if ( ( eGraphicType
== GRAPHIC_BITMAP
) || ( eGraphicType
== GRAPHIC_GDIMETAFILE
) )
3811 sal_uInt32 nErrCode
;
3812 if ( !aGraphic
.IsAnimated() )
3813 // !EMF nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG : CVT_WMF );
3814 nErrCode
= GraphicConverter::Export( aStream
, aGraphic
, ( eGraphicType
== GRAPHIC_BITMAP
) ? CVT_PNG
: CVT_EMF
);
3816 { // to store a animation, a gif has to be included into the msOG chunk of a png #I5583#
3817 GraphicFilter
* pFilter
= GetGrfFilter();
3818 SvMemoryStream aGIFStream
;
3819 ByteString
aVersion( "MSOFFICE9.0" );
3820 aGIFStream
.Write( aVersion
.GetBuffer(), aVersion
.Len() );
3821 nErrCode
= pFilter
->ExportGraphic( aGraphic
, String(), aGIFStream
,
3822 pFilter
->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "GIF" ) ) ), NULL
);
3823 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aFilterData( 1 );
3824 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aAdditionalChunkSequence( 1 );
3825 sal_uInt32 nGIFSreamLen
= aGIFStream
.Tell();
3826 com::sun::star::uno::Sequence
< sal_Int8
> aGIFSeq( nGIFSreamLen
);
3827 sal_Int8
* pSeq
= aGIFSeq
.getArray();
3828 aGIFStream
.Seek( STREAM_SEEK_TO_BEGIN
);
3829 aGIFStream
.Read( pSeq
, nGIFSreamLen
);
3830 com::sun::star::beans::PropertyValue aChunkProp
, aFilterProp
;
3831 aChunkProp
.Name
= String( RTL_CONSTASCII_USTRINGPARAM( "msOG" ) );
3832 aChunkProp
.Value
<<= aGIFSeq
;
3833 aAdditionalChunkSequence
[ 0 ] = aChunkProp
;
3834 aFilterProp
.Name
= String( RTL_CONSTASCII_USTRINGPARAM( "AdditionalChunks" ) );
3835 aFilterProp
.Value
<<= aAdditionalChunkSequence
;
3836 aFilterData
[ 0 ] = aFilterProp
;
3837 nErrCode
= pFilter
->ExportGraphic( aGraphic
, String(), aStream
,
3838 pFilter
->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ) ), &aFilterData
);
3840 if ( nErrCode
== ERRCODE_NONE
)
3842 // !EMF p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : WMF;
3843 p_EscherBlibEntry
->meBlibType
= ( eGraphicType
== GRAPHIC_BITMAP
) ? PNG
: EMF
;
3844 aStream
.Seek( STREAM_SEEK_TO_END
);
3845 p_EscherBlibEntry
->mnSize
= aStream
.Tell();
3846 pGraphicAry
= (sal_uInt8
*)aStream
.GetData();
3848 if ( p_EscherBlibEntry
->meBlibType
== WMF
) // the fileheader is not used
3850 p_EscherBlibEntry
->mnSize
-= 22;
3857 ESCHER_BlibType eBlibType
= p_EscherBlibEntry
->meBlibType
;
3858 if ( p_EscherBlibEntry
->mnSize
&& pGraphicAry
&& ( eBlibType
!= UNKNOWN
) )
3860 sal_uInt32 nExtra
, nAtomSize
= 0;
3861 sal_uInt32 nInstance
, nUncompressedSize
= p_EscherBlibEntry
->mnSize
;
3863 if ( mnFlags
& _E_GRAPH_PROV_USE_INSTANCES
)
3865 rPicOutStrm
<< (UINT32
)( 0x7f90000 | (UINT16
)( mnBlibEntrys
<< 4 ) )
3867 nAtomSize
= rPicOutStrm
.Tell();
3868 if ( eBlibType
== PNG
)
3869 rPicOutStrm
<< (sal_uInt16
)0x0606;
3870 else if ( eBlibType
== WMF
)
3871 rPicOutStrm
<< (sal_uInt16
)0x0403;
3872 else if ( eBlibType
== EMF
)
3873 rPicOutStrm
<< (sal_uInt16
)0x0402;
3874 else if ( eBlibType
== PEG
)
3875 rPicOutStrm
<< (sal_uInt16
)0x0505;
3877 if ( ( eBlibType
== PEG
) || ( eBlibType
== PNG
) )
3880 p_EscherBlibEntry
->mnSizeExtra
= nExtra
+ 8;
3881 nInstance
= ( eBlibType
== PNG
) ? 0xf01e6e00 : 0xf01d46a0;
3882 rPicOutStrm
<< nInstance
<< (sal_uInt32
)( p_EscherBlibEntry
->mnSize
+ nExtra
);
3883 rPicOutStrm
.Write( p_EscherBlibEntry
->mnIdentifier
, 16 );
3884 rPicOutStrm
<< (sal_uInt8
)0xff;
3885 rPicOutStrm
.Write( pGraphicAry
, p_EscherBlibEntry
->mnSize
);
3889 ZCodec
aZCodec( 0x8000, 0x8000 );
3890 aZCodec
.BeginCompression();
3891 SvMemoryStream aDestStrm
;
3892 aZCodec
.Write( aDestStrm
, pGraphicAry
, p_EscherBlibEntry
->mnSize
);
3893 aZCodec
.EndCompression();
3894 aDestStrm
.Seek( STREAM_SEEK_TO_END
);
3895 p_EscherBlibEntry
->mnSize
= aDestStrm
.Tell();
3896 pGraphicAry
= (sal_uInt8
*)aDestStrm
.GetData();
3897 if ( p_EscherBlibEntry
->mnSize
&& pGraphicAry
)
3899 nExtra
= eBlibType
== WMF
? 0x42 : 0x32; // !EMF -> no change
3900 p_EscherBlibEntry
->mnSizeExtra
= nExtra
+ 8;
3901 nInstance
= ( eBlibType
== WMF
) ? 0xf01b2170 : 0xf01a3d40; // !EMF -> no change
3902 rPicOutStrm
<< nInstance
<< (sal_uInt32
)( p_EscherBlibEntry
->mnSize
+ nExtra
);
3903 if ( eBlibType
== WMF
) // !EMF -> no change
3904 rPicOutStrm
.Write( p_EscherBlibEntry
->mnIdentifier
, 16 );
3905 rPicOutStrm
.Write( p_EscherBlibEntry
->mnIdentifier
, 16 );
3909 For Word the stored size of the graphic is critical the
3910 metafile boundaries must match the actual graphics
3911 boundaries, and the width and height must be in EMU's
3913 If you don't do it this way then objects edited in the
3914 msoffice app may show strange behaviour as the size jumps
3915 around, and the original size and scaling factor in word
3916 will be a very strange figure
3918 UINT32 nPrefWidth
= p_EscherBlibEntry
->maPrefSize
.Width();
3919 UINT32 nPrefHeight
= p_EscherBlibEntry
->maPrefSize
.Height();
3920 UINT32 nWidth
, nHeight
;
3923 nWidth
= pVisArea
->Width
* 360;
3924 nHeight
= pVisArea
->Height
* 360;
3928 Size
aPrefSize(lcl_SizeToEmu(p_EscherBlibEntry
->maPrefSize
, p_EscherBlibEntry
->maPrefMapMode
));
3929 nWidth
= aPrefSize
.Width() * 360;
3930 nHeight
= aPrefSize
.Height() * 360;
3932 rPicOutStrm
<< nUncompressedSize
// WMFSize without FileHeader
3933 << (sal_Int32
)0 // da die Originalgroesse des WMF's (ohne FileHeader)
3934 << (sal_Int32
)0 // nicht mehr feststellbar ist, schreiben wir 10cm / x
3939 << p_EscherBlibEntry
->mnSize
3940 << (sal_uInt16
)0xfe00; // compression Flags
3941 rPicOutStrm
.Write( pGraphicAry
, p_EscherBlibEntry
->mnSize
);
3946 sal_uInt32 nPos
= rPicOutStrm
.Tell();
3947 rPicOutStrm
.Seek( nAtomSize
- 4 );
3948 rPicOutStrm
<< (sal_uInt32
)( nPos
- nAtomSize
);
3949 rPicOutStrm
.Seek( nPos
);
3951 nBlibId
= ImplInsertBlib( p_EscherBlibEntry
), p_EscherBlibEntry
= NULL
;
3954 if ( p_EscherBlibEntry
)
3955 delete p_EscherBlibEntry
;
3959 // ---------------------------------------------------------------------------------------------
3960 // ---------------------------------------------------------------------------------------------
3961 // ---------------------------------------------------------------------------------------------
3963 struct EscherConnectorRule
3966 sal_uInt32 nShapeA
; // SPID of shape A
3967 sal_uInt32 nShapeB
; // SPID of shape B
3968 sal_uInt32 nShapeC
; // SPID of connector shape
3969 sal_uInt32 ncptiA
; // Connection site Index of shape A
3970 sal_uInt32 ncptiB
; // Connection site Index of shape B
3973 struct EscherShapeListEntry
3975 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> aXShape
;
3976 sal_uInt32 n_EscherId
;
3978 EscherShapeListEntry( const ::com::sun::star::uno::Reference
3979 < ::com::sun::star::drawing::XShape
> & rShape
, sal_uInt32 nId
) :
3981 n_EscherId ( nId
) {}
3984 sal_uInt32
EscherConnectorListEntry::GetClosestPoint( const Polygon
& rPoly
, const ::com::sun::star::awt::Point
& rPoint
)
3986 sal_uInt16 nCount
= rPoly
.GetSize();
3987 sal_uInt16 nClosest
= nCount
;
3988 double fDist
= (sal_uInt32
)0xffffffff;
3991 double fDistance
= hypot( rPoint
.X
- rPoly
[ nCount
].X(), rPoint
.Y
- rPoly
[ nCount
].Y() );
3992 if ( fDistance
< fDist
)
4001 // ---------------------------------------------------------------------------------------------
4002 // bei Rechtecken bei Ellipsen bei Polygonen
4004 // nRule = 0 ->Top 0 ->Top nRule = Index auf ein (Poly)Polygon Punkt
4005 // 1 ->Left 2 ->Left
4006 // 2 ->Bottom 4 ->Bottom
4007 // 3 ->Right 6 ->Right
4009 sal_uInt32
EscherConnectorListEntry::GetConnectorRule( sal_Bool bFirst
)
4011 sal_uInt32 nRule
= 0;
4013 ::com::sun::star::uno::Any aAny
;
4014 ::com::sun::star::awt::Point
aRefPoint( ( bFirst
) ? maPointA
: maPointB
);
4015 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>
4016 aXShape( ( bFirst
) ? mXConnectToA
: mXConnectToB
);
4018 String
aString( (::rtl::OUString
)aXShape
->getShapeType() );
4019 ByteString
aType( aString
, RTL_TEXTENCODING_UTF8
);
4020 aType
.Erase( 0, 13 ); // removing "com.sun.star."
4021 sal_uInt16 nPos
= aType
.Search( "Shape" );
4022 aType
.Erase( nPos
, 5 );
4024 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>
4025 aPropertySet( aXShape
, ::com::sun::star::uno::UNO_QUERY
);
4027 if ( aType
== "drawing.PolyPolygon" || aType
== "drawing.PolyLine" )
4029 if ( aPropertySet
.is() )
4031 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
,
4032 aPropertySet
, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ) ) )
4034 ::com::sun::star::drawing::PointSequenceSequence
* pSourcePolyPolygon
=
4035 (::com::sun::star::drawing::PointSequenceSequence
*)aAny
.getValue();
4036 sal_Int32 nOuterSequenceCount
= pSourcePolyPolygon
->getLength();
4037 ::com::sun::star::drawing::PointSequence
* pOuterSequence
= pSourcePolyPolygon
->getArray();
4039 if ( pOuterSequence
)
4041 sal_Int32 a
, b
, nIndex
= 0;
4042 sal_uInt32 nDistance
= 0xffffffff;
4043 for( a
= 0; a
< nOuterSequenceCount
; a
++ )
4045 ::com::sun::star::drawing::PointSequence
* pInnerSequence
= pOuterSequence
++;
4046 if ( pInnerSequence
)
4048 ::com::sun::star::awt::Point
* pArray
= pInnerSequence
->getArray();
4051 for ( b
= 0; b
< pInnerSequence
->getLength(); b
++, nIndex
++, pArray
++ )
4053 sal_uInt32 nDist
= (sal_uInt32
)hypot( aRefPoint
.X
- pArray
->X
, aRefPoint
.Y
- pArray
->Y
);
4054 if ( nDist
< nDistance
)
4067 else if ( ( aType
== "drawing.OpenBezier" ) || ( aType
== "drawing.OpenFreeHand" ) || ( aType
== "drawing.PolyLinePath" )
4068 || ( aType
== "drawing.ClosedBezier" ) || ( aType
== "drawing.ClosedFreeHand" ) || ( aType
== "drawing.PolyPolygonPath" ) )
4070 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
>
4071 aPropertySet2( aXShape
, ::com::sun::star::uno::UNO_QUERY
);
4072 if ( aPropertySet2
.is() )
4074 if ( EscherPropertyValueHelper::GetPropertyValue( aAny
,
4075 aPropertySet2
, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ) ) )
4077 ::com::sun::star::drawing::PolyPolygonBezierCoords
* pSourcePolyPolygon
=
4078 (::com::sun::star::drawing::PolyPolygonBezierCoords
*)aAny
.getValue();
4079 sal_Int32 nOuterSequenceCount
= pSourcePolyPolygon
->Coordinates
.getLength();
4081 // Zeiger auf innere sequences holen
4082 ::com::sun::star::drawing::PointSequence
* pOuterSequence
=
4083 pSourcePolyPolygon
->Coordinates
.getArray();
4084 ::com::sun::star::drawing::FlagSequence
* pOuterFlags
=
4085 pSourcePolyPolygon
->Flags
.getArray();
4087 if ( pOuterSequence
&& pOuterFlags
)
4089 sal_Int32 a
, b
, nIndex
= 0;
4090 sal_uInt32 nDistance
= 0xffffffff;
4092 for ( a
= 0; a
< nOuterSequenceCount
; a
++ )
4094 ::com::sun::star::drawing::PointSequence
* pInnerSequence
= pOuterSequence
++;
4095 ::com::sun::star::drawing::FlagSequence
* pInnerFlags
= pOuterFlags
++;
4096 if ( pInnerSequence
&& pInnerFlags
)
4098 ::com::sun::star::awt::Point
* pArray
= pInnerSequence
->getArray();
4099 ::com::sun::star::drawing::PolygonFlags
* pFlags
= pInnerFlags
->getArray();
4100 if ( pArray
&& pFlags
)
4102 for ( b
= 0; b
< pInnerSequence
->getLength(); b
++, pArray
++ )
4104 PolyFlags ePolyFlags
= *( (PolyFlags
*)pFlags
++ );
4105 if ( ePolyFlags
== POLY_CONTROL
)
4107 sal_uInt32 nDist
= (sal_uInt32
)hypot( aRefPoint
.X
- pArray
->X
, aRefPoint
.Y
- pArray
->Y
);
4108 if ( nDist
< nDistance
)
4124 bool bRectangularConnection
= true;
4126 if ( aType
== "drawing.Custom" )
4128 SdrObject
* pCustoShape( GetSdrObjectFromXShape( aXShape
) );
4129 if ( pCustoShape
&& pCustoShape
->ISA( SdrObjCustomShape
) )
4131 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)(const SdrCustomShapeGeometryItem
&)
4132 pCustoShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
4134 const rtl::OUString
sPath( RTL_CONSTASCII_USTRINGPARAM( "Path" ) );
4135 const rtl::OUString
sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
4136 const rtl::OUString
sGluePointType( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) );
4138 rtl::OUString sShapeType
;
4139 uno::Any
* pType
= rGeometryItem
.GetPropertyValueByName( sType
);
4141 *pType
>>= sShapeType
;
4142 MSO_SPT eSpType
= EnhancedCustomShapeTypeNames::Get( sShapeType
);
4144 uno::Any
* pGluePointType
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sGluePointType
);
4146 sal_Int16 nGluePointType
= sal_Int16();
4147 if ( !( pGluePointType
&&
4148 ( *pGluePointType
>>= nGluePointType
) ) )
4149 nGluePointType
= GetCustomShapeConnectionTypeDefault( eSpType
);
4151 if ( nGluePointType
== com::sun::star::drawing::EnhancedCustomShapeGluePointType::CUSTOM
)
4153 const SdrGluePointList
* pList
= pCustoShape
->GetGluePointList();
4157 USHORT nNum
, nAnz
= pList
->GetCount();
4160 for ( nNum
= 0; nNum
< nAnz
; nNum
++ )
4162 const SdrGluePoint
& rGP
= (*pList
)[ nNum
];
4163 Point
aPt( rGP
.GetAbsolutePos( *pCustoShape
) );
4164 aPoly
.Insert( POLY_APPEND
, aPt
);
4166 nRule
= GetClosestPoint( aPoly
, aRefPoint
);
4167 bRectangularConnection
= false;
4171 else if ( nGluePointType
== com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS
)
4173 SdrObject
* pPoly
= pCustoShape
->DoConvertToPolyObj( TRUE
);
4174 if ( pPoly
&& pPoly
->ISA( SdrPathObj
) )
4176 sal_Int16 a
, b
, nIndex
= 0;
4177 sal_uInt32 nDistance
= 0xffffffff;
4179 // #i74631# use explicit constructor here. Also XPolyPolygon is not necessary,
4180 // reducing to PolyPolygon
4181 const PolyPolygon
aPolyPoly(((SdrPathObj
*)pPoly
)->GetPathPoly());
4183 for ( a
= 0; a
< aPolyPoly
.Count(); a
++ )
4185 const Polygon
& rPoly
= aPolyPoly
.GetObject( a
);
4186 for ( b
= 0; b
< rPoly
.GetSize(); b
++ )
4188 if ( rPoly
.GetFlags( b
) != POLY_NORMAL
)
4190 const Point
& rPt
= rPoly
[ b
];
4191 sal_uInt32 nDist
= (sal_uInt32
)hypot( aRefPoint
.X
- rPt
.X(), aRefPoint
.Y
- rPt
.Y() );
4192 if ( nDist
< nDistance
)
4200 if ( nDistance
!= 0xffffffff )
4201 bRectangularConnection
= false;
4206 if ( bRectangularConnection
)
4208 ::com::sun::star::awt::Point
aPoint( aXShape
->getPosition() );
4209 ::com::sun::star::awt::Size
aSize( aXShape
->getSize() );
4211 Rectangle
aRect( Point( aPoint
.X
, aPoint
.Y
), Size( aSize
.Width
, aSize
.Height
) );
4212 Point
aCenter( aRect
.Center() );
4215 aPoly
[ 0 ] = Point( aCenter
.X(), aRect
.Top() );
4216 aPoly
[ 1 ] = Point( aRect
.Left(), aCenter
.Y() );
4217 aPoly
[ 2 ] = Point( aCenter
.X(), aRect
.Bottom() );
4218 aPoly
[ 3 ] = Point( aRect
.Right(), aCenter
.Y() );
4220 sal_Int32 nAngle
= ( EscherPropertyValueHelper::GetPropertyValue( aAny
,
4221 aPropertySet
, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True
) )
4222 ? *((sal_Int32
*)aAny
.getValue() )
4225 aPoly
.Rotate( aRect
.TopLeft(), (sal_uInt16
)( ( nAngle
+ 5 ) / 10 ) );
4226 nRule
= GetClosestPoint( aPoly
, aRefPoint
);
4228 if ( aType
== "drawing.Ellipse" )
4229 nRule
<<= 1; // In PPT hat eine Ellipse 8 Möglichkeiten sich zu connecten
4235 EscherSolverContainer::~EscherSolverContainer()
4239 for( pP
= maShapeList
.First(); pP
; pP
= maShapeList
.Next() )
4240 delete (EscherShapeListEntry
*)pP
;
4241 for( pP
= maConnectorList
.First(); pP
; pP
= maConnectorList
.Next() )
4242 delete (EscherConnectorListEntry
*)pP
;
4245 void EscherSolverContainer::AddShape( const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rXShape
, sal_uInt32 nId
)
4247 maShapeList
.Insert( new EscherShapeListEntry( rXShape
, nId
), LIST_APPEND
);
4250 void EscherSolverContainer::AddConnector( const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rConnector
,
4251 const ::com::sun::star::awt::Point
& rPA
,
4252 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rConA
,
4253 const ::com::sun::star::awt::Point
& rPB
,
4254 ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rConB
)
4256 maConnectorList
.Insert( new EscherConnectorListEntry( rConnector
, rPA
, rConA
, rPB
, rConB
), LIST_APPEND
);
4259 sal_uInt32
EscherSolverContainer::GetShapeId( const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> & rXShape
) const
4261 for ( EscherShapeListEntry
* pPtr
= (EscherShapeListEntry
*)((List
&)maShapeList
).First();
4262 pPtr
; pPtr
= (EscherShapeListEntry
*)((List
&)maShapeList
).Next() )
4264 if ( rXShape
== pPtr
->aXShape
)
4265 return ( pPtr
->n_EscherId
);
4270 void EscherSolverContainer::WriteSolver( SvStream
& rStrm
)
4272 sal_uInt32 nCount
= maConnectorList
.Count();
4275 sal_uInt32 nRecHdPos
, nCurrentPos
, nSize
;
4276 rStrm
<< (sal_uInt16
)( ( nCount
<< 4 ) | 0xf ) // open an ESCHER_SolverContainer
4277 << (sal_uInt16
)ESCHER_SolverContainer
//
4278 << (sal_uInt32
)0; //
4280 nRecHdPos
= rStrm
.Tell() - 4;
4282 EscherConnectorRule aConnectorRule
;
4283 aConnectorRule
.nRuleId
= 2;
4284 for ( EscherConnectorListEntry
* pPtr
= (EscherConnectorListEntry
*)maConnectorList
.First();
4285 pPtr
; pPtr
= (EscherConnectorListEntry
*)maConnectorList
.Next() )
4287 aConnectorRule
.ncptiA
= aConnectorRule
.ncptiB
= 0xffffffff;
4288 aConnectorRule
.nShapeC
= GetShapeId( pPtr
->mXConnector
);
4289 aConnectorRule
.nShapeA
= GetShapeId( pPtr
->mXConnectToA
);
4290 aConnectorRule
.nShapeB
= GetShapeId( pPtr
->mXConnectToB
);
4292 if ( aConnectorRule
.nShapeC
)
4294 if ( aConnectorRule
.nShapeA
)
4295 aConnectorRule
.ncptiA
= pPtr
->GetConnectorRule( sal_True
);
4296 if ( aConnectorRule
.nShapeB
)
4297 aConnectorRule
.ncptiB
= pPtr
->GetConnectorRule( sal_False
);
4299 rStrm
<< (sal_uInt32
)( ( ESCHER_ConnectorRule
<< 16 ) | 1 ) // atom hd
4300 << (sal_uInt32
)24 //
4301 << aConnectorRule
.nRuleId
4302 << aConnectorRule
.nShapeA
4303 << aConnectorRule
.nShapeB
4304 << aConnectorRule
.nShapeC
4305 << aConnectorRule
.ncptiA
4306 << aConnectorRule
.ncptiB
;
4308 aConnectorRule
.nRuleId
+= 2;
4311 nCurrentPos
= rStrm
.Tell(); // close the ESCHER_SolverContainer
4312 nSize
= ( nCurrentPos
- nRecHdPos
) - 4;//
4313 rStrm
.Seek( nRecHdPos
); //
4315 rStrm
.Seek( nCurrentPos
); //
4319 // ---------------------------------------------------------------------------------------------
4320 // ---------------------------------------------------------------------------------------------
4321 // ---------------------------------------------------------------------------------------------
4323 EscherEx::EscherEx( SvStream
& rOutStrm
, UINT32 nDrawings
) :
4324 EscherGraphicProvider ( 0 ),
4325 mpOutStrm ( &rOutStrm
),
4326 mnDrawings ( nDrawings
),
4329 mnHellLayerId ( USHRT_MAX
),
4331 mbEscherSpgr ( FALSE
),
4332 mbEscherDgg ( FALSE
), // TRUE, wenn jemals ein ESCHER_Dgg angelegt wurde, dieser wird dann im Dest. aktualisiert
4333 mbEscherDg ( FALSE
),
4336 mnStrmStartOfs
= mpOutStrm
->Tell();
4337 mpImplEscherExSdr
= new ImplEscherExSdr( *this );
4340 // ---------------------------------------------------------------------------------------------
4342 void EscherEx::Flush( SvStream
* pPicStreamMergeBSE
/* = NULL */ )
4344 if ( mbEscherDgg
) // ESCHER_Dgg anpassen
4346 PtReplaceOrInsert( ESCHER_Persist_CurrentPosition
, mpOutStrm
->Tell() );
4347 if ( DoSeek( ESCHER_Persist_Dgg
) )
4349 *mpOutStrm
<< mnCurrentShapeID
<< (UINT32
)( mnFIDCLs
+ 1 ) << mnTotalShapesDgg
<< mnDrawings
;
4351 if ( HasGraphics() )
4353 if ( DoSeek( ESCHER_Persist_BlibStoreContainer
) ) // ESCHER_BlibStoreContainer schreiben
4355 sal_uInt32 nAddBytes
= GetBlibStoreContainerSize( pPicStreamMergeBSE
);
4358 InsertAtCurrentPos( nAddBytes
, TRUE
); // platz schaffen fuer Blib Container samt seinen Blib Atomen
4359 WriteBlibStoreContainer( *mpOutStrm
, pPicStreamMergeBSE
);
4363 mpOutStrm
->Seek( PtGetOffsetByID( ESCHER_Persist_CurrentPosition
) );
4367 // ---------------------------------------------------------------------------------------------
4369 EscherEx::~EscherEx()
4371 delete mpImplEscherExSdr
;
4374 // ---------------------------------------------------------------------------------------------
4376 void EscherEx::InsertAtCurrentPos( UINT32 nBytes
, BOOL bContainer
)
4378 UINT32 nSize
, nType
, nSource
, nBufSize
, nToCopy
, nCurPos
= mpOutStrm
->Tell();
4381 // Persist table anpassen
4382 for ( void* pPtr
= maPersistTable
.First(); pPtr
; pPtr
= maPersistTable
.Next() )
4384 UINT32 nOfs
= ((EscherPersistEntry
*)pPtr
)->mnOffset
;
4385 if ( nOfs
>= nCurPos
)
4386 ((EscherPersistEntry
*)pPtr
)->mnOffset
+= nBytes
;
4389 // container und atom sizes anpassen
4390 mpOutStrm
->Seek( mnStrmStartOfs
);
4391 while ( mpOutStrm
->Tell() < nCurPos
)
4393 *mpOutStrm
>> nType
>> nSize
;
4394 if ( ( mpOutStrm
->Tell() + nSize
) >= ( ( bContainer
) ? nCurPos
+ 1 : nCurPos
) )
4396 mpOutStrm
->SeekRel( -4 );
4397 *mpOutStrm
<< (UINT32
)( nSize
+ nBytes
);
4398 if ( ( nType
& 0xf ) != 0xf )
4399 mpOutStrm
->SeekRel( nSize
);
4402 mpOutStrm
->SeekRel( nSize
);
4404 std::vector
< sal_uInt32
>::iterator
aIter( mOffsets
.begin() );
4405 std::vector
< sal_uInt32
>::iterator
aEnd( mOffsets
.end() );
4406 while( aIter
!= aEnd
)
4408 if ( *aIter
> nCurPos
)
4412 mpOutStrm
->Seek( STREAM_SEEK_TO_END
);
4413 nSource
= mpOutStrm
->Tell();
4414 nToCopy
= nSource
- nCurPos
; // Stream um nBytes vergroessern
4415 pBuf
= new BYTE
[ 0x40000 ]; // 256KB Buffer
4418 nBufSize
= ( nToCopy
>= 0x40000 ) ? 0x40000 : nToCopy
;
4419 nToCopy
-= nBufSize
;
4420 nSource
-= nBufSize
;
4421 mpOutStrm
->Seek( nSource
);
4422 mpOutStrm
->Read( pBuf
, nBufSize
);
4423 mpOutStrm
->Seek( nSource
+ nBytes
);
4424 mpOutStrm
->Write( pBuf
, nBufSize
);
4427 mpOutStrm
->Seek( nCurPos
);
4430 // ---------------------------------------------------------------------------------------------
4432 BOOL
EscherEx::SeekBehindRecHeader( UINT16 nRecType
)
4434 UINT32 nOldPos
, nStreamEnd
, nType
, nSize
;
4436 nOldPos
= mpOutStrm
->Tell();
4437 nStreamEnd
= mpOutStrm
->Seek( STREAM_SEEK_TO_END
);
4438 mpOutStrm
->Seek( nOldPos
);
4439 while ( mpOutStrm
->Tell() < nStreamEnd
)
4441 *mpOutStrm
>> nType
>> nSize
;
4442 if ( ( nType
>> 16 ) == nRecType
)
4444 if ( ( nType
& 0xf ) != 0xf )
4445 mpOutStrm
->SeekRel( nSize
);
4447 mpOutStrm
->Seek( nOldPos
);
4451 // ---------------------------------------------------------------------------------------------
4453 void EscherEx::InsertPersistOffset( UINT32 nKey
, UINT32 nOffset
)
4455 PtInsert( ESCHER_Persist_PrivateEntry
| nKey
, nOffset
);
4458 // ---------------------------------------------------------------------------------------------
4460 BOOL
EscherEx::DoSeek( UINT32 nKey
)
4462 UINT32 nPos
= PtGetOffsetByID( nKey
);
4464 mpOutStrm
->Seek( nPos
);
4467 if (! PtIsID( nKey
) )
4469 mpOutStrm
->Seek( 0 );
4474 // ---------------------------------------------------------------------------------------------
4476 BOOL
EscherEx::SeekToPersistOffset( UINT32 nKey
)
4478 return DoSeek( ESCHER_Persist_PrivateEntry
| nKey
);
4481 // ---------------------------------------------------------------------------------------------
4483 BOOL
EscherEx::InsertAtPersistOffset( UINT32 nKey
, UINT32 nValue
)
4485 UINT32 nOldPos
= mpOutStrm
->Tell();
4486 BOOL bRetValue
= SeekToPersistOffset( nKey
);
4489 *mpOutStrm
<< nValue
;
4490 mpOutStrm
->Seek( nOldPos
);
4495 // ---------------------------------------------------------------------------------------------
4497 void EscherEx::OpenContainer( UINT16 nEscherContainer
, int nRecInstance
)
4499 *mpOutStrm
<< (UINT16
)( ( nRecInstance
<< 4 ) | 0xf ) << nEscherContainer
<< (UINT32
)0;
4500 mOffsets
.push_back( mpOutStrm
->Tell() - 4 );
4501 mRecTypes
.push_back( nEscherContainer
);
4502 switch( nEscherContainer
)
4504 case ESCHER_DggContainer
:
4507 mnFIDCLs
= mnDrawings
;
4509 mnCurrentShapeID
= 0;
4510 mnTotalShapesDgg
= 0;
4511 mnCurrentShapeMaximumID
= 0;
4512 AddAtom( 16 + ( mnDrawings
<< 3 ), ESCHER_Dgg
); // an FDGG and several FIDCLs
4513 PtReplaceOrInsert( ESCHER_Persist_Dgg
, mpOutStrm
->Tell() );
4514 *mpOutStrm
<< (UINT32
)0 // the current maximum shape ID
4515 << (UINT32
)0 // the number of ID clusters + 1
4516 << (UINT32
)0 // the number of total shapes saved
4517 << (UINT32
)0; // the total number of drawings saved
4518 PtReplaceOrInsert( ESCHER_Persist_Dgg_FIDCL
, mpOutStrm
->Tell() );
4519 for ( UINT32 i
= 0; i
< mnFIDCLs
; i
++ ) // Dummy FIDCLs einfuegen
4521 *mpOutStrm
<< (UINT32
)0 << (UINT32
)0; // Drawing Nummer, Anzahl der Shapes in diesem IDCL
4523 PtReplaceOrInsert( ESCHER_Persist_BlibStoreContainer
, mpOutStrm
->Tell() );
4527 case ESCHER_DgContainer
:
4535 mnTotalShapesDg
= 0;
4536 mnTotalShapeIdUsedDg
= 0;
4537 mnCurrentShapeID
= ( mnCurrentShapeMaximumID
&~0x3ff ) + 0x400; // eine neue Seite bekommt immer eine neue ShapeId die ein vielfaches von 1024 ist,
4538 // damit ist erste aktuelle Shape ID 0x400
4539 AddAtom( 8, ESCHER_Dg
, 0, mnCurrentDg
);
4540 PtReplaceOrInsert( ESCHER_Persist_Dg
| mnCurrentDg
, mpOutStrm
->Tell() );
4541 *mpOutStrm
<< (UINT32
)0 // The number of shapes in this drawing
4542 << (UINT32
)0; // The last MSOSPID given to an SP in this DG
4548 case ESCHER_SpgrContainer
:
4552 mbEscherSpgr
= TRUE
;
4557 case ESCHER_SpContainer
:
4567 // ---------------------------------------------------------------------------------------------
4569 void EscherEx::CloseContainer()
4571 sal_uInt32 nSize
, nPos
= mpOutStrm
->Tell();
4572 nSize
= ( nPos
- mOffsets
.back() ) - 4;
4573 mpOutStrm
->Seek( mOffsets
.back() );
4574 *mpOutStrm
<< nSize
;
4576 switch( mRecTypes
.back() )
4578 case ESCHER_DgContainer
:
4583 if ( DoSeek( ESCHER_Persist_Dg
| mnCurrentDg
) )
4585 // shapeanzahl des drawings setzen
4586 mnTotalShapesDgg
+= mnTotalShapesDg
;
4587 *mpOutStrm
<< mnTotalShapesDg
<< mnCurrentShapeMaximumID
;
4588 if ( DoSeek( ESCHER_Persist_Dgg_FIDCL
) )
4590 if ( mnTotalShapesDg
== 0 )
4592 mpOutStrm
->SeekRel( 8 );
4596 if ( mnTotalShapeIdUsedDg
)
4598 // die benutzten Shape Ids des drawings in die fidcls setzen
4599 UINT32 i
, nFIDCL
= ( ( mnTotalShapeIdUsedDg
- 1 ) / 0x400 );
4602 if ( nPos
> mpOutStrm
->Tell() )
4603 nPos
+= ( nFIDCL
<< 3 );
4606 InsertAtCurrentPos( nFIDCL
<< 3 ); // platz schaffen fuer weitere FIDCL's
4608 for ( i
= 0; i
<= nFIDCL
; i
++ )
4610 *mpOutStrm
<< mnCurrentDg
;
4612 *mpOutStrm
<< (UINT32
)0x400;
4615 UINT32 nShapesLeft
= mnTotalShapeIdUsedDg
% 0x400;
4617 nShapesLeft
= 0x400;
4618 *mpOutStrm
<< (UINT32
)nShapesLeft
;
4623 PtReplaceOrInsert( ESCHER_Persist_Dgg_FIDCL
, mpOutStrm
->Tell() ); // neuen FIDCL Offset fuer naechste Seite
4630 case ESCHER_SpgrContainer
:
4634 mbEscherSpgr
= FALSE
;
4643 mOffsets
.pop_back();
4644 mRecTypes
.pop_back();
4645 mpOutStrm
->Seek( nPos
);
4648 // ---------------------------------------------------------------------------------------------
4650 void EscherEx::BeginAtom()
4652 mnCountOfs
= mpOutStrm
->Tell();
4653 *mpOutStrm
<< (UINT32
)0 << (UINT32
)0; // record header wird spaeter geschrieben
4656 // ---------------------------------------------------------------------------------------------
4658 void EscherEx::EndAtom( UINT16 nRecType
, int nRecVersion
, int nRecInstance
)
4660 UINT32 nOldPos
= mpOutStrm
->Tell();
4661 mpOutStrm
->Seek( mnCountOfs
);
4662 sal_uInt32 nSize
= nOldPos
- mnCountOfs
;
4663 *mpOutStrm
<< (UINT16
)( ( nRecInstance
<< 4 ) | ( nRecVersion
& 0xf ) ) << nRecType
<< (UINT32
)( nSize
- 8 );
4664 mpOutStrm
->Seek( nOldPos
);
4667 // ---------------------------------------------------------------------------------------------
4669 void EscherEx::AddAtom( UINT32 nAtomSize
, UINT16 nRecType
, int nRecVersion
, int nRecInstance
)
4671 *mpOutStrm
<< (UINT16
)( ( nRecInstance
<< 4 ) | ( nRecVersion
& 0xf ) ) << nRecType
<< nAtomSize
;
4674 // ---------------------------------------------------------------------------------------------
4676 void EscherEx::AddChildAnchor( const Rectangle
& rRect
)
4678 AddAtom( 16, ESCHER_ChildAnchor
);
4679 GetStream() << (INT32
)rRect
.Left()
4680 << (INT32
)rRect
.Top()
4681 << (INT32
)rRect
.Right()
4682 << (INT32
)rRect
.Bottom();
4685 // ---------------------------------------------------------------------------------------------
4687 void EscherEx::AddClientAnchor( const Rectangle
& rRect
)
4689 AddAtom( 8, ESCHER_ClientAnchor
);
4690 *mpOutStrm
<< (sal_Int16
)rRect
.Top()
4691 << (sal_Int16
)rRect
.Left()
4692 << (sal_Int16
)( rRect
.GetWidth() + rRect
.Left() )
4693 << (sal_Int16
)( rRect
.GetHeight() + rRect
.Top() );
4696 // ---------------------------------------------------------------------------------------------
4698 EscherExHostAppData
* EscherEx::EnterAdditionalTextGroup()
4703 // ---------------------------------------------------------------------------------------------
4705 UINT32
EscherEx::EnterGroup( const String
& rShapeName
, const Rectangle
* pBoundRect
)
4709 aRect
= *pBoundRect
;
4711 OpenContainer( ESCHER_SpgrContainer
);
4712 OpenContainer( ESCHER_SpContainer
);
4713 AddAtom( 16, ESCHER_Spgr
, 1 );
4714 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
,
4715 mpOutStrm
->Tell() );
4716 *mpOutStrm
<< (INT32
)aRect
.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
4717 << (INT32
)aRect
.Top()
4718 << (INT32
)aRect
.Right()
4719 << (INT32
)aRect
.Bottom();
4721 UINT32 nShapeId
= GetShapeID();
4722 if ( !mnGroupLevel
)
4723 AddShape( ESCHER_ShpInst_Min
, 5, nShapeId
); // Flags: Group | Patriarch
4726 AddShape( ESCHER_ShpInst_Min
, 0x201, nShapeId
); // Flags: Group | HaveAnchor
4727 EscherPropertyContainer aPropOpt
;
4728 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x00040004 );
4729 aPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
, 0 );
4730 aPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
, 0 );
4732 // #i51348# shape name
4733 if( rShapeName
.Len() > 0 )
4734 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, rShapeName
);
4736 Commit( aPropOpt
, aRect
);
4737 if ( mnGroupLevel
> 1 )
4738 AddChildAnchor( aRect
);
4740 EscherExHostAppData
* pAppData
= mpImplEscherExSdr
->ImplGetHostData();
4743 if ( mnGroupLevel
<= 1 )
4744 pAppData
->WriteClientAnchor( *this, aRect
);
4745 pAppData
->WriteClientData( *this );
4748 CloseContainer(); // ESCHER_SpContainer
4753 UINT32
EscherEx::EnterGroup( const Rectangle
* pBoundRect
)
4755 return EnterGroup( String::EmptyString(), pBoundRect
);
4758 // ---------------------------------------------------------------------------------------------
4760 BOOL
EscherEx::SetGroupSnapRect( UINT32 nGroupLevel
, const Rectangle
& rRect
)
4762 BOOL bRetValue
= FALSE
;
4765 UINT32 nCurrentPos
= mpOutStrm
->Tell();
4766 if ( DoSeek( ESCHER_Persist_Grouping_Snap
| ( nGroupLevel
- 1 ) ) )
4768 *mpOutStrm
<< (INT32
)rRect
.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
4769 << (INT32
)rRect
.Top()
4770 << (INT32
)rRect
.Right()
4771 << (INT32
)rRect
.Bottom();
4772 mpOutStrm
->Seek( nCurrentPos
);
4778 // ---------------------------------------------------------------------------------------------
4780 BOOL
EscherEx::SetGroupLogicRect( UINT32 nGroupLevel
, const Rectangle
& rRect
)
4782 BOOL bRetValue
= FALSE
;
4785 UINT32 nCurrentPos
= mpOutStrm
->Tell();
4786 if ( DoSeek( ESCHER_Persist_Grouping_Logic
| ( nGroupLevel
- 1 ) ) )
4788 *mpOutStrm
<< (INT16
)rRect
.Top() << (INT16
)rRect
.Left() << (INT16
)rRect
.Right() << (INT16
)rRect
.Bottom();
4789 mpOutStrm
->Seek( nCurrentPos
);
4795 // ---------------------------------------------------------------------------------------------
4797 void EscherEx::LeaveGroup()
4800 PtDelete( ESCHER_Persist_Grouping_Snap
| mnGroupLevel
);
4801 PtDelete( ESCHER_Persist_Grouping_Logic
| mnGroupLevel
);
4805 // ---------------------------------------------------------------------------------------------
4807 void EscherEx::AddShape( UINT32 nShpInstance
, UINT32 nFlags
, UINT32 nShapeID
)
4809 AddAtom( 8, ESCHER_Sp
, 2, nShpInstance
);
4812 nShapeID
= GetShapeID();
4814 if ( nFlags
^ 1 ) // is this a group shape ?
4816 if ( mnGroupLevel
> 1 )
4817 nFlags
|= 2; // this not a topmost shape
4819 *mpOutStrm
<< nShapeID
<< nFlags
;
4825 // ---------------------------------------------------------------------------------------------
4827 UINT32
EscherEx::GetShapeID()
4829 mnCurrentShapeMaximumID
= mnCurrentShapeID
; // maximum setzen
4830 mnCurrentShapeID
++; // mnCurrentShape ID auf nachste freie ID
4831 mnTotalShapeIdUsedDg
++;
4832 return mnCurrentShapeMaximumID
;
4835 // ---------------------------------------------------------------------------------------------
4837 void EscherEx::Commit( EscherPropertyContainer
& rProps
, const Rectangle
& )
4839 rProps
.Commit( GetStream() );
4842 // ---------------------------------------------------------------------------------------------
4844 UINT32
EscherEx::GetColor( const UINT32 nSOColor
, BOOL bSwap
)
4848 UINT32 nColor
= nSOColor
& 0xff00; // GRUEN
4849 nColor
|= (BYTE
)( nSOColor
) << 16; // ROT
4850 nColor
|= (BYTE
)( nSOColor
>> 16 ); // BLAU
4854 return nSOColor
& 0xffffff;
4857 // ---------------------------------------------------------------------------------------------
4859 UINT32
EscherEx::GetColor( const Color
& rSOColor
, BOOL bSwap
)
4861 UINT32 nColor
= ( rSOColor
.GetRed() << 16 );
4862 nColor
|= ( rSOColor
.GetGreen() << 8 );
4863 nColor
|= rSOColor
.GetBlue();
4866 nColor
= GetColor( nColor
, TRUE
);
4871 // ---------------------------------------------------------------------------------------------