xref: /trunk/main/svx/source/svdraw/svdoashp.cxx (revision 3a7cf181c55416e69e525ddc0b38c22235ec1569)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/svdoashp.hxx>
31 #include "svx/unoapi.hxx"
32 #include <svx/unoshape.hxx>
33 #include <ucbhelper/content.hxx>
34 #include <ucbhelper/contentbroker.hxx>
35 #include <unotools/datetime.hxx>
36 #include <sfx2/lnkbase.hxx>
37 #include <tools/urlobj.hxx>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/drawing/XShape.hpp>
40 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
41 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
42 #include <com/sun/star/beans/PropertyValue.hpp>
43 #include <com/sun/star/awt/Rectangle.hpp>
44 #include "unopolyhelper.hxx"
45 #include <comphelper/processfactory.hxx>
46 #include <svl/urihelper.hxx>
47 #include <com/sun/star/uno/Sequence.h>
48 #include <svx/svdogrp.hxx>
49 #include <vcl/salbtype.hxx>     // FRound
50 #include <svx/svddrag.hxx>
51 #include <svx/xpool.hxx>
52 #include <svx/xpoly.hxx>
53 #include <svx/svdmodel.hxx>
54 #include <svx/svdpage.hxx>
55 #include "svx/svditer.hxx"
56 #include <svx/svdobj.hxx>
57 #include <svx/svdtrans.hxx>
58 #include <svx/svdetc.hxx>
59 #include <svx/svdattrx.hxx>  // NotPersistItems
60 #include <svx/svdoedge.hxx>  // #32383# Die Verbinder nach Move nochmal anbroadcasten
61 #include "svx/svdglob.hxx"   // StringCache
62 #include "svx/svdstr.hrc"    // Objektname
63 #include <editeng/eeitem.hxx>
64 #include "editeng/editstat.hxx"
65 #include <svx/svdoutl.hxx>
66 #include <editeng/outlobj.hxx>
67 #include <svx/sdtfchim.hxx>
68 #include "../svx/EnhancedCustomShapeGeometry.hxx"
69 #include "../svx/EnhancedCustomShapeTypeNames.hxx"
70 #include "../svx/EnhancedCustomShape2d.hxx"
71 #include <com/sun/star/beans/PropertyValues.hpp>
72 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
73 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
74 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
75 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
76 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
77 #include <editeng/writingmodeitem.hxx>
78 #include <svx/xlnclit.hxx>
79 #include <svx/svxids.hrc>
80 #include <svl/whiter.hxx>
81 #include <svx/sdr/properties/customshapeproperties.hxx>
82 #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
83 #include <svx/xlnclit.hxx>
84 #include <svx/xlntrit.hxx>
85 #include <svx/xfltrit.hxx>
86 #include <svx/xflclit.hxx>
87 #include <svx/xflgrit.hxx>
88 #include <svx/xflhtit.hxx>
89 #include <svx/xbtmpit.hxx>
90 #include <vcl/bmpacc.hxx>
91 #include <svx/svdview.hxx>
92 #include <basegfx/polygon/b2dpolypolygontools.hxx>
93 #include <basegfx/matrix/b2dhommatrix.hxx>
94 #include <basegfx/matrix/b2dhommatrixtools.hxx>
95 
96 // #104018# replace macros above with type-safe methods
97 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
98 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
99 
100 using namespace ::com::sun::star;
101 using namespace ::com::sun::star::uno;
102 using namespace ::com::sun::star::lang;
103 using namespace ::com::sun::star::beans;
104 using namespace ::com::sun::star::drawing;
105 
106 static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape )
107 {
108     MSO_SPT eRetValue = mso_sptNil;
109 
110     rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
111     if ( !aEngine.getLength() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) )
112     {
113         rtl::OUString sShapeType;
114         const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
115         SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
116         Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
117         if ( pAny && ( *pAny >>= sShapeType ) )
118             eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType );
119     }
120     return eRetValue;
121 };
122 
123 static sal_Bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape )
124 {
125     sal_Bool bRet = sal_False;
126     MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) );
127     switch( eShapeType )
128     {
129         case mso_sptAccentBorderCallout90 :     // 2 ortho
130         case mso_sptBorderCallout1 :            // 2 diag
131         case mso_sptBorderCallout2 :            // 3
132         {
133             bRet = sal_True;
134         }
135         break;
136 /*
137         case mso_sptCallout1 :
138         case mso_sptAccentCallout1 :
139         case mso_sptAccentBorderCallout1 :
140         case mso_sptBorderCallout90 :
141         case mso_sptCallout90 :
142         case mso_sptAccentCallout90 :
143         case mso_sptCallout2 :
144         case mso_sptCallout3 :
145         case mso_sptAccentCallout2 :
146         case mso_sptAccentCallout3 :
147         case mso_sptBorderCallout3 :
148         case mso_sptAccentBorderCallout2 :
149         case mso_sptAccentBorderCallout3 :
150 */
151         default: break;
152     }
153     return bRet;
154 }
155 
156 ////////////////////////////////////////////////////////////////////////////////////////////////////
157 // #i37011# create a clone with all attributes changed to shadow attributes
158 // and translation executed, too.
159 SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet)
160 {
161     SdrObject* pRetval = 0L;
162     const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue());
163 
164     if(bShadow)
165     {
166         // create a shadow representing object
167         const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue());
168         const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
169         const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
170         const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
171         pRetval = rOriginal.Clone();
172         DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)");
173 
174         // look for used stuff
175         SdrObjListIter aIterator(rOriginal);
176         sal_Bool bLineUsed(sal_False);
177         sal_Bool bAllFillUsed(sal_False);
178         sal_Bool bSolidFillUsed(sal_False);
179         sal_Bool bGradientFillUsed(sal_False);
180         sal_Bool bHatchFillUsed(sal_False);
181         sal_Bool bBitmapFillUsed(sal_False);
182 
183         while(aIterator.IsMore())
184         {
185             SdrObject* pObj = aIterator.Next();
186             XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue();
187 
188             if(!bLineUsed)
189             {
190                 XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue();
191 
192                 if(XLINE_NONE != eLineStyle)
193                 {
194                     bLineUsed = sal_True;
195                 }
196             }
197 
198             if(!bAllFillUsed)
199             {
200                 if(!bSolidFillUsed && XFILL_SOLID == eFillStyle)
201                 {
202                     bSolidFillUsed = sal_True;
203                     bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
204                 }
205                 if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle)
206                 {
207                     bGradientFillUsed = sal_True;
208                     bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
209                 }
210                 if(!bHatchFillUsed && XFILL_HATCH == eFillStyle)
211                 {
212                     bHatchFillUsed = sal_True;
213                     bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
214                 }
215                 if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle)
216                 {
217                     bBitmapFillUsed = sal_True;
218                     bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
219                 }
220             }
221         }
222 
223         // translate to shadow coordinates
224         pRetval->NbcMove(Size(nXDist, nYDist));
225 
226         // set items as needed
227         SfxItemSet aTempSet(rOriginalSet);
228 
229         // SJ: #40108# :-(  if a SvxWritingModeItem (Top->Bottom) is set the text object
230         // is creating a paraobject, but paraobjects can not be created without model. So
231         // we are preventing the crash by setting the writing mode always left to right,
232         // this is not bad since our shadow geometry does not contain text.
233         aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) );
234 
235         // no shadow
236         aTempSet.Put(SdrShadowItem(sal_False));
237         aTempSet.Put(SdrShadowXDistItem(0L));
238         aTempSet.Put(SdrShadowYDistItem(0L));
239 
240         // line color and transparence like shadow
241         if(bLineUsed)
242         {
243             aTempSet.Put(XLineColorItem(String(), aShadowColor));
244             aTempSet.Put(XLineTransparenceItem(nShadowTransparence));
245         }
246 
247         // fill color and transparence like shadow
248         if(bSolidFillUsed)
249         {
250             aTempSet.Put(XFillColorItem(String(), aShadowColor));
251             aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
252         }
253 
254         // gradient and transparence like shadow
255         if(bGradientFillUsed)
256         {
257             XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
258             sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
259             sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
260 
261             if(aGradient.GetStartIntens() != 100)
262             {
263                 nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0));
264             }
265 
266             if(aGradient.GetEndIntens() != 100)
267             {
268                 nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0));
269             }
270 
271             ::Color aStartColor(
272                 (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256),
273                 (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256),
274                 (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256));
275 
276             ::Color aEndColor(
277                 (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256),
278                 (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256),
279                 (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256));
280 
281             aGradient.SetStartColor(aStartColor);
282             aGradient.SetEndColor(aEndColor);
283             aTempSet.Put(XFillGradientItem(aTempSet.GetPool(), aGradient));
284             aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
285         }
286 
287         // hatch and transparence like shadow
288         if(bHatchFillUsed)
289         {
290             XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue());
291             aHatch.SetColor(aShadowColor);
292             aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch));
293             aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
294         }
295 
296         // bitmap and transparence like shadow
297         if(bBitmapFillUsed)
298         {
299             XOBitmap aFillBitmap(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetBitmapValue());
300             Bitmap aSourceBitmap(aFillBitmap.GetBitmap());
301             BitmapReadAccess* pReadAccess = aSourceBitmap.AcquireReadAccess();
302 
303             if(!aSourceBitmap.IsEmpty())
304             {
305                 if(pReadAccess)
306                 {
307                     Bitmap aDestBitmap(aSourceBitmap.GetSizePixel(), 24L);
308                     BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess();
309 
310                     if(pWriteAccess)
311                     {
312                         for(sal_Int32 y(0L); y < pReadAccess->Height(); y++)
313                         {
314                             for(sal_Int32 x(0L); x < pReadAccess->Width(); x++)
315                             {
316                                 sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1);
317                                 const BitmapColor aDestColor(
318                                     (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L),
319                                     (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L),
320                                     (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L));
321                                 pWriteAccess->SetPixel(y, x, aDestColor);
322                             }
323                         }
324 
325                         aDestBitmap.ReleaseAccess(pWriteAccess);
326                         aFillBitmap.SetBitmap(aDestBitmap);
327                     }
328 
329                     aSourceBitmap.ReleaseAccess(pReadAccess);
330                 }
331             }
332 
333             aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aFillBitmap));
334             aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
335         }
336 
337         // set attributes and paint shadow object
338         pRetval->SetMergedItemSet( aTempSet );
339     }
340     return pRetval;
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////////////////////////
344 
345 Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine( const SdrObjCustomShape* pCustomShape )
346 {
347     Reference< XCustomShapeEngine > xCustomShapeEngine;
348     String aEngine(((SdrCustomShapeEngineItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue());
349     if ( !aEngine.Len() )
350         aEngine = String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
351 
352     Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
353 
354     Reference< XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
355     if ( aXShape.is() )
356     {
357         if ( aEngine.Len() && xFactory.is() )
358         {
359             Sequence< Any > aArgument( 1 );
360             Sequence< PropertyValue > aPropValues( 1 );
361             aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" );
362             aPropValues[ 0 ].Value <<= aXShape;
363             aArgument[ 0 ] <<= aPropValues;
364             Reference< XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
365             if ( xInterface.is() )
366                 xCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY );
367         }
368     }
369     return xCustomShapeEngine;
370 }
371 const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
372 {
373     if ( !mXRenderedCustomShape.is() )
374     {
375         Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) );
376         if ( xCustomShapeEngine.is() )
377             ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render();
378     }
379     SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
380                 ? GetSdrObjectFromXShape( mXRenderedCustomShape )
381                 : NULL;
382     return pRenderedCustomShape;
383 }
384 
385 // #i37011# Shadow geometry creation
386 const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
387 {
388     if(!mpLastShadowGeometry)
389     {
390         const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
391         if(pSdrObject)
392         {
393             const SfxItemSet& rOriginalSet = GetObjectItemSet();
394             const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue());
395 
396             if(bShadow)
397             {
398                 // create a clone with all attributes changed to shadow attributes
399                 // and translation executed, too.
400                 ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
401             }
402         }
403     }
404 
405     return mpLastShadowGeometry;
406 }
407 
408 sal_Bool SdrObjCustomShape::IsTextPath() const
409 {
410     const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
411     sal_Bool bTextPathOn = sal_False;
412     SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
413     Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
414     if ( pAny )
415         *pAny >>= bTextPathOn;
416     return bTextPathOn;
417 }
418 
419 sal_Bool SdrObjCustomShape::UseNoFillStyle() const
420 {
421     sal_Bool bRet = sal_False;
422     rtl::OUString sShapeType;
423     const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
424     SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
425     Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
426     if ( pAny )
427         *pAny >>= sShapeType;
428     bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == 0;
429 
430     return bRet;
431 }
432 
433 sal_Bool SdrObjCustomShape::IsMirroredX() const
434 {
435     sal_Bool bMirroredX = sal_False;
436     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
437     const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
438     com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
439     if ( pAny )
440         *pAny >>= bMirroredX;
441     return bMirroredX;
442 }
443 sal_Bool SdrObjCustomShape::IsMirroredY() const
444 {
445     sal_Bool bMirroredY = sal_False;
446     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
447     const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
448     com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
449     if ( pAny )
450         *pAny >>= bMirroredY;
451     return bMirroredY;
452 }
453 void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX )
454 {
455     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
456     const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
457     //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
458     PropertyValue aPropVal;
459     aPropVal.Name = sMirroredX;
460     aPropVal.Value <<= bMirrorX;
461     aGeometryItem.SetPropertyValue( aPropVal );
462     SetMergedItem( aGeometryItem );
463 }
464 void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY )
465 {
466     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
467     const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
468     //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
469     PropertyValue aPropVal;
470     aPropVal.Name = sMirroredY;
471     aPropVal.Value <<= bMirrorY;
472     aGeometryItem.SetPropertyValue( aPropVal );
473     SetMergedItem( aGeometryItem );
474 }
475 
476 double SdrObjCustomShape::GetObjectRotation() const
477 {
478     return fObjectRotation;
479 }
480 
481 double SdrObjCustomShape::GetExtraTextRotation() const
482 {
483     const com::sun::star::uno::Any* pAny;
484     SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
485     const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
486     pAny = rGeometryItem.GetPropertyValueByName( sTextRotateAngle );
487     double fExtraTextRotateAngle = 0.0;
488     if ( pAny )
489         *pAny >>= fExtraTextRotateAngle;
490     return fExtraTextRotateAngle;
491 }
492 sal_Bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const
493 {
494     sal_Bool bRet = sal_False;
495     Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); // a candidate for being cached
496     if ( xCustomShapeEngine.is() )
497     {
498         awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
499         if ( aR.Width || aR.Height )
500         {
501             rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
502             bRet = sal_True;
503         }
504     }
505     return bRet;
506 }
507 basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const sal_Bool bBezierAllowed )
508 {
509     basegfx::B2DPolyPolygon aRetval;
510     sal_Bool bRet = sal_False;
511     Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
512     if ( xCustomShapeEngine.is() )
513     {
514         com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
515         try
516         {
517             aRetval = SvxConvertPolyPolygonBezierToB2DPolyPolygon( &aBezierCoords );
518             if ( !bBezierAllowed && aRetval.areControlPointsUsed())
519             {
520                 aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval);
521             }
522             bRet = sal_True;
523         }
524         catch ( const com::sun::star::lang::IllegalArgumentException )
525         {
526         }
527     }
528     return aRetval;
529 }
530 
531 std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const
532 {
533     std::vector< SdrCustomShapeInteraction > xRet;
534     try
535     {
536         Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
537         if ( xCustomShapeEngine.is() )
538         {
539             int i;
540             Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() );
541             for ( i = 0; i < xInteractionHandles.getLength(); i++ )
542             {
543                 if ( xInteractionHandles[ i ].is() )
544                 {
545                     SdrCustomShapeInteraction aSdrCustomShapeInteraction;
546                     aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
547                     aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
548 
549                     sal_Int32 nMode = 0;
550                     switch( ImpGetCustomShapeType( *this ) )
551                     {
552                         case mso_sptAccentBorderCallout90 :     // 2 ortho
553                         {
554                             if ( !i )
555                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
556                             else if ( i == 1)
557                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4;
558                         }
559                         break;
560 
561                         case mso_sptWedgeRectCallout :
562                         case mso_sptWedgeRRectCallout :
563                         case mso_sptCloudCallout :
564                         case mso_sptWedgeEllipseCallout :
565                         {
566                             if ( !i )
567                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED;
568                         }
569                         break;
570 
571                         case mso_sptBorderCallout1 :            // 2 diag
572                         {
573                             if ( !i )
574                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
575                             else if ( i == 1 )
576                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
577                         }
578                         break;
579                         case mso_sptBorderCallout2 :            // 3
580                         {
581                             if ( !i )
582                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
583                             else if ( i == 2 )
584                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
585                         }
586                         break;
587                         case mso_sptCallout90 :
588                         case mso_sptAccentCallout90 :
589                         case mso_sptBorderCallout90 :
590                         case mso_sptCallout1 :
591                         case mso_sptCallout2 :
592                         case mso_sptCallout3 :
593                         case mso_sptAccentCallout1 :
594                         case mso_sptAccentCallout2 :
595                         case mso_sptAccentCallout3 :
596                         case mso_sptBorderCallout3 :
597                         case mso_sptAccentBorderCallout1 :
598                         case mso_sptAccentBorderCallout2 :
599                         case mso_sptAccentBorderCallout3 :
600                         {
601                             if ( !i )
602                                 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
603                         }
604                         break;
605                         default: break;
606                     }
607                     aSdrCustomShapeInteraction.nMode = nMode;
608                     xRet.push_back( aSdrCustomShapeInteraction );
609                 }
610             }
611         }
612     }
613     catch( const uno::RuntimeException& )
614     {
615     }
616     return xRet;
617 }
618 
619 //////////////////////////////////////////////////////////////////////////////
620 // BaseProperties section
621 #define DEFAULT_MINIMUM_SIGNED_COMPARE  ((sal_Int32)0x80000000)
622 #define DEFAULT_MAXIMUM_SIGNED_COMPARE  ((sal_Int32)0x7fffffff)
623 
624 sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties()
625 {
626     return new sdr::properties::CustomShapeProperties(*this);
627 }
628 
629 TYPEINIT1(SdrObjCustomShape,SdrTextObj);
630 SdrObjCustomShape::SdrObjCustomShape() :
631     SdrTextObj(),
632     fObjectRotation( 0.0 ),
633     mpLastShadowGeometry(0L)
634 {
635     bTextFrame = sal_True;
636 }
637 
638 SdrObjCustomShape::~SdrObjCustomShape()
639 {
640     // delete buffered display geometry
641     InvalidateRenderGeometry();
642 }
643 
644 void SdrObjCustomShape::MergeDefaultAttributes( const rtl::OUString* pType )
645 {
646     PropertyValue aPropVal;
647     rtl::OUString sShapeType;
648     const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
649     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
650     if ( pType && pType->getLength() )
651     {
652         sal_Int32 nType = pType->toInt32();
653         if ( nType )
654             sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
655         else
656             sShapeType = *pType;
657 
658         aPropVal.Name = sType;
659         aPropVal.Value <<= sShapeType;
660         aGeometryItem.SetPropertyValue( aPropVal );
661     }
662     else
663     {
664         Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
665         if ( pAny )
666             *pAny >>= sShapeType;
667     }
668     MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
669 
670     const sal_Int32* pDefData = NULL;
671     const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
672     if ( pDefCustomShape )
673         pDefData = pDefCustomShape->pDefData;
674 
675     com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
676 
677     //////////////////////
678     // AdjustmentValues //
679     //////////////////////
680     const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
681     const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
682     if ( pAny )
683         *pAny >>= seqAdjustmentValues;
684     if ( pDefCustomShape && pDefData )  // now check if we have to default some adjustment values
685     {
686         // first check if there are adjustment values are to be appended
687         sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
688         sal_Int32 nAdjustmentDefaults = *pDefData++;
689         if ( nAdjustmentDefaults > nAdjustmentValues )
690         {
691             seqAdjustmentValues.realloc( nAdjustmentDefaults );
692             for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
693             {
694                 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
695                 seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // com::sun::star::beans::PropertyState_DEFAULT_VALUE;
696             }
697         }
698         // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
699         sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues;
700         for ( i = 0; i < nCount; i++ )
701         {
702             if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE )
703             {
704                 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
705                 seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
706             }
707         }
708     }
709     aPropVal.Name = sAdjustmentValues;
710     aPropVal.Value <<= seqAdjustmentValues;
711     aGeometryItem.SetPropertyValue( aPropVal );
712 
713     ///////////////
714     // Coordsize //
715     ///////////////
716     const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
717     const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
718     com::sun::star::awt::Rectangle aViewBox;
719     if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
720     {
721         if ( pDefCustomShape )
722         {
723             aViewBox.X = 0;
724             aViewBox.Y = 0;
725             aViewBox.Width = pDefCustomShape->nCoordWidth;
726             aViewBox.Height= pDefCustomShape->nCoordHeight;
727             aPropVal.Name = sViewBox;
728             aPropVal.Value <<= aViewBox;
729             aGeometryItem.SetPropertyValue( aPropVal );
730         }
731     }
732 
733     const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
734 
735     //////////////////////
736     // Path/Coordinates //
737     //////////////////////
738     const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
739     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
740     if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
741     {
742         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
743 
744         sal_Int32 i, nCount = pDefCustomShape->nVertices;
745         seqCoordinates.realloc( nCount );
746         for ( i = 0; i < nCount; i++ )
747         {
748             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
749             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
750         }
751         aPropVal.Name = sCoordinates;
752         aPropVal.Value <<= seqCoordinates;
753         aGeometryItem.SetPropertyValue( sPath, aPropVal );
754     }
755 
756     /////////////////////
757     // Path/GluePoints //
758     /////////////////////
759     const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
760     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
761     if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
762     {
763         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
764         sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
765         seqGluePoints.realloc( nCount );
766         for ( i = 0; i < nCount; i++ )
767         {
768             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
769             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
770         }
771         aPropVal.Name = sGluePoints;
772         aPropVal.Value <<= seqGluePoints;
773         aGeometryItem.SetPropertyValue( sPath, aPropVal );
774     }
775 
776     ///////////////////
777     // Path/Segments //
778     ///////////////////
779     const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
780     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
781     if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
782     {
783         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
784 
785         sal_Int32 i, nCount = pDefCustomShape->nElements;
786         seqSegments.realloc( nCount );
787         for ( i = 0; i < nCount; i++ )
788         {
789             EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ];
790             sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
791             switch( nSDat >> 8 )
792             {
793                 case 0x00 :
794                 {
795                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
796                     rSegInfo.Count   = nSDat & 0xff;
797                     if ( !rSegInfo.Count )
798                         rSegInfo.Count = 1;
799                 }
800                 break;
801                 case 0x20 :
802                 {
803                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
804                     rSegInfo.Count   = nSDat & 0xff;
805                     if ( !rSegInfo.Count )
806                         rSegInfo.Count = 1;
807                 }
808                 break;
809                 case 0x40 :
810                 {
811                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
812                     rSegInfo.Count   = nSDat & 0xff;
813                     if ( !rSegInfo.Count )
814                         rSegInfo.Count = 1;
815                 }
816                 break;
817                 case 0x60 :
818                 {
819                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
820                     rSegInfo.Count   = 0;
821                 }
822                 break;
823                 case 0x80 :
824                 {
825                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
826                     rSegInfo.Count   = 0;
827                 }
828                 break;
829                 case 0xa1 :
830                 {
831                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
832                     rSegInfo.Count   = ( nSDat & 0xff ) / 3;
833                 }
834                 break;
835                 case 0xa2 :
836                 {
837                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
838                     rSegInfo.Count   = ( nSDat & 0xff ) / 3;
839                 }
840                 break;
841                 case 0xa3 :
842                 {
843                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
844                     rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
845                 }
846                 break;
847                 case 0xa4 :
848                 {
849                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
850                     rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
851                 }
852                 break;
853                 case 0xa5 :
854                 {
855                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
856                     rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
857                 }
858                 break;
859                 case 0xa6 :
860                 {
861                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
862                     rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
863                 }
864                 break;
865                 case 0xa7 :
866                 {
867                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
868                     rSegInfo.Count   = nSDat & 0xff;
869                 }
870                 break;
871                 case 0xa8 :
872                 {
873                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
874                     rSegInfo.Count   = nSDat & 0xff;
875                 }
876                 break;
877                 case 0xaa :
878                 {
879                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
880                     rSegInfo.Count   = 0;
881                 }
882                 break;
883                 case 0xab :
884                 {
885                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
886                     rSegInfo.Count   = 0;
887                 }
888                 break;
889                 default:
890                 case 0xf8 :
891                 {
892                     rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
893                     rSegInfo.Count   = nSDat;
894                 }
895                 break;
896             }
897         }
898         aPropVal.Name = sSegments;
899         aPropVal.Value <<= seqSegments;
900         aGeometryItem.SetPropertyValue( sPath, aPropVal );
901     }
902 
903     ///////////////////
904     // Path/StretchX //
905     ///////////////////
906     const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
907     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
908     if ( !pAny && pDefCustomShape )
909     {
910         sal_Int32 nXRef = pDefCustomShape->nXRef;
911         if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
912         {
913             aPropVal.Name = sStretchX;
914             aPropVal.Value <<= nXRef;
915             aGeometryItem.SetPropertyValue( sPath, aPropVal );
916         }
917     }
918 
919     ///////////////////
920     // Path/StretchY //
921     ///////////////////
922     const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
923     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
924     if ( !pAny && pDefCustomShape )
925     {
926         sal_Int32 nYRef = pDefCustomShape->nYRef;
927         if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
928         {
929             aPropVal.Name = sStretchY;
930             aPropVal.Value <<= nYRef;
931             aGeometryItem.SetPropertyValue( sPath, aPropVal );
932         }
933     }
934 
935     /////////////////////
936     // Path/TextFrames //
937     /////////////////////
938     const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
939     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
940     if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
941     {
942         com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames;
943 
944         sal_Int32 i, nCount = pDefCustomShape->nTextRect;
945         seqTextFrames.realloc( nCount );
946         const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
947         for ( i = 0; i < nCount; i++, pRectangles++ )
948         {
949             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First,     pRectangles->nPairA.nValA );
950             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second,    pRectangles->nPairA.nValB );
951             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First,  pRectangles->nPairB.nValA );
952             EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
953         }
954         aPropVal.Name = sTextFrames;
955         aPropVal.Value <<= seqTextFrames;
956         aGeometryItem.SetPropertyValue( sPath, aPropVal );
957     }
958 
959     ///////////////
960     // Equations //
961     ///////////////
962     const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
963     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
964     if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
965     {
966         com::sun::star::uno::Sequence< rtl::OUString > seqEquations;
967 
968         sal_Int32 i, nCount = pDefCustomShape->nCalculation;
969         seqEquations.realloc( nCount );
970         const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
971         for ( i = 0; i < nCount; i++, pData++ )
972             seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
973         aPropVal.Name = sEquations;
974         aPropVal.Value <<= seqEquations;
975         aGeometryItem.SetPropertyValue( aPropVal );
976     }
977 
978     /////////////
979     // Handles //
980     /////////////
981     const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
982     pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
983     if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
984     {
985         com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles;
986 
987         sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
988         const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
989         seqHandles.realloc( nCount );
990         for ( i = 0; i < nCount; i++, pData++ )
991         {
992             sal_Int32 nPropertiesNeeded = 1;    // position is always needed
993             sal_Int32 nFlags = pData->nFlags;
994             if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
995                 nPropertiesNeeded++;
996             if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
997                 nPropertiesNeeded++;
998             if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
999                 nPropertiesNeeded++;
1000             if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1001             {
1002                 nPropertiesNeeded++;
1003                 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1004                 {
1005                     if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1006                         nPropertiesNeeded++;
1007                     if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1008                         nPropertiesNeeded++;
1009                 }
1010             }
1011             else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1012             {
1013                 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1014                     nPropertiesNeeded++;
1015                 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1016                     nPropertiesNeeded++;
1017                 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1018                     nPropertiesNeeded++;
1019                 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1020                     nPropertiesNeeded++;
1021             }
1022 
1023             n = 0;
1024             com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ];
1025             rPropValues.realloc( nPropertiesNeeded );
1026 
1027             // POSITION
1028             {
1029                 const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
1030                 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
1031                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
1032                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
1033                 rPropValues[ n ].Name = sPosition;
1034                 rPropValues[ n++ ].Value <<= aPosition;
1035             }
1036             if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1037             {
1038                 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1039                 sal_Bool bMirroredX = sal_True;
1040                 rPropValues[ n ].Name = sMirroredX;
1041                 rPropValues[ n++ ].Value <<= bMirroredX;
1042             }
1043             if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1044             {
1045                 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1046                 sal_Bool bMirroredY = sal_True;
1047                 rPropValues[ n ].Name = sMirroredY;
1048                 rPropValues[ n++ ].Value <<= bMirroredY;
1049             }
1050             if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1051             {
1052                 const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
1053                 sal_Bool bSwitched = sal_True;
1054                 rPropValues[ n ].Name = sSwitched;
1055                 rPropValues[ n++ ].Value <<= bSwitched;
1056             }
1057             if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1058             {
1059                 const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
1060                 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
1061                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First,  pData->nCenterX,
1062                     ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True  );
1063                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
1064                     ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
1065                 rPropValues[ n ].Name = sPolar;
1066                 rPropValues[ n++ ].Value <<= aCenter;
1067                 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1068                 {
1069                     if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1070                     {
1071                         const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
1072                         ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
1073                         EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
1074                             ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
1075                         rPropValues[ n ].Name = sRadiusRangeMinimum;
1076                         rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
1077                     }
1078                     if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1079                     {
1080                         const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
1081                         ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
1082                         EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
1083                             ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1084                         rPropValues[ n ].Name = sRadiusRangeMaximum;
1085                         rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
1086                     }
1087                 }
1088             }
1089             else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1090             {
1091                 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1092                 {
1093                     const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
1094                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
1095                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
1096                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
1097                     rPropValues[ n ].Name = sRangeXMinimum;
1098                     rPropValues[ n++ ].Value <<= aRangeXMinimum;
1099                 }
1100                 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1101                 {
1102                     const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
1103                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
1104                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
1105                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1106                     rPropValues[ n ].Name = sRangeXMaximum;
1107                     rPropValues[ n++ ].Value <<= aRangeXMaximum;
1108                 }
1109                 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1110                 {
1111                     const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
1112                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
1113                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
1114                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
1115                     rPropValues[ n ].Name = sRangeYMinimum;
1116                     rPropValues[ n++ ].Value <<= aRangeYMinimum;
1117                 }
1118                 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1119                 {
1120                     const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
1121                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
1122                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
1123                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
1124                     rPropValues[ n ].Name = sRangeYMaximum;
1125                     rPropValues[ n++ ].Value <<= aRangeYMaximum;
1126                 }
1127             }
1128         }
1129         aPropVal.Name = sHandles;
1130         aPropVal.Value <<= seqHandles;
1131         aGeometryItem.SetPropertyValue( aPropVal );
1132     }
1133     SetMergedItem( aGeometryItem );
1134 }
1135 
1136 sal_Bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const
1137 {
1138     sal_Bool bIsDefaultGeometry = sal_False;
1139 
1140     PropertyValue aPropVal;
1141     rtl::OUString sShapeType;
1142     const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1143     SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1144 
1145     Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
1146     if ( pAny )
1147         *pAny >>= sShapeType;
1148 
1149     MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1150 
1151     const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
1152     const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1153     switch( eDefaultType )
1154     {
1155         case DEFAULT_VIEWBOX :
1156         {
1157             const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
1158             const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
1159             com::sun::star::awt::Rectangle aViewBox;
1160             if ( pViewBox && ( *pViewBox >>= aViewBox ) )
1161             {
1162                 if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
1163                     && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
1164                     bIsDefaultGeometry = sal_True;
1165             }
1166         }
1167         break;
1168 
1169         case DEFAULT_PATH :
1170         {
1171             const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1172             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
1173             if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
1174             {
1175                 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
1176                 if ( *pAny >>= seqCoordinates1 )
1177                 {
1178                     sal_Int32 i, nCount = pDefCustomShape->nVertices;
1179                     seqCoordinates2.realloc( nCount );
1180                     for ( i = 0; i < nCount; i++ )
1181                     {
1182                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
1183                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
1184                     }
1185                     if ( seqCoordinates1 == seqCoordinates2 )
1186                         bIsDefaultGeometry = sal_True;
1187                 }
1188             }
1189             else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) )
1190                 bIsDefaultGeometry = sal_True;
1191         }
1192         break;
1193 
1194         case DEFAULT_GLUEPOINTS :
1195         {
1196             const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1197             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
1198             if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
1199             {
1200                 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2;
1201                 if ( *pAny >>= seqGluePoints1 )
1202                 {
1203                     sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
1204                     seqGluePoints2.realloc( nCount );
1205                     for ( i = 0; i < nCount; i++ )
1206                     {
1207                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
1208                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
1209                     }
1210                     if ( seqGluePoints1 == seqGluePoints2 )
1211                         bIsDefaultGeometry = sal_True;
1212                 }
1213             }
1214             else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
1215                 bIsDefaultGeometry = sal_True;
1216         }
1217         break;
1218 
1219         case DEFAULT_SEGMENTS :
1220         {
1221             ///////////////////
1222             // Path/Segments //
1223             ///////////////////
1224             const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1225             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
1226             if ( pAny )
1227             {
1228                 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2;
1229                 if ( *pAny >>= seqSegments1 )
1230                 {
1231                     if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1232                     {
1233                         sal_Int32 i, nCount = pDefCustomShape->nElements;
1234                         if ( nCount )
1235                         {
1236                             seqSegments2.realloc( nCount );
1237                             for ( i = 0; i < nCount; i++ )
1238                             {
1239                                 EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ];
1240                                 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1241                                 switch( nSDat >> 8 )
1242                                 {
1243                                     case 0x00 :
1244                                     {
1245                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1246                                         rSegInfo.Count   = nSDat & 0xff;
1247                                         if ( !rSegInfo.Count )
1248                                             rSegInfo.Count = 1;
1249                                     }
1250                                     break;
1251                                     case 0x20 :
1252                                     {
1253                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1254                                         rSegInfo.Count   = nSDat & 0xff;
1255                                         if ( !rSegInfo.Count )
1256                                             rSegInfo.Count = 1;
1257                                     }
1258                                     break;
1259                                     case 0x40 :
1260                                     {
1261                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1262                                         rSegInfo.Count   = nSDat & 0xff;
1263                                         if ( !rSegInfo.Count )
1264                                             rSegInfo.Count = 1;
1265                                     }
1266                                     break;
1267                                     case 0x60 :
1268                                     {
1269                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1270                                         rSegInfo.Count   = 0;
1271                                     }
1272                                     break;
1273                                     case 0x80 :
1274                                     {
1275                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1276                                         rSegInfo.Count   = 0;
1277                                     }
1278                                     break;
1279                                     case 0xa1 :
1280                                     {
1281                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
1282                                         rSegInfo.Count   = ( nSDat & 0xff ) / 3;
1283                                     }
1284                                     break;
1285                                     case 0xa2 :
1286                                     {
1287                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
1288                                         rSegInfo.Count   = ( nSDat & 0xff ) / 3;
1289                                     }
1290                                     break;
1291                                     case 0xa3 :
1292                                     {
1293                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
1294                                         rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
1295                                     }
1296                                     break;
1297                                     case 0xa4 :
1298                                     {
1299                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
1300                                         rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
1301                                     }
1302                                     break;
1303                                     case 0xa5 :
1304                                     {
1305                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
1306                                         rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
1307                                     }
1308                                     break;
1309                                     case 0xa6 :
1310                                     {
1311                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
1312                                         rSegInfo.Count   = ( nSDat & 0xff ) >> 2;
1313                                     }
1314                                     break;
1315                                     case 0xa7 :
1316                                     {
1317                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
1318                                         rSegInfo.Count   = nSDat & 0xff;
1319                                     }
1320                                     break;
1321                                     case 0xa8 :
1322                                     {
1323                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
1324                                         rSegInfo.Count   = nSDat & 0xff;
1325                                     }
1326                                     break;
1327                                     case 0xaa :
1328                                     {
1329                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
1330                                         rSegInfo.Count   = 0;
1331                                     }
1332                                     break;
1333                                     case 0xab :
1334                                     {
1335                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1336                                         rSegInfo.Count   = 0;
1337                                     }
1338                                     break;
1339                                     default:
1340                                     case 0xf8 :
1341                                     {
1342                                         rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
1343                                         rSegInfo.Count   = nSDat;
1344                                     }
1345                                     break;
1346                                 }
1347                             }
1348                             if ( seqSegments1 == seqSegments2 )
1349                                 bIsDefaultGeometry = sal_True;
1350                         }
1351                     }
1352                     else
1353                     {
1354                         // check if its the default segment description ( M L Z N )
1355                         if ( seqSegments1.getLength() == 4 )
1356                         {
1357                             if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO )
1358                                 && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO )
1359                                 && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
1360                                 && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
1361                                 bIsDefaultGeometry = sal_True;
1362                         }
1363                     }
1364                 }
1365             }
1366             else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) )
1367                 bIsDefaultGeometry = sal_True;
1368         }
1369         break;
1370 
1371         case DEFAULT_STRETCHX :
1372         {
1373             const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
1374             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1375             if ( pAny && pDefCustomShape )
1376             {
1377                 sal_Int32 nStretchX = 0;
1378                 if ( *pAny >>= nStretchX )
1379                 {
1380                     if ( pDefCustomShape->nXRef == nStretchX )
1381                         bIsDefaultGeometry = sal_True;
1382                 }
1383             }
1384             else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1385                 bIsDefaultGeometry = sal_True;
1386         }
1387         break;
1388 
1389         case DEFAULT_STRETCHY :
1390         {
1391             const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
1392             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1393             if ( pAny && pDefCustomShape )
1394             {
1395                 sal_Int32 nStretchY = 0;
1396                 if ( *pAny >>= nStretchY )
1397                 {
1398                     if ( pDefCustomShape->nYRef == nStretchY )
1399                         bIsDefaultGeometry = sal_True;
1400                 }
1401             }
1402             else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1403                 bIsDefaultGeometry = sal_True;
1404         }
1405         break;
1406 
1407         case DEFAULT_EQUATIONS :
1408         {
1409             const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
1410             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1411             if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1412             {
1413                 com::sun::star::uno::Sequence< rtl::OUString > seqEquations1, seqEquations2;
1414                 if ( *pAny >>= seqEquations1 )
1415                 {
1416                     sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1417                     seqEquations2.realloc( nCount );
1418 
1419                     const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1420                     for ( i = 0; i < nCount; i++, pData++ )
1421                         seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1422 
1423                     if ( seqEquations1 == seqEquations2 )
1424                         bIsDefaultGeometry = sal_True;
1425                 }
1426             }
1427             else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) )
1428                 bIsDefaultGeometry = sal_True;
1429         }
1430         break;
1431 
1432         case DEFAULT_TEXTFRAMES :
1433         {
1434             const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) );
1435             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1436             if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1437             {
1438                 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2;
1439                 if ( *pAny >>= seqTextFrames1 )
1440                 {
1441                     sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1442                     seqTextFrames2.realloc( nCount );
1443                     const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1444                     for ( i = 0; i < nCount; i++, pRectangles++ )
1445                     {
1446                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First,    pRectangles->nPairA.nValA );
1447                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second,   pRectangles->nPairA.nValB );
1448                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First,  pRectangles->nPairB.nValA );
1449                         EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1450                     }
1451                     if ( seqTextFrames1 == seqTextFrames2 )
1452                         bIsDefaultGeometry = sal_True;
1453                 }
1454             }
1455             else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) )
1456                 bIsDefaultGeometry = sal_True;
1457         }
1458         break;
1459 
1460         case DEFAULT_HANDLES :
1461         {
1462             const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
1463             pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1464             if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1465             {
1466                 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2;
1467                 if ( *pAny >>= seqHandles1 )
1468                 {
1469                     sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
1470                     const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1471                     seqHandles2.realloc( nCount );
1472                     for ( i = 0; i < nCount; i++, pData++ )
1473                     {
1474                         sal_Int32 nPropertiesNeeded = 1;    // position is always needed
1475                         sal_Int32 nFlags = pData->nFlags;
1476                         if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1477                             nPropertiesNeeded++;
1478                         if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1479                             nPropertiesNeeded++;
1480                         if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1481                             nPropertiesNeeded++;
1482                         if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1483                         {
1484                             nPropertiesNeeded++;
1485                             if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1486                             {
1487                                 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1488                                     nPropertiesNeeded++;
1489                                 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1490                                     nPropertiesNeeded++;
1491                             }
1492                         }
1493                         else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1494                         {
1495                             if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1496                                 nPropertiesNeeded++;
1497                             if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1498                                 nPropertiesNeeded++;
1499                             if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1500                                 nPropertiesNeeded++;
1501                             if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1502                                 nPropertiesNeeded++;
1503                         }
1504 
1505                         n = 0;
1506                         com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ];
1507                         rPropValues.realloc( nPropertiesNeeded );
1508 
1509                         // POSITION
1510                         {
1511                             const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
1512                             ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
1513                             EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
1514                             EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
1515                             rPropValues[ n ].Name = sPosition;
1516                             rPropValues[ n++ ].Value <<= aPosition;
1517                         }
1518                         if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1519                         {
1520                             const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1521                             sal_Bool bMirroredX = sal_True;
1522                             rPropValues[ n ].Name = sMirroredX;
1523                             rPropValues[ n++ ].Value <<= bMirroredX;
1524                         }
1525                         if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1526                         {
1527                             const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1528                             sal_Bool bMirroredY = sal_True;
1529                             rPropValues[ n ].Name = sMirroredY;
1530                             rPropValues[ n++ ].Value <<= bMirroredY;
1531                         }
1532                         if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1533                         {
1534                             const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
1535                             sal_Bool bSwitched = sal_True;
1536                             rPropValues[ n ].Name = sSwitched;
1537                             rPropValues[ n++ ].Value <<= bSwitched;
1538                         }
1539                         if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1540                         {
1541                             const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
1542                             ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
1543                             EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First,  pData->nCenterX,
1544                                 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True  );
1545                             EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
1546                                 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
1547                             rPropValues[ n ].Name = sPolar;
1548                             rPropValues[ n++ ].Value <<= aCenter;
1549                             if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1550                             {
1551                                 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1552                                 {
1553                                     const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
1554                                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
1555                                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
1556                                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
1557                                     rPropValues[ n ].Name = sRadiusRangeMinimum;
1558                                     rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
1559                                 }
1560                                 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1561                                 {
1562                                     const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
1563                                     ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
1564                                     EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
1565                                         ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1566                                     rPropValues[ n ].Name = sRadiusRangeMaximum;
1567                                     rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
1568                                 }
1569                             }
1570                         }
1571                         else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1572                         {
1573                             if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1574                             {
1575                                 const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
1576                                 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
1577                                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
1578                                     ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
1579                                 rPropValues[ n ].Name = sRangeXMinimum;
1580                                 rPropValues[ n++ ].Value <<= aRangeXMinimum;
1581                             }
1582                             if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1583                             {
1584                                 const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
1585                                 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
1586                                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
1587                                     ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1588                                 rPropValues[ n ].Name = sRangeXMaximum;
1589                                 rPropValues[ n++ ].Value <<= aRangeXMaximum;
1590                             }
1591                             if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1592                             {
1593                                 const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
1594                                 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
1595                                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
1596                                     ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
1597                                 rPropValues[ n ].Name = sRangeYMinimum;
1598                                 rPropValues[ n++ ].Value <<= aRangeYMinimum;
1599                             }
1600                             if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1601                             {
1602                                 const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
1603                                 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
1604                                 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
1605                                     ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
1606                                 rPropValues[ n ].Name = sRangeYMaximum;
1607                                 rPropValues[ n++ ].Value <<= aRangeYMaximum;
1608                             }
1609                         }
1610                     }
1611                     if ( seqHandles1 == seqHandles2 )
1612                         bIsDefaultGeometry = sal_True;
1613                 }
1614             }
1615             else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) )
1616                 bIsDefaultGeometry = sal_True;
1617         }
1618         break;
1619     }
1620     return bIsDefaultGeometry;
1621 }
1622 
1623 void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1624 {
1625     rInfo.bResizeFreeAllowed=fObjectRotation == 0.0;
1626     rInfo.bResizePropAllowed=sal_True;
1627     rInfo.bRotateFreeAllowed=sal_True;
1628     rInfo.bRotate90Allowed  =sal_True;
1629     rInfo.bMirrorFreeAllowed=sal_True;
1630     rInfo.bMirror45Allowed  =sal_True;
1631     rInfo.bMirror90Allowed  =sal_True;
1632     rInfo.bTransparenceAllowed = sal_False;
1633     rInfo.bGradientAllowed = sal_False;
1634     rInfo.bShearAllowed     =sal_True;
1635     rInfo.bEdgeRadiusAllowed=sal_False;
1636     rInfo.bNoContortion     =sal_True;
1637 
1638     // #i37011#
1639     if ( mXRenderedCustomShape.is() )
1640     {
1641         const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1642         if ( pRenderedCustomShape )
1643         {
1644             // #i37262#
1645             // Iterate self over the contained objects, since there are combinations of
1646             // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1647             // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1648             SdrObjListIter aIterator(*pRenderedCustomShape);
1649             while(aIterator.IsMore())
1650             {
1651                 SdrObject* pCandidate = aIterator.Next();
1652                 SdrObjTransformInfoRec aInfo;
1653                 pCandidate->TakeObjInfo(aInfo);
1654 
1655                 // set path and poly conversion if one is possible since
1656                 // this object will first be broken
1657                 const sal_Bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
1658                 if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
1659                 {
1660                     rInfo.bCanConvToPath = bCanConvToPathOrPoly;
1661                 }
1662 
1663                 if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
1664                 {
1665                     rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
1666                 }
1667 
1668                 if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
1669                 {
1670                     rInfo.bCanConvToContour = aInfo.bCanConvToContour;
1671                 }
1672             }
1673         }
1674     }
1675 }
1676 
1677 void SdrObjCustomShape::SetModel(SdrModel* pNewModel)
1678 {
1679     SdrTextObj::SetModel(pNewModel);
1680     mXRenderedCustomShape.clear();
1681 }
1682 
1683 sal_uInt16 SdrObjCustomShape::GetObjIdentifier() const
1684 {
1685     return sal_uInt16(OBJ_CUSTOMSHAPE);
1686 }
1687 
1688 ////////////////////////////////////////////////////////////////////////////////////////////////////
1689 ////////////////////////////////////////////////////////////////////////////////////////////////////
1690 ////////////////////////////////////////////////////////////////////////////////////////////////////
1691 
1692 void SdrObjCustomShape::RecalcSnapRect()
1693 {
1694     SdrTextObj::RecalcSnapRect();
1695 }
1696 const Rectangle& SdrObjCustomShape::GetSnapRect() const
1697 {
1698     return SdrTextObj::GetSnapRect();
1699 }
1700 const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const
1701 {
1702     return SdrTextObj::GetCurrentBoundRect();
1703 }
1704 const Rectangle& SdrObjCustomShape::GetLogicRect() const
1705 {
1706     return SdrTextObj::GetLogicRect();
1707 }
1708 void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect )
1709 {
1710     aRect=rRect;
1711     ImpJustifyRect(aRect);
1712     InvalidateRenderGeometry();
1713     Rectangle aTextBound( aRect );
1714     if ( GetTextBounds( aTextBound ) )
1715     {
1716         if ( pModel==NULL || !pModel->IsPasteResize() )
1717         {
1718             long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1719             long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1720             long nTWdt=aTextBound.GetWidth ()-1-nHDist; if (nTWdt<0) nTWdt=0;
1721             long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1722             if ( IsAutoGrowWidth() )
1723                 NbcSetMinTextFrameWidth( nTWdt );
1724             if ( IsAutoGrowHeight() )
1725                 NbcSetMinTextFrameHeight( nTHgt );
1726             NbcAdjustTextFrameWidthAndHeight();
1727         }
1728     }
1729     ImpCheckShear();
1730     SetRectsDirty();
1731     SetChanged();
1732 }
1733 void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect )
1734 {
1735     Rectangle aBoundRect0;
1736     if ( pUserCall )
1737         aBoundRect0 = GetLastBoundRect();
1738     NbcSetSnapRect( rRect );
1739     BroadcastObjectChange();
1740     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1741 }
1742 void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect )
1743 {
1744     aRect = rRect;
1745     ImpJustifyRect( aRect );
1746     InvalidateRenderGeometry();
1747     Rectangle aTextBound( aRect );
1748     if ( GetTextBounds( aTextBound ) )
1749     {
1750         long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1751         long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1752 
1753         long nTWdt=aTextBound.GetWidth()-1-nHDist; if (nTWdt<0) nTWdt=0;
1754         long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1755         if ( IsAutoGrowWidth() )
1756             NbcSetMinTextFrameWidth( nTWdt );
1757         if ( IsAutoGrowHeight() )
1758             NbcSetMinTextFrameHeight( nTHgt );
1759         NbcAdjustTextFrameWidthAndHeight();
1760     }
1761     SetRectsDirty();
1762     SetChanged();
1763 }
1764 void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect )
1765 {
1766     Rectangle aBoundRect0;
1767     if ( pUserCall )
1768         aBoundRect0 = GetLastBoundRect();
1769     NbcSetLogicRect(rRect);
1770     BroadcastObjectChange();
1771     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1772 }
1773 void SdrObjCustomShape::Move( const Size& rSiz )
1774 {
1775     if ( rSiz.Width() || rSiz.Height() )
1776     {
1777         Rectangle aBoundRect0;
1778         if ( pUserCall )
1779             aBoundRect0 = GetLastBoundRect();
1780         // #110094#-14 SendRepaintBroadcast();
1781         NbcMove(rSiz);
1782         SetChanged();
1783         BroadcastObjectChange();
1784         SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1785     }
1786 }
1787 void SdrObjCustomShape::NbcMove( const Size& rSiz )
1788 {
1789     SdrTextObj::NbcMove( rSiz );
1790     if ( mXRenderedCustomShape.is() )
1791     {
1792         SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1793         if ( pRenderedCustomShape )
1794         {
1795             // #i97149# the visualisation shape needs to be informed
1796             // about change, too
1797             pRenderedCustomShape->ActionChanged();
1798             pRenderedCustomShape->NbcMove( rSiz );
1799         }
1800     }
1801 
1802     // #i37011# adapt geometry shadow
1803     if(mpLastShadowGeometry)
1804     {
1805         mpLastShadowGeometry->NbcMove( rSiz );
1806     }
1807 }
1808 void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact )
1809 {
1810     SdrTextObj::Resize( rRef, xFact, yFact );
1811 }
1812 
1813 void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
1814 {
1815     Fraction xFact( rxFact );
1816     Fraction yFact( ryFact );
1817 
1818     // taking care of handles that should not been changed
1819     Rectangle aOld( aRect );
1820     std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1821 
1822     SdrTextObj::NbcResize( rRef, xFact, yFact );
1823 
1824     if ( ( xFact.GetNumerator() != xFact.GetDenominator() )
1825         || ( yFact.GetNumerator()!= yFact.GetDenominator() ) )
1826     {
1827         if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) ||
1828             ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) )
1829         {
1830             SetMirroredX( IsMirroredX() == sal_False );
1831         }
1832         if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) ||
1833             ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) )
1834         {
1835             SetMirroredY( IsMirroredY() == sal_False );
1836         }
1837     }
1838 
1839     std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
1840     while ( aIter != aInteractionHandles.end() )
1841     {
1842         try
1843         {
1844             if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
1845                 aIter->xInteraction->setControllerPosition( aIter->aPosition );
1846             if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
1847             {
1848                 sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left();
1849                 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
1850             }
1851             if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
1852             {
1853                 sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top();
1854                 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
1855             }
1856         }
1857         catch ( const uno::RuntimeException& )
1858         {
1859         }
1860         aIter++;
1861     }
1862     InvalidateRenderGeometry();
1863 }
1864 void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs )
1865 {
1866     sal_Bool bMirroredX = IsMirroredX();
1867     sal_Bool bMirroredY = IsMirroredY();
1868 
1869     fObjectRotation = fmod( fObjectRotation, 360.0 );
1870     if ( fObjectRotation < 0 )
1871         fObjectRotation = 360 + fObjectRotation;
1872 
1873     // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1874     // has to be applied to the text object (which is internally using aGeo.nWink).
1875     SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink,        // retrieving the unrotated text object
1876                             sin( (-aGeo.nDrehWink) * F_PI18000 ),
1877                             cos( (-aGeo.nDrehWink) * F_PI18000 ) );
1878     aGeo.nDrehWink = 0;                                             // resetting aGeo data
1879     aGeo.RecalcSinCos();
1880 
1881     long nW = (long)( fObjectRotation * 100 );                      // applying our object rotation
1882     if ( bMirroredX )
1883         nW = 36000 - nW;
1884     if ( bMirroredY )
1885         nW = 18000 - nW;
1886     nW = nW % 36000;
1887     if ( nW < 0 )
1888         nW = 36000 + nW;
1889     SdrTextObj::NbcRotate( aRect.TopLeft(), nW,                     // applying text rotation
1890                             sin( nW * F_PI18000 ),
1891                             cos( nW * F_PI18000 ) );
1892 
1893     int nSwap = 0;
1894     if ( bMirroredX )
1895         nSwap ^= 1;
1896     if ( bMirroredY )
1897         nSwap ^= 1;
1898 
1899     double fWink = nWink;                                                   // updating to our new object rotation
1900     fWink /= 100.0;
1901     fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 );
1902     if ( fObjectRotation < 0 )
1903         fObjectRotation = 360 + fObjectRotation;
1904 
1905     SdrTextObj::NbcRotate( rRef, nWink, sn, cs );                           // applying text rotation
1906     InvalidateRenderGeometry();
1907 }
1908 
1909 void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
1910 {
1911     // storing horizontal and vertical flipping without modifying the rotate angle
1912 
1913     sal_Bool bHorz = sal_False;
1914     sal_Bool bVert = sal_False;
1915     if ( rRef1.X() == rRef2.X() )
1916         bHorz = sal_True;
1917     if ( rRef1.Y() == rRef2.Y() )
1918         bVert = sal_True;
1919     if ( !bHorz && !bVert )
1920         bHorz = bVert = sal_True;
1921 
1922     if ( bHorz || bVert )
1923     {
1924         SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1925 
1926         /////////////////
1927         // "MirroredX" //
1928         /////////////////
1929         if ( bHorz )
1930         {
1931             const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1932             com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
1933             if ( pAny )
1934             {
1935                 sal_Bool bFlip = sal_Bool();
1936                 if ( *pAny >>= bFlip )
1937                 {
1938                     if ( bFlip )
1939                         bHorz = sal_False;
1940                 }
1941             }
1942             PropertyValue aPropVal;
1943             aPropVal.Name = sMirroredX;
1944             aPropVal.Value <<= bHorz;
1945             aGeometryItem.SetPropertyValue( aPropVal );
1946         }
1947 
1948         /////////////////
1949         // "MirroredY" //
1950         /////////////////
1951         if ( bVert )
1952         {
1953             const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1954             com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
1955             if ( pAny )
1956             {
1957                 sal_Bool bFlip = sal_Bool();
1958                 if ( *pAny >>= bFlip )
1959                 {
1960                     if ( bFlip )
1961                         bVert = sal_False;
1962                 }
1963             }
1964             PropertyValue aPropVal;
1965             aPropVal.Name = sMirroredY;
1966             aPropVal.Value <<= bVert;
1967             aGeometryItem.SetPropertyValue( aPropVal );
1968         }
1969         SetMergedItem( aGeometryItem );
1970     }
1971     SdrTextObj::NbcMirror( rRef1, rRef2 );
1972     InvalidateRenderGeometry();
1973 }
1974 
1975 void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
1976 {
1977     SdrTextObj::Shear( rRef, nWink, tn, bVShear );
1978     InvalidateRenderGeometry();
1979 }
1980 void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
1981 {
1982     long nDrehWink = aGeo.nDrehWink;
1983     if ( nDrehWink )
1984     {
1985         aGeo.nDrehWink = -nDrehWink;
1986         aGeo.RecalcSinCos();
1987         NbcRotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
1988     }
1989     SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
1990     if ( nDrehWink )
1991     {
1992         aGeo.nDrehWink = nDrehWink;
1993         aGeo.RecalcSinCos();
1994         Rotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
1995     }
1996     InvalidateRenderGeometry();
1997 }
1998 
1999 ////////////////////////////////////////////////////////////////////////////////////////////////////
2000 
2001 SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum) const
2002 {
2003     sal_Int32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
2004 
2005     // #i25616#
2006     if(!LineIsOutsideGeometry())
2007     {
2008         nWdt++;
2009         nWdt /= 2;
2010     }
2011 
2012     Point aPt;
2013     switch (nPosNum) {
2014         case 0: aPt=aRect.TopCenter();    aPt.Y()-=nWdt; break;
2015         case 1: aPt=aRect.RightCenter();  aPt.X()+=nWdt; break;
2016         case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
2017         case 3: aPt=aRect.LeftCenter();   aPt.X()-=nWdt; break;
2018     }
2019     if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
2020     if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
2021     aPt-=GetSnapRect().Center();
2022     SdrGluePoint aGP(aPt);
2023     aGP.SetPercent(sal_False);
2024     return aGP;
2025 }
2026 
2027 ////////////////////////////////////////////////////////////////////////////////////////////////////
2028 
2029 // #i38892#
2030 void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
2031 {
2032     const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
2033 
2034     if(pSdrObject)
2035     {
2036         const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
2037 
2038         if(pSource && pSource->GetCount())
2039         {
2040             if(!SdrTextObj::GetGluePointList())
2041             {
2042                 SdrTextObj::ForceGluePointList();
2043             }
2044 
2045             const SdrGluePointList* pList = SdrTextObj::GetGluePointList();
2046 
2047             if(pList)
2048             {
2049                 SdrGluePointList aNewList;
2050                 sal_uInt16 a;
2051 
2052                 for(a = 0; a < pSource->GetCount(); a++)
2053                 {
2054                     SdrGluePoint aCopy((*pSource)[a]);
2055                     aCopy.SetUserDefined(sal_False);
2056                     aNewList.Insert(aCopy);
2057                 }
2058 
2059                 sal_Bool bMirroredX = IsMirroredX();
2060                 sal_Bool bMirroredY = IsMirroredY();
2061 
2062                 long nShearWink = aGeo.nShearWink;
2063                 double fTan = aGeo.nTan;
2064 
2065                 if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY )
2066                 {
2067                     Polygon aPoly( aRect );
2068                     if( nShearWink )
2069                     {
2070                         sal_uInt16 nPointCount=aPoly.GetSize();
2071                         for (sal_uInt16 i=0; i<nPointCount; i++)
2072                             ShearPoint(aPoly[i],aRect.Center(), fTan, sal_False );
2073                     }
2074                     if ( aGeo.nDrehWink )
2075                         aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 );
2076 
2077                     Rectangle aBoundRect( aPoly.GetBoundRect() );
2078                     sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left();
2079                     sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top();
2080 
2081                     if (nShearWink&&((bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX)))
2082                     {
2083                         nShearWink = -nShearWink;
2084                         fTan = -fTan;
2085                     }
2086 
2087                     Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
2088                     for ( a = 0; a < aNewList.GetCount(); a++ )
2089                     {
2090                         SdrGluePoint& rPoint = aNewList[ a ];
2091                         Point aGlue( rPoint.GetPos() );
2092                         if ( nShearWink )
2093                             ShearPoint( aGlue, aRef, fTan );
2094 
2095                         RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) );
2096                         if ( bMirroredX )
2097                             aGlue.X() = aRect.GetWidth() - aGlue.X();
2098                         if ( bMirroredY )
2099                             aGlue.Y() = aRect.GetHeight() - aGlue.Y();
2100                         aGlue.X() -= nXDiff;
2101                         aGlue.Y() -= nYDiff;
2102                         rPoint.SetPos( aGlue );
2103                     }
2104                 }
2105 
2106                 for(a = 0; a < pList->GetCount(); a++)
2107                 {
2108                     const SdrGluePoint& rCandidate = (*pList)[a];
2109 
2110                     if(rCandidate.IsUserDefined())
2111                     {
2112                         aNewList.Insert(rCandidate);
2113                     }
2114                 }
2115 
2116                 // copy new list to local. This is NOT very convenient behaviour, the local
2117                 // GluePointList should not be set, but be delivered by using GetGluePointList(),
2118                 // maybe on demand. Since the local object is changed here, this is assumed to
2119                 // be a result of GetGluePointList and thus the list is copied
2120                 if(pPlusData)
2121                 {
2122                     *pPlusData->pGluePoints = aNewList;
2123                 }
2124             }
2125         }
2126     }
2127 }
2128 
2129 // #i38892#
2130 const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const
2131 {
2132     ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded();
2133     return SdrTextObj::GetGluePointList();
2134 }
2135 
2136 // #i38892#
2137 //SdrGluePointList* SdrObjCustomShape::GetGluePointList()
2138 //{
2139 //  ImpCheckCustomGluePointsAreAdded();
2140 //  return SdrTextObj::GetGluePointList();
2141 //}
2142 
2143 // #i38892#
2144 SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
2145 {
2146     if(SdrTextObj::ForceGluePointList())
2147     {
2148         ImpCheckCustomGluePointsAreAdded();
2149         return SdrTextObj::ForceGluePointList();
2150     }
2151     else
2152     {
2153         return 0L;
2154     }
2155 }
2156 
2157 ////////////////////////////////////////////////////////////////////////////////////////////////////
2158 ////////////////////////////////////////////////////////////////////////////////////////////////////
2159 ////////////////////////////////////////////////////////////////////////////////////////////////////
2160 
2161 sal_uInt32 SdrObjCustomShape::GetHdlCount() const
2162 {
2163     const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
2164     std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2165     return ( aInteractionHandles.size() + nBasicHdlCount );
2166 }
2167 
2168 SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
2169 {
2170     SdrHdl* pH = NULL;
2171     const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
2172 
2173     if ( nHdlNum < nBasicHdlCount )
2174         pH = SdrTextObj::GetHdl( nHdlNum );
2175     else
2176     {
2177         std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2178         const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);
2179 
2180         if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2181         {
2182             if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
2183             {
2184                 try
2185                 {
2186                     com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
2187                     pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 );
2188                     pH->SetPointNum( nCustomShapeHdlNum );
2189                     pH->SetObj( (SdrObject*)this );
2190                 }
2191                 catch ( const uno::RuntimeException& )
2192                 {
2193                 }
2194             }
2195         }
2196     }
2197     return pH;
2198 }
2199 
2200 ////////////////////////////////////////////////////////////////////////////////////////////////////
2201 
2202 bool SdrObjCustomShape::hasSpecialDrag() const
2203 {
2204     return true;
2205 }
2206 
2207 bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const
2208 {
2209     const SdrHdl* pHdl = rDrag.GetHdl();
2210 
2211     if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind())
2212     {
2213         rDrag.SetEndDragChangesAttributes(true);
2214         rDrag.SetNoSnap(true);
2215     }
2216     else
2217     {
2218         const SdrHdl* pHdl2 = rDrag.GetHdl();
2219         const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind());
2220 
2221         switch( eHdl )
2222         {
2223             case HDL_UPLFT :
2224             case HDL_UPPER :
2225             case HDL_UPRGT :
2226             case HDL_LEFT  :
2227             case HDL_RIGHT :
2228             case HDL_LWLFT :
2229             case HDL_LOWER :
2230             case HDL_LWRGT :
2231             case HDL_MOVE  :
2232             {
2233                 break;
2234             }
2235             default:
2236             {
2237                 return false;
2238             }
2239         }
2240     }
2241 
2242     return true;
2243 }
2244 
2245 void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const
2246 {
2247     Rectangle   aOld( pObj->aRect );
2248     sal_Bool    bOldMirroredX( pObj->IsMirroredX() );
2249     sal_Bool    bOldMirroredY( pObj->IsMirroredY() );
2250 
2251     Rectangle aNewRect( rNewRect );
2252     aNewRect.Justify();
2253 
2254     std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2255 
2256     GeoStat aGeoStat( pObj->GetGeoStat() );
2257     if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() &&
2258         ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) )
2259     {
2260         Point aNewPos( aNewRect.TopLeft() );
2261         if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan );
2262         if ( pObj->aGeo.nDrehWink )  RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos );
2263         aNewRect.SetPos( aNewPos );
2264     }
2265     if ( aNewRect != pObj->aRect )
2266     {
2267         pObj->SetLogicRect( aNewRect );
2268         pObj->InvalidateRenderGeometry();
2269 
2270         if ( rNewRect.Left() > rNewRect.Right() )
2271         {
2272             Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() );
2273             Point aBottom( aTop.X(), aTop.Y() + 1000 );
2274             pObj->NbcMirror( aTop, aBottom );
2275         }
2276         if ( rNewRect.Top() > rNewRect.Bottom() )
2277         {
2278             Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 );
2279             Point aRight( aLeft.X() + 1000, aLeft.Y() );
2280             pObj->NbcMirror( aLeft, aRight );
2281         }
2282 
2283         std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2284         while ( aIter != aInteractionHandles.end() )
2285         {
2286             try
2287             {
2288                 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2289                     aIter->xInteraction->setControllerPosition( aIter->aPosition );
2290                 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
2291                 {
2292                     sal_Int32 nX;
2293                     if ( bOldMirroredX )
2294                     {
2295                         nX = ( aIter->aPosition.X - aOld.Right() );
2296                         if ( rNewRect.Left() > rNewRect.Right() )
2297                             nX = pObj->aRect.Left() - nX;
2298                         else
2299                             nX += pObj->aRect.Right();
2300                     }
2301                     else
2302                     {
2303                         nX = ( aIter->aPosition.X - aOld.Left() );
2304                         if ( rNewRect.Left() > rNewRect.Right() )
2305                             nX = pObj->aRect.Right() - nX;
2306                         else
2307                             nX += pObj->aRect.Left();
2308                     }
2309                     aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
2310                 }
2311                 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
2312                 {
2313                     sal_Int32 nY;
2314                     if ( bOldMirroredY )
2315                     {
2316                         nY = ( aIter->aPosition.Y - aOld.Bottom() );
2317                         if ( rNewRect.Top() > rNewRect.Bottom() )
2318                             nY = pObj->aRect.Top() - nY;
2319                         else
2320                             nY += pObj->aRect.Bottom();
2321                     }
2322                     else
2323                     {
2324                         nY = ( aIter->aPosition.Y - aOld.Top() );
2325                         if ( rNewRect.Top() > rNewRect.Bottom() )
2326                             nY = pObj->aRect.Bottom() - nY;
2327                         else
2328                             nY += pObj->aRect.Top();
2329                     }
2330                     aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
2331                 }
2332             }
2333             catch ( const uno::RuntimeException& )
2334             {
2335             }
2336             aIter++;
2337         }
2338     }
2339 }
2340 
2341 void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const
2342 {
2343     std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2344     if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2345     {
2346         SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
2347         if ( aInteractionHandle.xInteraction.is() )
2348         {
2349             try
2350             {
2351                 com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() );
2352                 if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE )
2353                 {
2354                     sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
2355                     sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
2356 
2357                     pObj->aRect.Move( nXDiff, nYDiff );
2358                     pObj->aOutRect.Move( nXDiff, nYDiff );
2359                     pObj->maSnapRect.Move( nXDiff, nYDiff );
2360                     pObj->SetRectsDirty(sal_True);
2361                     pObj->InvalidateRenderGeometry();
2362 
2363                     std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2364                     while ( aIter != aInteractionHandles.end() )
2365                     {
2366                         if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2367                         {
2368                             if ( aIter->xInteraction.is() )
2369                                 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2370                         }
2371                         aIter++;
2372                     }
2373                 }
2374                 aInteractionHandle.xInteraction->setControllerPosition( aPt );
2375             }
2376             catch ( const uno::RuntimeException& )
2377             {
2378             }
2379         }
2380     }
2381 }
2382 
2383 bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag)
2384 {
2385     const SdrHdl* pHdl = rDrag.GetHdl();
2386     const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2387 
2388     switch(eHdl)
2389     {
2390         case HDL_CUSTOMSHAPE1 :
2391         {
2392             rDrag.SetEndDragChangesGeoAndAttributes(true);
2393             DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this );
2394             SetRectsDirty();
2395             InvalidateRenderGeometry();
2396             SetChanged();
2397             break;
2398         }
2399 
2400         case HDL_UPLFT :
2401         case HDL_UPPER :
2402         case HDL_UPRGT :
2403         case HDL_LEFT  :
2404         case HDL_RIGHT :
2405         case HDL_LWLFT :
2406         case HDL_LOWER :
2407         case HDL_LWRGT :
2408         {
2409             DragResizeCustomShape(ImpDragCalcRect(rDrag), this);
2410             break;
2411         }
2412         case HDL_MOVE :
2413         {
2414             Move(Size(rDrag.GetDX(), rDrag.GetDY()));
2415             break;
2416         }
2417         default: break;
2418     }
2419 
2420     return true;
2421 }
2422 
2423 ////////////////////////////////////////////////////////////////////////////////////////////////////
2424 
2425 void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat )
2426 {
2427     Rectangle aRect1;
2428     rStat.TakeCreateRect( aRect1 );
2429 
2430     std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2431 
2432     sal_uInt32 nDefaultObjectSizeWidth = 3000;      // default width from SDOptions ?
2433     sal_uInt32 nDefaultObjectSizeHeight= 3000;
2434 
2435     if ( ImpVerticalSwitch( *this ) )
2436     {
2437         SetMirroredX( aRect1.Left() > aRect1.Right() );
2438 
2439         aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
2440         // subtracting the horizontal difference of the latest handle from shape position
2441         if ( !aInteractionHandles.empty() )
2442         {
2443             sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
2444             aRect1.Move( aRect.Left() - nHandlePos, 0 );
2445         }
2446     }
2447     ImpJustifyRect( aRect1 );
2448     rStat.SetActionRect( aRect1 );
2449     aRect = aRect1;
2450     SetRectsDirty();
2451 
2452     std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2453     while ( aIter != aInteractionHandles.end() )
2454     {
2455         try
2456         {
2457             if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED )
2458                 aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
2459         }
2460         catch ( const uno::RuntimeException& )
2461         {
2462         }
2463         aIter++;
2464     }
2465 
2466     SetBoundRectDirty();
2467     bSnapRectDirty=sal_True;
2468 }
2469 
2470 FASTBOOL SdrObjCustomShape::BegCreate( SdrDragStat& rDrag )
2471 {
2472     return SdrTextObj::BegCreate( rDrag );
2473 }
2474 
2475 FASTBOOL SdrObjCustomShape::MovCreate(SdrDragStat& rStat)
2476 {
2477     SdrView* pView = rStat.GetView();       // #i37448#
2478     if( pView && pView->IsSolidDragging() )
2479     {
2480         InvalidateRenderGeometry();
2481     }
2482     DragCreateObject( rStat );
2483     SetRectsDirty();
2484     return sal_True;
2485 }
2486 
2487 FASTBOOL SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
2488 {
2489     DragCreateObject( rStat );
2490 
2491     if ( bTextFrame )
2492     {
2493         if ( IsAutoGrowHeight() )
2494         {
2495             // MinTextHeight
2496             long nHgt=aRect.GetHeight()-1;
2497             if (nHgt==1) nHgt=0;
2498             NbcSetMinTextFrameHeight( nHgt );
2499         }
2500         if ( IsAutoGrowWidth() )
2501         {
2502             // MinTextWidth
2503             long nWdt=aRect.GetWidth()-1;
2504             if (nWdt==1) nWdt=0;
2505             NbcSetMinTextFrameWidth( nWdt );
2506         }
2507         // Textrahmen neu berechnen
2508         NbcAdjustTextFrameWidthAndHeight();
2509     }
2510     SetRectsDirty();
2511     return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 );
2512 }
2513 
2514 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
2515 {
2516     return GetLineGeometry( this, sal_False );
2517 }
2518 
2519 ////////////////////////////////////////////////////////////////////////////////////////////////////
2520 ////////////////////////////////////////////////////////////////////////////////////////////////////
2521 ////////////////////////////////////////////////////////////////////////////////////////////////////
2522 
2523 // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2524 //                                     the SdrTextAutoGrowWidthItem  == true -> Word wrap text in Shape
2525 FASTBOOL SdrObjCustomShape::IsAutoGrowHeight() const
2526 {
2527     const SfxItemSet& rSet = GetMergedItemSet();
2528     FASTBOOL bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2529     if ( bIsAutoGrowHeight && IsVerticalWriting() )
2530         bIsAutoGrowHeight = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False;
2531     return bIsAutoGrowHeight;
2532 }
2533 FASTBOOL SdrObjCustomShape::IsAutoGrowWidth() const
2534 {
2535     const SfxItemSet& rSet = GetMergedItemSet();
2536     FASTBOOL bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2537     if ( bIsAutoGrowWidth && !IsVerticalWriting() )
2538         bIsAutoGrowWidth = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False;
2539     return bIsAutoGrowWidth;
2540 }
2541 
2542 /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2543    is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2544    mode has been changed */
2545 
2546 void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical )
2547 {
2548     ForceOutlinerParaObject();
2549 
2550     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2551 
2552     DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2553 
2554     if( pOutlinerParaObject )
2555     {
2556         if(pOutlinerParaObject->IsVertical() != (bool)bVertical)
2557         {
2558             // get item settings
2559             const SfxItemSet& rSet = GetObjectItemSet();
2560 
2561             // #103516# Also exchange hor/ver adjust items
2562             SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
2563             SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
2564 
2565             // rescue object size
2566             Rectangle aObjectRect = GetSnapRect();
2567 
2568             // prepare ItemSet to set exchanged width and height items
2569             SfxItemSet aNewSet(*rSet.GetPool(),
2570                 SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
2571                 // #103516# Expanded item ranges to also support hor and ver adjust.
2572                 SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
2573                 SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
2574                 0, 0);
2575 
2576             aNewSet.Put(rSet);
2577 
2578             // #103516# Exchange horz and vert adjusts
2579             switch(eVert)
2580             {
2581                 case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
2582                 case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
2583                 case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
2584                 case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
2585             }
2586             switch(eHorz)
2587             {
2588                 case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
2589                 case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
2590                 case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
2591                 case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
2592             }
2593 
2594             SetObjectItemSet( aNewSet );
2595             pOutlinerParaObject = GetOutlinerParaObject();
2596             if ( pOutlinerParaObject )
2597                 pOutlinerParaObject->SetVertical(bVertical);
2598 
2599             // restore object size
2600             SetSnapRect(aObjectRect);
2601         }
2602     }
2603 }
2604 FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const
2605 {
2606     if ( pModel && HasText() && !rR.IsEmpty() )
2607     {
2608         FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth();
2609         FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight();
2610         if ( bWdtGrow || bHgtGrow )
2611         {
2612             Rectangle aR0(rR);
2613             long nHgt=0,nMinHgt=0,nMaxHgt=0;
2614             long nWdt=0,nMinWdt=0,nMaxWdt=0;
2615             Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
2616             Size aMaxSiz(100000,100000);
2617             Size aTmpSiz(pModel->GetMaxObjSize());
2618             if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2619             if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2620             if (bWdtGrow)
2621             {
2622                 nMinWdt=GetMinTextFrameWidth();
2623                 nMaxWdt=GetMaxTextFrameWidth();
2624                 if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
2625                 if (nMinWdt<=0) nMinWdt=1;
2626                 aSiz.Width()=nMaxWdt;
2627             }
2628             if (bHgtGrow)
2629             {
2630                 nMinHgt=GetMinTextFrameHeight();
2631                 nMaxHgt=GetMaxTextFrameHeight();
2632                 if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
2633                 if (nMinHgt<=0) nMinHgt=1;
2634                 aSiz.Height()=nMaxHgt;
2635             }
2636             long nHDist=GetTextLeftDistance()+GetTextRightDistance();
2637             long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
2638             aSiz.Width()-=nHDist;
2639             aSiz.Height()-=nVDist;
2640             if ( aSiz.Width() < 2 )
2641                 aSiz.Width() = 2;   // Mindestgroesse 2
2642             if ( aSiz.Height() < 2 )
2643                 aSiz.Height() = 2; // Mindestgroesse 2
2644 
2645             if(pEdtOutl)
2646             {
2647                 pEdtOutl->SetMaxAutoPaperSize( aSiz );
2648                 if (bWdtGrow)
2649                 {
2650                     Size aSiz2(pEdtOutl->CalcTextSize());
2651                     nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
2652                     if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
2653                 } else
2654                 {
2655                     nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz
2656                 }
2657             }
2658             else
2659             {
2660                 Outliner& rOutliner=ImpGetDrawOutliner();
2661                 rOutliner.SetPaperSize(aSiz);
2662                 rOutliner.SetUpdateMode(sal_True);
2663                 // !!! hier sollte ich wohl auch noch mal die Optimierung mit
2664                 // bPortionInfoChecked usw einbauen
2665                 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2666                 if( pOutlinerParaObject != NULL )
2667                 {
2668                     rOutliner.SetText(*pOutlinerParaObject);
2669                     rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
2670                 }
2671                 if ( bWdtGrow )
2672                 {
2673                     Size aSiz2(rOutliner.CalcTextSize());
2674                     nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
2675                     if ( bHgtGrow )
2676                         nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
2677                 }
2678                 else
2679                     nHgt = rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz
2680                 rOutliner.Clear();
2681             }
2682             if ( nWdt < nMinWdt )
2683                 nWdt = nMinWdt;
2684             if ( nWdt > nMaxWdt )
2685                 nWdt = nMaxWdt;
2686             nWdt += nHDist;
2687             if ( nWdt < 1 )
2688                 nWdt = 1; // nHDist kann auch negativ sein
2689             if ( nHgt < nMinHgt )
2690                 nHgt = nMinHgt;
2691             if ( nHgt > nMaxHgt )
2692                 nHgt = nMaxHgt;
2693             nHgt+=nVDist;
2694             if ( nHgt < 1 )
2695                 nHgt = 1; // nVDist kann auch negativ sein
2696             long nWdtGrow = nWdt-(rR.Right()-rR.Left());
2697             long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
2698             if ( nWdtGrow == 0 )
2699                 bWdtGrow = sal_False;
2700             if ( nHgtGrow == 0 )
2701                 bHgtGrow=sal_False;
2702             if ( bWdtGrow || bHgtGrow )
2703             {
2704                 if ( bWdtGrow )
2705                 {
2706                     SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2707                     if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2708                         rR.Right()+=nWdtGrow;
2709                     else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2710                         rR.Left()-=nWdtGrow;
2711                     else
2712                     {
2713                         long nWdtGrow2=nWdtGrow/2;
2714                         rR.Left()-=nWdtGrow2;
2715                         rR.Right()=rR.Left()+nWdt;
2716                     }
2717                 }
2718                 if ( bHgtGrow )
2719                 {
2720                     SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2721                     if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2722                         rR.Bottom()+=nHgtGrow;
2723                     else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2724                         rR.Top()-=nHgtGrow;
2725                     else
2726                     {
2727                         long nHgtGrow2=nHgtGrow/2;
2728                         rR.Top()-=nHgtGrow2;
2729                         rR.Bottom()=rR.Top()+nHgt;
2730                     }
2731                 }
2732                 if ( aGeo.nDrehWink )
2733                 {
2734                     Point aD1(rR.TopLeft());
2735                     aD1-=aR0.TopLeft();
2736                     Point aD2(aD1);
2737                     RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
2738                     aD2-=aD1;
2739                     rR.Move(aD2.X(),aD2.Y());
2740                 }
2741                 return sal_True;
2742             }
2743         }
2744     }
2745     return sal_False;
2746 }
2747 
2748 Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const FASTBOOL bHgt, const FASTBOOL bWdt )
2749 {
2750     Rectangle aReturnValue;
2751 
2752     Rectangle aOldTextRect( aRect );        // <- initial text rectangle
2753 
2754     Rectangle aNewTextRect( aRect );        // <- new text rectangle returned from the custom shape renderer,
2755     GetTextBounds( aNewTextRect );          //    it depends to the current logical shape size
2756 
2757     Rectangle aAdjustedTextRect( aNewTextRect );                            // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2758     if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) )   //    that the new text rectangle is matching the current text size from the outliner
2759     {
2760         if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) )
2761         {
2762             aReturnValue = aRect;
2763             double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth();
2764             double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight();
2765             double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
2766             double fLeftDiff  = (double)( aAdjustedTextRect.Left()  - aNewTextRect.Left()  ) * fXScale;
2767             double fTopDiff   = (double)( aAdjustedTextRect.Top()   - aNewTextRect.Top()   ) * fYScale;
2768             double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
2769             aReturnValue.Left() += (sal_Int32)fLeftDiff;
2770             aReturnValue.Right() += (sal_Int32)fRightDiff;
2771             aReturnValue.Top() += (sal_Int32)fTopDiff;
2772             aReturnValue.Bottom() += (sal_Int32)fBottomDiff;
2773         }
2774     }
2775     return aReturnValue;
2776 }
2777 
2778 FASTBOOL SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2779 {
2780     Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2781     sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2782     if ( bRet )
2783     {
2784         // taking care of handles that should not been changed
2785         std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2786 
2787         aRect = aNewTextRect;
2788         SetRectsDirty();
2789         SetChanged();
2790 
2791         std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2792         while ( aIter != aInteractionHandles.end() )
2793         {
2794             try
2795             {
2796                 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2797                     aIter->xInteraction->setControllerPosition( aIter->aPosition );
2798             }
2799             catch ( const uno::RuntimeException& )
2800             {
2801             }
2802             aIter++;
2803         }
2804         InvalidateRenderGeometry();
2805     }
2806     return bRet;
2807 }
2808 FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2809 {
2810     Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2811     sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2812     if ( bRet )
2813     {
2814         Rectangle aBoundRect0;
2815         if ( pUserCall )
2816             aBoundRect0 = GetCurrentBoundRect();
2817 
2818         // taking care of handles that should not been changed
2819         std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2820 
2821 //      SendRepaintBroadcast();
2822         aRect = aNewTextRect;
2823         SetRectsDirty();
2824 
2825         std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2826         while ( aIter != aInteractionHandles.end() )
2827         {
2828             try
2829             {
2830                 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2831                     aIter->xInteraction->setControllerPosition( aIter->aPosition );
2832             }
2833             catch ( const uno::RuntimeException& )
2834             {
2835             }
2836             aIter++;
2837         }
2838 
2839         InvalidateRenderGeometry();
2840         SetChanged();
2841 //      SendRepaintBroadcast();
2842         BroadcastObjectChange();
2843         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2844     }
2845     return bRet;
2846 }
2847 sal_Bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl )
2848 {
2849     return SdrTextObj::BegTextEdit( rOutl );
2850 }
2851 void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
2852 {
2853     Size aPaperMin,aPaperMax;
2854     Rectangle aViewInit;
2855     TakeTextAnchorRect( aViewInit );
2856     if ( aGeo.nDrehWink )
2857     {
2858         Point aCenter(aViewInit.Center());
2859         aCenter-=aViewInit.TopLeft();
2860         Point aCenter0(aCenter);
2861         RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
2862         aCenter-=aCenter0;
2863         aViewInit.Move(aCenter.X(),aCenter.Y());
2864     }
2865     Size aAnkSiz(aViewInit.GetSize());
2866     aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
2867     Size aMaxSiz(1000000,1000000);
2868     if (pModel!=NULL) {
2869         Size aTmpSiz(pModel->GetMaxObjSize());
2870         if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2871         if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2872     }
2873     SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
2874     SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
2875 
2876     long nMinWdt = GetMinTextFrameWidth();
2877     long nMinHgt = GetMinTextFrameHeight();
2878     long nMaxWdt = GetMaxTextFrameWidth();
2879     long nMaxHgt = GetMaxTextFrameHeight();
2880     if (nMinWdt<1) nMinWdt=1;
2881     if (nMinHgt<1) nMinHgt=1;
2882     if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
2883         nMaxWdt = aMaxSiz.Width();
2884     if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
2885         nMaxHgt=aMaxSiz.Height();
2886 
2887     if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2888     {
2889         if ( IsVerticalWriting() )
2890         {
2891             nMaxHgt = aAnkSiz.Height();
2892             nMinHgt = nMaxHgt;
2893         }
2894         else
2895         {
2896             nMaxWdt = aAnkSiz.Width();
2897             nMinWdt = nMaxWdt;
2898         }
2899     }
2900     aPaperMax.Width()=nMaxWdt;
2901     aPaperMax.Height()=nMaxHgt;
2902 
2903     aPaperMin.Width()=nMinWdt;
2904     aPaperMin.Height()=nMinHgt;
2905 
2906     if ( pViewMin )
2907     {
2908         *pViewMin = aViewInit;
2909 
2910         long nXFree = aAnkSiz.Width() - aPaperMin.Width();
2911         if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2912             pViewMin->Right() -= nXFree;
2913         else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2914             pViewMin->Left() += nXFree;
2915         else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); }
2916 
2917         long nYFree = aAnkSiz.Height() - aPaperMin.Height();
2918         if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2919             pViewMin->Bottom() -= nYFree;
2920         else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2921             pViewMin->Top() += nYFree;
2922         else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); }
2923     }
2924 
2925     if( IsVerticalWriting() )
2926         aPaperMin.Width() = 0;
2927     else
2928         aPaperMin.Height() = 0; // #33102#
2929 
2930     if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
2931         aPaperMin.Width()=0;
2932 
2933     // #103516# For complete ver adjust support, set paper min height to 0, here.
2934     if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
2935         aPaperMin.Height() = 0;
2936 
2937     if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
2938     if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
2939     if (pViewInit!=NULL) *pViewInit=aViewInit;
2940 }
2941 void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl )
2942 {
2943     SdrTextObj::EndTextEdit( rOutl );
2944     InvalidateRenderGeometry();
2945 }
2946 void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const
2947 {
2948     if ( GetTextBounds( rAnchorRect ) )
2949     {
2950         Point aRotateRef( maSnapRect.Center() );
2951         rAnchorRect.Left()   += GetTextLeftDistance();
2952         rAnchorRect.Top()    += GetTextUpperDistance();
2953         rAnchorRect.Right()  -= GetTextRightDistance();
2954         rAnchorRect.Bottom() -= GetTextLowerDistance();
2955         ImpJustifyRect( rAnchorRect );
2956 
2957         if ( rAnchorRect.GetWidth() < 2 )
2958             rAnchorRect.Right() = rAnchorRect.Left() + 1;   // minimal width is 2
2959         if ( rAnchorRect.GetHeight() < 2 )
2960             rAnchorRect.Bottom() = rAnchorRect.Top() + 1;   // minimal height is 2
2961         if ( aGeo.nDrehWink )
2962         {
2963             Point aP( rAnchorRect.TopLeft() );
2964             RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos );
2965             rAnchorRect.SetPos( aP );
2966         }
2967     }
2968     else
2969         SdrTextObj::TakeTextAnchorRect( rAnchorRect );
2970 }
2971 void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
2972                                Rectangle* pAnchorRect, sal_Bool /*bLineWidth*/) const
2973 {
2974     Rectangle aAnkRect; // Rect innerhalb dem geankert wird
2975     TakeTextAnchorRect(aAnkRect);
2976     SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2977     SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2978     sal_uIntPtr nStat0=rOutliner.GetControlWord();
2979     Size aNullSize;
2980 
2981     rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
2982     rOutliner.SetMinAutoPaperSize(aNullSize);
2983     sal_Int32 nMaxAutoPaperWidth = 1000000;
2984     sal_Int32 nMaxAutoPaperHeight= 1000000;
2985 
2986     long nAnkWdt=aAnkRect.GetWidth();
2987     long nAnkHgt=aAnkRect.GetHeight();
2988 
2989     if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2990     {
2991         if ( IsVerticalWriting() )
2992             nMaxAutoPaperHeight = nAnkHgt;
2993         else
2994             nMaxAutoPaperWidth = nAnkWdt;
2995     }
2996     if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
2997     {
2998         rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
2999     }
3000 
3001     if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
3002     {
3003         rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
3004     }
3005     rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
3006     rOutliner.SetPaperSize( aNullSize );
3007 
3008     // Text in den Outliner stecken - ggf. den aus dem EditOutliner
3009     OutlinerParaObject* pPara= GetOutlinerParaObject();
3010     if (pEdtOutl && !bNoEditText)
3011         pPara=pEdtOutl->CreateParaObject();
3012 
3013     if (pPara)
3014     {
3015         sal_Bool bHitTest = sal_False;
3016         if( pModel )
3017             bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
3018 
3019         const SdrTextObj* pTestObj = rOutliner.GetTextObj();
3020         if( !pTestObj || !bHitTest || pTestObj != this ||
3021             pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() )
3022         {
3023             if( bHitTest )
3024                 rOutliner.SetTextObj( this );
3025 
3026             rOutliner.SetUpdateMode(sal_True);
3027             rOutliner.SetText(*pPara);
3028         }
3029     }
3030     else
3031     {
3032         rOutliner.SetTextObj( NULL );
3033     }
3034     if (pEdtOutl && !bNoEditText && pPara)
3035         delete pPara;
3036 
3037     rOutliner.SetUpdateMode(sal_True);
3038     rOutliner.SetControlWord(nStat0);
3039 
3040     SdrText* pText = getActiveText();
3041     if( pText )
3042         pText->CheckPortionInfo( rOutliner );
3043 
3044     Point aTextPos(aAnkRect.TopLeft());
3045     Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
3046 
3047     // #106653#
3048     // For draw objects containing text correct hor/ver alignment if text is bigger
3049     // than the object itself. Without that correction, the text would always be
3050         // formatted to the left edge (or top edge when vertical) of the draw object.
3051 
3052     if( !IsTextFrame() )
3053     {
3054         if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
3055         {
3056             // #110129#
3057             // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
3058             // else the alignment is wanted.
3059             if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
3060             {
3061                 eHAdj = SDRTEXTHORZADJUST_CENTER;
3062             }
3063         }
3064 
3065         if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
3066         {
3067             // #110129#
3068             // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
3069             // else the alignment is wanted.
3070             if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
3071             {
3072                 eVAdj = SDRTEXTVERTADJUST_CENTER;
3073             }
3074         }
3075     }
3076 
3077     if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
3078     {
3079         long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
3080         if (eHAdj==SDRTEXTHORZADJUST_CENTER)
3081             aTextPos.X()+=nFreeWdt/2;
3082         if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
3083             aTextPos.X()+=nFreeWdt;
3084     }
3085     if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
3086     {
3087         long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
3088         if (eVAdj==SDRTEXTVERTADJUST_CENTER)
3089             aTextPos.Y()+=nFreeHgt/2;
3090         if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
3091             aTextPos.Y()+=nFreeHgt;
3092     }
3093     if (aGeo.nDrehWink!=0)
3094         RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
3095 
3096     if (pAnchorRect)
3097         *pAnchorRect=aAnkRect;
3098 
3099     // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
3100     rTextRect=Rectangle(aTextPos,aTextSiz);
3101 }
3102 
3103 void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
3104 {
3105     SdrTextObj::NbcSetOutlinerParaObject( pTextObject );
3106     SetBoundRectDirty();
3107     SetRectsDirty(sal_True);
3108     InvalidateRenderGeometry();
3109 }
3110 
3111 void SdrObjCustomShape::operator=(const SdrObject& rObj)
3112 {
3113     SdrTextObj::operator=( rObj );
3114     aName =((SdrObjCustomShape&)rObj).aName;
3115     fObjectRotation = ((SdrObjCustomShape&)rObj).fObjectRotation;
3116     InvalidateRenderGeometry();
3117 }
3118 
3119 
3120 void SdrObjCustomShape::TakeObjNameSingul(XubString& rName) const
3121 {
3122     rName = ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE);
3123     String aNm( GetName() );
3124     if( aNm.Len() )
3125     {
3126         rName += sal_Unicode(' ');
3127         rName += sal_Unicode('\'');
3128         rName += aNm;
3129         rName += sal_Unicode('\'');
3130     }
3131 }
3132 
3133 void SdrObjCustomShape::TakeObjNamePlural(XubString& rName) const
3134 {
3135     rName=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE);
3136 }
3137 
3138 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const
3139 {
3140     return GetLineGeometry( (SdrObjCustomShape*)this, sal_False );
3141 }
3142 
3143 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const
3144 {
3145     const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
3146     if ( pSdrObject )
3147         return pSdrObject->TakeContour();
3148     return basegfx::B2DPolyPolygon();
3149 }
3150 
3151 SdrObject* SdrObjCustomShape::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
3152 {
3153     // #i37011#
3154     SdrObject* pRetval = 0L;
3155     SdrObject* pRenderedCustomShape = 0L;
3156 
3157     if ( !mXRenderedCustomShape.is() )
3158     {
3159         // force CustomShape
3160         ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape();
3161     }
3162 
3163     if ( mXRenderedCustomShape.is() )
3164     {
3165         pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
3166     }
3167 
3168     if ( pRenderedCustomShape )
3169     {
3170         SdrObject* pCandidate = pRenderedCustomShape->Clone();
3171         DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
3172         pCandidate->SetModel(GetModel());
3173         pRetval = pCandidate->DoConvertToPolyObj(bBezier, bAddText);
3174         SdrObject::Free( pCandidate );
3175 
3176         if(pRetval)
3177         {
3178             const sal_Bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue());
3179             if(bShadow)
3180             {
3181                 pRetval->SetMergedItem(SdrShadowItem(sal_True));
3182             }
3183         }
3184 
3185         if(bAddText && HasText() && !IsTextPath())
3186         {
3187             pRetval = ImpConvertAddText(pRetval, bBezier);
3188         }
3189     }
3190 
3191     return pRetval;
3192 }
3193 
3194 void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr )
3195 {
3196     // #i40944#
3197     InvalidateRenderGeometry();
3198     SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
3199 }
3200 
3201 void SdrObjCustomShape::SetPage( SdrPage* pNewPage )
3202 {
3203     SdrTextObj::SetPage( pNewPage );
3204 
3205     if( pNewPage )
3206     {
3207         // invalidating rectangles by SetRectsDirty is not sufficient,
3208         // AdjustTextFrameWidthAndHeight() also has to be made, both
3209         // actions are done by NbcSetSnapRect
3210         Rectangle aTmp( aRect );    //creating temporary rectangle #i61108#
3211         NbcSetSnapRect( aTmp );
3212     }
3213 }
3214 
3215 SdrObjGeoData* SdrObjCustomShape::NewGeoData() const
3216 {
3217     return new SdrAShapeObjGeoData;
3218 }
3219 
3220 void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const
3221 {
3222     SdrTextObj::SaveGeoData( rGeo );
3223     SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
3224     rAGeo.fObjectRotation = fObjectRotation;
3225     rAGeo.bMirroredX = IsMirroredX();
3226     rAGeo.bMirroredY = IsMirroredY();
3227 
3228     const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3229     Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) );
3230     if ( pAny )
3231         *pAny >>= rAGeo.aAdjustmentSeq;
3232 }
3233 
3234 void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo)
3235 {
3236     SdrTextObj::RestGeoData( rGeo );
3237     SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
3238     fObjectRotation = rAGeo.fObjectRotation;
3239     SetMirroredX( rAGeo.bMirroredX );
3240     SetMirroredY( rAGeo.bMirroredY );
3241 
3242     SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
3243     const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3244     PropertyValue aPropVal;
3245     aPropVal.Name = sAdjustmentValues;
3246     aPropVal.Value <<= rAGeo.aAdjustmentSeq;
3247     rGeometryItem.SetPropertyValue( aPropVal );
3248     SetMergedItem( rGeometryItem );
3249 
3250     InvalidateRenderGeometry();
3251 }
3252 
3253 void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
3254 {
3255     // break up matrix
3256     basegfx::B2DTuple aScale;
3257     basegfx::B2DTuple aTranslate;
3258     double fRotate, fShearX;
3259     rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3260 
3261     // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
3262     // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
3263     if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
3264     {
3265         aScale.setX(fabs(aScale.getX()));
3266         aScale.setY(fabs(aScale.getY()));
3267         fRotate = fmod(fRotate + F_PI, F_2PI);
3268     }
3269 
3270     // reset object shear and rotations
3271     aGeo.nDrehWink = 0;
3272     aGeo.RecalcSinCos();
3273     aGeo.nShearWink = 0;
3274     aGeo.RecalcTan();
3275 
3276     // force metric to pool metric
3277     SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3278     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3279     {
3280         switch(eMapUnit)
3281         {
3282             case SFX_MAPUNIT_TWIP :
3283             {
3284                 // position
3285                 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3286                 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3287 
3288                 // size
3289                 aScale.setX(ImplMMToTwips(aScale.getX()));
3290                 aScale.setY(ImplMMToTwips(aScale.getY()));
3291 
3292                 break;
3293             }
3294             default:
3295             {
3296                 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3297             }
3298         }
3299     }
3300 
3301     // if anchor is used, make position relative to it
3302     if( pModel && pModel->IsWriter() )
3303     {
3304         if(GetAnchorPos().X() || GetAnchorPos().Y())
3305         {
3306             aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3307         }
3308     }
3309 
3310     // build and set BaseRect (use scale)
3311     Point aPoint = Point();
3312     Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
3313     Rectangle aBaseRect(aPoint, aSize);
3314     SetSnapRect(aBaseRect);
3315 
3316     // shear?
3317     if(!basegfx::fTools::equalZero(fShearX))
3318     {
3319         GeoStat aGeoStat;
3320         aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
3321         aGeoStat.RecalcTan();
3322         Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
3323     }
3324 
3325     // rotation?
3326     if(!basegfx::fTools::equalZero(fRotate))
3327     {
3328         GeoStat aGeoStat;
3329 
3330         // #i78696#
3331         // fRotate is mathematically correct, but aGeoStat.nDrehWink is
3332         // mirrored -> mirror value here
3333         aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
3334         aGeoStat.RecalcSinCos();
3335         Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
3336     }
3337 
3338     // translate?
3339     if(!aTranslate.equalZero())
3340     {
3341         Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
3342     }
3343 }
3344 
3345 // taking fObjectRotation instead of aGeo.nWink
3346 sal_Bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3347 {
3348     // get turn and shear
3349 //  double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
3350     double fRotate = fObjectRotation * F_PI180;
3351     double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
3352 
3353     // get aRect, this is the unrotated snaprect
3354     Rectangle aRectangle(aRect);
3355 
3356     sal_Bool bMirroredX = IsMirroredX();
3357     sal_Bool bMirroredY = IsMirroredY();
3358     if ( bMirroredX || bMirroredY )
3359     {   // we have to retrieve the unmirrored rect
3360 
3361         GeoStat aNewGeo( aGeo );
3362 
3363         if ( bMirroredX )
3364         {
3365             Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
3366             Rectangle aBoundRect( aPol.GetBoundRect() );
3367 
3368             Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
3369             Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
3370             sal_uInt16 i;
3371             sal_uInt16 nPntAnz=aPol.GetSize();
3372             for (i=0; i<nPntAnz; i++)
3373             {
3374                 MirrorPoint(aPol[i],aRef1,aRef2);
3375             }
3376             // Polygon wenden und etwas schieben
3377             Polygon aPol0(aPol);
3378             aPol[0]=aPol0[1];
3379             aPol[1]=aPol0[0];
3380             aPol[2]=aPol0[3];
3381             aPol[3]=aPol0[2];
3382             aPol[4]=aPol0[1];
3383             Poly2Rect(aPol,aRectangle,aNewGeo);
3384         }
3385         if ( bMirroredY )
3386         {
3387             Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
3388             Rectangle aBoundRect( aPol.GetBoundRect() );
3389 
3390             Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
3391             Point aRef2( aRef1.X() + 1000, aRef1.Y() );
3392             sal_uInt16 i;
3393             sal_uInt16 nPntAnz=aPol.GetSize();
3394             for (i=0; i<nPntAnz; i++)
3395             {
3396                 MirrorPoint(aPol[i],aRef1,aRef2);
3397             }
3398             // Polygon wenden und etwas schieben
3399             Polygon aPol0(aPol);
3400             aPol[0]=aPol0[1];
3401             aPol[1]=aPol0[0];
3402             aPol[2]=aPol0[3];
3403             aPol[3]=aPol0[2];
3404             aPol[4]=aPol0[1];
3405             Poly2Rect(aPol,aRectangle,aNewGeo);
3406         }
3407     }
3408 
3409     // fill other values
3410     basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3411     basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3412 
3413     // position maybe relative to anchorpos, convert
3414     if( pModel && pModel->IsWriter() )
3415     {
3416         if(GetAnchorPos().X() || GetAnchorPos().Y())
3417         {
3418             aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3419         }
3420     }
3421 
3422     // force MapUnit to 100th mm
3423     SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3424     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3425     {
3426         switch(eMapUnit)
3427         {
3428             case SFX_MAPUNIT_TWIP :
3429             {
3430                 // postion
3431                 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3432                 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3433 
3434                 // size
3435                 aScale.setX(ImplTwipsToMM(aScale.getX()));
3436                 aScale.setY(ImplTwipsToMM(aScale.getY()));
3437 
3438                 break;
3439             }
3440             default:
3441             {
3442                 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3443             }
3444         }
3445     }
3446 
3447     // build matrix
3448     rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
3449         aScale,
3450         basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
3451         basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
3452         aTranslate);
3453 
3454     return sal_False;
3455 }
3456 
3457 sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact()
3458 {
3459     return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
3460 }
3461 
3462 // #i33136#
3463 bool SdrObjCustomShape::doConstructOrthogonal(const ::rtl::OUString& rName)
3464 {
3465     bool bRetval(false);
3466     static ::rtl::OUString Imps_sNameASOrtho_quadrat( RTL_CONSTASCII_USTRINGPARAM( "quadrat" ) );
3467     static ::rtl::OUString Imps_sNameASOrtho_round_quadrat( RTL_CONSTASCII_USTRINGPARAM( "round-quadrat" ) );
3468     static ::rtl::OUString Imps_sNameASOrtho_circle( RTL_CONSTASCII_USTRINGPARAM( "circle" ) );
3469     static ::rtl::OUString Imps_sNameASOrtho_circle_pie( RTL_CONSTASCII_USTRINGPARAM( "circle-pie" ) );
3470     static ::rtl::OUString Imps_sNameASOrtho_ring( RTL_CONSTASCII_USTRINGPARAM( "ring" ) );
3471 
3472     if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName))
3473     {
3474         bRetval = true;
3475     }
3476     else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName))
3477     {
3478         bRetval = true;
3479     }
3480     else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName))
3481     {
3482         bRetval = true;
3483     }
3484     else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName))
3485     {
3486         bRetval = true;
3487     }
3488     else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName))
3489     {
3490         bRetval = true;
3491     }
3492 
3493     return bRetval;
3494 }
3495 
3496 // #i37011# centralize throw-away of render geometry
3497 void SdrObjCustomShape::InvalidateRenderGeometry()
3498 {
3499     mXRenderedCustomShape = 0L;
3500     SdrObject::Free( mpLastShadowGeometry );
3501     mpLastShadowGeometry = 0L;
3502 }
3503 
3504 // eof
3505