xref: /aoo42x/main/svx/source/svdraw/svdoashp.cxx (revision 6381da86)
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