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