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
)
106 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::LINETO
;
107 rSegInfo
.Count
= nSDat
& 0xff;
108 if ( !rSegInfo
.Count
)
112 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CURVETO
;
113 rSegInfo
.Count
= nSDat
& 0xff;
114 if ( !rSegInfo
.Count
)
118 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::MOVETO
;
119 rSegInfo
.Count
= nSDat
& 0xff;
120 if ( !rSegInfo
.Count
)
124 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
128 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
132 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO
;
133 rSegInfo
.Count
= ( nSDat
& 0xff ) / 3;
136 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE
;
137 rSegInfo
.Count
= ( nSDat
& 0xff ) / 3;
140 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ARCTO
;
141 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
144 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ARC
;
145 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
148 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
;
149 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
152 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
;
153 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
156 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX
;
157 rSegInfo
.Count
= nSDat
& 0xff;
160 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY
;
161 rSegInfo
.Count
= nSDat
& 0xff;
164 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::NOFILL
;
168 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::NOSTROKE
;
173 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::UNKNOWN
;
174 rSegInfo
.Count
= nSDat
;
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
);
197 static sal_Bool
ImpVerticalSwitch( const SdrObjCustomShape
& rCustoShape
)
199 sal_Bool bRet
= sal_False
;
200 MSO_SPT
eShapeType( ImpGetCustomShapeType( rCustoShape
) );
203 case mso_sptAccentBorderCallout90
: // 2 ortho
204 case mso_sptBorderCallout1
: // 2 diag
205 case mso_sptBorderCallout2
: // 3
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());
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();
248 XLineStyle eLineStyle
= ((XLineStyleItem
&)(pObj
->GetMergedItem(XATTR_LINESTYLE
))).GetValue();
250 if(XLINE_NONE
!= eLineStyle
)
252 bLineUsed
= sal_True
;
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
) );
294 aTempSet
.Put(SdrShadowItem(sal_False
));
295 aTempSet
.Put(SdrShadowXDistItem(0L));
296 aTempSet
.Put(SdrShadowYDistItem(0L));
298 // line color and transparency like shadow
301 aTempSet
.Put(XLineColorItem(String(), aShadowColor
));
302 aTempSet
.Put(XLineTransparenceItem(nShadowTransparence
));
305 // fill color and transparency like shadow
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));
330 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetRed()) / 256),
331 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetGreen()) / 256),
332 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetBlue()) / 256));
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
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
357 XOBitmap
aFillBitmap(((XFillBitmapItem
&)(rOriginalSet
.Get(XATTR_FILLBITMAP
))).GetBitmapValue());
358 Bitmap
aSourceBitmap(aFillBitmap
.GetBitmap());
359 BitmapReadAccess
* pReadAccess
= aSourceBitmap
.AcquireReadAccess();
361 if(!aSourceBitmap
.IsEmpty())
365 Bitmap
aDestBitmap(aSourceBitmap
.GetSizePixel(), 24L);
366 BitmapWriteAccess
* pWriteAccess
= aDestBitmap
.AcquireWriteAccess();
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
);
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
);
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
)
440 return pRenderedCustomShape
;
443 // #i37011# Shadow geometry creation
444 const SdrObject
* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
446 if(!mpLastShadowGeometry
)
448 const SdrObject
* pSdrObject
= GetSdrObjectFromCustomShape();
451 const SfxItemSet
& rOriginalSet
= GetObjectItemSet();
452 const sal_Bool
bShadow(((SdrShadowItem
&)rOriginalSet
.Get( SDRATTR_SHADOW
)).GetValue());
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
);
473 *pAny
>>= 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
);
485 *pAny
>>= sShapeType
;
486 bRet
= IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType
) ) == 0;
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
);
498 *pAny
>>= 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
);
508 *pAny
>>= 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" );
544 *pAny
>>= 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;
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
) );
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
& )
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() )
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();
616 switch( ImpGetCustomShapeType( *this ) )
618 case mso_sptAccentBorderCallout90
: // 2 ortho
621 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
623 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
| CUSTOMSHAPE_HANDLE_ORTHO4
;
627 case mso_sptWedgeRectCallout
:
628 case mso_sptWedgeRRectCallout
:
629 case mso_sptCloudCallout
:
630 case mso_sptWedgeEllipseCallout
:
633 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
;
637 case mso_sptBorderCallout1
: // 2 diag
640 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
642 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
;
645 case mso_sptBorderCallout2
: // 3
648 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
650 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
;
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
:
668 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
673 aSdrCustomShapeInteraction
.nMode
= nMode
;
674 xRet
.push_back( aSdrCustomShapeInteraction
);
679 catch( const uno::RuntimeException
& )
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
)
697 if ( nFlags
& MSDFF_HANDLE_FLAGS_MIRRORED_Y
)
699 if ( nFlags
& MSDFF_HANDLE_FLAGS_SWITCHED
)
701 if ( nFlags
& MSDFF_HANDLE_FLAGS_POLAR
)
704 if ( nFlags
& MSDFF_HANDLE_FLAGS_RADIUS_RANGE
)
706 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
708 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
712 else if ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE
)
714 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
716 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
718 if ( pData
->nRangeYMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
720 if ( pData
->nRangeYMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
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;
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
;
835 sdr::properties::BaseProperties
* SdrObjCustomShape::CreateObjectSpecificProperties()
837 return new sdr::properties::CustomShapeProperties(*this);
840 TYPEINIT1(SdrObjCustomShape
,SdrTextObj
);
841 SdrObjCustomShape::SdrObjCustomShape() :
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();
865 sShapeType
= EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT
>( nType
) );
869 aPropVal
.Name
= sType
;
870 aPropVal
.Value
<<= sShapeType
;
871 aGeometryItem
.SetPropertyValue( aPropVal
);
875 Any
*pAny
= aGeometryItem
.GetPropertyValueByName( sType
);
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
);
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
);
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
)
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
);
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
);
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
);
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
);
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
);
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
);
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
;
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
;
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
;
1180 case DEFAULT_SEGMENTS
:
1183 const rtl::OUString
sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1184 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sSegments
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
1362 if ( mXRenderedCustomShape
.is() )
1364 const SdrObject
* pRenderedCustomShape
= GetSdrObjectFromXShape( mXRenderedCustomShape
);
1365 if ( pRenderedCustomShape
)
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
)
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();
1464 void SdrObjCustomShape::SetSnapRect( const Rectangle
& rRect
)
1466 Rectangle aBoundRect0
;
1468 aBoundRect0
= GetLastBoundRect();
1469 NbcSetSnapRect( rRect
);
1470 BroadcastObjectChange();
1471 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
1473 void SdrObjCustomShape::NbcSetLogicRect( const Rectangle
& 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();
1495 void SdrObjCustomShape::SetLogicRect( const Rectangle
& rRect
)
1497 Rectangle aBoundRect0
;
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
;
1510 aBoundRect0
= GetLastBoundRect();
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
& )
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
1619 SdrTextObj::NbcRotate( aRect
.TopLeft(), nW
, // applying text rotation
1620 sin( nW
* F_PI18000
),
1621 cos( nW
* F_PI18000
) );
1629 double fWink
= nWink
; // updating to our new object rotation
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() )
1646 if ( rRef1
.Y() == rRef2
.Y() )
1648 if ( !bHorz
&& !bVert
)
1649 bHorz
= bVert
= sal_True
;
1651 if ( bHorz
|| bVert
)
1653 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
1658 const rtl::OUString
sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1659 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredX
);
1662 sal_Bool bFlip
= sal_Bool();
1663 if ( *pAny
>>= bFlip
)
1669 PropertyValue aPropVal
;
1670 aPropVal
.Name
= sMirroredX
;
1671 aPropVal
.Value
<<= bHorz
;
1672 aGeometryItem
.SetPropertyValue( aPropVal
);
1678 const rtl::OUString
sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1679 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredY
);
1682 sal_Bool bFlip
= sal_Bool();
1683 if ( *pAny
>>= bFlip
)
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
;
1710 aGeo
.nDrehWink
= -nDrehWink
;
1711 aGeo
.RecalcSinCos();
1712 NbcRotate( rRef
, aGeo
.nDrehWink
, aGeo
.nSin
, aGeo
.nCos
);
1714 SdrTextObj::NbcShear(rRef
,nWink
,tn
,bVShear
);
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#
1731 if(!LineIsOutsideGeometry())
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
);
1752 ////////////////////////////////////////////////////////////////////////////////////////////////////
1755 void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
1757 const SdrObject
* pSdrObject
= GetSdrObjectFromCustomShape();
1761 const SdrGluePointList
* pSource
= pSdrObject
->GetGluePointList();
1763 if(pSource
&& pSource
->GetCount())
1765 if(!SdrTextObj::GetGluePointList())
1767 SdrTextObj::ForceGluePointList();
1770 const SdrGluePointList
* pList
= SdrTextObj::GetGluePointList();
1774 SdrGluePointList aNewList
;
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
);
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
;
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() );
1818 ShearPoint( aGlue
, aRef
, fTan
);
1820 RotatePoint( aGlue
, aRef
, sin( fObjectRotation
* F_PI180
), cos( fObjectRotation
* F_PI180
) );
1822 aGlue
.X() = aRect
.GetWidth() - aGlue
.X();
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
1847 pPlusData
->SetGluePoints(aNewList
);
1855 const SdrGluePointList
* SdrObjCustomShape::GetGluePointList() const
1857 ((SdrObjCustomShape
*)this)->ImpCheckCustomGluePointsAreAdded();
1858 return SdrTextObj::GetGluePointList();
1862 SdrGluePointList
* SdrObjCustomShape::ForceGluePointList()
1864 if(SdrTextObj::ForceGluePointList())
1866 ImpCheckCustomGluePointsAreAdded();
1867 return SdrTextObj::ForceGluePointList();
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
1887 const sal_uInt32
nBasicHdlCount(SdrTextObj::GetHdlCount());
1889 if ( nHdlNum
< nBasicHdlCount
)
1890 pH
= SdrTextObj::GetHdl( nHdlNum
);
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
& )
1916 ////////////////////////////////////////////////////////////////////////////////////////////////////
1918 bool SdrObjCustomShape::hasSpecialDrag() const
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);
1934 const SdrHdl
* pHdl2
= rDrag
.GetHdl();
1935 const SdrHdlKind
eHdl((pHdl2
== NULL
) ? HDL_MOVE
: pHdl2
->GetKind());
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
);
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
)
2009 if ( bOldMirroredX
)
2011 nX
= ( aIter
->aPosition
.X
- aOld
.Right() );
2012 if ( rNewRect
.Left() > rNewRect
.Right() )
2013 nX
= pObj
->aRect
.Left() - nX
;
2015 nX
+= pObj
->aRect
.Right();
2019 nX
= ( aIter
->aPosition
.X
- aOld
.Left() );
2020 if ( rNewRect
.Left() > rNewRect
.Right() )
2021 nX
= pObj
->aRect
.Right() - nX
;
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
)
2030 if ( bOldMirroredY
)
2032 nY
= ( aIter
->aPosition
.Y
- aOld
.Bottom() );
2033 if ( rNewRect
.Top() > rNewRect
.Bottom() )
2034 nY
= pObj
->aRect
.Top() - nY
;
2036 nY
+= pObj
->aRect
.Bottom();
2040 nY
= ( aIter
->aPosition
.Y
- aOld
.Top() );
2041 if ( rNewRect
.Top() > rNewRect
.Bottom() )
2042 nY
= pObj
->aRect
.Bottom() - nY
;
2044 nY
+= pObj
->aRect
.Top();
2046 aIter
->xInteraction
->setControllerPosition( com::sun::star::awt::Point( aIter
->xInteraction
->getPosition().X
, nY
) );
2049 catch ( const uno::RuntimeException
& )
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
);
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());
2106 case HDL_CUSTOMSHAPE1
:
2108 rDrag
.SetEndDragChangesGeoAndAttributes(true);
2109 DragMoveCustomShapeHdl( rDrag
.GetNow(), (sal_uInt16
)pHdl
->GetPointNum(), this );
2111 InvalidateRenderGeometry();
2125 DragResizeCustomShape(ImpDragCalcRect(rDrag
), this);
2130 Move(Size(rDrag
.GetDX(), rDrag
.GetDY()));
2139 ////////////////////////////////////////////////////////////////////////////////////////////////////
2141 void SdrObjCustomShape::DragCreateObject( SdrDragStat
& rStat
)
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
);
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
& )
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
);
2203 bool SdrObjCustomShape::EndCreate( SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
2205 DragCreateObject( rStat
);
2209 if ( IsAutoGrowHeight() )
2212 long nHgt
=aRect
.GetHeight()-1;
2213 if (nHgt
==1) nHgt
=0;
2214 NbcSetMinTextFrameHeight( nHgt
);
2216 if ( IsAutoGrowWidth() )
2219 long nWdt
=aRect
.GetWidth()-1;
2220 if (nWdt
==1) nWdt
=0;
2221 NbcSetMinTextFrameWidth( nWdt
);
2223 // re-calculate text frame
2224 NbcAdjustTextFrameWidthAndHeight();
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
,
2292 // Exchange horizontal and vertical adjusts
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;
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
)
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();
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
;
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
2361 pEdtOutl
->SetMaxAutoPaperSize( aSiz
);
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
2369 nHgt
=pEdtOutl
->GetTextHeight()+1; // a little more tolerance
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());
2386 Size
aSiz2(rOutliner
.CalcTextSize());
2387 nWdt
=aSiz2
.Width()+1; // a little more tolerance
2389 nHgt
=aSiz2
.Height()+1; // a little more tolerance
2392 nHgt
= rOutliner
.GetTextHeight()+1; // a little more tolerance
2395 if ( nWdt
< nMinWdt
)
2397 if ( nWdt
> nMaxWdt
)
2401 nWdt
= 1; // nHDist may also be negative
2402 if ( nHgt
< nMinHgt
)
2404 if ( nHgt
> nMaxHgt
)
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 )
2415 if ( bWdtGrow
|| bHgtGrow
)
2419 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
2420 if ( eHAdj
== SDRTEXTHORZADJUST_LEFT
)
2421 rR
.Right()+=nWdtGrow
;
2422 else if ( eHAdj
== SDRTEXTHORZADJUST_RIGHT
)
2423 rR
.Left()-=nWdtGrow
;
2426 long nWdtGrow2
=nWdtGrow
/2;
2427 rR
.Left()-=nWdtGrow2
;
2428 rR
.Right()=rR
.Left()+nWdt
;
2433 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
2434 if ( eVAdj
== SDRTEXTVERTADJUST_TOP
)
2435 rR
.Bottom()+=nHgtGrow
;
2436 else if ( eVAdj
== SDRTEXTVERTADJUST_BOTTOM
)
2440 long nHgtGrow2
=nHgtGrow
/2;
2441 rR
.Top()-=nHgtGrow2
;
2442 rR
.Bottom()=rR
.Top()+nHgt
;
2445 if ( aGeo
.nDrehWink
)
2447 Point
aD1(rR
.TopLeft());
2450 RotatePoint(aD2
,Point(),aGeo
.nSin
,aGeo
.nCos
);
2452 rR
.Move(aD2
.X(),aD2
.Y());
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
);
2497 // taking care of handles that should not been changed
2498 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
2500 aRect
= aNewTextRect
;
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
& )
2517 InvalidateRenderGeometry();
2521 bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(bool bHgt
, bool bWdt
)
2523 Rectangle aNewTextRect
= ImpCalculateTextFrame( bHgt
, bWdt
);
2524 sal_Bool bRet
= !aNewTextRect
.IsEmpty() && ( aNewTextRect
!= aRect
);
2527 Rectangle aBoundRect0
;
2529 aBoundRect0
= GetCurrentBoundRect();
2531 // taking care of handles that should not been changed
2532 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
2534 aRect
= aNewTextRect
;
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
& )
2551 InvalidateRenderGeometry();
2553 BroadcastObjectChange();
2554 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
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
);
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);
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();
2607 nMaxWdt
= aAnkSiz
.Width();
2611 aPaperMax
.Width()=nMaxWdt
;
2612 aPaperMax
.Height()=nMaxHgt
;
2614 aPaperMin
.Width()=nMinWdt
;
2615 aPaperMin
.Height()=nMinHgt
;
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;
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
);
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();
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
;
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();
2726 sal_Bool bHitTest
= sal_False
;
2728 bHitTest
= &pModel
->GetHitTestOutliner() == &rOutliner
;
2730 const SdrTextObj
* pTestObj
= rOutliner
.GetTextObj();
2731 if( !pTestObj
|| !bHitTest
|| pTestObj
!= this ||
2732 pTestObj
->GetOutlinerParaObject() != GetOutlinerParaObject() )
2735 rOutliner
.SetTextObj( this );
2737 rOutliner
.SetUpdateMode(sal_True
);
2738 rOutliner
.SetText(*pPara
);
2743 rOutliner
.SetTextObj( NULL
);
2745 if (pEdtOutl
&& !bNoEditText
&& pPara
)
2748 rOutliner
.SetUpdateMode(sal_True
);
2749 rOutliner
.SetControlWord(nStat0
);
2751 SdrText
* pText
= getActiveText();
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
);
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
)
2828 SdrTextObj::operator=( rObj
);
2830 fObjectRotation
= rObj
.fObjectRotation
;
2831 InvalidateRenderGeometry();
2836 void SdrObjCustomShape::TakeObjNameSingul(XubString
& rName
) const
2838 rName
= ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE
);
2839 String
aNm( GetName() );
2842 rName
+= sal_Unicode(' ');
2843 rName
+= sal_Unicode('\'');
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();
2863 return pSdrObject
->TakeContour();
2864 return basegfx::B2DPolyPolygon();
2867 SdrObject
* SdrObjCustomShape::DoConvertToPolyObj(sal_Bool bBezier
) const
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
);
2894 const sal_Bool
bShadow(((SdrShadowItem
&)GetMergedItem(SDRATTR_SHADOW
)).GetValue());
2897 pRetval
->SetMergedItem(SdrShadowItem(sal_True
));
2901 if(HasText() && !IsTextPath())
2903 pRetval
= ImpConvertAddText(pRetval
, bBezier
);
2910 void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet
* pNewStyleSheet
, sal_Bool bDontRemoveHardAttr
)
2913 InvalidateRenderGeometry();
2914 SdrObject::NbcSetStyleSheet( pNewStyleSheet
, bDontRemoveHardAttr
);
2917 void SdrObjCustomShape::SetPage( SdrPage
* pNewPage
)
2919 SdrTextObj::SetPage( 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
) );
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*/)
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
2988 aGeo
.RecalcSinCos();
2989 aGeo
.nShearWink
= 0;
2992 // force metric to pool metric
2993 SfxMapUnit eMapUnit
= GetObjectItemSet().GetPool()->GetMetric(0);
2994 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
2998 case SFX_MAPUNIT_TWIP
:
3001 aTranslate
.setX(ImplMMToTwips(aTranslate
.getX()));
3002 aTranslate
.setY(ImplMMToTwips(aTranslate
.getY()));
3005 aScale
.setX(ImplMMToTwips(aScale
.getX()));
3006 aScale
.setY(ImplMMToTwips(aScale
.getY()));
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
);
3033 if(!basegfx::fTools::equalZero(fShearX
))
3036 aGeoStat
.nShearWink
= FRound((atan(fShearX
) / F_PI180
) * 100.0);
3037 aGeoStat
.RecalcTan();
3038 Shear(Point(), aGeoStat
.nShearWink
, aGeoStat
.nTan
, sal_False
);
3042 if(!basegfx::fTools::equalZero(fRotate
))
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
);
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
);
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 );
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
);
3098 Poly2Rect(aPol
,aRectangle
,aNewGeo
);
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() );
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
);
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
)
3143 case SFX_MAPUNIT_TWIP
:
3146 aTranslate
.setX(ImplTwipsToMM(aTranslate
.getX()));
3147 aTranslate
.setY(ImplTwipsToMM(aTranslate
.getY()));
3150 aScale
.setX(ImplTwipsToMM(aScale
.getX()));
3151 aScale
.setY(ImplTwipsToMM(aScale
.getY()));
3157 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3163 rMatrix
= basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
3165 basegfx::fTools::equalZero(fShearX
) ? 0.0 : tan(fShearX
),
3166 basegfx::fTools::equalZero(fRotate
) ? 0.0 : -fRotate
,
3172 sdr::contact::ViewContact
* SdrObjCustomShape::CreateObjectSpecificViewContact()
3174 return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
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
))
3191 else if(Imps_sNameASOrtho_round_quadrat
.equalsIgnoreAsciiCase(rName
))
3195 else if(Imps_sNameASOrtho_circle
.equalsIgnoreAsciiCase(rName
))
3199 else if(Imps_sNameASOrtho_circle_pie
.equalsIgnoreAsciiCase(rName
))
3203 else if(Imps_sNameASOrtho_ring
.equalsIgnoreAsciiCase(rName
))
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: */