Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / svdraw / svdoashp.cxx
blob1e66287d8b83f14d259860cf92df221826549c01
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <svx/svdoashp.hxx>
30 #include "svx/unoapi.hxx"
31 #include <svx/unoshape.hxx>
32 #include <ucbhelper/content.hxx>
33 #include <ucbhelper/contentbroker.hxx>
34 #include <unotools/datetime.hxx>
35 #include <sfx2/lnkbase.hxx>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/drawing/XShape.hpp>
38 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
39 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <com/sun/star/awt/Rectangle.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <svl/urihelper.hxx>
44 #include <com/sun/star/uno/Sequence.h>
45 #include <svx/svdogrp.hxx>
46 #include <vcl/salbtype.hxx> // FRound
47 #include <svx/svddrag.hxx>
48 #include <svx/xpool.hxx>
49 #include <svx/xpoly.hxx>
50 #include <svx/svdmodel.hxx>
51 #include <svx/svdpage.hxx>
52 #include "svx/svditer.hxx"
53 #include <svx/svdobj.hxx>
54 #include <svx/svdtrans.hxx>
55 #include <svx/svdetc.hxx>
56 #include <svx/svdattrx.hxx> // NotPersistItems
57 #include <svx/svdoedge.hxx> // for broadcasting connectors to Move
58 #include "svx/svdglob.hxx" // StringCache
59 #include "svx/svdstr.hrc" // the object's name
60 #include <editeng/eeitem.hxx>
61 #include "editeng/editstat.hxx"
62 #include <svx/svdoutl.hxx>
63 #include <editeng/outlobj.hxx>
64 #include <svx/sdtfchim.hxx>
65 #include "../svx/EnhancedCustomShapeGeometry.hxx"
66 #include "../svx/EnhancedCustomShapeTypeNames.hxx"
67 #include "../svx/EnhancedCustomShape2d.hxx"
68 #include <com/sun/star/beans/PropertyValues.hpp>
69 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
70 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
71 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
72 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
73 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
74 #include <editeng/writingmodeitem.hxx>
75 #include <svx/xlnclit.hxx>
76 #include <svx/svxids.hrc>
77 #include <svl/whiter.hxx>
78 #include <svx/sdr/properties/customshapeproperties.hxx>
79 #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
80 #include <svx/xlntrit.hxx>
81 #include <svx/xfltrit.hxx>
82 #include <svx/xflclit.hxx>
83 #include <svx/xflgrit.hxx>
84 #include <svx/xflhtit.hxx>
85 #include <svx/xbtmpit.hxx>
86 #include <vcl/bmpacc.hxx>
87 #include <svx/svdview.hxx>
88 #include <basegfx/polygon/b2dpolypolygontools.hxx>
89 #include <basegfx/matrix/b2dhommatrix.hxx>
90 #include <basegfx/matrix/b2dhommatrixtools.hxx>
91 #include <basegfx/tools/unotools.hxx>
92 #include "svdconv.hxx"
94 using namespace ::com::sun::star;
95 using namespace ::com::sun::star::uno;
96 using namespace ::com::sun::star::lang;
97 using namespace ::com::sun::star::beans;
98 using namespace ::com::sun::star::drawing;
101 static void lcl_ShapeSegmentFromBinary( EnhancedCustomShapeSegment& rSegInfo, sal_uInt16 nSDat )
103 switch( nSDat >> 8 )
105 case 0x00 :
106 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
107 rSegInfo.Count = nSDat & 0xff;
108 if ( !rSegInfo.Count )
109 rSegInfo.Count = 1;
110 break;
111 case 0x20 :
112 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
113 rSegInfo.Count = nSDat & 0xff;
114 if ( !rSegInfo.Count )
115 rSegInfo.Count = 1;
116 break;
117 case 0x40 :
118 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
119 rSegInfo.Count = nSDat & 0xff;
120 if ( !rSegInfo.Count )
121 rSegInfo.Count = 1;
122 break;
123 case 0x60 :
124 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
125 rSegInfo.Count = 0;
126 break;
127 case 0x80 :
128 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
129 rSegInfo.Count = 0;
130 break;
131 case 0xa1 :
132 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
133 rSegInfo.Count = ( nSDat & 0xff ) / 3;
134 break;
135 case 0xa2 :
136 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
137 rSegInfo.Count = ( nSDat & 0xff ) / 3;
138 break;
139 case 0xa3 :
140 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
141 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
142 break;
143 case 0xa4 :
144 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
145 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
146 break;
147 case 0xa5 :
148 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
149 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
150 break;
151 case 0xa6 :
152 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
153 rSegInfo.Count = ( nSDat & 0xff ) >> 2;
154 break;
155 case 0xa7 :
156 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
157 rSegInfo.Count = nSDat & 0xff;
158 break;
159 case 0xa8 :
160 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
161 rSegInfo.Count = nSDat & 0xff;
162 break;
163 case 0xaa :
164 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
165 rSegInfo.Count = 0;
166 break;
167 case 0xab :
168 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
169 rSegInfo.Count = 0;
170 break;
171 default:
172 case 0xf8 :
173 rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
174 rSegInfo.Count = nSDat;
175 break;
177 return;
180 static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape )
182 MSO_SPT eRetValue = mso_sptNil;
184 rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
185 if ( aEngine.isEmpty() || aEngine == "com.sun.star.drawing.EnhancedCustomShapeEngine" )
187 rtl::OUString sShapeType;
188 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
189 SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
190 Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
191 if ( pAny && ( *pAny >>= sShapeType ) )
192 eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType );
194 return eRetValue;
197 static sal_Bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape )
199 sal_Bool bRet = sal_False;
200 MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) );
201 switch( eShapeType )
203 case mso_sptAccentBorderCallout90 : // 2 ortho
204 case mso_sptBorderCallout1 : // 2 diag
205 case mso_sptBorderCallout2 : // 3
207 bRet = sal_True;
209 break;
210 default: break;
212 return bRet;
215 // #i37011# create a clone with all attributes changed to shadow attributes
216 // and translation executed, too.
217 SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet)
219 SdrObject* pRetval = 0L;
220 const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue());
222 if(bShadow)
224 // create a shadow representing object
225 const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue());
226 const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
227 const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
228 const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
229 pRetval = rOriginal.Clone();
230 DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)");
232 // look for used stuff
233 SdrObjListIter aIterator(rOriginal);
234 sal_Bool bLineUsed(sal_False);
235 sal_Bool bAllFillUsed(sal_False);
236 sal_Bool bSolidFillUsed(sal_False);
237 sal_Bool bGradientFillUsed(sal_False);
238 sal_Bool bHatchFillUsed(sal_False);
239 sal_Bool bBitmapFillUsed(sal_False);
241 while(aIterator.IsMore())
243 SdrObject* pObj = aIterator.Next();
244 XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue();
246 if(!bLineUsed)
248 XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue();
250 if(XLINE_NONE != eLineStyle)
252 bLineUsed = sal_True;
256 if(!bAllFillUsed)
258 if(!bSolidFillUsed && XFILL_SOLID == eFillStyle)
260 bSolidFillUsed = sal_True;
261 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
263 if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle)
265 bGradientFillUsed = sal_True;
266 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
268 if(!bHatchFillUsed && XFILL_HATCH == eFillStyle)
270 bHatchFillUsed = sal_True;
271 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
273 if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle)
275 bBitmapFillUsed = sal_True;
276 bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
281 // translate to shadow coordinates
282 pRetval->NbcMove(Size(nXDist, nYDist));
284 // set items as needed
285 SfxItemSet aTempSet(rOriginalSet);
287 // if a SvxWritingModeItem (Top->Bottom) is set the text object
288 // is creating a paraobject, but paraobjects can not be created without model. So
289 // we are preventing the crash by setting the writing mode always left to right,
290 // this is not bad since our shadow geometry does not contain text.
291 aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) );
293 // no shadow
294 aTempSet.Put(SdrShadowItem(sal_False));
295 aTempSet.Put(SdrShadowXDistItem(0L));
296 aTempSet.Put(SdrShadowYDistItem(0L));
298 // line color and transparency like shadow
299 if(bLineUsed)
301 aTempSet.Put(XLineColorItem(String(), aShadowColor));
302 aTempSet.Put(XLineTransparenceItem(nShadowTransparence));
305 // fill color and transparency like shadow
306 if(bSolidFillUsed)
308 aTempSet.Put(XFillColorItem(String(), aShadowColor));
309 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
312 // gradient and transparency like shadow
313 if(bGradientFillUsed)
315 XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
316 sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
317 sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
319 if(aGradient.GetStartIntens() != 100)
321 nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0));
324 if(aGradient.GetEndIntens() != 100)
326 nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0));
329 ::Color aStartColor(
330 (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256),
331 (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256),
332 (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256));
334 ::Color aEndColor(
335 (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256),
336 (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256),
337 (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256));
339 aGradient.SetStartColor(aStartColor);
340 aGradient.SetEndColor(aEndColor);
341 aTempSet.Put(XFillGradientItem(aGradient));
342 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
345 // hatch and transparency like shadow
346 if(bHatchFillUsed)
348 XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue());
349 aHatch.SetColor(aShadowColor);
350 aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch));
351 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
354 // bitmap and transparency like shadow
355 if(bBitmapFillUsed)
357 XOBitmap aFillBitmap(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetBitmapValue());
358 Bitmap aSourceBitmap(aFillBitmap.GetBitmap());
359 BitmapReadAccess* pReadAccess = aSourceBitmap.AcquireReadAccess();
361 if(!aSourceBitmap.IsEmpty())
363 if(pReadAccess)
365 Bitmap aDestBitmap(aSourceBitmap.GetSizePixel(), 24L);
366 BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess();
368 if(pWriteAccess)
370 for(sal_Int32 y(0L); y < pReadAccess->Height(); y++)
372 for(sal_Int32 x(0L); x < pReadAccess->Width(); x++)
374 sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1);
375 const BitmapColor aDestColor(
376 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L),
377 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L),
378 (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L));
379 pWriteAccess->SetPixel(y, x, aDestColor);
383 aDestBitmap.ReleaseAccess(pWriteAccess);
384 aFillBitmap.SetBitmap(aDestBitmap);
387 aSourceBitmap.ReleaseAccess(pReadAccess);
391 aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aFillBitmap));
392 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
395 // set attributes and paint shadow object
396 pRetval->SetMergedItemSet( aTempSet );
398 return pRetval;
401 ////////////////////////////////////////////////////////////////////////////////////////////////////
403 Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine( const SdrObjCustomShape* pCustomShape )
405 Reference< XCustomShapeEngine > xCustomShapeEngine;
406 String aEngine(((SdrCustomShapeEngineItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue());
407 if ( !aEngine.Len() )
408 aEngine = String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
410 Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
412 Reference< XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
413 if ( aXShape.is() )
415 if ( aEngine.Len() && xFactory.is() )
417 Sequence< Any > aArgument( 1 );
418 Sequence< PropertyValue > aPropValues( 1 );
419 aPropValues[ 0 ].Name = rtl::OUString("CustomShape");
420 aPropValues[ 0 ].Value <<= aXShape;
421 aArgument[ 0 ] <<= aPropValues;
422 Reference< XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
423 if ( xInterface.is() )
424 xCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY );
427 return xCustomShapeEngine;
429 const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
431 if ( !mXRenderedCustomShape.is() )
433 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) );
434 if ( xCustomShapeEngine.is() )
435 ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render();
437 SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
438 ? GetSdrObjectFromXShape( mXRenderedCustomShape )
439 : NULL;
440 return pRenderedCustomShape;
443 // #i37011# Shadow geometry creation
444 const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
446 if(!mpLastShadowGeometry)
448 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
449 if(pSdrObject)
451 const SfxItemSet& rOriginalSet = GetObjectItemSet();
452 const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue());
454 if(bShadow)
456 // create a clone with all attributes changed to shadow attributes
457 // and translation executed, too.
458 ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
463 return mpLastShadowGeometry;
466 sal_Bool SdrObjCustomShape::IsTextPath() const
468 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
469 sal_Bool bTextPathOn = sal_False;
470 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
471 Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
472 if ( pAny )
473 *pAny >>= bTextPathOn;
474 return bTextPathOn;
477 sal_Bool SdrObjCustomShape::UseNoFillStyle() const
479 sal_Bool bRet = sal_False;
480 rtl::OUString sShapeType;
481 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
482 SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
483 Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
484 if ( pAny )
485 *pAny >>= sShapeType;
486 bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == 0;
488 return bRet;
491 sal_Bool SdrObjCustomShape::IsMirroredX() const
493 sal_Bool bMirroredX = sal_False;
494 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
495 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
496 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
497 if ( pAny )
498 *pAny >>= bMirroredX;
499 return bMirroredX;
501 sal_Bool SdrObjCustomShape::IsMirroredY() const
503 sal_Bool bMirroredY = sal_False;
504 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
505 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
506 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
507 if ( pAny )
508 *pAny >>= bMirroredY;
509 return bMirroredY;
511 void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX )
513 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
514 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
515 PropertyValue aPropVal;
516 aPropVal.Name = sMirroredX;
517 aPropVal.Value <<= bMirrorX;
518 aGeometryItem.SetPropertyValue( aPropVal );
519 SetMergedItem( aGeometryItem );
521 void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY )
523 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
524 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
525 PropertyValue aPropVal;
526 aPropVal.Name = sMirroredY;
527 aPropVal.Value <<= bMirrorY;
528 aGeometryItem.SetPropertyValue( aPropVal );
529 SetMergedItem( aGeometryItem );
532 double SdrObjCustomShape::GetObjectRotation() const
534 return fObjectRotation;
537 bool SdrObjCustomShape::IsPostRotate() const
539 const com::sun::star::uno::Any* pAny;
540 bool bPostRotate = false;
541 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
542 pAny = rGeometryItem.GetPropertyValueByName( "IsPostRotateAngle" );
543 if ( pAny )
544 *pAny >>= bPostRotate;
545 return bPostRotate;
548 double SdrObjCustomShape::GetExtraTextRotation( const bool bPreRotation ) const
550 const com::sun::star::uno::Any* pAny;
551 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
552 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
553 const rtl::OUString sTextPreRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextPreRotateAngle" ) );
554 pAny = rGeometryItem.GetPropertyValueByName( bPreRotation ? sTextPreRotateAngle : sTextRotateAngle );
555 double fExtraTextRotateAngle = 0.0;
556 if ( pAny )
557 *pAny >>= fExtraTextRotateAngle;
558 return fExtraTextRotateAngle;
560 sal_Bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const
562 sal_Bool bRet = sal_False;
563 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); // a candidate for being cached
564 if ( xCustomShapeEngine.is() )
566 awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
567 if ( aR.Width > 1 && aR.Height > 1 )
569 rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
570 bRet = sal_True;
573 return bRet;
575 basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const sal_Bool bBezierAllowed )
577 basegfx::B2DPolyPolygon aRetval;
578 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
579 if ( xCustomShapeEngine.is() )
581 com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
584 aRetval = basegfx::unotools::polyPolygonBezierToB2DPolyPolygon( aBezierCoords );
585 if ( !bBezierAllowed && aRetval.areControlPointsUsed())
587 aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval);
590 catch ( const com::sun::star::lang::IllegalArgumentException & )
594 return aRetval;
597 std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const
599 std::vector< SdrCustomShapeInteraction > xRet;
602 Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
603 if ( xCustomShapeEngine.is() )
605 int i;
606 Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() );
607 for ( i = 0; i < xInteractionHandles.getLength(); i++ )
609 if ( xInteractionHandles[ i ].is() )
611 SdrCustomShapeInteraction aSdrCustomShapeInteraction;
612 aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
613 aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
615 sal_Int32 nMode = 0;
616 switch( ImpGetCustomShapeType( *this ) )
618 case mso_sptAccentBorderCallout90 : // 2 ortho
620 if ( !i )
621 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
622 else if ( i == 1)
623 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4;
625 break;
627 case mso_sptWedgeRectCallout :
628 case mso_sptWedgeRRectCallout :
629 case mso_sptCloudCallout :
630 case mso_sptWedgeEllipseCallout :
632 if ( !i )
633 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED;
635 break;
637 case mso_sptBorderCallout1 : // 2 diag
639 if ( !i )
640 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
641 else if ( i == 1 )
642 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
644 break;
645 case mso_sptBorderCallout2 : // 3
647 if ( !i )
648 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
649 else if ( i == 2 )
650 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
652 break;
653 case mso_sptCallout90 :
654 case mso_sptAccentCallout90 :
655 case mso_sptBorderCallout90 :
656 case mso_sptCallout1 :
657 case mso_sptCallout2 :
658 case mso_sptCallout3 :
659 case mso_sptAccentCallout1 :
660 case mso_sptAccentCallout2 :
661 case mso_sptAccentCallout3 :
662 case mso_sptBorderCallout3 :
663 case mso_sptAccentBorderCallout1 :
664 case mso_sptAccentBorderCallout2 :
665 case mso_sptAccentBorderCallout3 :
667 if ( !i )
668 nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
670 break;
671 default: break;
673 aSdrCustomShapeInteraction.nMode = nMode;
674 xRet.push_back( aSdrCustomShapeInteraction );
679 catch( const uno::RuntimeException& )
682 return xRet;
685 //////////////////////////////////////////////////////////////////////////////
686 // BaseProperties section
687 #define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000)
688 #define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff)
690 static sal_Int32 GetNumberOfProperties ( const SvxMSDffHandle* pData )
692 sal_Int32 nPropertiesNeeded=1; // position is always needed
693 sal_Int32 nFlags = pData->nFlags;
695 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
696 nPropertiesNeeded++;
697 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
698 nPropertiesNeeded++;
699 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
700 nPropertiesNeeded++;
701 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
703 nPropertiesNeeded++;
704 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
706 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
707 nPropertiesNeeded++;
708 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
709 nPropertiesNeeded++;
712 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
714 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
715 nPropertiesNeeded++;
716 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
717 nPropertiesNeeded++;
718 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
719 nPropertiesNeeded++;
720 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
721 nPropertiesNeeded++;
724 return nPropertiesNeeded;
727 static void lcl_ShapePropertiesFromDFF( const SvxMSDffHandle* pData, com::sun::star::beans::PropertyValues& rPropValues )
729 sal_Int32 nFlags = pData->nFlags, n=0;
731 // POSITION
733 const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
734 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
735 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
736 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
737 rPropValues[ n ].Name = sPosition;
738 rPropValues[ n++ ].Value <<= aPosition;
740 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
742 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
743 sal_Bool bMirroredX = sal_True;
744 rPropValues[ n ].Name = sMirroredX;
745 rPropValues[ n++ ].Value <<= bMirroredX;
747 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
749 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
750 sal_Bool bMirroredY = sal_True;
751 rPropValues[ n ].Name = sMirroredY;
752 rPropValues[ n++ ].Value <<= bMirroredY;
754 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
756 const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
757 sal_Bool bSwitched = sal_True;
758 rPropValues[ n ].Name = sSwitched;
759 rPropValues[ n++ ].Value <<= bSwitched;
761 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
763 const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
764 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
765 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
766 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True );
767 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
768 ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
769 rPropValues[ n ].Name = sPolar;
770 rPropValues[ n++ ].Value <<= aCenter;
771 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
773 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
775 const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
776 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
777 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
778 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
779 rPropValues[ n ].Name = sRadiusRangeMinimum;
780 rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
782 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
784 const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
785 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
786 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
787 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
788 rPropValues[ n ].Name = sRadiusRangeMaximum;
789 rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
793 else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
795 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
797 const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
798 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
799 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
800 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
801 rPropValues[ n ].Name = sRangeXMinimum;
802 rPropValues[ n++ ].Value <<= aRangeXMinimum;
804 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
806 const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
807 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
808 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
809 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
810 rPropValues[ n ].Name = sRangeXMaximum;
811 rPropValues[ n++ ].Value <<= aRangeXMaximum;
813 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
815 const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
816 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
817 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
818 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
819 rPropValues[ n ].Name = sRangeYMinimum;
820 rPropValues[ n++ ].Value <<= aRangeYMinimum;
822 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
824 const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
825 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
826 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
827 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
828 rPropValues[ n ].Name = sRangeYMaximum;
829 rPropValues[ n++ ].Value <<= aRangeYMaximum;
832 return;
835 sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties()
837 return new sdr::properties::CustomShapeProperties(*this);
840 TYPEINIT1(SdrObjCustomShape,SdrTextObj);
841 SdrObjCustomShape::SdrObjCustomShape() :
842 SdrTextObj(),
843 fObjectRotation( 0.0 ),
844 mpLastShadowGeometry(0L)
846 bTextFrame = sal_True;
849 SdrObjCustomShape::~SdrObjCustomShape()
851 // delete buffered display geometry
852 InvalidateRenderGeometry();
855 void SdrObjCustomShape::MergeDefaultAttributes( const rtl::OUString* pType )
857 PropertyValue aPropVal;
858 rtl::OUString sShapeType;
859 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
860 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
861 if ( pType && !pType->isEmpty() )
863 sal_Int32 nType = pType->toInt32();
864 if ( nType )
865 sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
866 else
867 sShapeType = *pType;
869 aPropVal.Name = sType;
870 aPropVal.Value <<= sShapeType;
871 aGeometryItem.SetPropertyValue( aPropVal );
873 else
875 Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
876 if ( pAny )
877 *pAny >>= sShapeType;
879 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
881 const sal_Int32* pDefData = NULL;
882 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
883 if ( pDefCustomShape )
884 pDefData = pDefCustomShape->pDefData;
886 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
888 //////////////////////
889 // AdjustmentValues //
890 //////////////////////
891 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
892 const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
893 if ( pAny )
894 *pAny >>= seqAdjustmentValues;
895 if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values
897 // first check if there are adjustment values are to be appended
898 sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
899 sal_Int32 nAdjustmentDefaults = *pDefData++;
900 if ( nAdjustmentDefaults > nAdjustmentValues )
902 seqAdjustmentValues.realloc( nAdjustmentDefaults );
903 for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
905 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
906 seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
909 // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
910 sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues;
911 for ( i = 0; i < nCount; i++ )
913 if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE )
915 seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
916 seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
920 aPropVal.Name = sAdjustmentValues;
921 aPropVal.Value <<= seqAdjustmentValues;
922 aGeometryItem.SetPropertyValue( aPropVal );
924 ///////////////
925 // Coordsize //
926 ///////////////
927 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
928 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
929 com::sun::star::awt::Rectangle aViewBox;
930 if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
932 if ( pDefCustomShape )
934 aViewBox.X = 0;
935 aViewBox.Y = 0;
936 aViewBox.Width = pDefCustomShape->nCoordWidth;
937 aViewBox.Height= pDefCustomShape->nCoordHeight;
938 aPropVal.Name = sViewBox;
939 aPropVal.Value <<= aViewBox;
940 aGeometryItem.SetPropertyValue( aPropVal );
944 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
946 //////////////////////
947 // Path/Coordinates //
948 //////////////////////
949 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
950 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
951 if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
953 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
955 sal_Int32 i, nCount = pDefCustomShape->nVertices;
956 seqCoordinates.realloc( nCount );
957 for ( i = 0; i < nCount; i++ )
959 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
960 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
962 aPropVal.Name = sCoordinates;
963 aPropVal.Value <<= seqCoordinates;
964 aGeometryItem.SetPropertyValue( sPath, aPropVal );
967 // Path/GluePoints //
968 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
969 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
970 if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
972 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
973 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
974 seqGluePoints.realloc( nCount );
975 for ( i = 0; i < nCount; i++ )
977 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
978 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
980 aPropVal.Name = sGluePoints;
981 aPropVal.Value <<= seqGluePoints;
982 aGeometryItem.SetPropertyValue( sPath, aPropVal );
985 // Path/Segments //
986 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
987 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
988 if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
990 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
992 sal_Int32 i, nCount = pDefCustomShape->nElements;
993 seqSegments.realloc( nCount );
994 for ( i = 0; i < nCount; i++ )
996 EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ];
997 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
998 lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
1000 aPropVal.Name = sSegments;
1001 aPropVal.Value <<= seqSegments;
1002 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1005 // Path/StretchX //
1006 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
1007 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1008 if ( !pAny && pDefCustomShape )
1010 sal_Int32 nXRef = pDefCustomShape->nXRef;
1011 if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1013 aPropVal.Name = sStretchX;
1014 aPropVal.Value <<= nXRef;
1015 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1019 // Path/StretchY //
1020 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
1021 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1022 if ( !pAny && pDefCustomShape )
1024 sal_Int32 nYRef = pDefCustomShape->nYRef;
1025 if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1027 aPropVal.Name = sStretchY;
1028 aPropVal.Value <<= nYRef;
1029 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1033 // Path/TextFrames //
1034 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
1035 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1036 if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1038 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames;
1040 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1041 seqTextFrames.realloc( nCount );
1042 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1043 for ( i = 0; i < nCount; i++, pRectangles++ )
1045 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1046 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1047 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1048 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1050 aPropVal.Name = sTextFrames;
1051 aPropVal.Value <<= seqTextFrames;
1052 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1055 // Equations //
1056 const rtl::OUString sEquations( "Equations" );
1057 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1058 if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1060 com::sun::star::uno::Sequence< rtl::OUString > seqEquations;
1062 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1063 seqEquations.realloc( nCount );
1064 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1065 for ( i = 0; i < nCount; i++, pData++ )
1066 seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1067 aPropVal.Name = sEquations;
1068 aPropVal.Value <<= seqEquations;
1069 aGeometryItem.SetPropertyValue( aPropVal );
1072 // Handles //
1073 const rtl::OUString sHandles( "Handles" );
1074 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1075 if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1077 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles;
1079 sal_Int32 i, nCount = pDefCustomShape->nHandles;
1080 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1081 seqHandles.realloc( nCount );
1082 for ( i = 0; i < nCount; i++, pData++ )
1084 sal_Int32 nPropertiesNeeded;
1085 com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ];
1086 nPropertiesNeeded = GetNumberOfProperties( pData );
1087 rPropValues.realloc( nPropertiesNeeded );
1088 lcl_ShapePropertiesFromDFF( pData, rPropValues );
1090 aPropVal.Name = sHandles;
1091 aPropVal.Value <<= seqHandles;
1092 aGeometryItem.SetPropertyValue( aPropVal );
1094 SetMergedItem( aGeometryItem );
1097 sal_Bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const
1099 sal_Bool bIsDefaultGeometry = sal_False;
1101 PropertyValue aPropVal;
1102 rtl::OUString sShapeType;
1103 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1104 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1106 Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
1107 if ( pAny )
1108 *pAny >>= sShapeType;
1110 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1112 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
1113 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1114 switch( eDefaultType )
1116 case DEFAULT_VIEWBOX :
1118 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
1119 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
1120 com::sun::star::awt::Rectangle aViewBox;
1121 if ( pViewBox && ( *pViewBox >>= aViewBox ) )
1123 if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
1124 && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
1125 bIsDefaultGeometry = sal_True;
1128 break;
1130 case DEFAULT_PATH :
1132 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1133 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
1134 if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
1136 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
1137 if ( *pAny >>= seqCoordinates1 )
1139 sal_Int32 i, nCount = pDefCustomShape->nVertices;
1140 seqCoordinates2.realloc( nCount );
1141 for ( i = 0; i < nCount; i++ )
1143 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
1144 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
1146 if ( seqCoordinates1 == seqCoordinates2 )
1147 bIsDefaultGeometry = sal_True;
1150 else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) )
1151 bIsDefaultGeometry = sal_True;
1153 break;
1155 case DEFAULT_GLUEPOINTS :
1157 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1158 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
1159 if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
1161 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2;
1162 if ( *pAny >>= seqGluePoints1 )
1164 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
1165 seqGluePoints2.realloc( nCount );
1166 for ( i = 0; i < nCount; i++ )
1168 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
1169 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
1171 if ( seqGluePoints1 == seqGluePoints2 )
1172 bIsDefaultGeometry = sal_True;
1175 else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
1176 bIsDefaultGeometry = sal_True;
1178 break;
1180 case DEFAULT_SEGMENTS :
1182 // Path/Segments //
1183 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1184 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
1185 if ( pAny )
1187 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2;
1188 if ( *pAny >>= seqSegments1 )
1190 if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1192 sal_Int32 i, nCount = pDefCustomShape->nElements;
1193 if ( nCount )
1195 seqSegments2.realloc( nCount );
1196 for ( i = 0; i < nCount; i++ )
1198 EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ];
1199 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1200 lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
1202 if ( seqSegments1 == seqSegments2 )
1203 bIsDefaultGeometry = sal_True;
1206 else
1208 // check if its the default segment description ( M L Z N )
1209 if ( seqSegments1.getLength() == 4 )
1211 if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO )
1212 && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO )
1213 && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
1214 && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
1215 bIsDefaultGeometry = sal_True;
1220 else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) )
1221 bIsDefaultGeometry = sal_True;
1223 break;
1225 case DEFAULT_STRETCHX :
1227 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
1228 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1229 if ( pAny && pDefCustomShape )
1231 sal_Int32 nStretchX = 0;
1232 if ( *pAny >>= nStretchX )
1234 if ( pDefCustomShape->nXRef == nStretchX )
1235 bIsDefaultGeometry = sal_True;
1238 else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1239 bIsDefaultGeometry = sal_True;
1241 break;
1243 case DEFAULT_STRETCHY :
1245 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
1246 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1247 if ( pAny && pDefCustomShape )
1249 sal_Int32 nStretchY = 0;
1250 if ( *pAny >>= nStretchY )
1252 if ( pDefCustomShape->nYRef == nStretchY )
1253 bIsDefaultGeometry = sal_True;
1256 else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1257 bIsDefaultGeometry = sal_True;
1259 break;
1261 case DEFAULT_EQUATIONS :
1263 const rtl::OUString sEquations( "Equations" );
1264 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1265 if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1267 com::sun::star::uno::Sequence< rtl::OUString > seqEquations1, seqEquations2;
1268 if ( *pAny >>= seqEquations1 )
1270 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1271 seqEquations2.realloc( nCount );
1273 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1274 for ( i = 0; i < nCount; i++, pData++ )
1275 seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1277 if ( seqEquations1 == seqEquations2 )
1278 bIsDefaultGeometry = sal_True;
1281 else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) )
1282 bIsDefaultGeometry = sal_True;
1284 break;
1286 case DEFAULT_TEXTFRAMES :
1288 const rtl::OUString sTextFrames( "TextFrames" );
1289 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1290 if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1292 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2;
1293 if ( *pAny >>= seqTextFrames1 )
1295 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1296 seqTextFrames2.realloc( nCount );
1297 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1298 for ( i = 0; i < nCount; i++, pRectangles++ )
1300 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1301 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1302 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1303 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1305 if ( seqTextFrames1 == seqTextFrames2 )
1306 bIsDefaultGeometry = sal_True;
1309 else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) )
1310 bIsDefaultGeometry = sal_True;
1312 break;
1314 case DEFAULT_HANDLES :
1316 const rtl::OUString sHandles( "Handles" );
1317 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1318 if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1320 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2;
1321 if ( *pAny >>= seqHandles1 )
1323 sal_Int32 i, nCount = pDefCustomShape->nHandles;
1324 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1325 seqHandles2.realloc( nCount );
1326 for ( i = 0; i < nCount; i++, pData++ )
1328 sal_Int32 nPropertiesNeeded;
1329 com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ];
1330 nPropertiesNeeded = GetNumberOfProperties( pData );
1331 rPropValues.realloc( nPropertiesNeeded );
1332 lcl_ShapePropertiesFromDFF( pData, rPropValues );
1334 if ( seqHandles1 == seqHandles2 )
1335 bIsDefaultGeometry = sal_True;
1338 else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) )
1339 bIsDefaultGeometry = sal_True;
1341 break;
1343 return bIsDefaultGeometry;
1346 void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1348 rInfo.bResizeFreeAllowed=fObjectRotation == 0.0;
1349 rInfo.bResizePropAllowed=sal_True;
1350 rInfo.bRotateFreeAllowed=sal_True;
1351 rInfo.bRotate90Allowed =sal_True;
1352 rInfo.bMirrorFreeAllowed=sal_True;
1353 rInfo.bMirror45Allowed =sal_True;
1354 rInfo.bMirror90Allowed =sal_True;
1355 rInfo.bTransparenceAllowed = sal_False;
1356 rInfo.bGradientAllowed = sal_False;
1357 rInfo.bShearAllowed =sal_True;
1358 rInfo.bEdgeRadiusAllowed=sal_False;
1359 rInfo.bNoContortion =sal_True;
1361 // #i37011#
1362 if ( mXRenderedCustomShape.is() )
1364 const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1365 if ( pRenderedCustomShape )
1367 // #i37262#
1368 // Iterate self over the contained objects, since there are combinations of
1369 // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1370 // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1371 SdrObjListIter aIterator(*pRenderedCustomShape);
1372 while(aIterator.IsMore())
1374 SdrObject* pCandidate = aIterator.Next();
1375 SdrObjTransformInfoRec aInfo;
1376 pCandidate->TakeObjInfo(aInfo);
1378 // set path and poly conversion if one is possible since
1379 // this object will first be broken
1380 const bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
1381 if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
1383 rInfo.bCanConvToPath = bCanConvToPathOrPoly;
1386 if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
1388 rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
1391 if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
1393 rInfo.bCanConvToContour = aInfo.bCanConvToContour;
1396 if(rInfo.bShearAllowed != aInfo.bShearAllowed)
1398 rInfo.bShearAllowed = aInfo.bShearAllowed;
1401 if(rInfo.bEdgeRadiusAllowed != aInfo.bEdgeRadiusAllowed)
1403 rInfo.bEdgeRadiusAllowed = aInfo.bEdgeRadiusAllowed;
1410 void SdrObjCustomShape::SetModel(SdrModel* pNewModel)
1412 SdrTextObj::SetModel(pNewModel);
1413 mXRenderedCustomShape.clear();
1416 sal_uInt16 SdrObjCustomShape::GetObjIdentifier() const
1418 return sal_uInt16(OBJ_CUSTOMSHAPE);
1421 ////////////////////////////////////////////////////////////////////////////////////////////////////
1423 void SdrObjCustomShape::RecalcSnapRect()
1425 SdrTextObj::RecalcSnapRect();
1427 const Rectangle& SdrObjCustomShape::GetSnapRect() const
1429 return SdrTextObj::GetSnapRect();
1431 const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const
1433 return SdrTextObj::GetCurrentBoundRect();
1435 const Rectangle& SdrObjCustomShape::GetLogicRect() const
1437 return SdrTextObj::GetLogicRect();
1439 void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect )
1441 aRect=rRect;
1442 ImpJustifyRect(aRect);
1443 InvalidateRenderGeometry();
1444 Rectangle aTextBound( aRect );
1445 if ( GetTextBounds( aTextBound ) )
1447 if ( pModel==NULL || !pModel->IsPasteResize() )
1449 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1450 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1451 long nTWdt=aTextBound.GetWidth ()-1-nHDist; if (nTWdt<0) nTWdt=0;
1452 long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1453 if ( IsAutoGrowWidth() )
1454 NbcSetMinTextFrameWidth( nTWdt );
1455 if ( IsAutoGrowHeight() )
1456 NbcSetMinTextFrameHeight( nTHgt );
1457 NbcAdjustTextFrameWidthAndHeight();
1460 ImpCheckShear();
1461 SetRectsDirty();
1462 SetChanged();
1464 void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect )
1466 Rectangle aBoundRect0;
1467 if ( pUserCall )
1468 aBoundRect0 = GetLastBoundRect();
1469 NbcSetSnapRect( rRect );
1470 BroadcastObjectChange();
1471 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1473 void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect )
1475 aRect = rRect;
1476 ImpJustifyRect( aRect );
1477 InvalidateRenderGeometry();
1478 Rectangle aTextBound( aRect );
1479 if ( GetTextBounds( aTextBound ) )
1481 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
1482 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
1484 long nTWdt=aTextBound.GetWidth()-1-nHDist; if (nTWdt<0) nTWdt=0;
1485 long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
1486 if ( IsAutoGrowWidth() )
1487 NbcSetMinTextFrameWidth( nTWdt );
1488 if ( IsAutoGrowHeight() )
1489 NbcSetMinTextFrameHeight( nTHgt );
1490 NbcAdjustTextFrameWidthAndHeight();
1492 SetRectsDirty();
1493 SetChanged();
1495 void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect )
1497 Rectangle aBoundRect0;
1498 if ( pUserCall )
1499 aBoundRect0 = GetLastBoundRect();
1500 NbcSetLogicRect(rRect);
1501 BroadcastObjectChange();
1502 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1504 void SdrObjCustomShape::Move( const Size& rSiz )
1506 if ( rSiz.Width() || rSiz.Height() )
1508 Rectangle aBoundRect0;
1509 if ( pUserCall )
1510 aBoundRect0 = GetLastBoundRect();
1511 NbcMove(rSiz);
1512 SetChanged();
1513 BroadcastObjectChange();
1514 SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1517 void SdrObjCustomShape::NbcMove( const Size& rSiz )
1519 SdrTextObj::NbcMove( rSiz );
1520 if ( mXRenderedCustomShape.is() )
1522 SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1523 if ( pRenderedCustomShape )
1525 // #i97149# the visualisation shape needs to be informed
1526 // about change, too
1527 pRenderedCustomShape->ActionChanged();
1528 pRenderedCustomShape->NbcMove( rSiz );
1532 // #i37011# adapt geometry shadow
1533 if(mpLastShadowGeometry)
1535 mpLastShadowGeometry->NbcMove( rSiz );
1538 void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact )
1540 SdrTextObj::Resize( rRef, xFact, yFact );
1543 void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
1545 Fraction xFact( rxFact );
1546 Fraction yFact( ryFact );
1548 // taking care of handles that should not been changed
1549 Rectangle aOld( aRect );
1550 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1552 SdrTextObj::NbcResize( rRef, xFact, yFact );
1554 if ( ( xFact.GetNumerator() != xFact.GetDenominator() )
1555 || ( yFact.GetNumerator()!= yFact.GetDenominator() ) )
1557 if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) ||
1558 ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) )
1560 SetMirroredX( IsMirroredX() == sal_False );
1562 if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) ||
1563 ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) )
1565 SetMirroredY( IsMirroredY() == sal_False );
1569 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
1570 while ( aIter != aInteractionHandles.end() )
1574 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
1575 aIter->xInteraction->setControllerPosition( aIter->aPosition );
1576 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
1578 sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left();
1579 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
1581 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
1583 sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top();
1584 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
1587 catch ( const uno::RuntimeException& )
1590 aIter++;
1592 InvalidateRenderGeometry();
1594 void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs )
1596 sal_Bool bMirroredX = IsMirroredX();
1597 sal_Bool bMirroredY = IsMirroredY();
1599 fObjectRotation = fmod( fObjectRotation, 360.0 );
1600 if ( fObjectRotation < 0 )
1601 fObjectRotation = 360 + fObjectRotation;
1603 // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1604 // has to be applied to the text object (which is internally using aGeo.nWink).
1605 SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink, // retrieving the unrotated text object
1606 sin( (-aGeo.nDrehWink) * F_PI18000 ),
1607 cos( (-aGeo.nDrehWink) * F_PI18000 ) );
1608 aGeo.nDrehWink = 0; // resetting aGeo data
1609 aGeo.RecalcSinCos();
1611 long nW = (long)( fObjectRotation * 100 ); // applying our object rotation
1612 if ( bMirroredX )
1613 nW = 36000 - nW;
1614 if ( bMirroredY )
1615 nW = 18000 - nW;
1616 nW = nW % 36000;
1617 if ( nW < 0 )
1618 nW = 36000 + nW;
1619 SdrTextObj::NbcRotate( aRect.TopLeft(), nW, // applying text rotation
1620 sin( nW * F_PI18000 ),
1621 cos( nW * F_PI18000 ) );
1623 int nSwap = 0;
1624 if ( bMirroredX )
1625 nSwap ^= 1;
1626 if ( bMirroredY )
1627 nSwap ^= 1;
1629 double fWink = nWink; // updating to our new object rotation
1630 fWink /= 100.0;
1631 fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 );
1632 if ( fObjectRotation < 0 )
1633 fObjectRotation = 360 + fObjectRotation;
1635 SdrTextObj::NbcRotate( rRef, nWink, sn, cs ); // applying text rotation
1636 InvalidateRenderGeometry();
1639 void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
1641 // storing horizontal and vertical flipping without modifying the rotate angle
1642 sal_Bool bHorz = sal_False;
1643 sal_Bool bVert = sal_False;
1644 if ( rRef1.X() == rRef2.X() )
1645 bHorz = sal_True;
1646 if ( rRef1.Y() == rRef2.Y() )
1647 bVert = sal_True;
1648 if ( !bHorz && !bVert )
1649 bHorz = bVert = sal_True;
1651 if ( bHorz || bVert )
1653 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1655 // "MirroredX" //
1656 if ( bHorz )
1658 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1659 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
1660 if ( pAny )
1662 sal_Bool bFlip = sal_Bool();
1663 if ( *pAny >>= bFlip )
1665 if ( bFlip )
1666 bHorz = sal_False;
1669 PropertyValue aPropVal;
1670 aPropVal.Name = sMirroredX;
1671 aPropVal.Value <<= bHorz;
1672 aGeometryItem.SetPropertyValue( aPropVal );
1675 // "MirroredY" //
1676 if ( bVert )
1678 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1679 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
1680 if ( pAny )
1682 sal_Bool bFlip = sal_Bool();
1683 if ( *pAny >>= bFlip )
1685 if ( bFlip )
1686 bVert = sal_False;
1689 PropertyValue aPropVal;
1690 aPropVal.Name = sMirroredY;
1691 aPropVal.Value <<= bVert;
1692 aGeometryItem.SetPropertyValue( aPropVal );
1694 SetMergedItem( aGeometryItem );
1696 SdrTextObj::NbcMirror( rRef1, rRef2 );
1697 InvalidateRenderGeometry();
1700 void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, bool bVShear )
1702 SdrTextObj::Shear( rRef, nWink, tn, bVShear );
1703 InvalidateRenderGeometry();
1705 void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, bool bVShear )
1707 long nDrehWink = aGeo.nDrehWink;
1708 if ( nDrehWink )
1710 aGeo.nDrehWink = -nDrehWink;
1711 aGeo.RecalcSinCos();
1712 NbcRotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
1714 SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
1715 if ( nDrehWink )
1717 aGeo.nDrehWink = nDrehWink;
1718 aGeo.RecalcSinCos();
1719 Rotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
1721 InvalidateRenderGeometry();
1724 ////////////////////////////////////////////////////////////////////////////////////////////////////
1726 SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum) const
1728 sal_Int32 nWdt = ImpGetLineWdt(); // #i25616#
1730 // #i25616#
1731 if(!LineIsOutsideGeometry())
1733 nWdt++;
1734 nWdt /= 2;
1737 Point aPt;
1738 switch (nPosNum) {
1739 case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break;
1740 case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break;
1741 case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
1742 case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break;
1744 if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
1745 if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1746 aPt-=GetSnapRect().Center();
1747 SdrGluePoint aGP(aPt);
1748 aGP.SetPercent(sal_False);
1749 return aGP;
1752 ////////////////////////////////////////////////////////////////////////////////////////////////////
1754 // #i38892#
1755 void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
1757 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
1759 if(pSdrObject)
1761 const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
1763 if(pSource && pSource->GetCount())
1765 if(!SdrTextObj::GetGluePointList())
1767 SdrTextObj::ForceGluePointList();
1770 const SdrGluePointList* pList = SdrTextObj::GetGluePointList();
1772 if(pList)
1774 SdrGluePointList aNewList;
1775 sal_uInt16 a;
1777 for(a = 0; a < pSource->GetCount(); a++)
1779 SdrGluePoint aCopy((*pSource)[a]);
1780 aCopy.SetUserDefined(sal_False);
1781 aNewList.Insert(aCopy);
1784 sal_Bool bMirroredX = IsMirroredX();
1785 sal_Bool bMirroredY = IsMirroredY();
1787 long nShearWink = aGeo.nShearWink;
1788 double fTan = aGeo.nTan;
1790 if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY )
1792 Polygon aPoly( aRect );
1793 if( nShearWink )
1795 sal_uInt16 nPointCount=aPoly.GetSize();
1796 for (sal_uInt16 i=0; i<nPointCount; i++)
1797 ShearPoint(aPoly[i],aRect.Center(), fTan, sal_False );
1799 if ( aGeo.nDrehWink )
1800 aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 );
1802 Rectangle aBoundRect( aPoly.GetBoundRect() );
1803 sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left();
1804 sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top();
1806 if (nShearWink&&((bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX)))
1808 nShearWink = -nShearWink;
1809 fTan = -fTan;
1812 Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
1813 for ( a = 0; a < aNewList.GetCount(); a++ )
1815 SdrGluePoint& rPoint = aNewList[ a ];
1816 Point aGlue( rPoint.GetPos() );
1817 if ( nShearWink )
1818 ShearPoint( aGlue, aRef, fTan );
1820 RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) );
1821 if ( bMirroredX )
1822 aGlue.X() = aRect.GetWidth() - aGlue.X();
1823 if ( bMirroredY )
1824 aGlue.Y() = aRect.GetHeight() - aGlue.Y();
1825 aGlue.X() -= nXDiff;
1826 aGlue.Y() -= nYDiff;
1827 rPoint.SetPos( aGlue );
1831 for(a = 0; a < pList->GetCount(); a++)
1833 const SdrGluePoint& rCandidate = (*pList)[a];
1835 if(rCandidate.IsUserDefined())
1837 aNewList.Insert(rCandidate);
1841 // copy new list to local. This is NOT very convenient behavior, the local
1842 // GluePointList should not be set, but we delivered by using GetGluePointList(),
1843 // maybe on demand. Since the local object is changed here, this is assumed to
1844 // be a result of GetGluePointList and thus the list is copied
1845 if(pPlusData)
1847 pPlusData->SetGluePoints(aNewList);
1854 // #i38892#
1855 const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const
1857 ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded();
1858 return SdrTextObj::GetGluePointList();
1861 // #i38892#
1862 SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
1864 if(SdrTextObj::ForceGluePointList())
1866 ImpCheckCustomGluePointsAreAdded();
1867 return SdrTextObj::ForceGluePointList();
1869 else
1871 return 0L;
1875 ////////////////////////////////////////////////////////////////////////////////////////////////////
1877 sal_uInt32 SdrObjCustomShape::GetHdlCount() const
1879 const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
1880 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1881 return ( aInteractionHandles.size() + nBasicHdlCount );
1884 SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
1886 SdrHdl* pH = NULL;
1887 const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
1889 if ( nHdlNum < nBasicHdlCount )
1890 pH = SdrTextObj::GetHdl( nHdlNum );
1891 else
1893 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1894 const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);
1896 if ( nCustomShapeHdlNum < aInteractionHandles.size() )
1898 if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
1902 com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
1903 pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 );
1904 pH->SetPointNum( nCustomShapeHdlNum );
1905 pH->SetObj( (SdrObject*)this );
1907 catch ( const uno::RuntimeException& )
1913 return pH;
1916 ////////////////////////////////////////////////////////////////////////////////////////////////////
1918 bool SdrObjCustomShape::hasSpecialDrag() const
1920 return true;
1923 bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const
1925 const SdrHdl* pHdl = rDrag.GetHdl();
1927 if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind())
1929 rDrag.SetEndDragChangesAttributes(true);
1930 rDrag.SetNoSnap(true);
1932 else
1934 const SdrHdl* pHdl2 = rDrag.GetHdl();
1935 const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind());
1937 switch( eHdl )
1939 case HDL_UPLFT :
1940 case HDL_UPPER :
1941 case HDL_UPRGT :
1942 case HDL_LEFT :
1943 case HDL_RIGHT :
1944 case HDL_LWLFT :
1945 case HDL_LOWER :
1946 case HDL_LWRGT :
1947 case HDL_MOVE :
1949 break;
1951 default:
1953 return false;
1958 return true;
1961 void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const
1963 Rectangle aOld( pObj->aRect );
1964 sal_Bool bOldMirroredX( pObj->IsMirroredX() );
1965 sal_Bool bOldMirroredY( pObj->IsMirroredY() );
1967 Rectangle aNewRect( rNewRect );
1968 aNewRect.Justify();
1970 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
1972 GeoStat aGeoStat( pObj->GetGeoStat() );
1973 if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() &&
1974 ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) )
1976 Point aNewPos( aNewRect.TopLeft() );
1977 if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan );
1978 if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos );
1979 aNewRect.SetPos( aNewPos );
1981 if ( aNewRect != pObj->aRect )
1983 pObj->SetLogicRect( aNewRect );
1984 pObj->InvalidateRenderGeometry();
1986 if ( rNewRect.Left() > rNewRect.Right() )
1988 Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() );
1989 Point aBottom( aTop.X(), aTop.Y() + 1000 );
1990 pObj->NbcMirror( aTop, aBottom );
1992 if ( rNewRect.Top() > rNewRect.Bottom() )
1994 Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 );
1995 Point aRight( aLeft.X() + 1000, aLeft.Y() );
1996 pObj->NbcMirror( aLeft, aRight );
1999 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2000 while ( aIter != aInteractionHandles.end() )
2004 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2005 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2006 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
2008 sal_Int32 nX;
2009 if ( bOldMirroredX )
2011 nX = ( aIter->aPosition.X - aOld.Right() );
2012 if ( rNewRect.Left() > rNewRect.Right() )
2013 nX = pObj->aRect.Left() - nX;
2014 else
2015 nX += pObj->aRect.Right();
2017 else
2019 nX = ( aIter->aPosition.X - aOld.Left() );
2020 if ( rNewRect.Left() > rNewRect.Right() )
2021 nX = pObj->aRect.Right() - nX;
2022 else
2023 nX += pObj->aRect.Left();
2025 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
2027 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
2029 sal_Int32 nY;
2030 if ( bOldMirroredY )
2032 nY = ( aIter->aPosition.Y - aOld.Bottom() );
2033 if ( rNewRect.Top() > rNewRect.Bottom() )
2034 nY = pObj->aRect.Top() - nY;
2035 else
2036 nY += pObj->aRect.Bottom();
2038 else
2040 nY = ( aIter->aPosition.Y - aOld.Top() );
2041 if ( rNewRect.Top() > rNewRect.Bottom() )
2042 nY = pObj->aRect.Bottom() - nY;
2043 else
2044 nY += pObj->aRect.Top();
2046 aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
2049 catch ( const uno::RuntimeException& )
2052 aIter++;
2057 void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const
2059 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2060 if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2062 SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
2063 if ( aInteractionHandle.xInteraction.is() )
2067 com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() );
2068 if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE )
2070 sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
2071 sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
2073 pObj->aRect.Move( nXDiff, nYDiff );
2074 pObj->aOutRect.Move( nXDiff, nYDiff );
2075 pObj->maSnapRect.Move( nXDiff, nYDiff );
2076 pObj->SetRectsDirty(sal_True);
2077 pObj->InvalidateRenderGeometry();
2079 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2080 while ( aIter != aInteractionHandles.end() )
2082 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2084 if ( aIter->xInteraction.is() )
2085 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2087 aIter++;
2090 aInteractionHandle.xInteraction->setControllerPosition( aPt );
2092 catch ( const uno::RuntimeException& )
2099 bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag)
2101 const SdrHdl* pHdl = rDrag.GetHdl();
2102 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2104 switch(eHdl)
2106 case HDL_CUSTOMSHAPE1 :
2108 rDrag.SetEndDragChangesGeoAndAttributes(true);
2109 DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this );
2110 SetRectsDirty();
2111 InvalidateRenderGeometry();
2112 SetChanged();
2113 break;
2116 case HDL_UPLFT :
2117 case HDL_UPPER :
2118 case HDL_UPRGT :
2119 case HDL_LEFT :
2120 case HDL_RIGHT :
2121 case HDL_LWLFT :
2122 case HDL_LOWER :
2123 case HDL_LWRGT :
2125 DragResizeCustomShape(ImpDragCalcRect(rDrag), this);
2126 break;
2128 case HDL_MOVE :
2130 Move(Size(rDrag.GetDX(), rDrag.GetDY()));
2131 break;
2133 default: break;
2136 return true;
2139 ////////////////////////////////////////////////////////////////////////////////////////////////////
2141 void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat )
2143 Rectangle aRect1;
2144 rStat.TakeCreateRect( aRect1 );
2146 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2148 sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ?
2149 sal_uInt32 nDefaultObjectSizeHeight= 3000;
2151 if ( ImpVerticalSwitch( *this ) )
2153 SetMirroredX( aRect1.Left() > aRect1.Right() );
2155 aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
2156 // subtracting the horizontal difference of the latest handle from shape position
2157 if ( !aInteractionHandles.empty() )
2159 sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
2160 aRect1.Move( aRect.Left() - nHandlePos, 0 );
2163 ImpJustifyRect( aRect1 );
2164 rStat.SetActionRect( aRect1 );
2165 aRect = aRect1;
2166 SetRectsDirty();
2168 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2169 while ( aIter != aInteractionHandles.end() )
2173 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED )
2174 aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
2176 catch ( const uno::RuntimeException& )
2179 aIter++;
2182 SetBoundRectDirty();
2183 bSnapRectDirty=sal_True;
2186 bool SdrObjCustomShape::BegCreate( SdrDragStat& rDrag )
2188 return SdrTextObj::BegCreate( rDrag );
2191 bool SdrObjCustomShape::MovCreate(SdrDragStat& rStat)
2193 SdrView* pView = rStat.GetView(); // #i37448#
2194 if( pView && pView->IsSolidDragging() )
2196 InvalidateRenderGeometry();
2198 DragCreateObject( rStat );
2199 SetRectsDirty();
2200 return sal_True;
2203 bool SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
2205 DragCreateObject( rStat );
2207 if ( bTextFrame )
2209 if ( IsAutoGrowHeight() )
2211 // MinTextHeight
2212 long nHgt=aRect.GetHeight()-1;
2213 if (nHgt==1) nHgt=0;
2214 NbcSetMinTextFrameHeight( nHgt );
2216 if ( IsAutoGrowWidth() )
2218 // MinTextWidth
2219 long nWdt=aRect.GetWidth()-1;
2220 if (nWdt==1) nWdt=0;
2221 NbcSetMinTextFrameWidth( nWdt );
2223 // re-calculate text frame
2224 NbcAdjustTextFrameWidthAndHeight();
2226 SetRectsDirty();
2227 return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 );
2230 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
2232 return GetLineGeometry( this, sal_False );
2235 ////////////////////////////////////////////////////////////////////////////////////////////////////
2237 // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2238 // the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
2239 bool SdrObjCustomShape::IsAutoGrowHeight() const
2241 const SfxItemSet& rSet = GetMergedItemSet();
2242 bool bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2243 if ( bIsAutoGrowHeight && IsVerticalWriting() )
2244 bIsAutoGrowHeight = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False;
2245 return bIsAutoGrowHeight;
2247 bool SdrObjCustomShape::IsAutoGrowWidth() const
2249 const SfxItemSet& rSet = GetMergedItemSet();
2250 bool bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2251 if ( bIsAutoGrowWidth && !IsVerticalWriting() )
2252 bIsAutoGrowWidth = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False;
2253 return bIsAutoGrowWidth;
2256 /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2257 is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2258 mode has been changed */
2260 void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical )
2262 ForceOutlinerParaObject();
2264 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2266 DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2268 if( pOutlinerParaObject )
2270 if(pOutlinerParaObject->IsVertical() != (bool)bVertical)
2272 // get item settings
2273 const SfxItemSet& rSet = GetObjectItemSet();
2275 // Also exchange horizontal and vertical adjust items
2276 SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
2277 SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
2279 // rescue object size
2280 Rectangle aObjectRect = GetSnapRect();
2282 // prepare ItemSet to set exchanged width and height items
2283 SfxItemSet aNewSet(*rSet.GetPool(),
2284 SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
2285 // Expanded item ranges to also support horizontal and vertical adjust.
2286 SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
2287 SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
2288 0, 0);
2290 aNewSet.Put(rSet);
2292 // Exchange horizontal and vertical adjusts
2293 switch(eVert)
2295 case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
2296 case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
2297 case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
2298 case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
2300 switch(eHorz)
2302 case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
2303 case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
2304 case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
2305 case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
2308 SetObjectItemSet( aNewSet );
2309 pOutlinerParaObject = GetOutlinerParaObject();
2310 if ( pOutlinerParaObject )
2311 pOutlinerParaObject->SetVertical(bVertical);
2313 // restore object size
2314 SetSnapRect(aObjectRect);
2318 bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, bool bHgt, bool bWdt) const
2320 if ( pModel && HasText() && !rR.IsEmpty() )
2322 bool bWdtGrow=bWdt && IsAutoGrowWidth();
2323 bool bHgtGrow=bHgt && IsAutoGrowHeight();
2324 if ( bWdtGrow || bHgtGrow )
2326 Rectangle aR0(rR);
2327 long nHgt=0,nMinHgt=0,nMaxHgt=0;
2328 long nWdt=0,nMinWdt=0,nMaxWdt=0;
2329 Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
2330 Size aMaxSiz(100000,100000);
2331 Size aTmpSiz(pModel->GetMaxObjSize());
2332 if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2333 if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2334 if (bWdtGrow)
2336 nMinWdt=GetMinTextFrameWidth();
2337 nMaxWdt=GetMaxTextFrameWidth();
2338 if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
2339 if (nMinWdt<=0) nMinWdt=1;
2340 aSiz.Width()=nMaxWdt;
2342 if (bHgtGrow)
2344 nMinHgt=GetMinTextFrameHeight();
2345 nMaxHgt=GetMaxTextFrameHeight();
2346 if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
2347 if (nMinHgt<=0) nMinHgt=1;
2348 aSiz.Height()=nMaxHgt;
2350 long nHDist=GetTextLeftDistance()+GetTextRightDistance();
2351 long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
2352 aSiz.Width()-=nHDist;
2353 aSiz.Height()-=nVDist;
2354 if ( aSiz.Width() < 2 )
2355 aSiz.Width() = 2; // minimum size=2
2356 if ( aSiz.Height() < 2 )
2357 aSiz.Height() = 2; // minimum size=2
2359 if(pEdtOutl)
2361 pEdtOutl->SetMaxAutoPaperSize( aSiz );
2362 if (bWdtGrow)
2364 Size aSiz2(pEdtOutl->CalcTextSize());
2365 nWdt=aSiz2.Width()+1; // a little more tolerance
2366 if (bHgtGrow) nHgt=aSiz2.Height()+1; // a little more tolerance
2367 } else
2369 nHgt=pEdtOutl->GetTextHeight()+1; // a little more tolerance
2372 else
2374 Outliner& rOutliner=ImpGetDrawOutliner();
2375 rOutliner.SetPaperSize(aSiz);
2376 rOutliner.SetUpdateMode(sal_True);
2377 // TODO: add the optimization with bPortionInfoChecked again.
2378 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2379 if( pOutlinerParaObject != NULL )
2381 rOutliner.SetText(*pOutlinerParaObject);
2382 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
2384 if ( bWdtGrow )
2386 Size aSiz2(rOutliner.CalcTextSize());
2387 nWdt=aSiz2.Width()+1; // a little more tolerance
2388 if ( bHgtGrow )
2389 nHgt=aSiz2.Height()+1; // a little more tolerance
2391 else
2392 nHgt = rOutliner.GetTextHeight()+1; // a little more tolerance
2393 rOutliner.Clear();
2395 if ( nWdt < nMinWdt )
2396 nWdt = nMinWdt;
2397 if ( nWdt > nMaxWdt )
2398 nWdt = nMaxWdt;
2399 nWdt += nHDist;
2400 if ( nWdt < 1 )
2401 nWdt = 1; // nHDist may also be negative
2402 if ( nHgt < nMinHgt )
2403 nHgt = nMinHgt;
2404 if ( nHgt > nMaxHgt )
2405 nHgt = nMaxHgt;
2406 nHgt+=nVDist;
2407 if ( nHgt < 1 )
2408 nHgt = 1; // nVDist may also be negative
2409 long nWdtGrow = nWdt-(rR.Right()-rR.Left());
2410 long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
2411 if ( nWdtGrow == 0 )
2412 bWdtGrow = sal_False;
2413 if ( nHgtGrow == 0 )
2414 bHgtGrow=sal_False;
2415 if ( bWdtGrow || bHgtGrow )
2417 if ( bWdtGrow )
2419 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2420 if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2421 rR.Right()+=nWdtGrow;
2422 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2423 rR.Left()-=nWdtGrow;
2424 else
2426 long nWdtGrow2=nWdtGrow/2;
2427 rR.Left()-=nWdtGrow2;
2428 rR.Right()=rR.Left()+nWdt;
2431 if ( bHgtGrow )
2433 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2434 if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2435 rR.Bottom()+=nHgtGrow;
2436 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2437 rR.Top()-=nHgtGrow;
2438 else
2440 long nHgtGrow2=nHgtGrow/2;
2441 rR.Top()-=nHgtGrow2;
2442 rR.Bottom()=rR.Top()+nHgt;
2445 if ( aGeo.nDrehWink )
2447 Point aD1(rR.TopLeft());
2448 aD1-=aR0.TopLeft();
2449 Point aD2(aD1);
2450 RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
2451 aD2-=aD1;
2452 rR.Move(aD2.X(),aD2.Y());
2454 return sal_True;
2458 return sal_False;
2461 Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const bool bHgt, const bool bWdt )
2463 Rectangle aReturnValue;
2465 Rectangle aOldTextRect( aRect ); // <- initial text rectangle
2467 Rectangle aNewTextRect( aRect ); // <- new text rectangle returned from the custom shape renderer,
2468 GetTextBounds( aNewTextRect ); // it depends to the current logical shape size
2470 Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2471 if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner
2473 if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) )
2475 aReturnValue = aRect;
2476 double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth();
2477 double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight();
2478 double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
2479 double fLeftDiff = (double)( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale;
2480 double fTopDiff = (double)( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale;
2481 double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
2482 aReturnValue.Left() += (sal_Int32)fLeftDiff;
2483 aReturnValue.Right() += (sal_Int32)fRightDiff;
2484 aReturnValue.Top() += (sal_Int32)fTopDiff;
2485 aReturnValue.Bottom() += (sal_Int32)fBottomDiff;
2488 return aReturnValue;
2491 bool SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
2493 Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2494 sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2495 if ( bRet )
2497 // taking care of handles that should not been changed
2498 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2500 aRect = aNewTextRect;
2501 SetRectsDirty();
2502 SetChanged();
2504 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2505 while ( aIter != aInteractionHandles.end() )
2509 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2510 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2512 catch ( const uno::RuntimeException& )
2515 aIter++;
2517 InvalidateRenderGeometry();
2519 return bRet;
2521 bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
2523 Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2524 sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2525 if ( bRet )
2527 Rectangle aBoundRect0;
2528 if ( pUserCall )
2529 aBoundRect0 = GetCurrentBoundRect();
2531 // taking care of handles that should not been changed
2532 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2534 aRect = aNewTextRect;
2535 SetRectsDirty();
2537 std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
2538 while ( aIter != aInteractionHandles.end() )
2542 if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2543 aIter->xInteraction->setControllerPosition( aIter->aPosition );
2545 catch ( const uno::RuntimeException& )
2548 aIter++;
2551 InvalidateRenderGeometry();
2552 SetChanged();
2553 BroadcastObjectChange();
2554 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2556 return bRet;
2558 sal_Bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl )
2560 return SdrTextObj::BegTextEdit( rOutl );
2562 void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
2564 Size aPaperMin,aPaperMax;
2565 Rectangle aViewInit;
2566 TakeTextAnchorRect( aViewInit );
2567 if ( aGeo.nDrehWink )
2569 Point aCenter(aViewInit.Center());
2570 aCenter-=aViewInit.TopLeft();
2571 Point aCenter0(aCenter);
2572 RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
2573 aCenter-=aCenter0;
2574 aViewInit.Move(aCenter.X(),aCenter.Y());
2576 Size aAnkSiz(aViewInit.GetSize());
2577 aAnkSiz.Width()--; aAnkSiz.Height()--; // because GetSize() adds 1
2578 Size aMaxSiz(1000000,1000000);
2579 if (pModel!=NULL) {
2580 Size aTmpSiz(pModel->GetMaxObjSize());
2581 if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2582 if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2584 SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
2585 SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
2587 long nMinWdt = GetMinTextFrameWidth();
2588 long nMinHgt = GetMinTextFrameHeight();
2589 long nMaxWdt = GetMaxTextFrameWidth();
2590 long nMaxHgt = GetMaxTextFrameHeight();
2591 if (nMinWdt<1) nMinWdt=1;
2592 if (nMinHgt<1) nMinHgt=1;
2593 if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
2594 nMaxWdt = aMaxSiz.Width();
2595 if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
2596 nMaxHgt=aMaxSiz.Height();
2598 if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2600 if ( IsVerticalWriting() )
2602 nMaxHgt = aAnkSiz.Height();
2603 nMinHgt = nMaxHgt;
2605 else
2607 nMaxWdt = aAnkSiz.Width();
2608 nMinWdt = nMaxWdt;
2611 aPaperMax.Width()=nMaxWdt;
2612 aPaperMax.Height()=nMaxHgt;
2614 aPaperMin.Width()=nMinWdt;
2615 aPaperMin.Height()=nMinHgt;
2617 if ( pViewMin )
2619 *pViewMin = aViewInit;
2621 long nXFree = aAnkSiz.Width() - aPaperMin.Width();
2622 if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2623 pViewMin->Right() -= nXFree;
2624 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2625 pViewMin->Left() += nXFree;
2626 else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); }
2628 long nYFree = aAnkSiz.Height() - aPaperMin.Height();
2629 if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2630 pViewMin->Bottom() -= nYFree;
2631 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2632 pViewMin->Top() += nYFree;
2633 else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); }
2636 if( IsVerticalWriting() )
2637 aPaperMin.Width() = 0;
2638 else
2639 aPaperMin.Height() = 0;
2641 if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
2642 aPaperMin.Width()=0;
2644 // For complete vertical adjust support, set paper min height to 0, here.
2645 if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
2646 aPaperMin.Height() = 0;
2648 if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
2649 if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
2650 if (pViewInit!=NULL) *pViewInit=aViewInit;
2652 void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl )
2654 SdrTextObj::EndTextEdit( rOutl );
2655 InvalidateRenderGeometry();
2657 void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const
2659 if ( GetTextBounds( rAnchorRect ) )
2661 Point aRotateRef( maSnapRect.Center() );
2662 rAnchorRect.Left() += GetTextLeftDistance();
2663 rAnchorRect.Top() += GetTextUpperDistance();
2664 rAnchorRect.Right() -= GetTextRightDistance();
2665 rAnchorRect.Bottom() -= GetTextLowerDistance();
2666 ImpJustifyRect( rAnchorRect );
2668 if ( rAnchorRect.GetWidth() < 2 )
2669 rAnchorRect.Right() = rAnchorRect.Left() + 1; // minimal width is 2
2670 if ( rAnchorRect.GetHeight() < 2 )
2671 rAnchorRect.Bottom() = rAnchorRect.Top() + 1; // minimal height is 2
2672 if ( aGeo.nDrehWink )
2674 Point aP( rAnchorRect.TopLeft() );
2675 RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos );
2676 rAnchorRect.SetPos( aP );
2679 else
2680 SdrTextObj::TakeTextAnchorRect( rAnchorRect );
2682 void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText,
2683 Rectangle* pAnchorRect, bool /*bLineWidth*/) const
2685 Rectangle aAnkRect; // Rect in which we anchor
2686 TakeTextAnchorRect(aAnkRect);
2687 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2688 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2689 sal_uIntPtr nStat0=rOutliner.GetControlWord();
2690 Size aNullSize;
2692 rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
2693 rOutliner.SetMinAutoPaperSize(aNullSize);
2694 sal_Int32 nMaxAutoPaperWidth = 1000000;
2695 sal_Int32 nMaxAutoPaperHeight= 1000000;
2697 long nAnkWdt=aAnkRect.GetWidth();
2698 long nAnkHgt=aAnkRect.GetHeight();
2700 if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2702 if ( IsVerticalWriting() )
2703 nMaxAutoPaperHeight = nAnkHgt;
2704 else
2705 nMaxAutoPaperWidth = nAnkWdt;
2707 if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
2709 rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
2712 if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
2714 rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
2716 rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
2717 rOutliner.SetPaperSize( aNullSize );
2719 // put text into the Outliner - if necessary the use the text from the EditOutliner
2720 OutlinerParaObject* pPara= GetOutlinerParaObject();
2721 if (pEdtOutl && !bNoEditText)
2722 pPara=pEdtOutl->CreateParaObject();
2724 if (pPara)
2726 sal_Bool bHitTest = sal_False;
2727 if( pModel )
2728 bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
2730 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
2731 if( !pTestObj || !bHitTest || pTestObj != this ||
2732 pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() )
2734 if( bHitTest )
2735 rOutliner.SetTextObj( this );
2737 rOutliner.SetUpdateMode(sal_True);
2738 rOutliner.SetText(*pPara);
2741 else
2743 rOutliner.SetTextObj( NULL );
2745 if (pEdtOutl && !bNoEditText && pPara)
2746 delete pPara;
2748 rOutliner.SetUpdateMode(sal_True);
2749 rOutliner.SetControlWord(nStat0);
2751 SdrText* pText = getActiveText();
2752 if( pText )
2753 pText->CheckPortionInfo( rOutliner );
2755 Point aTextPos(aAnkRect.TopLeft());
2756 Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() has a little added tolerance, no?
2758 // For draw objects containing text correct horizontal/vertical alignment if text is bigger
2759 // than the object itself. Without that correction, the text would always be
2760 // formatted to the left edge (or top edge when vertical) of the draw object.
2762 if( !IsTextFrame() )
2764 if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
2766 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
2767 // else the alignment is wanted.
2768 if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
2770 eHAdj = SDRTEXTHORZADJUST_CENTER;
2774 if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
2776 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
2777 // else the alignment is wanted.
2778 if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
2780 eVAdj = SDRTEXTVERTADJUST_CENTER;
2785 if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
2787 long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
2788 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
2789 aTextPos.X()+=nFreeWdt/2;
2790 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
2791 aTextPos.X()+=nFreeWdt;
2793 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
2795 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
2796 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
2797 aTextPos.Y()+=nFreeHgt/2;
2798 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
2799 aTextPos.Y()+=nFreeHgt;
2801 if (aGeo.nDrehWink!=0)
2802 RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
2804 if (pAnchorRect)
2805 *pAnchorRect=aAnkRect;
2807 // using rTextRect together with ContourFrame doesn't always work correctly
2808 rTextRect=Rectangle(aTextPos,aTextSiz);
2811 void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
2813 SdrTextObj::NbcSetOutlinerParaObject( pTextObject );
2814 SetBoundRectDirty();
2815 SetRectsDirty(sal_True);
2816 InvalidateRenderGeometry();
2819 SdrObjCustomShape* SdrObjCustomShape::Clone() const
2821 return CloneHelper< SdrObjCustomShape >();
2824 SdrObjCustomShape& SdrObjCustomShape::operator=(const SdrObjCustomShape& rObj)
2826 if( this == &rObj )
2827 return *this;
2828 SdrTextObj::operator=( rObj );
2829 aName = rObj.aName;
2830 fObjectRotation = rObj.fObjectRotation;
2831 InvalidateRenderGeometry();
2832 return *this;
2836 void SdrObjCustomShape::TakeObjNameSingul(XubString& rName) const
2838 rName = ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE);
2839 String aNm( GetName() );
2840 if( aNm.Len() )
2842 rName += sal_Unicode(' ');
2843 rName += sal_Unicode('\'');
2844 rName += aNm;
2845 rName += sal_Unicode('\'');
2849 void SdrObjCustomShape::TakeObjNamePlural(XubString& rName) const
2851 rName=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE);
2854 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const
2856 return GetLineGeometry( (SdrObjCustomShape*)this, sal_False );
2859 basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const
2861 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
2862 if ( pSdrObject )
2863 return pSdrObject->TakeContour();
2864 return basegfx::B2DPolyPolygon();
2867 SdrObject* SdrObjCustomShape::DoConvertToPolyObj(sal_Bool bBezier) const
2869 // #i37011#
2870 SdrObject* pRetval = 0L;
2871 SdrObject* pRenderedCustomShape = 0L;
2873 if ( !mXRenderedCustomShape.is() )
2875 // force CustomShape
2876 ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape();
2879 if ( mXRenderedCustomShape.is() )
2881 pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
2884 if ( pRenderedCustomShape )
2886 SdrObject* pCandidate = pRenderedCustomShape->Clone();
2887 DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
2888 pCandidate->SetModel(GetModel());
2889 pRetval = pCandidate->DoConvertToPolyObj(bBezier);
2890 SdrObject::Free( pCandidate );
2892 if(pRetval)
2894 const sal_Bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue());
2895 if(bShadow)
2897 pRetval->SetMergedItem(SdrShadowItem(sal_True));
2901 if(HasText() && !IsTextPath())
2903 pRetval = ImpConvertAddText(pRetval, bBezier);
2907 return pRetval;
2910 void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr )
2912 // #i40944#
2913 InvalidateRenderGeometry();
2914 SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
2917 void SdrObjCustomShape::SetPage( SdrPage* pNewPage )
2919 SdrTextObj::SetPage( pNewPage );
2921 if( pNewPage )
2923 // invalidating rectangles by SetRectsDirty is not sufficient,
2924 // AdjustTextFrameWidthAndHeight() also has to be made, both
2925 // actions are done by NbcSetSnapRect
2926 Rectangle aTmp( aRect ); //creating temporary rectangle #i61108#
2927 NbcSetSnapRect( aTmp );
2931 SdrObjGeoData* SdrObjCustomShape::NewGeoData() const
2933 return new SdrAShapeObjGeoData;
2936 void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const
2938 SdrTextObj::SaveGeoData( rGeo );
2939 SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
2940 rAGeo.fObjectRotation = fObjectRotation;
2941 rAGeo.bMirroredX = IsMirroredX();
2942 rAGeo.bMirroredY = IsMirroredY();
2944 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
2945 Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) );
2946 if ( pAny )
2947 *pAny >>= rAGeo.aAdjustmentSeq;
2950 void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo)
2952 SdrTextObj::RestGeoData( rGeo );
2953 SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
2954 fObjectRotation = rAGeo.fObjectRotation;
2955 SetMirroredX( rAGeo.bMirroredX );
2956 SetMirroredY( rAGeo.bMirroredY );
2958 SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
2959 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
2960 PropertyValue aPropVal;
2961 aPropVal.Name = sAdjustmentValues;
2962 aPropVal.Value <<= rAGeo.aAdjustmentSeq;
2963 rGeometryItem.SetPropertyValue( aPropVal );
2964 SetMergedItem( rGeometryItem );
2966 InvalidateRenderGeometry();
2969 void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
2971 // break up matrix
2972 basegfx::B2DTuple aScale;
2973 basegfx::B2DTuple aTranslate;
2974 double fRotate, fShearX;
2975 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
2977 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
2978 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
2979 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
2981 aScale.setX(fabs(aScale.getX()));
2982 aScale.setY(fabs(aScale.getY()));
2983 fRotate = fmod(fRotate + F_PI, F_2PI);
2986 // reset object shear and rotations
2987 aGeo.nDrehWink = 0;
2988 aGeo.RecalcSinCos();
2989 aGeo.nShearWink = 0;
2990 aGeo.RecalcTan();
2992 // force metric to pool metric
2993 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
2994 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
2996 switch(eMapUnit)
2998 case SFX_MAPUNIT_TWIP :
3000 // position
3001 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3002 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3004 // size
3005 aScale.setX(ImplMMToTwips(aScale.getX()));
3006 aScale.setY(ImplMMToTwips(aScale.getY()));
3008 break;
3010 default:
3012 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3017 // if anchor is used, make position relative to it
3018 if( pModel && pModel->IsWriter() )
3020 if(GetAnchorPos().X() || GetAnchorPos().Y())
3022 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3026 // build and set BaseRect (use scale)
3027 Point aPoint = Point();
3028 Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
3029 Rectangle aBaseRect(aPoint, aSize);
3030 SetSnapRect(aBaseRect);
3032 // shear?
3033 if(!basegfx::fTools::equalZero(fShearX))
3035 GeoStat aGeoStat;
3036 aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
3037 aGeoStat.RecalcTan();
3038 Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
3041 // rotation?
3042 if(!basegfx::fTools::equalZero(fRotate))
3044 GeoStat aGeoStat;
3046 // #i78696#
3047 // fRotate is mathematically correct, but aGeoStat.nDrehWink is
3048 // mirrored -> mirror value here
3049 aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
3050 aGeoStat.RecalcSinCos();
3051 Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
3054 // translate?
3055 if(!aTranslate.equalZero())
3057 Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
3061 // taking fObjectRotation instead of aGeo.nWink
3062 sal_Bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3064 // get turn and shear
3065 double fRotate = fObjectRotation * F_PI180;
3066 double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
3068 // get aRect, this is the unrotated snaprect
3069 Rectangle aRectangle(aRect);
3071 sal_Bool bMirroredX = IsMirroredX();
3072 sal_Bool bMirroredY = IsMirroredY();
3073 if ( bMirroredX || bMirroredY )
3074 { // we have to retrieve the unmirrored rect
3076 GeoStat aNewGeo( aGeo );
3078 if ( bMirroredX )
3080 Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
3081 Rectangle aBoundRect( aPol.GetBoundRect() );
3083 Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
3084 Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
3085 sal_uInt16 i;
3086 sal_uInt16 nPntAnz=aPol.GetSize();
3087 for (i=0; i<nPntAnz; i++)
3089 MirrorPoint(aPol[i],aRef1,aRef2);
3091 // mirror polygon and move it a bit
3092 Polygon aPol0(aPol);
3093 aPol[0]=aPol0[1];
3094 aPol[1]=aPol0[0];
3095 aPol[2]=aPol0[3];
3096 aPol[3]=aPol0[2];
3097 aPol[4]=aPol0[1];
3098 Poly2Rect(aPol,aRectangle,aNewGeo);
3100 if ( bMirroredY )
3102 Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
3103 Rectangle aBoundRect( aPol.GetBoundRect() );
3105 Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
3106 Point aRef2( aRef1.X() + 1000, aRef1.Y() );
3107 sal_uInt16 i;
3108 sal_uInt16 nPntAnz=aPol.GetSize();
3109 for (i=0; i<nPntAnz; i++)
3111 MirrorPoint(aPol[i],aRef1,aRef2);
3113 // mirror polygon and move it a bit
3114 Polygon aPol0(aPol);
3115 aPol[0]=aPol0[1];
3116 aPol[1]=aPol0[0];
3117 aPol[2]=aPol0[3];
3118 aPol[3]=aPol0[2];
3119 aPol[4]=aPol0[1];
3120 Poly2Rect(aPol,aRectangle,aNewGeo);
3124 // fill other values
3125 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3126 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3128 // position may be relative to anchorpos, convert
3129 if( pModel && pModel->IsWriter() )
3131 if(GetAnchorPos().X() || GetAnchorPos().Y())
3133 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3137 // force MapUnit to 100th mm
3138 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
3139 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3141 switch(eMapUnit)
3143 case SFX_MAPUNIT_TWIP :
3145 // position
3146 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3147 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3149 // size
3150 aScale.setX(ImplTwipsToMM(aScale.getX()));
3151 aScale.setY(ImplTwipsToMM(aScale.getY()));
3153 break;
3155 default:
3157 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3162 // build matrix
3163 rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
3164 aScale,
3165 basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
3166 basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
3167 aTranslate);
3169 return sal_False;
3172 sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact()
3174 return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
3177 // #i33136#
3178 bool SdrObjCustomShape::doConstructOrthogonal(const ::rtl::OUString& rName)
3180 bool bRetval(false);
3181 static ::rtl::OUString Imps_sNameASOrtho_quadrat( "quadrat" );
3182 static ::rtl::OUString Imps_sNameASOrtho_round_quadrat( "round-quadrat" );
3183 static ::rtl::OUString Imps_sNameASOrtho_circle( "circle" );
3184 static ::rtl::OUString Imps_sNameASOrtho_circle_pie( "circle-pie" );
3185 static ::rtl::OUString Imps_sNameASOrtho_ring( "ring" );
3187 if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName))
3189 bRetval = true;
3191 else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName))
3193 bRetval = true;
3195 else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName))
3197 bRetval = true;
3199 else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName))
3201 bRetval = true;
3203 else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName))
3205 bRetval = true;
3208 return bRetval;
3211 // #i37011# centralize throw-away of render geometry
3212 void SdrObjCustomShape::InvalidateRenderGeometry()
3214 mXRenderedCustomShape = 0L;
3215 SdrObject::Free( mpLastShadowGeometry );
3216 mpLastShadowGeometry = 0L;
3219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */