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