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