merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdoashp.cxx
blob56a27c0753ca81e7c5f38637c0beb14e63382d5f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdoashp.cxx,v $
10 * $Revision: 1.51.52.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/svdoashp.hxx>
34 #include "unoapi.hxx"
35 #include <svx/unoshape.hxx>
36 #include <ucbhelper/content.hxx>
37 #include <ucbhelper/contentbroker.hxx>
38 #include <unotools/datetime.hxx>
39 #include <sfx2/lnkbase.hxx>
40 #include <tools/urlobj.hxx>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/drawing/XShape.hpp>
43 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
44 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/awt/Rectangle.hpp>
47 #include "unopolyhelper.hxx"
48 #include <comphelper/processfactory.hxx>
49 #include <svtools/urihelper.hxx>
50 #include <com/sun/star/uno/Sequence.h>
51 #include <svx/svdogrp.hxx>
52 #include <vcl/salbtype.hxx> // FRound
53 #include <svx/svddrag.hxx>
54 #include <svx/xpool.hxx>
55 #include <svx/xpoly.hxx>
56 #include <svx/svdmodel.hxx>
57 #include <svx/svdpage.hxx>
58 #include "svditer.hxx"
59 #include <svx/svdobj.hxx>
60 #include <svx/svdtrans.hxx>
61 #include <svx/svdetc.hxx>
62 #include <svx/svdattrx.hxx> // NotPersistItems
63 #include <svx/svdoedge.hxx> // #32383# Die Verbinder nach Move nochmal anbroadcasten
64 #include "svdglob.hxx" // StringCache
65 #include "svdstr.hrc" // Objektname
66 #include <svx/eeitem.hxx>
67 #include "editstat.hxx"
68 #include <svx/svdoutl.hxx>
69 #include <svx/outlobj.hxx>
70 #include <svx/sdtfchim.hxx>
71 #include "../customshapes/EnhancedCustomShapeGeometry.hxx"
72 #include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
73 #include "../customshapes/EnhancedCustomShape2d.hxx"
74 #include <com/sun/star/beans/PropertyValues.hpp>
75 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
76 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
77 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
78 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
79 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
80 #include <svx/writingmodeitem.hxx>
81 #include <svx/xlnclit.hxx>
82 #include <svx/svxids.hrc>
83 #include <svtools/whiter.hxx>
84 #include <svx/sdr/properties/customshapeproperties.hxx>
85 #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
86 #include <svx/xlnclit.hxx>
87 #include <svx/xlntrit.hxx>
88 #include <svx/xfltrit.hxx>
89 #include <svx/xflclit.hxx>
90 #include <svx/xflgrit.hxx>
91 #include <svx/xflhtit.hxx>
92 #include <svx/xbtmpit.hxx>
93 #include <vcl/bmpacc.hxx>
94 #include <svx/svdview.hxx>
95 #include <basegfx/polygon/b2dpolypolygontools.hxx>
96 #include <basegfx/matrix/b2dhommatrix.hxx>
98 // #104018# replace macros above with type-safe methods
99 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
100 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::lang;
105 using namespace ::com::sun::star::beans;
106 using namespace ::com::sun::star::drawing;
108 static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape )
110 MSO_SPT eRetValue = mso_sptNil;
112 rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
113 if ( !aEngine.getLength() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) )
115 rtl::OUString sShapeType;
116 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
117 SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
118 Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
119 if ( pAny && ( *pAny >>= sShapeType ) )
120 eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType );
122 return eRetValue;
125 static sal_Bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape )
127 sal_Bool bRet = sal_False;
128 MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) );
129 switch( eShapeType )
131 case mso_sptAccentBorderCallout90 : // 2 ortho
132 case mso_sptBorderCallout1 : // 2 diag
133 case mso_sptBorderCallout2 : // 3
135 bRet = sal_True;
137 break;
139 case mso_sptCallout1 :
140 case mso_sptAccentCallout1 :
141 case mso_sptAccentBorderCallout1 :
142 case mso_sptBorderCallout90 :
143 case mso_sptCallout90 :
144 case mso_sptAccentCallout90 :
145 case mso_sptCallout2 :
146 case mso_sptCallout3 :
147 case mso_sptAccentCallout2 :
148 case mso_sptAccentCallout3 :
149 case mso_sptBorderCallout3 :
150 case mso_sptAccentBorderCallout2 :
151 case mso_sptAccentBorderCallout3 :
153 default: break;
155 return bRet;
158 ////////////////////////////////////////////////////////////////////////////////////////////////////
159 // #i37011# create a clone with all attributes changed to shadow attributes
160 // and translation executed, too.
161 SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet)
163 SdrObject* pRetval = 0L;
164 const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue());
166 if(bShadow)
168 // create a shadow representing object
169 const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue());
170 const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
171 const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
172 const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
173 pRetval = rOriginal.Clone();
174 DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)");
176 // look for used stuff
177 SdrObjListIter aIterator(rOriginal);
178 sal_Bool bLineUsed(sal_False);
179 sal_Bool bAllFillUsed(sal_False);
180 sal_Bool bSolidFillUsed(sal_False);
181 sal_Bool bGradientFillUsed(sal_False);
182 sal_Bool bHatchFillUsed(sal_False);
183 sal_Bool bBitmapFillUsed(sal_False);
185 while(aIterator.IsMore())
187 SdrObject* pObj = aIterator.Next();
188 XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue();
190 if(!bLineUsed)
192 XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue();
194 if(XLINE_NONE != eLineStyle)
196 bLineUsed = sal_True;
200 if(!bAllFillUsed)
202 if(!bSolidFillUsed && XFILL_SOLID == eFillStyle)
204 bSolidFillUsed = sal_True;
205 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
207 if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle)
209 bGradientFillUsed = sal_True;
210 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
212 if(!bHatchFillUsed && XFILL_HATCH == eFillStyle)
214 bHatchFillUsed = sal_True;
215 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
217 if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle)
219 bBitmapFillUsed = sal_True;
220 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
225 // translate to shadow coordinates
226 pRetval->NbcMove(Size(nXDist, nYDist));
228 // set items as needed
229 SfxItemSet aTempSet(rOriginalSet);
231 // SJ: #40108# :-( if a SvxWritingModeItem (Top->Bottom) is set the text object
232 // is creating a paraobject, but paraobjects can not be created without model. So
233 // we are preventing the crash by setting the writing mode always left to right,
234 // this is not bad since our shadow geometry does not contain text.
235 aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) );
237 // no shadow
238 aTempSet.Put(SdrShadowItem(sal_False));
239 aTempSet.Put(SdrShadowXDistItem(0L));
240 aTempSet.Put(SdrShadowYDistItem(0L));
242 // line color and transparence like shadow
243 if(bLineUsed)
245 aTempSet.Put(XLineColorItem(String(), aShadowColor));
246 aTempSet.Put(XLineTransparenceItem(nShadowTransparence));
249 // fill color and transparence like shadow
250 if(bSolidFillUsed)
252 aTempSet.Put(XFillColorItem(String(), aShadowColor));
253 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
256 // gradient and transparence like shadow
257 if(bGradientFillUsed)
259 XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
260 sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
261 sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
263 if(aGradient.GetStartIntens() != 100)
265 nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0));
268 if(aGradient.GetEndIntens() != 100)
270 nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0));
273 ::Color aStartColor(
274 (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256),
275 (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256),
276 (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256));
278 ::Color aEndColor(
279 (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256),
280 (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256),
281 (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256));
283 aGradient.SetStartColor(aStartColor);
284 aGradient.SetEndColor(aEndColor);
285 aTempSet.Put(XFillGradientItem(aTempSet.GetPool(), aGradient));
286 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
289 // hatch and transparence like shadow
290 if(bHatchFillUsed)
292 XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue());
293 aHatch.SetColor(aShadowColor);
294 aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch));
295 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
298 // bitmap and transparence like shadow
299 if(bBitmapFillUsed)
301 XOBitmap aFillBitmap(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetBitmapValue());
302 Bitmap aSourceBitmap(aFillBitmap.GetBitmap());
303 BitmapReadAccess* pReadAccess = aSourceBitmap.AcquireReadAccess();
305 if(!aSourceBitmap.IsEmpty())
307 if(pReadAccess)
309 Bitmap aDestBitmap(aSourceBitmap.GetSizePixel(), 24L);
310 BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess();
312 if(pWriteAccess)
314 for(sal_Int32 y(0L); y < pReadAccess->Height(); y++)
316 for(sal_Int32 x(0L); x < pReadAccess->Width(); x++)
318 sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1);
319 const BitmapColor aDestColor(
320 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L),
321 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L),
322 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L));
323 pWriteAccess->SetPixel(y, x, aDestColor);
327 aDestBitmap.ReleaseAccess(pWriteAccess);
328 aFillBitmap.SetBitmap(aDestBitmap);
331 aSourceBitmap.ReleaseAccess(pReadAccess);
335 aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aFillBitmap));
336 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
339 // set attributes and paint shadow object
340 pRetval->SetMergedItemSet( aTempSet );
342 return pRetval;
345 ////////////////////////////////////////////////////////////////////////////////////////////////////
347 Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine( const SdrObjCustomShape* pCustomShape )
349 Reference< XCustomShapeEngine > xCustomShapeEngine;
350 String aEngine(((SdrCustomShapeEngineItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue());
351 if ( !aEngine.Len() )
352 aEngine = String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
354 Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
356 Reference< XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
357 if ( aXShape.is() )
359 if ( aEngine.Len() && xFactory.is() )
361 Sequence< Any > aArgument( 1 );
362 Sequence< PropertyValue > aPropValues( 1 );
363 aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" );
364 aPropValues[ 0 ].Value <<= aXShape;
365 aArgument[ 0 ] <<= aPropValues;
366 Reference< XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
367 if ( xInterface.is() )
368 xCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY );
371 return xCustomShapeEngine;
373 const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
375 if ( !mXRenderedCustomShape.is() )
377 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) );
378 if ( xCustomShapeEngine.is() )
379 ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render();
381 SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
382 ? GetSdrObjectFromXShape( mXRenderedCustomShape )
383 : NULL;
384 return pRenderedCustomShape;
387 // #i37011# Shadow geometry creation
388 const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
390 if(!mpLastShadowGeometry)
392 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
393 if(pSdrObject)
395 const SfxItemSet& rOriginalSet = GetObjectItemSet();
396 const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue());
398 if(bShadow)
400 // create a clone with all attributes changed to shadow attributes
401 // and translation executed, too.
402 ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
407 return mpLastShadowGeometry;
410 sal_Bool SdrObjCustomShape::IsTextPath() const
412 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
413 sal_Bool bTextPathOn = sal_False;
414 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
415 Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
416 if ( pAny )
417 *pAny >>= bTextPathOn;
418 return bTextPathOn;
421 sal_Bool SdrObjCustomShape::UseNoFillStyle() const
423 sal_Bool bRet = sal_False;
424 rtl::OUString sShapeType;
425 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
426 SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
427 Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
428 if ( pAny )
429 *pAny >>= sShapeType;
430 bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == 0;
432 return bRet;
435 sal_Bool SdrObjCustomShape::IsMirroredX() const
437 sal_Bool bMirroredX = sal_False;
438 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
439 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
440 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
441 if ( pAny )
442 *pAny >>= bMirroredX;
443 return bMirroredX;
445 sal_Bool SdrObjCustomShape::IsMirroredY() const
447 sal_Bool bMirroredY = sal_False;
448 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
449 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
450 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
451 if ( pAny )
452 *pAny >>= bMirroredY;
453 return bMirroredY;
455 void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX )
457 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
458 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
459 //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
460 PropertyValue aPropVal;
461 aPropVal.Name = sMirroredX;
462 aPropVal.Value <<= bMirrorX;
463 aGeometryItem.SetPropertyValue( aPropVal );
464 SetMergedItem( aGeometryItem );
466 void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY )
468 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
469 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
470 //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
471 PropertyValue aPropVal;
472 aPropVal.Name = sMirroredY;
473 aPropVal.Value <<= bMirrorY;
474 aGeometryItem.SetPropertyValue( aPropVal );
475 SetMergedItem( aGeometryItem );
478 double SdrObjCustomShape::GetObjectRotation() const
480 return fObjectRotation;
483 double SdrObjCustomShape::GetExtraTextRotation() const
485 const com::sun::star::uno::Any* pAny;
486 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
487 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
488 pAny = rGeometryItem.GetPropertyValueByName( sTextRotateAngle );
489 double fExtraTextRotateAngle = 0.0;
490 if ( pAny )
491 *pAny >>= fExtraTextRotateAngle;
492 return fExtraTextRotateAngle;
494 sal_Bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const
496 sal_Bool bRet = sal_False;
497 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); // a candidate for being cached
498 if ( xCustomShapeEngine.is() )
500 awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
501 if ( aR.Width || aR.Height )
503 rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
504 bRet = sal_True;
507 return bRet;
509 basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const sal_Bool bBezierAllowed )
511 basegfx::B2DPolyPolygon aRetval;
512 sal_Bool bRet = sal_False;
513 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
514 if ( xCustomShapeEngine.is() )
516 com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
519 aRetval = SvxConvertPolyPolygonBezierToB2DPolyPolygon( &aBezierCoords );
520 if ( !bBezierAllowed && aRetval.areControlPointsUsed())
522 aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval);
524 bRet = sal_True;
526 catch ( const com::sun::star::lang::IllegalArgumentException )
530 return aRetval;
533 std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const
535 std::vector< SdrCustomShapeInteraction > xRet;
538 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
539 if ( xCustomShapeEngine.is() )
541 int i;
542 Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() );
543 for ( i = 0; i < xInteractionHandles.getLength(); i++ )
545 if ( xInteractionHandles[ i ].is() )
547 SdrCustomShapeInteraction aSdrCustomShapeInteraction;
548 aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
549 aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
551 sal_Int32 nMode = 0;
552 switch( ImpGetCustomShapeType( *this ) )
554 case mso_sptAccentBorderCallout90 : // 2 ortho
556 if ( !i )
557 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
558 else if ( i == 1)
559 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4;
561 break;
563 case mso_sptWedgeRectCallout :
564 case mso_sptWedgeRRectCallout :
565 case mso_sptCloudCallout :
566 case mso_sptWedgeEllipseCallout :
568 if ( !i )
569 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED;
571 break;
573 case mso_sptBorderCallout1 : // 2 diag
575 if ( !i )
576 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
577 else if ( i == 1 )
578 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
580 break;
581 case mso_sptBorderCallout2 : // 3
583 if ( !i )
584 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
585 else if ( i == 2 )
586 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
588 break;
589 case mso_sptCallout90 :
590 case mso_sptAccentCallout90 :
591 case mso_sptBorderCallout90 :
592 case mso_sptCallout1 :
593 case mso_sptCallout2 :
594 case mso_sptCallout3 :
595 case mso_sptAccentCallout1 :
596 case mso_sptAccentCallout2 :
597 case mso_sptAccentCallout3 :
598 case mso_sptBorderCallout3 :
599 case mso_sptAccentBorderCallout1 :
600 case mso_sptAccentBorderCallout2 :
601 case mso_sptAccentBorderCallout3 :
603 if ( !i )
604 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
606 break;
607 default: break;
609 aSdrCustomShapeInteraction.nMode = nMode;
610 xRet.push_back( aSdrCustomShapeInteraction );
615 catch( const uno::RuntimeException& )
618 return xRet;
621 //////////////////////////////////////////////////////////////////////////////
622 // BaseProperties section
623 #define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000)
624 #define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff)
626 sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties()
628 return new sdr::properties::CustomShapeProperties(*this);
631 TYPEINIT1(SdrObjCustomShape,SdrTextObj);
632 SdrObjCustomShape::SdrObjCustomShape() :
633 SdrTextObj(),
634 fObjectRotation( 0.0 ),
635 mpLastShadowGeometry(0L)
637 bTextFrame = TRUE;
640 SdrObjCustomShape::~SdrObjCustomShape()
642 // delete buffered display geometry
643 InvalidateRenderGeometry();
646 void SdrObjCustomShape::MergeDefaultAttributes( const rtl::OUString* pType )
648 PropertyValue aPropVal;
649 rtl::OUString sShapeType;
650 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
651 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
652 if ( pType && pType->getLength() )
654 sal_Int32 nType = pType->toInt32();
655 if ( nType )
656 sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
657 else
658 sShapeType = *pType;
660 aPropVal.Name = sType;
661 aPropVal.Value <<= sShapeType;
662 aGeometryItem.SetPropertyValue( aPropVal );
664 else
666 Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
667 if ( pAny )
668 *pAny >>= sShapeType;
670 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
672 const sal_Int32* pDefData = NULL;
673 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
674 if ( pDefCustomShape )
675 pDefData = pDefCustomShape->pDefData;
677 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
679 //////////////////////
680 // AdjustmentValues //
681 //////////////////////
682 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
683 const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
684 if ( pAny )
685 *pAny >>= seqAdjustmentValues;
686 if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values
688 // first check if there are adjustment values are to be appended
689 sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
690 sal_Int32 nAdjustmentDefaults = *pDefData++;
691 if ( nAdjustmentDefaults > nAdjustmentValues )
693 seqAdjustmentValues.realloc( nAdjustmentDefaults );
694 for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
696 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
697 seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // com::sun::star::beans::PropertyState_DEFAULT_VALUE;
700 // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
701 sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues;
702 for ( i = 0; i < nCount; i++ )
704 if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE )
705 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
708 aPropVal.Name = sAdjustmentValues;
709 aPropVal.Value <<= seqAdjustmentValues;
710 aGeometryItem.SetPropertyValue( aPropVal );
712 ///////////////
713 // Coordsize //
714 ///////////////
715 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
716 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
717 com::sun::star::awt::Rectangle aViewBox;
718 if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
720 if ( pDefCustomShape )
722 aViewBox.X = 0;
723 aViewBox.Y = 0;
724 aViewBox.Width = pDefCustomShape->nCoordWidth;
725 aViewBox.Height= pDefCustomShape->nCoordHeight;
726 aPropVal.Name = sViewBox;
727 aPropVal.Value <<= aViewBox;
728 aGeometryItem.SetPropertyValue( aPropVal );
732 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
734 //////////////////////
735 // Path/Coordinates //
736 //////////////////////
737 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
738 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
739 if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
741 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
743 sal_Int32 i, nCount = pDefCustomShape->nVertices;
744 seqCoordinates.realloc( nCount );
745 for ( i = 0; i < nCount; i++ )
747 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
748 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
750 aPropVal.Name = sCoordinates;
751 aPropVal.Value <<= seqCoordinates;
752 aGeometryItem.SetPropertyValue( sPath, aPropVal );
755 /////////////////////
756 // Path/GluePoints //
757 /////////////////////
758 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
759 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
760 if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
762 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
763 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
764 seqGluePoints.realloc( nCount );
765 for ( i = 0; i < nCount; i++ )
767 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
768 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
770 aPropVal.Name = sGluePoints;
771 aPropVal.Value <<= seqGluePoints;
772 aGeometryItem.SetPropertyValue( sPath, aPropVal );
775 ///////////////////
776 // Path/Segments //
777 ///////////////////
778 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
779 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
780 if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
782 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
784 sal_Int32 i, nCount = pDefCustomShape->nElements;
785 seqSegments.realloc( nCount );
786 for ( i = 0; i < nCount; i++ )
788 EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ];
789 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
790 switch( nSDat >> 8 )
792 case 0x00 :
794 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
795 rSegInfo.Count = nSDat & 0xff;
796 if ( !rSegInfo.Count )
797 rSegInfo.Count = 1;
799 break;
800 case 0x20 :
802 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
803 rSegInfo.Count = nSDat & 0xff;
804 if ( !rSegInfo.Count )
805 rSegInfo.Count = 1;
807 break;
808 case 0x40 :
810 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
811 rSegInfo.Count = nSDat & 0xff;
812 if ( !rSegInfo.Count )
813 rSegInfo.Count = 1;
815 break;
816 case 0x60 :
818 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
819 rSegInfo.Count = 0;
821 break;
822 case 0x80 :
824 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
825 rSegInfo.Count = 0;
827 break;
828 case 0xa1 :
830 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
831 rSegInfo.Count = ( nSDat & 0xff ) / 3;
833 break;
834 case 0xa2 :
836 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
837 rSegInfo.Count = ( nSDat & 0xff ) / 3;
839 break;
840 case 0xa3 :
842 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
843 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
845 break;
846 case 0xa4 :
848 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
849 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
851 break;
852 case 0xa5 :
854 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
855 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
857 break;
858 case 0xa6 :
860 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
861 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
863 break;
864 case 0xa7 :
866 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
867 rSegInfo.Count = nSDat & 0xff;
869 break;
870 case 0xa8 :
872 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
873 rSegInfo.Count = nSDat & 0xff;
875 break;
876 case 0xaa :
878 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
879 rSegInfo.Count = 0;
881 break;
882 case 0xab :
884 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
885 rSegInfo.Count = 0;
887 break;
888 default:
889 case 0xf8 :
891 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
892 rSegInfo.Count = nSDat;
894 break;
897 aPropVal.Name = sSegments;
898 aPropVal.Value <<= seqSegments;
899 aGeometryItem.SetPropertyValue( sPath, aPropVal );
902 ///////////////////
903 // Path/StretchX //
904 ///////////////////
905 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
906 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
907 if ( !pAny && pDefCustomShape )
909 sal_Int32 nXRef = pDefCustomShape->nXRef;
910 if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
912 aPropVal.Name = sStretchX;
913 aPropVal.Value <<= nXRef;
914 aGeometryItem.SetPropertyValue( sPath, aPropVal );
918 ///////////////////
919 // Path/StretchY //
920 ///////////////////
921 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
922 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
923 if ( !pAny && pDefCustomShape )
925 sal_Int32 nYRef = pDefCustomShape->nYRef;
926 if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
928 aPropVal.Name = sStretchY;
929 aPropVal.Value <<= nYRef;
930 aGeometryItem.SetPropertyValue( sPath, aPropVal );
934 /////////////////////
935 // Path/TextFrames //
936 /////////////////////
937 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
938 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
939 if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
941 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames;
943 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
944 seqTextFrames.realloc( nCount );
945 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
946 for ( i = 0; i < nCount; i++, pRectangles++ )
948 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA );
949 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
950 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA );
951 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
953 aPropVal.Name = sTextFrames;
954 aPropVal.Value <<= seqTextFrames;
955 aGeometryItem.SetPropertyValue( sPath, aPropVal );
958 ///////////////
959 // Equations //
960 ///////////////
961 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
962 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
963 if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
965 com::sun::star::uno::Sequence< rtl::OUString > seqEquations;
967 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
968 seqEquations.realloc( nCount );
969 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
970 for ( i = 0; i < nCount; i++, pData++ )
971 seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
972 aPropVal.Name = sEquations;
973 aPropVal.Value <<= seqEquations;
974 aGeometryItem.SetPropertyValue( aPropVal );
977 /////////////
978 // Handles //
979 /////////////
980 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
981 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
982 if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
984 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles;
986 sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
987 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
988 seqHandles.realloc( nCount );
989 for ( i = 0; i < nCount; i++, pData++ )
991 sal_Int32 nPropertiesNeeded = 1; // position is always needed
992 sal_Int32 nFlags = pData->nFlags;
993 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
994 nPropertiesNeeded++;
995 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
996 nPropertiesNeeded++;
997 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
998 nPropertiesNeeded++;
999 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1001 nPropertiesNeeded++;
1002 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1004 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1005 nPropertiesNeeded++;
1006 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1007 nPropertiesNeeded++;
1010 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1012 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1013 nPropertiesNeeded++;
1014 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1015 nPropertiesNeeded++;
1016 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1017 nPropertiesNeeded++;
1018 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1019 nPropertiesNeeded++;
1022 n = 0;
1023 com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ];
1024 rPropValues.realloc( nPropertiesNeeded );
1026 // POSITION
1028 const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
1029 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
1030 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
1031 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
1032 rPropValues[ n ].Name = sPosition;
1033 rPropValues[ n++ ].Value <<= aPosition;
1035 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1037 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1038 sal_Bool bMirroredX = sal_True;
1039 rPropValues[ n ].Name = sMirroredX;
1040 rPropValues[ n++ ].Value <<= bMirroredX;
1042 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1044 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1045 sal_Bool bMirroredY = sal_True;
1046 rPropValues[ n ].Name = sMirroredY;
1047 rPropValues[ n++ ].Value <<= bMirroredY;
1049 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1051 const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
1052 sal_Bool bSwitched = sal_True;
1053 rPropValues[ n ].Name = sSwitched;
1054 rPropValues[ n++ ].Value <<= bSwitched;
1056 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1058 const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
1059 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
1060 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
1061 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True );
1062 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
1063 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
1064 rPropValues[ n ].Name = sPolar;
1065 rPropValues[ n++ ].Value <<= aCenter;
1066 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1068 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1070 const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
1071 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
1072 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
1073 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
1074 rPropValues[ n ].Name = sRadiusRangeMinimum;
1075 rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
1077 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1079 const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
1080 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
1081 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
1082 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1083 rPropValues[ n ].Name = sRadiusRangeMaximum;
1084 rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
1088 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1090 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1092 const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
1093 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
1094 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
1095 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
1096 rPropValues[ n ].Name = sRangeXMinimum;
1097 rPropValues[ n++ ].Value <<= aRangeXMinimum;
1099 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1101 const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
1102 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
1103 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
1104 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1105 rPropValues[ n ].Name = sRangeXMaximum;
1106 rPropValues[ n++ ].Value <<= aRangeXMaximum;
1108 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1110 const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
1111 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
1112 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
1113 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
1114 rPropValues[ n ].Name = sRangeYMinimum;
1115 rPropValues[ n++ ].Value <<= aRangeYMinimum;
1117 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1119 const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
1120 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
1121 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
1122 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
1123 rPropValues[ n ].Name = sRangeYMaximum;
1124 rPropValues[ n++ ].Value <<= aRangeYMaximum;
1128 aPropVal.Name = sHandles;
1129 aPropVal.Value <<= seqHandles;
1130 aGeometryItem.SetPropertyValue( aPropVal );
1132 SetMergedItem( aGeometryItem );
1135 sal_Bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const
1137 sal_Bool bIsDefaultGeometry = sal_False;
1139 PropertyValue aPropVal;
1140 rtl::OUString sShapeType;
1141 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1142 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1144 Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
1145 if ( pAny )
1146 *pAny >>= sShapeType;
1148 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1150 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
1151 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1152 switch( eDefaultType )
1154 case DEFAULT_VIEWBOX :
1156 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
1157 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
1158 com::sun::star::awt::Rectangle aViewBox;
1159 if ( pViewBox && ( *pViewBox >>= aViewBox ) )
1161 if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
1162 && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
1163 bIsDefaultGeometry = sal_True;
1166 break;
1168 case DEFAULT_PATH :
1170 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1171 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
1172 if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
1174 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
1175 if ( *pAny >>= seqCoordinates1 )
1177 sal_Int32 i, nCount = pDefCustomShape->nVertices;
1178 seqCoordinates2.realloc( nCount );
1179 for ( i = 0; i < nCount; i++ )
1181 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
1182 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
1184 if ( seqCoordinates1 == seqCoordinates2 )
1185 bIsDefaultGeometry = sal_True;
1188 else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) )
1189 bIsDefaultGeometry = sal_True;
1191 break;
1193 case DEFAULT_GLUEPOINTS :
1195 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1196 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
1197 if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
1199 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2;
1200 if ( *pAny >>= seqGluePoints1 )
1202 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
1203 seqGluePoints2.realloc( nCount );
1204 for ( i = 0; i < nCount; i++ )
1206 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
1207 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
1209 if ( seqGluePoints1 == seqGluePoints2 )
1210 bIsDefaultGeometry = sal_True;
1213 else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
1214 bIsDefaultGeometry = sal_True;
1216 break;
1218 case DEFAULT_SEGMENTS :
1220 ///////////////////
1221 // Path/Segments //
1222 ///////////////////
1223 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1224 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
1225 if ( pAny )
1227 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2;
1228 if ( *pAny >>= seqSegments1 )
1230 if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1232 sal_Int32 i, nCount = pDefCustomShape->nElements;
1233 if ( nCount )
1235 seqSegments2.realloc( nCount );
1236 for ( i = 0; i < nCount; i++ )
1238 EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ];
1239 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1240 switch( nSDat >> 8 )
1242 case 0x00 :
1244 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1245 rSegInfo.Count = nSDat & 0xff;
1246 if ( !rSegInfo.Count )
1247 rSegInfo.Count = 1;
1249 break;
1250 case 0x20 :
1252 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1253 rSegInfo.Count = nSDat & 0xff;
1254 if ( !rSegInfo.Count )
1255 rSegInfo.Count = 1;
1257 break;
1258 case 0x40 :
1260 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1261 rSegInfo.Count = nSDat & 0xff;
1262 if ( !rSegInfo.Count )
1263 rSegInfo.Count = 1;
1265 break;
1266 case 0x60 :
1268 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1269 rSegInfo.Count = 0;
1271 break;
1272 case 0x80 :
1274 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1275 rSegInfo.Count = 0;
1277 break;
1278 case 0xa1 :
1280 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
1281 rSegInfo.Count = ( nSDat & 0xff ) / 3;
1283 break;
1284 case 0xa2 :
1286 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
1287 rSegInfo.Count = ( nSDat & 0xff ) / 3;
1289 break;
1290 case 0xa3 :
1292 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
1293 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
1295 break;
1296 case 0xa4 :
1298 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
1299 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
1301 break;
1302 case 0xa5 :
1304 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
1305 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
1307 break;
1308 case 0xa6 :
1310 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
1311 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
1313 break;
1314 case 0xa7 :
1316 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
1317 rSegInfo.Count = nSDat & 0xff;
1319 break;
1320 case 0xa8 :
1322 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
1323 rSegInfo.Count = nSDat & 0xff;
1325 break;
1326 case 0xaa :
1328 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
1329 rSegInfo.Count = 0;
1331 break;
1332 case 0xab :
1334 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1335 rSegInfo.Count = 0;
1337 break;
1338 default:
1339 case 0xf8 :
1341 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
1342 rSegInfo.Count = nSDat;
1344 break;
1347 if ( seqSegments1 == seqSegments2 )
1348 bIsDefaultGeometry = sal_True;
1351 else
1353 // check if its the default segment description ( M L Z N )
1354 if ( seqSegments1.getLength() == 4 )
1356 if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO )
1357 && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO )
1358 && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
1359 && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
1360 bIsDefaultGeometry = sal_True;
1365 else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) )
1366 bIsDefaultGeometry = sal_True;
1368 break;
1370 case DEFAULT_STRETCHX :
1372 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
1373 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1374 if ( pAny && pDefCustomShape )
1376 sal_Int32 nStretchX = 0;
1377 if ( *pAny >>= nStretchX )
1379 if ( pDefCustomShape->nXRef == nStretchX )
1380 bIsDefaultGeometry = sal_True;
1383 else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1384 bIsDefaultGeometry = sal_True;
1386 break;
1388 case DEFAULT_STRETCHY :
1390 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
1391 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1392 if ( pAny && pDefCustomShape )
1394 sal_Int32 nStretchY = 0;
1395 if ( *pAny >>= nStretchY )
1397 if ( pDefCustomShape->nYRef == nStretchY )
1398 bIsDefaultGeometry = sal_True;
1401 else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1402 bIsDefaultGeometry = sal_True;
1404 break;
1406 case DEFAULT_EQUATIONS :
1408 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
1409 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1410 if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1412 com::sun::star::uno::Sequence< rtl::OUString > seqEquations1, seqEquations2;
1413 if ( *pAny >>= seqEquations1 )
1415 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1416 seqEquations2.realloc( nCount );
1418 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1419 for ( i = 0; i < nCount; i++, pData++ )
1420 seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1422 if ( seqEquations1 == seqEquations2 )
1423 bIsDefaultGeometry = sal_True;
1426 else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) )
1427 bIsDefaultGeometry = sal_True;
1429 break;
1431 case DEFAULT_TEXTFRAMES :
1433 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) );
1434 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1435 if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1437 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2;
1438 if ( *pAny >>= seqTextFrames1 )
1440 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1441 seqTextFrames2.realloc( nCount );
1442 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1443 for ( i = 0; i < nCount; i++, pRectangles++ )
1445 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1446 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1447 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1448 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1450 if ( seqTextFrames1 == seqTextFrames2 )
1451 bIsDefaultGeometry = sal_True;
1454 else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) )
1455 bIsDefaultGeometry = sal_True;
1457 break;
1459 case DEFAULT_HANDLES :
1461 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
1462 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1463 if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1465 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2;
1466 if ( *pAny >>= seqHandles1 )
1468 sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
1469 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1470 seqHandles2.realloc( nCount );
1471 for ( i = 0; i < nCount; i++, pData++ )
1473 sal_Int32 nPropertiesNeeded = 1; // position is always needed
1474 sal_Int32 nFlags = pData->nFlags;
1475 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1476 nPropertiesNeeded++;
1477 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1478 nPropertiesNeeded++;
1479 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1480 nPropertiesNeeded++;
1481 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1483 nPropertiesNeeded++;
1484 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1486 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1487 nPropertiesNeeded++;
1488 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1489 nPropertiesNeeded++;
1492 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1494 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1495 nPropertiesNeeded++;
1496 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1497 nPropertiesNeeded++;
1498 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1499 nPropertiesNeeded++;
1500 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1501 nPropertiesNeeded++;
1504 n = 0;
1505 com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ];
1506 rPropValues.realloc( nPropertiesNeeded );
1508 // POSITION
1510 const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
1511 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
1512 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
1513 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
1514 rPropValues[ n ].Name = sPosition;
1515 rPropValues[ n++ ].Value <<= aPosition;
1517 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
1519 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1520 sal_Bool bMirroredX = sal_True;
1521 rPropValues[ n ].Name = sMirroredX;
1522 rPropValues[ n++ ].Value <<= bMirroredX;
1524 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
1526 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1527 sal_Bool bMirroredY = sal_True;
1528 rPropValues[ n ].Name = sMirroredY;
1529 rPropValues[ n++ ].Value <<= bMirroredY;
1531 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
1533 const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
1534 sal_Bool bSwitched = sal_True;
1535 rPropValues[ n ].Name = sSwitched;
1536 rPropValues[ n++ ].Value <<= bSwitched;
1538 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
1540 const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
1541 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
1542 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
1543 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True );
1544 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
1545 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
1546 rPropValues[ n ].Name = sPolar;
1547 rPropValues[ n++ ].Value <<= aCenter;
1548 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
1550 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1552 const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
1553 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
1554 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
1555 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
1556 rPropValues[ n ].Name = sRadiusRangeMinimum;
1557 rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
1559 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1561 const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
1562 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
1563 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
1564 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1565 rPropValues[ n ].Name = sRadiusRangeMaximum;
1566 rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
1570 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
1572 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1574 const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
1575 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
1576 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
1577 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
1578 rPropValues[ n ].Name = sRangeXMinimum;
1579 rPropValues[ n++ ].Value <<= aRangeXMinimum;
1581 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1583 const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
1584 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
1585 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
1586 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
1587 rPropValues[ n ].Name = sRangeXMaximum;
1588 rPropValues[ n++ ].Value <<= aRangeXMaximum;
1590 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
1592 const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
1593 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
1594 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
1595 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
1596 rPropValues[ n ].Name = sRangeYMinimum;
1597 rPropValues[ n++ ].Value <<= aRangeYMinimum;
1599 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
1601 const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
1602 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
1603 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
1604 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
1605 rPropValues[ n ].Name = sRangeYMaximum;
1606 rPropValues[ n++ ].Value <<= aRangeYMaximum;
1610 if ( seqHandles1 == seqHandles2 )
1611 bIsDefaultGeometry = sal_True;
1614 else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) )
1615 bIsDefaultGeometry = sal_True;
1617 break;
1619 return bIsDefaultGeometry;
1622 void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1624 rInfo.bResizeFreeAllowed=fObjectRotation == 0.0;
1625 rInfo.bResizePropAllowed=TRUE;
1626 rInfo.bRotateFreeAllowed=TRUE;
1627 rInfo.bRotate90Allowed =TRUE;
1628 rInfo.bMirrorFreeAllowed=TRUE;
1629 rInfo.bMirror45Allowed =TRUE;
1630 rInfo.bMirror90Allowed =TRUE;
1631 rInfo.bTransparenceAllowed = FALSE;
1632 rInfo.bGradientAllowed = FALSE;
1633 rInfo.bShearAllowed =TRUE;
1634 rInfo.bEdgeRadiusAllowed=FALSE;
1635 rInfo.bNoContortion =TRUE;
1637 // #i37011#
1638 if ( mXRenderedCustomShape.is() )
1640 const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1641 if ( pRenderedCustomShape )
1643 // #i37262#
1644 // Iterate self over the contained objects, since there are combinations of
1645 // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1646 // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1647 SdrObjListIter aIterator(*pRenderedCustomShape);
1648 while(aIterator.IsMore())
1650 SdrObject* pCandidate = aIterator.Next();
1651 SdrObjTransformInfoRec aInfo;
1652 pCandidate->TakeObjInfo(aInfo);
1654 // set path and poly conversion if one is possible since
1655 // this object will first be broken
1656 const sal_Bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
1657 if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
1659 rInfo.bCanConvToPath = bCanConvToPathOrPoly;
1662 if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
1664 rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
1667 if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
1669 rInfo.bCanConvToContour = aInfo.bCanConvToContour;
1672 if( !rInfo.bShearAllowed )
1673 rInfo.bShearAllowed=FALSE;
1674 if( !aInfo.bEdgeRadiusAllowed )
1675 rInfo.bEdgeRadiusAllowed=FALSE;
1681 void SdrObjCustomShape::SetModel(SdrModel* pNewModel)
1683 SdrTextObj::SetModel(pNewModel);
1684 mXRenderedCustomShape.clear();
1687 UINT16 SdrObjCustomShape::GetObjIdentifier() const
1689 return UINT16(OBJ_CUSTOMSHAPE);
1692 ////////////////////////////////////////////////////////////////////////////////////////////////////
1693 ////////////////////////////////////////////////////////////////////////////////////////////////////
1694 ////////////////////////////////////////////////////////////////////////////////////////////////////
1696 void SdrObjCustomShape::RecalcSnapRect()
1698 SdrTextObj::RecalcSnapRect();
1700 const Rectangle& SdrObjCustomShape::GetSnapRect() const
1702 return SdrTextObj::GetSnapRect();
1704 const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const
1706 return SdrTextObj::GetCurrentBoundRect();
1708 const Rectangle& SdrObjCustomShape::GetLogicRect() const
1710 return SdrTextObj::GetLogicRect();
1712 void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect )
1714 aRect=rRect;
1715 ImpJustifyRect(aRect);
1716 InvalidateRenderGeometry();
1717 Rectangle aTextBound( aRect );
1718 if ( GetTextBounds( aTextBound ) )
1720 if ( pModel==NULL || !pModel->IsPasteResize() )
1722 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1723 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1724 long nTWdt=aTextBound.GetWidth ()-1-nHDist; if (nTWdt<0) nTWdt=0;
1725 long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1726 if ( IsAutoGrowWidth() )
1727 NbcSetMinTextFrameWidth( nTWdt );
1728 if ( IsAutoGrowHeight() )
1729 NbcSetMinTextFrameHeight( nTHgt );
1730 NbcAdjustTextFrameWidthAndHeight();
1733 ImpCheckShear();
1734 SetRectsDirty();
1735 SetChanged();
1737 void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect )
1739 Rectangle aBoundRect0;
1740 if ( pUserCall )
1741 aBoundRect0 = GetLastBoundRect();
1742 NbcSetSnapRect( rRect );
1743 BroadcastObjectChange();
1744 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1746 void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect )
1748 aRect = rRect;
1749 ImpJustifyRect( aRect );
1750 InvalidateRenderGeometry();
1751 Rectangle aTextBound( aRect );
1752 if ( GetTextBounds( aTextBound ) )
1754 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1755 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1757 long nTWdt=aTextBound.GetWidth()-1-nHDist; if (nTWdt<0) nTWdt=0;
1758 long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1759 if ( IsAutoGrowWidth() )
1760 NbcSetMinTextFrameWidth( nTWdt );
1761 if ( IsAutoGrowHeight() )
1762 NbcSetMinTextFrameHeight( nTHgt );
1763 NbcAdjustTextFrameWidthAndHeight();
1765 SetRectsDirty();
1766 SetChanged();
1768 void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect )
1770 Rectangle aBoundRect0;
1771 if ( pUserCall )
1772 aBoundRect0 = GetLastBoundRect();
1773 NbcSetLogicRect(rRect);
1774 BroadcastObjectChange();
1775 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1777 void SdrObjCustomShape::Move( const Size& rSiz )
1779 if ( rSiz.Width() || rSiz.Height() )
1781 Rectangle aBoundRect0;
1782 if ( pUserCall )
1783 aBoundRect0 = GetLastBoundRect();
1784 // #110094#-14 SendRepaintBroadcast();
1785 NbcMove(rSiz);
1786 SetChanged();
1787 BroadcastObjectChange();
1788 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1791 void SdrObjCustomShape::NbcMove( const Size& rSiz )
1793 SdrTextObj::NbcMove( rSiz );
1794 if ( mXRenderedCustomShape.is() )
1796 SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1797 if ( pRenderedCustomShape )
1799 // #i97149# the visualisation shape needs to be informed
1800 // about change, too
1801 pRenderedCustomShape->ActionChanged();
1802 pRenderedCustomShape->NbcMove( rSiz );
1806 // #i37011# adapt geometry shadow
1807 if(mpLastShadowGeometry)
1809 mpLastShadowGeometry->NbcMove( rSiz );
1812 void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact )
1814 SdrTextObj::Resize( rRef, xFact, yFact );
1817 void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
1819 Fraction xFact( rxFact );
1820 Fraction yFact( ryFact );
1822 // taking care of handles that should not been changed
1823 Rectangle aOld( aRect );
1824 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1826 SdrTextObj::NbcResize( rRef, xFact, yFact );
1828 if ( ( xFact.GetNumerator() != xFact.GetDenominator() )
1829 || ( yFact.GetNumerator()!= yFact.GetDenominator() ) )
1831 if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) ||
1832 ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) )
1834 SetMirroredX( IsMirroredX() == sal_False );
1836 if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) ||
1837 ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) )
1839 SetMirroredY( IsMirroredY() == sal_False );
1843 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
1844 while ( aIter != aInteractionHandles.end() )
1848 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
1849 aIter->xInteraction->setControllerPosition( aIter->aPosition );
1850 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
1852 sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left();
1853 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
1855 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
1857 sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top();
1858 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
1861 catch ( const uno::RuntimeException& )
1864 aIter++;
1866 InvalidateRenderGeometry();
1868 void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs )
1870 sal_Bool bMirroredX = IsMirroredX();
1871 sal_Bool bMirroredY = IsMirroredY();
1873 fObjectRotation = fmod( fObjectRotation, 360.0 );
1874 if ( fObjectRotation < 0 )
1875 fObjectRotation = 360 + fObjectRotation;
1877 // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1878 // has to be applied to the text object (which is internally using aGeo.nWink).
1879 SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink, // retrieving the unrotated text object
1880 sin( (-aGeo.nDrehWink) * F_PI18000 ),
1881 cos( (-aGeo.nDrehWink) * F_PI18000 ) );
1882 aGeo.nDrehWink = 0; // resetting aGeo data
1883 aGeo.RecalcSinCos();
1885 long nW = (long)( fObjectRotation * 100 ); // applying our object rotation
1886 if ( bMirroredX )
1887 nW = 36000 - nW;
1888 if ( bMirroredY )
1889 nW = 18000 - nW;
1890 nW = nW % 36000;
1891 if ( nW < 0 )
1892 nW = 36000 + nW;
1893 SdrTextObj::NbcRotate( aRect.TopLeft(), nW, // applying text rotation
1894 sin( nW * F_PI18000 ),
1895 cos( nW * F_PI18000 ) );
1897 int nSwap = 0;
1898 if ( bMirroredX )
1899 nSwap ^= 1;
1900 if ( bMirroredY )
1901 nSwap ^= 1;
1903 double fWink = nWink; // updating to our new object rotation
1904 fWink /= 100.0;
1905 fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 );
1906 if ( fObjectRotation < 0 )
1907 fObjectRotation = 360 + fObjectRotation;
1909 SdrTextObj::NbcRotate( rRef, nWink, sn, cs ); // applying text rotation
1910 InvalidateRenderGeometry();
1913 void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
1915 // storing horizontal and vertical flipping without modifying the rotate angle
1917 sal_Bool bHorz = sal_False;
1918 sal_Bool bVert = sal_False;
1919 if ( rRef1.X() == rRef2.X() )
1920 bHorz = sal_True;
1921 if ( rRef1.Y() == rRef2.Y() )
1922 bVert = sal_True;
1923 if ( !bHorz && !bVert )
1924 bHorz = bVert = sal_True;
1926 if ( bHorz || bVert )
1928 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1930 /////////////////
1931 // "MirroredX" //
1932 /////////////////
1933 if ( bHorz )
1935 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1936 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
1937 if ( pAny )
1939 sal_Bool bFlip = sal_Bool();
1940 if ( *pAny >>= bFlip )
1942 if ( bFlip )
1943 bHorz = sal_False;
1946 PropertyValue aPropVal;
1947 aPropVal.Name = sMirroredX;
1948 aPropVal.Value <<= bHorz;
1949 aGeometryItem.SetPropertyValue( aPropVal );
1952 /////////////////
1953 // "MirroredY" //
1954 /////////////////
1955 if ( bVert )
1957 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1958 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
1959 if ( pAny )
1961 sal_Bool bFlip = sal_Bool();
1962 if ( *pAny >>= bFlip )
1964 if ( bFlip )
1965 bVert = sal_False;
1968 PropertyValue aPropVal;
1969 aPropVal.Name = sMirroredY;
1970 aPropVal.Value <<= bVert;
1971 aGeometryItem.SetPropertyValue( aPropVal );
1973 SetMergedItem( aGeometryItem );
1975 SdrTextObj::NbcMirror( rRef1, rRef2 );
1976 InvalidateRenderGeometry();
1979 void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
1981 SdrTextObj::Shear( rRef, nWink, tn, bVShear );
1982 InvalidateRenderGeometry();
1984 void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
1986 long nDrehWink = aGeo.nDrehWink;
1987 if ( nDrehWink )
1989 aGeo.nDrehWink = -nDrehWink;
1990 aGeo.RecalcSinCos();
1991 NbcRotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
1993 SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
1994 if ( nDrehWink )
1996 aGeo.nDrehWink = nDrehWink;
1997 aGeo.RecalcSinCos();
1998 Rotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
2000 InvalidateRenderGeometry();
2003 ////////////////////////////////////////////////////////////////////////////////////////////////////
2005 SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(USHORT nPosNum) const
2007 INT32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
2009 // #i25616#
2010 if(!LineIsOutsideGeometry())
2012 nWdt++;
2013 nWdt /= 2;
2016 Point aPt;
2017 switch (nPosNum) {
2018 case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break;
2019 case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break;
2020 case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
2021 case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break;
2023 if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
2024 if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
2025 aPt-=GetSnapRect().Center();
2026 SdrGluePoint aGP(aPt);
2027 aGP.SetPercent(FALSE);
2028 return aGP;
2031 ////////////////////////////////////////////////////////////////////////////////////////////////////
2033 // #i38892#
2034 void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
2036 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
2038 if(pSdrObject)
2040 const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
2042 if(pSource && pSource->GetCount())
2044 if(!SdrTextObj::GetGluePointList())
2046 SdrTextObj::ForceGluePointList();
2049 const SdrGluePointList* pList = SdrTextObj::GetGluePointList();
2051 if(pList)
2053 SdrGluePointList aNewList;
2054 sal_uInt16 a;
2056 for(a = 0; a < pSource->GetCount(); a++)
2058 SdrGluePoint aCopy((*pSource)[a]);
2059 aCopy.SetUserDefined(FALSE);
2060 aNewList.Insert(aCopy);
2063 sal_Bool bMirroredX = IsMirroredX();
2064 sal_Bool bMirroredY = IsMirroredY();
2066 long nShearWink = aGeo.nShearWink;
2067 double fTan = aGeo.nTan;
2069 if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY )
2071 Polygon aPoly( aRect );
2072 if( nShearWink )
2074 USHORT nPointCount=aPoly.GetSize();
2075 for (USHORT i=0; i<nPointCount; i++)
2076 ShearPoint(aPoly[i],aRect.Center(), fTan, FALSE );
2078 if ( aGeo.nDrehWink )
2079 aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 );
2081 Rectangle aBoundRect( aPoly.GetBoundRect() );
2082 sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left();
2083 sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top();
2085 if (nShearWink&&(bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX))
2087 nShearWink = -nShearWink;
2088 fTan = -fTan;
2091 Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
2092 for ( a = 0; a < aNewList.GetCount(); a++ )
2094 SdrGluePoint& rPoint = aNewList[ a ];
2095 Point aGlue( rPoint.GetPos() );
2096 if ( nShearWink )
2097 ShearPoint( aGlue, aRef, fTan );
2099 RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) );
2100 if ( bMirroredX )
2101 aGlue.X() = aRect.GetWidth() - aGlue.X();
2102 if ( bMirroredY )
2103 aGlue.Y() = aRect.GetHeight() - aGlue.Y();
2104 aGlue.X() -= nXDiff;
2105 aGlue.Y() -= nYDiff;
2106 rPoint.SetPos( aGlue );
2110 for(a = 0; a < pList->GetCount(); a++)
2112 const SdrGluePoint& rCandidate = (*pList)[a];
2114 if(rCandidate.IsUserDefined())
2116 aNewList.Insert(rCandidate);
2120 // copy new list to local. This is NOT very convenient behaviour, the local
2121 // GluePointList should not be set, but be delivered by using GetGluePointList(),
2122 // maybe on demand. Since the local object is changed here, this is assumed to
2123 // be a result of GetGluePointList and thus the list is copied
2124 if(pPlusData)
2126 *pPlusData->pGluePoints = aNewList;
2133 // #i38892#
2134 const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const
2136 ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded();
2137 return SdrTextObj::GetGluePointList();
2140 // #i38892#
2141 //SdrGluePointList* SdrObjCustomShape::GetGluePointList()
2143 // ImpCheckCustomGluePointsAreAdded();
2144 // return SdrTextObj::GetGluePointList();
2147 // #i38892#
2148 SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
2150 if(SdrTextObj::ForceGluePointList())
2152 ImpCheckCustomGluePointsAreAdded();
2153 return SdrTextObj::ForceGluePointList();
2155 else
2157 return 0L;
2161 ////////////////////////////////////////////////////////////////////////////////////////////////////
2162 ////////////////////////////////////////////////////////////////////////////////////////////////////
2163 ////////////////////////////////////////////////////////////////////////////////////////////////////
2165 sal_uInt32 SdrObjCustomShape::GetHdlCount() const
2167 const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
2168 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2169 return ( aInteractionHandles.size() + nBasicHdlCount );
2172 SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
2174 SdrHdl* pH = NULL;
2175 const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
2177 if ( nHdlNum < nBasicHdlCount )
2178 pH = SdrTextObj::GetHdl( nHdlNum );
2179 else
2181 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2182 const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);
2184 if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2186 if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
2190 com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
2191 pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 );
2192 pH->SetPointNum( nCustomShapeHdlNum );
2193 pH->SetObj( (SdrObject*)this );
2195 catch ( const uno::RuntimeException& )
2201 return pH;
2204 ////////////////////////////////////////////////////////////////////////////////////////////////////
2206 bool SdrObjCustomShape::hasSpecialDrag() const
2208 return true;
2211 bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const
2213 const SdrHdl* pHdl = rDrag.GetHdl();
2215 if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind())
2217 rDrag.SetEndDragChangesAttributes(true);
2218 rDrag.SetNoSnap(true);
2220 else
2222 const SdrHdl* pHdl2 = rDrag.GetHdl();
2223 const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind());
2225 switch( eHdl )
2227 case HDL_UPLFT :
2228 case HDL_UPPER :
2229 case HDL_UPRGT :
2230 case HDL_LEFT :
2231 case HDL_RIGHT :
2232 case HDL_LWLFT :
2233 case HDL_LOWER :
2234 case HDL_LWRGT :
2235 case HDL_MOVE :
2237 break;
2239 default:
2241 return false;
2246 return true;
2249 void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const
2251 Rectangle aOld( pObj->aRect );
2252 sal_Bool bOldMirroredX( pObj->IsMirroredX() );
2253 sal_Bool bOldMirroredY( pObj->IsMirroredY() );
2255 Rectangle aNewRect( rNewRect );
2256 aNewRect.Justify();
2258 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2260 GeoStat aGeoStat( pObj->GetGeoStat() );
2261 if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() &&
2262 ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) )
2264 Point aNewPos( aNewRect.TopLeft() );
2265 if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan );
2266 if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos );
2267 aNewRect.SetPos( aNewPos );
2269 if ( aNewRect != pObj->aRect )
2271 pObj->SetLogicRect( aNewRect );
2272 pObj->InvalidateRenderGeometry();
2274 if ( rNewRect.Left() > rNewRect.Right() )
2276 Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() );
2277 Point aBottom( aTop.X(), aTop.Y() + 1000 );
2278 pObj->NbcMirror( aTop, aBottom );
2280 if ( rNewRect.Top() > rNewRect.Bottom() )
2282 Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 );
2283 Point aRight( aLeft.X() + 1000, aLeft.Y() );
2284 pObj->NbcMirror( aLeft, aRight );
2287 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2288 while ( aIter != aInteractionHandles.end() )
2292 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2293 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2294 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
2296 sal_Int32 nX;
2297 if ( bOldMirroredX )
2299 nX = ( aIter->aPosition.X - aOld.Right() );
2300 if ( rNewRect.Left() > rNewRect.Right() )
2301 nX = pObj->aRect.Left() - nX;
2302 else
2303 nX += pObj->aRect.Right();
2305 else
2307 nX = ( aIter->aPosition.X - aOld.Left() );
2308 if ( rNewRect.Left() > rNewRect.Right() )
2309 nX = pObj->aRect.Right() - nX;
2310 else
2311 nX += pObj->aRect.Left();
2313 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
2315 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
2317 sal_Int32 nY;
2318 if ( bOldMirroredY )
2320 nY = ( aIter->aPosition.Y - aOld.Bottom() );
2321 if ( rNewRect.Top() > rNewRect.Bottom() )
2322 nY = pObj->aRect.Top() - nY;
2323 else
2324 nY += pObj->aRect.Bottom();
2326 else
2328 nY = ( aIter->aPosition.Y - aOld.Top() );
2329 if ( rNewRect.Top() > rNewRect.Bottom() )
2330 nY = pObj->aRect.Bottom() - nY;
2331 else
2332 nY += pObj->aRect.Top();
2334 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
2337 catch ( const uno::RuntimeException& )
2340 aIter++;
2345 void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const
2347 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2348 if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2350 SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
2351 if ( aInteractionHandle.xInteraction.is() )
2355 com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() );
2356 if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE )
2358 sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
2359 sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
2361 pObj->aRect.Move( nXDiff, nYDiff );
2362 pObj->aOutRect.Move( nXDiff, nYDiff );
2363 pObj->maSnapRect.Move( nXDiff, nYDiff );
2364 pObj->SetRectsDirty(sal_True);
2365 pObj->InvalidateRenderGeometry();
2367 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2368 while ( aIter != aInteractionHandles.end() )
2370 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2372 if ( aIter->xInteraction.is() )
2373 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2375 aIter++;
2378 aInteractionHandle.xInteraction->setControllerPosition( aPt );
2380 catch ( const uno::RuntimeException& )
2387 bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag)
2389 const SdrHdl* pHdl = rDrag.GetHdl();
2390 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2392 switch(eHdl)
2394 case HDL_CUSTOMSHAPE1 :
2396 rDrag.SetEndDragChangesGeoAndAttributes(true);
2397 DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this );
2398 SetRectsDirty();
2399 InvalidateRenderGeometry();
2400 SetChanged();
2401 break;
2404 case HDL_UPLFT :
2405 case HDL_UPPER :
2406 case HDL_UPRGT :
2407 case HDL_LEFT :
2408 case HDL_RIGHT :
2409 case HDL_LWLFT :
2410 case HDL_LOWER :
2411 case HDL_LWRGT :
2413 DragResizeCustomShape(ImpDragCalcRect(rDrag), this);
2414 break;
2416 case HDL_MOVE :
2418 Move(Size(rDrag.GetDX(), rDrag.GetDY()));
2419 break;
2421 default: break;
2424 return true;
2427 ////////////////////////////////////////////////////////////////////////////////////////////////////
2429 void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat )
2431 Rectangle aRect1;
2432 rStat.TakeCreateRect( aRect1 );
2434 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2436 sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ?
2437 sal_uInt32 nDefaultObjectSizeHeight= 3000;
2439 if ( ImpVerticalSwitch( *this ) )
2441 SetMirroredX( aRect1.Left() > aRect1.Right() );
2443 aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
2444 // subtracting the horizontal difference of the latest handle from shape position
2445 if ( aInteractionHandles.size() )
2447 sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
2448 aRect1.Move( aRect.Left() - nHandlePos, 0 );
2451 ImpJustifyRect( aRect1 );
2452 rStat.SetActionRect( aRect1 );
2453 aRect = aRect1;
2454 SetRectsDirty();
2456 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2457 while ( aIter != aInteractionHandles.end() )
2461 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED )
2462 aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
2464 catch ( const uno::RuntimeException& )
2467 aIter++;
2470 SetBoundRectDirty();
2471 bSnapRectDirty=TRUE;
2474 FASTBOOL SdrObjCustomShape::BegCreate( SdrDragStat& rDrag )
2476 return SdrTextObj::BegCreate( rDrag );
2479 FASTBOOL SdrObjCustomShape::MovCreate(SdrDragStat& rStat)
2481 SdrView* pView = rStat.GetView(); // #i37448#
2482 if( pView && pView->IsSolidDragging() )
2484 InvalidateRenderGeometry();
2486 DragCreateObject( rStat );
2487 SetRectsDirty();
2488 return TRUE;
2491 FASTBOOL SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
2493 DragCreateObject( rStat );
2495 if ( bTextFrame )
2497 if ( IsAutoGrowHeight() )
2499 // MinTextHeight
2500 long nHgt=aRect.GetHeight()-1;
2501 if (nHgt==1) nHgt=0;
2502 NbcSetMinTextFrameHeight( nHgt );
2504 if ( IsAutoGrowWidth() )
2506 // MinTextWidth
2507 long nWdt=aRect.GetWidth()-1;
2508 if (nWdt==1) nWdt=0;
2509 NbcSetMinTextFrameWidth( nWdt );
2511 // Textrahmen neu berechnen
2512 NbcAdjustTextFrameWidthAndHeight();
2514 SetRectsDirty();
2515 return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 );
2518 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
2520 return GetLineGeometry( this, sal_False );
2523 ////////////////////////////////////////////////////////////////////////////////////////////////////
2524 ////////////////////////////////////////////////////////////////////////////////////////////////////
2525 ////////////////////////////////////////////////////////////////////////////////////////////////////
2527 // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2528 // the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
2529 FASTBOOL SdrObjCustomShape::IsAutoGrowHeight() const
2531 const SfxItemSet& rSet = GetMergedItemSet();
2532 FASTBOOL bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2533 if ( bIsAutoGrowHeight && IsVerticalWriting() )
2534 bIsAutoGrowHeight = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == FALSE;
2535 return bIsAutoGrowHeight;
2537 FASTBOOL SdrObjCustomShape::IsAutoGrowWidth() const
2539 const SfxItemSet& rSet = GetMergedItemSet();
2540 FASTBOOL bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2541 if ( bIsAutoGrowWidth && !IsVerticalWriting() )
2542 bIsAutoGrowWidth = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == FALSE;
2543 return bIsAutoGrowWidth;
2546 /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2547 is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2548 mode has been changed */
2550 void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical )
2552 ForceOutlinerParaObject();
2554 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2556 DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2558 if( pOutlinerParaObject )
2560 if(pOutlinerParaObject->IsVertical() != (bool)bVertical)
2562 // get item settings
2563 const SfxItemSet& rSet = GetObjectItemSet();
2565 // #103516# Also exchange hor/ver adjust items
2566 SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
2567 SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
2569 // rescue object size
2570 Rectangle aObjectRect = GetSnapRect();
2572 // prepare ItemSet to set exchanged width and height items
2573 SfxItemSet aNewSet(*rSet.GetPool(),
2574 SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
2575 // #103516# Expanded item ranges to also support hor and ver adjust.
2576 SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
2577 SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
2578 0, 0);
2580 aNewSet.Put(rSet);
2582 // #103516# Exchange horz and vert adjusts
2583 switch(eVert)
2585 case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
2586 case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
2587 case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
2588 case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
2590 switch(eHorz)
2592 case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
2593 case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
2594 case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
2595 case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
2598 SetObjectItemSet( aNewSet );
2599 pOutlinerParaObject = GetOutlinerParaObject();
2600 if ( pOutlinerParaObject )
2601 pOutlinerParaObject->SetVertical(bVertical);
2603 // restore object size
2604 SetSnapRect(aObjectRect);
2608 FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const
2610 if ( pModel && HasText() && !rR.IsEmpty() )
2612 FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth();
2613 FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight();
2614 if ( bWdtGrow || bHgtGrow )
2616 Rectangle aR0(rR);
2617 long nHgt=0,nMinHgt=0,nMaxHgt=0;
2618 long nWdt=0,nMinWdt=0,nMaxWdt=0;
2619 Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
2620 Size aMaxSiz(100000,100000);
2621 Size aTmpSiz(pModel->GetMaxObjSize());
2622 if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2623 if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2624 if (bWdtGrow)
2626 nMinWdt=GetMinTextFrameWidth();
2627 nMaxWdt=GetMaxTextFrameWidth();
2628 if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
2629 if (nMinWdt<=0) nMinWdt=1;
2630 aSiz.Width()=nMaxWdt;
2632 if (bHgtGrow)
2634 nMinHgt=GetMinTextFrameHeight();
2635 nMaxHgt=GetMaxTextFrameHeight();
2636 if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
2637 if (nMinHgt<=0) nMinHgt=1;
2638 aSiz.Height()=nMaxHgt;
2640 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
2641 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
2642 aSiz.Width()-=nHDist;
2643 aSiz.Height()-=nVDist;
2644 if ( aSiz.Width() < 2 )
2645 aSiz.Width() = 2; // Mindestgroesse 2
2646 if ( aSiz.Height() < 2 )
2647 aSiz.Height() = 2; // Mindestgroesse 2
2649 if(pEdtOutl)
2651 pEdtOutl->SetMaxAutoPaperSize( aSiz );
2652 if (bWdtGrow)
2654 Size aSiz2(pEdtOutl->CalcTextSize());
2655 nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
2656 if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
2657 } else
2659 nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz
2662 else
2664 Outliner& rOutliner=ImpGetDrawOutliner();
2665 rOutliner.SetPaperSize(aSiz);
2666 rOutliner.SetUpdateMode(TRUE);
2667 // !!! hier sollte ich wohl auch noch mal die Optimierung mit
2668 // bPortionInfoChecked usw einbauen
2669 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2670 if( pOutlinerParaObject != NULL )
2672 rOutliner.SetText(*pOutlinerParaObject);
2673 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
2675 if ( bWdtGrow )
2677 Size aSiz2(rOutliner.CalcTextSize());
2678 nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
2679 if ( bHgtGrow )
2680 nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
2682 else
2683 nHgt = rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz
2684 rOutliner.Clear();
2686 if ( nWdt < nMinWdt )
2687 nWdt = nMinWdt;
2688 if ( nWdt > nMaxWdt )
2689 nWdt = nMaxWdt;
2690 nWdt += nHDist;
2691 if ( nWdt < 1 )
2692 nWdt = 1; // nHDist kann auch negativ sein
2693 if ( nHgt < nMinHgt )
2694 nHgt = nMinHgt;
2695 if ( nHgt > nMaxHgt )
2696 nHgt = nMaxHgt;
2697 nHgt+=nVDist;
2698 if ( nHgt < 1 )
2699 nHgt = 1; // nVDist kann auch negativ sein
2700 long nWdtGrow = nWdt-(rR.Right()-rR.Left());
2701 long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
2702 if ( nWdtGrow == 0 )
2703 bWdtGrow = FALSE;
2704 if ( nHgtGrow == 0 )
2705 bHgtGrow=FALSE;
2706 if ( bWdtGrow || bHgtGrow )
2708 if ( bWdtGrow )
2710 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2711 if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2712 rR.Right()+=nWdtGrow;
2713 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2714 rR.Left()-=nWdtGrow;
2715 else
2717 long nWdtGrow2=nWdtGrow/2;
2718 rR.Left()-=nWdtGrow2;
2719 rR.Right()=rR.Left()+nWdt;
2722 if ( bHgtGrow )
2724 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2725 if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2726 rR.Bottom()+=nHgtGrow;
2727 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2728 rR.Top()-=nHgtGrow;
2729 else
2731 long nHgtGrow2=nHgtGrow/2;
2732 rR.Top()-=nHgtGrow2;
2733 rR.Bottom()=rR.Top()+nHgt;
2736 if ( aGeo.nDrehWink )
2738 Point aD1(rR.TopLeft());
2739 aD1-=aR0.TopLeft();
2740 Point aD2(aD1);
2741 RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
2742 aD2-=aD1;
2743 rR.Move(aD2.X(),aD2.Y());
2745 return TRUE;
2749 return FALSE;
2752 Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const FASTBOOL bHgt, const FASTBOOL bWdt )
2754 Rectangle aReturnValue;
2756 Rectangle aOldTextRect( aRect ); // <- initial text rectangle
2758 Rectangle aNewTextRect( aRect ); // <- new text rectangle returned from the custom shape renderer,
2759 GetTextBounds( aNewTextRect ); // it depends to the current logical shape size
2761 Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2762 if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner
2764 if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) )
2766 aReturnValue = aRect;
2767 double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth();
2768 double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight();
2769 double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
2770 double fLeftDiff = (double)( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale;
2771 double fTopDiff = (double)( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale;
2772 double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
2773 aReturnValue.Left() += (sal_Int32)fLeftDiff;
2774 aReturnValue.Right() += (sal_Int32)fRightDiff;
2775 aReturnValue.Top() += (sal_Int32)fTopDiff;
2776 aReturnValue.Bottom() += (sal_Int32)fBottomDiff;
2779 return aReturnValue;
2782 FASTBOOL SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2784 Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2785 sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2786 if ( bRet )
2788 // taking care of handles that should not been changed
2789 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2791 aRect = aNewTextRect;
2792 SetRectsDirty();
2793 SetChanged();
2795 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2796 while ( aIter != aInteractionHandles.end() )
2800 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2801 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2803 catch ( const uno::RuntimeException& )
2806 aIter++;
2808 InvalidateRenderGeometry();
2810 return bRet;
2812 FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2814 Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2815 sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2816 if ( bRet )
2818 Rectangle aBoundRect0;
2819 if ( pUserCall )
2820 aBoundRect0 = GetCurrentBoundRect();
2822 // taking care of handles that should not been changed
2823 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2825 // SendRepaintBroadcast();
2826 aRect = aNewTextRect;
2827 SetRectsDirty();
2829 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2830 while ( aIter != aInteractionHandles.end() )
2834 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2835 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2837 catch ( const uno::RuntimeException& )
2840 aIter++;
2843 InvalidateRenderGeometry();
2844 SetChanged();
2845 // SendRepaintBroadcast();
2846 BroadcastObjectChange();
2847 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2849 return bRet;
2851 sal_Bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl )
2853 return SdrTextObj::BegTextEdit( rOutl );
2855 void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
2857 Size aPaperMin,aPaperMax;
2858 Rectangle aViewInit;
2859 TakeTextAnchorRect( aViewInit );
2860 if ( aGeo.nDrehWink )
2862 Point aCenter(aViewInit.Center());
2863 aCenter-=aViewInit.TopLeft();
2864 Point aCenter0(aCenter);
2865 RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
2866 aCenter-=aCenter0;
2867 aViewInit.Move(aCenter.X(),aCenter.Y());
2869 Size aAnkSiz(aViewInit.GetSize());
2870 aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
2871 Size aMaxSiz(1000000,1000000);
2872 if (pModel!=NULL) {
2873 Size aTmpSiz(pModel->GetMaxObjSize());
2874 if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2875 if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2877 SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
2878 SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
2880 long nMinWdt = GetMinTextFrameWidth();
2881 long nMinHgt = GetMinTextFrameHeight();
2882 long nMaxWdt = GetMaxTextFrameWidth();
2883 long nMaxHgt = GetMaxTextFrameHeight();
2884 if (nMinWdt<1) nMinWdt=1;
2885 if (nMinHgt<1) nMinHgt=1;
2886 if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
2887 nMaxWdt = aMaxSiz.Width();
2888 if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
2889 nMaxHgt=aMaxSiz.Height();
2891 if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2893 if ( IsVerticalWriting() )
2895 nMaxHgt = aAnkSiz.Height();
2896 nMinHgt = nMaxHgt;
2898 else
2900 nMaxWdt = aAnkSiz.Width();
2901 nMinWdt = nMaxWdt;
2904 aPaperMax.Width()=nMaxWdt;
2905 aPaperMax.Height()=nMaxHgt;
2907 aPaperMin.Width()=nMinWdt;
2908 aPaperMin.Height()=nMinHgt;
2910 if ( pViewMin )
2912 *pViewMin = aViewInit;
2914 long nXFree = aAnkSiz.Width() - aPaperMin.Width();
2915 if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2916 pViewMin->Right() -= nXFree;
2917 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2918 pViewMin->Left() += nXFree;
2919 else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); }
2921 long nYFree = aAnkSiz.Height() - aPaperMin.Height();
2922 if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2923 pViewMin->Bottom() -= nYFree;
2924 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2925 pViewMin->Top() += nYFree;
2926 else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); }
2929 if( IsVerticalWriting() )
2930 aPaperMin.Width() = 0;
2931 else
2932 aPaperMin.Height() = 0; // #33102#
2934 if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
2935 aPaperMin.Width()=0;
2937 // #103516# For complete ver adjust support, set paper min height to 0, here.
2938 if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
2939 aPaperMin.Height() = 0;
2941 if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
2942 if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
2943 if (pViewInit!=NULL) *pViewInit=aViewInit;
2945 void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl )
2947 SdrTextObj::EndTextEdit( rOutl );
2948 InvalidateRenderGeometry();
2950 void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const
2952 if ( GetTextBounds( rAnchorRect ) )
2954 Point aRotateRef( maSnapRect.Center() );
2955 rAnchorRect.Left() += GetTextLeftDistance();
2956 rAnchorRect.Top() += GetTextUpperDistance();
2957 rAnchorRect.Right() -= GetTextRightDistance();
2958 rAnchorRect.Bottom() -= GetTextLowerDistance();
2959 ImpJustifyRect( rAnchorRect );
2961 if ( rAnchorRect.GetWidth() < 2 )
2962 rAnchorRect.Right() = rAnchorRect.Left() + 1; // minimal width is 2
2963 if ( rAnchorRect.GetHeight() < 2 )
2964 rAnchorRect.Bottom() = rAnchorRect.Top() + 1; // minimal height is 2
2965 if ( aGeo.nDrehWink )
2967 Point aP( rAnchorRect.TopLeft() );
2968 RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos );
2969 rAnchorRect.SetPos( aP );
2972 else
2973 SdrTextObj::TakeTextAnchorRect( rAnchorRect );
2975 void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
2976 Rectangle* pAnchorRect, BOOL /*bLineWidth*/) const
2978 Rectangle aAnkRect; // Rect innerhalb dem geankert wird
2979 TakeTextAnchorRect(aAnkRect);
2980 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2981 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2982 ULONG nStat0=rOutliner.GetControlWord();
2983 Size aNullSize;
2985 rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
2986 rOutliner.SetMinAutoPaperSize(aNullSize);
2987 sal_Int32 nMaxAutoPaperWidth = 1000000;
2988 sal_Int32 nMaxAutoPaperHeight= 1000000;
2990 long nAnkWdt=aAnkRect.GetWidth();
2991 long nAnkHgt=aAnkRect.GetHeight();
2993 if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2995 if ( IsVerticalWriting() )
2996 nMaxAutoPaperHeight = nAnkHgt;
2997 else
2998 nMaxAutoPaperWidth = nAnkWdt;
3000 if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
3002 rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
3005 if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
3007 rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
3009 rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
3010 rOutliner.SetPaperSize( aNullSize );
3012 // Text in den Outliner stecken - ggf. den aus dem EditOutliner
3013 OutlinerParaObject* pPara= GetOutlinerParaObject();
3014 if (pEdtOutl && !bNoEditText)
3015 pPara=pEdtOutl->CreateParaObject();
3017 if (pPara)
3019 BOOL bHitTest = FALSE;
3020 if( pModel )
3021 bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
3023 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
3024 if( !pTestObj || !bHitTest || pTestObj != this ||
3025 pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() )
3027 if( bHitTest )
3028 rOutliner.SetTextObj( this );
3030 rOutliner.SetUpdateMode(TRUE);
3031 rOutliner.SetText(*pPara);
3034 else
3036 rOutliner.SetTextObj( NULL );
3038 if (pEdtOutl && !bNoEditText && pPara)
3039 delete pPara;
3041 rOutliner.SetUpdateMode(TRUE);
3042 rOutliner.SetControlWord(nStat0);
3044 SdrText* pText = getActiveText();
3045 if( pText )
3046 pText->CheckPortionInfo( rOutliner );
3048 Point aTextPos(aAnkRect.TopLeft());
3049 Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
3051 // #106653#
3052 // For draw objects containing text correct hor/ver alignment if text is bigger
3053 // than the object itself. Without that correction, the text would always be
3054 // formatted to the left edge (or top edge when vertical) of the draw object.
3056 if( !IsTextFrame() )
3058 if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
3060 // #110129#
3061 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
3062 // else the alignment is wanted.
3063 if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
3065 eHAdj = SDRTEXTHORZADJUST_CENTER;
3069 if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
3071 // #110129#
3072 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
3073 // else the alignment is wanted.
3074 if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
3076 eVAdj = SDRTEXTVERTADJUST_CENTER;
3081 if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
3083 long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
3084 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
3085 aTextPos.X()+=nFreeWdt/2;
3086 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
3087 aTextPos.X()+=nFreeWdt;
3089 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
3091 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
3092 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
3093 aTextPos.Y()+=nFreeHgt/2;
3094 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
3095 aTextPos.Y()+=nFreeHgt;
3097 if (aGeo.nDrehWink!=0)
3098 RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
3100 if (pAnchorRect)
3101 *pAnchorRect=aAnkRect;
3103 // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
3104 rTextRect=Rectangle(aTextPos,aTextSiz);
3107 void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
3109 SdrTextObj::NbcSetOutlinerParaObject( pTextObject );
3110 SetBoundRectDirty();
3111 SetRectsDirty(TRUE);
3112 InvalidateRenderGeometry();
3115 void SdrObjCustomShape::operator=(const SdrObject& rObj)
3117 SdrTextObj::operator=( rObj );
3118 aName =((SdrObjCustomShape&)rObj).aName;
3119 fObjectRotation = ((SdrObjCustomShape&)rObj).fObjectRotation;
3120 InvalidateRenderGeometry();
3124 void SdrObjCustomShape::TakeObjNameSingul(XubString& rName) const
3126 rName = ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE);
3127 String aNm( GetName() );
3128 if( aNm.Len() )
3130 rName += sal_Unicode(' ');
3131 rName += sal_Unicode('\'');
3132 rName += aNm;
3133 rName += sal_Unicode('\'');
3137 void SdrObjCustomShape::TakeObjNamePlural(XubString& rName) const
3139 rName=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE);
3142 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const
3144 return GetLineGeometry( (SdrObjCustomShape*)this, sal_False );
3147 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const
3149 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
3150 if ( pSdrObject )
3151 return pSdrObject->TakeContour();
3152 return basegfx::B2DPolyPolygon();
3155 SdrObject* SdrObjCustomShape::DoConvertToPolyObj(BOOL bBezier) const
3157 // #i37011#
3158 SdrObject* pRetval = 0L;
3159 SdrObject* pRenderedCustomShape = 0L;
3161 if ( !mXRenderedCustomShape.is() )
3163 // force CustomShape
3164 ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape();
3167 if ( mXRenderedCustomShape.is() )
3169 pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
3172 if ( pRenderedCustomShape )
3174 SdrObject* pCandidate = pRenderedCustomShape->Clone();
3175 DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
3176 pCandidate->SetModel(GetModel());
3177 pRetval = pCandidate->DoConvertToPolyObj(bBezier);
3178 SdrObject::Free( pCandidate );
3180 if(pRetval)
3182 const sal_Bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue());
3183 if(bShadow)
3185 pRetval->SetMergedItem(SdrShadowItem(sal_True));
3189 if(HasText() && !IsTextPath())
3191 pRetval = ImpConvertAddText(pRetval, bBezier);
3195 return pRetval;
3198 void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr )
3200 // #i40944#
3201 InvalidateRenderGeometry();
3202 SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
3205 void SdrObjCustomShape::SetPage( SdrPage* pNewPage )
3207 SdrTextObj::SetPage( pNewPage );
3209 if( pNewPage )
3211 // invalidating rectangles by SetRectsDirty is not sufficient,
3212 // AdjustTextFrameWidthAndHeight() also has to be made, both
3213 // actions are done by NbcSetSnapRect
3214 Rectangle aTmp( aRect ); //creating temporary rectangle #i61108#
3215 NbcSetSnapRect( aTmp );
3219 SdrObjGeoData* SdrObjCustomShape::NewGeoData() const
3221 return new SdrAShapeObjGeoData;
3224 void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const
3226 SdrTextObj::SaveGeoData( rGeo );
3227 SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
3228 rAGeo.fObjectRotation = fObjectRotation;
3229 rAGeo.bMirroredX = IsMirroredX();
3230 rAGeo.bMirroredY = IsMirroredY();
3232 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3233 Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) );
3234 if ( pAny )
3235 *pAny >>= rAGeo.aAdjustmentSeq;
3238 void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo)
3240 SdrTextObj::RestGeoData( rGeo );
3241 SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
3242 fObjectRotation = rAGeo.fObjectRotation;
3243 SetMirroredX( rAGeo.bMirroredX );
3244 SetMirroredY( rAGeo.bMirroredY );
3246 SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
3247 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3248 PropertyValue aPropVal;
3249 aPropVal.Name = sAdjustmentValues;
3250 aPropVal.Value <<= rAGeo.aAdjustmentSeq;
3251 rGeometryItem.SetPropertyValue( aPropVal );
3252 SetMergedItem( rGeometryItem );
3254 InvalidateRenderGeometry();
3257 void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
3259 // break up matrix
3260 basegfx::B2DTuple aScale;
3261 basegfx::B2DTuple aTranslate;
3262 double fRotate, fShearX;
3263 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3265 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
3266 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
3267 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
3269 aScale.setX(fabs(aScale.getX()));
3270 aScale.setY(fabs(aScale.getY()));
3271 fRotate = fmod(fRotate + F_PI, F_2PI);
3274 // reset object shear and rotations
3275 aGeo.nDrehWink = 0;
3276 aGeo.RecalcSinCos();
3277 aGeo.nShearWink = 0;
3278 aGeo.RecalcTan();
3280 // force metric to pool metric
3281 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3282 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3284 switch(eMapUnit)
3286 case SFX_MAPUNIT_TWIP :
3288 // position
3289 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3290 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3292 // size
3293 aScale.setX(ImplMMToTwips(aScale.getX()));
3294 aScale.setY(ImplMMToTwips(aScale.getY()));
3296 break;
3298 default:
3300 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3305 // if anchor is used, make position relative to it
3306 if( pModel && pModel->IsWriter() )
3308 if(GetAnchorPos().X() || GetAnchorPos().Y())
3310 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3314 // build and set BaseRect (use scale)
3315 Point aPoint = Point();
3316 Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
3317 Rectangle aBaseRect(aPoint, aSize);
3318 SetSnapRect(aBaseRect);
3320 // shear?
3321 if(!basegfx::fTools::equalZero(fShearX))
3323 GeoStat aGeoStat;
3324 aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
3325 aGeoStat.RecalcTan();
3326 Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE);
3329 // rotation?
3330 if(!basegfx::fTools::equalZero(fRotate))
3332 GeoStat aGeoStat;
3334 // #i78696#
3335 // fRotate is mathematically correct, but aGeoStat.nDrehWink is
3336 // mirrored -> mirror value here
3337 aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
3338 aGeoStat.RecalcSinCos();
3339 Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
3342 // translate?
3343 if(!aTranslate.equalZero())
3345 Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
3349 // taking fObjectRotation instead of aGeo.nWink
3350 sal_Bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3352 // get turn and shear
3353 // double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
3354 double fRotate = fObjectRotation * F_PI180;
3355 double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
3357 // get aRect, this is the unrotated snaprect
3358 Rectangle aRectangle(aRect);
3360 sal_Bool bMirroredX = IsMirroredX();
3361 sal_Bool bMirroredY = IsMirroredY();
3362 if ( bMirroredX || bMirroredY )
3363 { // we have to retrieve the unmirrored rect
3365 GeoStat aNewGeo( aGeo );
3367 if ( bMirroredX )
3369 Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
3370 Rectangle aBoundRect( aPol.GetBoundRect() );
3372 Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
3373 Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
3374 USHORT i;
3375 USHORT nPntAnz=aPol.GetSize();
3376 for (i=0; i<nPntAnz; i++)
3378 MirrorPoint(aPol[i],aRef1,aRef2);
3380 // Polygon wenden und etwas schieben
3381 Polygon aPol0(aPol);
3382 aPol[0]=aPol0[1];
3383 aPol[1]=aPol0[0];
3384 aPol[2]=aPol0[3];
3385 aPol[3]=aPol0[2];
3386 aPol[4]=aPol0[1];
3387 Poly2Rect(aPol,aRectangle,aNewGeo);
3389 if ( bMirroredY )
3391 Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
3392 Rectangle aBoundRect( aPol.GetBoundRect() );
3394 Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
3395 Point aRef2( aRef1.X() + 1000, aRef1.Y() );
3396 USHORT i;
3397 USHORT nPntAnz=aPol.GetSize();
3398 for (i=0; i<nPntAnz; i++)
3400 MirrorPoint(aPol[i],aRef1,aRef2);
3402 // Polygon wenden und etwas schieben
3403 Polygon aPol0(aPol);
3404 aPol[0]=aPol0[1];
3405 aPol[1]=aPol0[0];
3406 aPol[2]=aPol0[3];
3407 aPol[3]=aPol0[2];
3408 aPol[4]=aPol0[1];
3409 Poly2Rect(aPol,aRectangle,aNewGeo);
3413 // fill other values
3414 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3415 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3417 // position maybe relative to anchorpos, convert
3418 if( pModel && pModel->IsWriter() )
3420 if(GetAnchorPos().X() || GetAnchorPos().Y())
3422 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3426 // force MapUnit to 100th mm
3427 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3428 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3430 switch(eMapUnit)
3432 case SFX_MAPUNIT_TWIP :
3434 // postion
3435 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3436 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3438 // size
3439 aScale.setX(ImplTwipsToMM(aScale.getX()));
3440 aScale.setY(ImplTwipsToMM(aScale.getY()));
3442 break;
3444 default:
3446 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3451 // build matrix
3452 rMatrix.identity();
3454 if(!basegfx::fTools::equal(aScale.getX(), 1.0) || !basegfx::fTools::equal(aScale.getY(), 1.0))
3456 rMatrix.scale(aScale.getX(), aScale.getY());
3459 if(!basegfx::fTools::equalZero(fShearX))
3461 rMatrix.shearX(tan(fShearX));
3464 if(!basegfx::fTools::equalZero(fRotate))
3466 // #i78696#
3467 // fRotate is from the old GeoStat struct and thus mathematically wrong orientated. For
3468 // the linear combination of matrices it needed to be fixed in the API, so it needs to
3469 // be mirrored here
3470 rMatrix.rotate(-fRotate);
3473 if(!aTranslate.equalZero())
3475 rMatrix.translate(aTranslate.getX(), aTranslate.getY());
3478 return sal_False;
3481 sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact()
3483 return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
3486 // #i33136#
3487 bool SdrObjCustomShape::doConstructOrthogonal(const ::rtl::OUString& rName)
3489 bool bRetval(false);
3490 static ::rtl::OUString Imps_sNameASOrtho_quadrat( RTL_CONSTASCII_USTRINGPARAM( "quadrat" ) );
3491 static ::rtl::OUString Imps_sNameASOrtho_round_quadrat( RTL_CONSTASCII_USTRINGPARAM( "round-quadrat" ) );
3492 static ::rtl::OUString Imps_sNameASOrtho_circle( RTL_CONSTASCII_USTRINGPARAM( "circle" ) );
3493 static ::rtl::OUString Imps_sNameASOrtho_circle_pie( RTL_CONSTASCII_USTRINGPARAM( "circle-pie" ) );
3494 static ::rtl::OUString Imps_sNameASOrtho_ring( RTL_CONSTASCII_USTRINGPARAM( "ring" ) );
3496 if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName))
3498 bRetval = true;
3500 else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName))
3502 bRetval = true;
3504 else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName))
3506 bRetval = true;
3508 else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName))
3510 bRetval = true;
3512 else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName))
3514 bRetval = true;
3517 return bRetval;
3520 // #i37011# centralize throw-away of render geometry
3521 void SdrObjCustomShape::InvalidateRenderGeometry()
3523 mXRenderedCustomShape = 0L;
3524 SdrObject::Free( mpLastShadowGeometry );
3525 mpLastShadowGeometry = 0L;
3528 // eof