1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svdoashp.hxx>
21 #include "svx/unoapi.hxx"
22 #include <svx/unoshape.hxx>
23 #include <ucbhelper/content.hxx>
24 #include <unotools/datetime.hxx>
25 #include <sfx2/lnkbase.hxx>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/drawing/XShape.hpp>
28 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
29 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/awt/Rectangle.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <svl/urihelper.hxx>
34 #include <com/sun/star/uno/Sequence.h>
35 #include <svx/svdogrp.hxx>
36 #include <tools/helpers.hxx>
37 #include <svx/svddrag.hxx>
38 #include <svx/xpool.hxx>
39 #include <svx/xpoly.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <svx/svdpage.hxx>
42 #include "svx/svditer.hxx"
43 #include <svx/svdobj.hxx>
44 #include <svx/svdtrans.hxx>
45 #include <svx/svdetc.hxx>
46 #include <svx/svdattrx.hxx> // NotPersistItems
47 #include <svx/svdoedge.hxx> // for broadcasting connectors to Move
48 #include "svx/svdglob.hxx" // StringCache
49 #include "svx/svdstr.hrc" // the object's name
50 #include <editeng/eeitem.hxx>
51 #include "editeng/editstat.hxx"
52 #include <svx/svdoutl.hxx>
53 #include <editeng/outlobj.hxx>
54 #include <svx/sdtfchim.hxx>
55 #include "svx/EnhancedCustomShapeGeometry.hxx"
56 #include "svx/EnhancedCustomShapeTypeNames.hxx"
57 #include "svx/EnhancedCustomShape2d.hxx"
58 #include <com/sun/star/beans/PropertyValues.hpp>
59 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
60 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
61 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
62 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
63 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
64 #include <editeng/writingmodeitem.hxx>
65 #include <svx/xlnclit.hxx>
66 #include <svx/svxids.hrc>
67 #include <svl/whiter.hxx>
68 #include <svx/sdr/properties/customshapeproperties.hxx>
69 #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
70 #include <svx/xlntrit.hxx>
71 #include <svx/xfltrit.hxx>
72 #include <svx/xflclit.hxx>
73 #include <svx/xflgrit.hxx>
74 #include <svx/xflhtit.hxx>
75 #include <svx/xbtmpit.hxx>
76 #include <vcl/bmpacc.hxx>
77 #include <svx/svdview.hxx>
78 #include <basegfx/polygon/b2dpolypolygontools.hxx>
79 #include <basegfx/matrix/b2dhommatrix.hxx>
80 #include <basegfx/matrix/b2dhommatrixtools.hxx>
81 #include <basegfx/tools/unotools.hxx>
82 #include "svdconv.hxx"
84 using namespace ::com::sun::star
;
85 using namespace ::com::sun::star::uno
;
86 using namespace ::com::sun::star::lang
;
87 using namespace ::com::sun::star::beans
;
88 using namespace ::com::sun::star::drawing
;
90 static void lcl_ShapeSegmentFromBinary( EnhancedCustomShapeSegment
& rSegInfo
, sal_uInt16 nSDat
)
95 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::LINETO
;
96 rSegInfo
.Count
= nSDat
& 0xff;
97 if ( !rSegInfo
.Count
)
101 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CURVETO
;
102 rSegInfo
.Count
= nSDat
& 0xff;
103 if ( !rSegInfo
.Count
)
107 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::MOVETO
;
108 rSegInfo
.Count
= nSDat
& 0xff;
109 if ( !rSegInfo
.Count
)
113 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
117 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
121 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO
;
122 rSegInfo
.Count
= ( nSDat
& 0xff ) / 3;
125 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE
;
126 rSegInfo
.Count
= ( nSDat
& 0xff ) / 3;
129 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ARCTO
;
130 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
133 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ARC
;
134 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
137 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
;
138 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
141 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
;
142 rSegInfo
.Count
= ( nSDat
& 0xff ) >> 2;
145 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX
;
146 rSegInfo
.Count
= nSDat
& 0xff;
149 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY
;
150 rSegInfo
.Count
= nSDat
& 0xff;
153 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::NOFILL
;
157 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::NOSTROKE
;
162 rSegInfo
.Command
= EnhancedCustomShapeSegmentCommand::UNKNOWN
;
163 rSegInfo
.Count
= nSDat
;
169 static MSO_SPT
ImpGetCustomShapeType( const SdrObjCustomShape
& rCustoShape
)
171 MSO_SPT eRetValue
= mso_sptNil
;
173 OUString
aEngine( ( (SdrCustomShapeEngineItem
&)rCustoShape
.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE
) ).GetValue() );
174 if ( aEngine
.isEmpty() || aEngine
== "com.sun.star.drawing.EnhancedCustomShapeEngine" )
177 const OUString
sType( "Type" );
178 SdrCustomShapeGeometryItem
& rGeometryItem( (SdrCustomShapeGeometryItem
&)rCustoShape
.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
179 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sType
);
180 if ( pAny
&& ( *pAny
>>= sShapeType
) )
181 eRetValue
= EnhancedCustomShapeTypeNames::Get( sShapeType
);
186 static bool ImpVerticalSwitch( const SdrObjCustomShape
& rCustoShape
)
189 MSO_SPT
eShapeType( ImpGetCustomShapeType( rCustoShape
) );
192 case mso_sptAccentBorderCallout90
: // 2 ortho
193 case mso_sptBorderCallout1
: // 2 diag
194 case mso_sptBorderCallout2
: // 3
204 // #i37011# create a clone with all attributes changed to shadow attributes
205 // and translation executed, too.
206 SdrObject
* ImpCreateShadowObjectClone(const SdrObject
& rOriginal
, const SfxItemSet
& rOriginalSet
)
208 SdrObject
* pRetval
= 0L;
209 const sal_Bool
bShadow(((SdrShadowItem
&)rOriginalSet
.Get(SDRATTR_SHADOW
)).GetValue());
213 // create a shadow representing object
214 const sal_Int32
nXDist(((SdrShadowXDistItem
&)(rOriginalSet
.Get(SDRATTR_SHADOWXDIST
))).GetValue());
215 const sal_Int32
nYDist(((SdrShadowYDistItem
&)(rOriginalSet
.Get(SDRATTR_SHADOWYDIST
))).GetValue());
216 const ::Color
aShadowColor(((SdrShadowColorItem
&)(rOriginalSet
.Get(SDRATTR_SHADOWCOLOR
))).GetColorValue());
217 const sal_uInt16
nShadowTransparence(((SdrShadowTransparenceItem
&)(rOriginalSet
.Get(SDRATTR_SHADOWTRANSPARENCE
))).GetValue());
218 pRetval
= rOriginal
.Clone();
219 DBG_ASSERT(pRetval
, "ImpCreateShadowObjectClone: Could not clone object (!)");
221 // look for used stuff
222 SdrObjListIter
aIterator(rOriginal
);
223 bool bLineUsed(false);
224 bool bAllFillUsed(false);
225 bool bSolidFillUsed(false);
226 bool bGradientFillUsed(false);
227 bool bHatchFillUsed(false);
228 bool bBitmapFillUsed(false);
230 while(aIterator
.IsMore())
232 SdrObject
* pObj
= aIterator
.Next();
233 XFillStyle eFillStyle
= ((XFillStyleItem
&)(pObj
->GetMergedItem(XATTR_FILLSTYLE
))).GetValue();
237 XLineStyle eLineStyle
= ((XLineStyleItem
&)(pObj
->GetMergedItem(XATTR_LINESTYLE
))).GetValue();
239 if(XLINE_NONE
!= eLineStyle
)
247 if(!bSolidFillUsed
&& XFILL_SOLID
== eFillStyle
)
249 bSolidFillUsed
= true;
250 bAllFillUsed
= (bSolidFillUsed
&& bGradientFillUsed
&& bHatchFillUsed
&& bBitmapFillUsed
);
252 if(!bGradientFillUsed
&& XFILL_GRADIENT
== eFillStyle
)
254 bGradientFillUsed
= true;
255 bAllFillUsed
= (bSolidFillUsed
&& bGradientFillUsed
&& bHatchFillUsed
&& bBitmapFillUsed
);
257 if(!bHatchFillUsed
&& XFILL_HATCH
== eFillStyle
)
259 bHatchFillUsed
= true;
260 bAllFillUsed
= (bSolidFillUsed
&& bGradientFillUsed
&& bHatchFillUsed
&& bBitmapFillUsed
);
262 if(!bBitmapFillUsed
&& XFILL_BITMAP
== eFillStyle
)
264 bBitmapFillUsed
= true;
265 bAllFillUsed
= (bSolidFillUsed
&& bGradientFillUsed
&& bHatchFillUsed
&& bBitmapFillUsed
);
270 // translate to shadow coordinates
271 pRetval
->NbcMove(Size(nXDist
, nYDist
));
273 // set items as needed
274 SfxItemSet
aTempSet(rOriginalSet
);
276 // if a SvxWritingModeItem (Top->Bottom) is set the text object
277 // is creating a paraobject, but paraobjects can not be created without model. So
278 // we are preventing the crash by setting the writing mode always left to right,
279 // this is not bad since our shadow geometry does not contain text.
280 aTempSet
.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB
, SDRATTR_TEXTDIRECTION
) );
283 aTempSet
.Put(SdrShadowItem(sal_False
));
284 aTempSet
.Put(SdrShadowXDistItem(0L));
285 aTempSet
.Put(SdrShadowYDistItem(0L));
287 // line color and transparency like shadow
290 aTempSet
.Put(XLineColorItem(String(), aShadowColor
));
291 aTempSet
.Put(XLineTransparenceItem(nShadowTransparence
));
294 // fill color and transparency like shadow
297 aTempSet
.Put(XFillColorItem(String(), aShadowColor
));
298 aTempSet
.Put(XFillTransparenceItem(nShadowTransparence
));
301 // gradient and transparency like shadow
302 if(bGradientFillUsed
)
304 XGradient
aGradient(((XFillGradientItem
&)(rOriginalSet
.Get(XATTR_FILLGRADIENT
))).GetGradientValue());
305 sal_uInt8
nStartLuminance(aGradient
.GetStartColor().GetLuminance());
306 sal_uInt8
nEndLuminance(aGradient
.GetEndColor().GetLuminance());
308 if(aGradient
.GetStartIntens() != 100)
310 nStartLuminance
= (sal_uInt8
)(nStartLuminance
* ((double)aGradient
.GetStartIntens() / 100.0));
313 if(aGradient
.GetEndIntens() != 100)
315 nEndLuminance
= (sal_uInt8
)(nEndLuminance
* ((double)aGradient
.GetEndIntens() / 100.0));
319 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetRed()) / 256),
320 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetGreen()) / 256),
321 (sal_uInt8
)((nStartLuminance
* aShadowColor
.GetBlue()) / 256));
324 (sal_uInt8
)((nEndLuminance
* aShadowColor
.GetRed()) / 256),
325 (sal_uInt8
)((nEndLuminance
* aShadowColor
.GetGreen()) / 256),
326 (sal_uInt8
)((nEndLuminance
* aShadowColor
.GetBlue()) / 256));
328 aGradient
.SetStartColor(aStartColor
);
329 aGradient
.SetEndColor(aEndColor
);
330 aTempSet
.Put(XFillGradientItem(aGradient
));
331 aTempSet
.Put(XFillTransparenceItem(nShadowTransparence
));
334 // hatch and transparency like shadow
337 XHatch
aHatch(((XFillHatchItem
&)(rOriginalSet
.Get(XATTR_FILLHATCH
))).GetHatchValue());
338 aHatch
.SetColor(aShadowColor
);
339 aTempSet
.Put(XFillHatchItem(aTempSet
.GetPool(), aHatch
));
340 aTempSet
.Put(XFillTransparenceItem(nShadowTransparence
));
343 // bitmap and transparency like shadow
346 GraphicObject
aGraphicObject(((XFillBitmapItem
&)(rOriginalSet
.Get(XATTR_FILLBITMAP
))).GetGraphicObject());
347 const BitmapEx
aBitmapEx(aGraphicObject
.GetGraphic().GetBitmapEx());
348 Bitmap
aBitmap(aBitmapEx
.GetBitmap());
350 if(!aBitmap
.IsEmpty())
352 BitmapReadAccess
* pReadAccess
= aBitmap
.AcquireReadAccess();
356 Bitmap
aDestBitmap(aBitmap
.GetSizePixel(), 24L);
357 BitmapWriteAccess
* pWriteAccess
= aDestBitmap
.AcquireWriteAccess();
361 for(sal_Int32
y(0L); y
< pReadAccess
->Height(); y
++)
363 for(sal_Int32
x(0L); x
< pReadAccess
->Width(); x
++)
365 sal_uInt16
nLuminance((sal_uInt16
)pReadAccess
->GetLuminance(y
, x
) + 1);
366 const BitmapColor
aDestColor(
367 (sal_uInt8
)((nLuminance
* (sal_uInt16
)aShadowColor
.GetRed()) >> 8L),
368 (sal_uInt8
)((nLuminance
* (sal_uInt16
)aShadowColor
.GetGreen()) >> 8L),
369 (sal_uInt8
)((nLuminance
* (sal_uInt16
)aShadowColor
.GetBlue()) >> 8L));
370 pWriteAccess
->SetPixel(y
, x
, aDestColor
);
374 aDestBitmap
.ReleaseAccess(pWriteAccess
);
377 aBitmap
.ReleaseAccess(pReadAccess
);
379 if(aBitmapEx
.IsTransparent())
381 if(aBitmapEx
.IsAlpha())
383 aGraphicObject
.SetGraphic(Graphic(BitmapEx(aDestBitmap
, aBitmapEx
.GetAlpha())));
387 aGraphicObject
.SetGraphic(Graphic(BitmapEx(aDestBitmap
, aBitmapEx
.GetMask())));
392 aGraphicObject
.SetGraphic(Graphic(aDestBitmap
));
397 aTempSet
.Put(XFillBitmapItem(aTempSet
.GetPool(), aGraphicObject
));
398 aTempSet
.Put(XFillTransparenceItem(nShadowTransparence
));
401 // set attributes and paint shadow object
402 pRetval
->SetMergedItemSet( aTempSet
);
407 ////////////////////////////////////////////////////////////////////////////////////////////////////
409 Reference
< XCustomShapeEngine
> SdrObjCustomShape::GetCustomShapeEngine() const
411 if (mxCustomShapeEngine
.is())
412 return mxCustomShapeEngine
;
414 String
aEngine(((SdrCustomShapeEngineItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE
)).GetValue());
415 if ( !aEngine
.Len() )
416 aEngine
= String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
418 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
420 Reference
< XShape
> aXShape
= GetXShapeForSdrObject(const_cast<SdrObjCustomShape
*>(this));
425 Sequence
< Any
> aArgument( 1 );
426 Sequence
< PropertyValue
> aPropValues( 1 );
427 aPropValues
[ 0 ].Name
= OUString("CustomShape");
428 aPropValues
[ 0 ].Value
<<= aXShape
;
429 aArgument
[ 0 ] <<= aPropValues
;
430 Reference
< XInterface
> xInterface( xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( aEngine
, aArgument
, xContext
) );
431 if ( xInterface
.is() )
432 mxCustomShapeEngine
= Reference
< XCustomShapeEngine
>( xInterface
, UNO_QUERY
);
436 return mxCustomShapeEngine
;
439 const SdrObject
* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
441 if ( !mXRenderedCustomShape
.is() )
443 Reference
< XCustomShapeEngine
> xCustomShapeEngine( GetCustomShapeEngine() );
444 if ( xCustomShapeEngine
.is() )
445 ((SdrObjCustomShape
*)this)->mXRenderedCustomShape
= xCustomShapeEngine
->render();
447 SdrObject
* pRenderedCustomShape
= mXRenderedCustomShape
.is()
448 ? GetSdrObjectFromXShape( mXRenderedCustomShape
)
450 return pRenderedCustomShape
;
453 // #i37011# Shadow geometry creation
454 const SdrObject
* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
456 if(!mpLastShadowGeometry
)
458 const SdrObject
* pSdrObject
= GetSdrObjectFromCustomShape();
461 const SfxItemSet
& rOriginalSet
= GetObjectItemSet();
462 const sal_Bool
bShadow(((SdrShadowItem
&)rOriginalSet
.Get( SDRATTR_SHADOW
)).GetValue());
466 // create a clone with all attributes changed to shadow attributes
467 // and translation executed, too.
468 ((SdrObjCustomShape
*)this)->mpLastShadowGeometry
= ImpCreateShadowObjectClone(*pSdrObject
, rOriginalSet
);
473 return mpLastShadowGeometry
;
476 sal_Bool
SdrObjCustomShape::IsTextPath() const
478 const OUString
sTextPath( "TextPath" );
479 sal_Bool bTextPathOn
= sal_False
;
480 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
481 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sTextPath
, sTextPath
);
483 *pAny
>>= bTextPathOn
;
487 sal_Bool
SdrObjCustomShape::UseNoFillStyle() const
489 sal_Bool bRet
= sal_False
;
491 const OUString
sType( "Type" );
492 SdrCustomShapeGeometryItem
& rGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
493 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sType
);
495 *pAny
>>= sShapeType
;
496 bRet
= IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType
) ) == 0;
501 sal_Bool
SdrObjCustomShape::IsMirroredX() const
503 sal_Bool bMirroredX
= sal_False
;
504 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
505 const OUString
sMirroredX( "MirroredX" );
506 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredX
);
508 *pAny
>>= bMirroredX
;
511 sal_Bool
SdrObjCustomShape::IsMirroredY() const
513 sal_Bool bMirroredY
= sal_False
;
514 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
515 const OUString
sMirroredY( "MirroredY" );
516 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredY
);
518 *pAny
>>= bMirroredY
;
521 void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX
)
523 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
524 const OUString
sMirroredX( "MirroredX" );
525 PropertyValue aPropVal
;
526 aPropVal
.Name
= sMirroredX
;
527 aPropVal
.Value
<<= bMirrorX
;
528 aGeometryItem
.SetPropertyValue( aPropVal
);
529 SetMergedItem( aGeometryItem
);
531 void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY
)
533 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
534 const OUString
sMirroredY( "MirroredY" );
535 PropertyValue aPropVal
;
536 aPropVal
.Name
= sMirroredY
;
537 aPropVal
.Value
<<= bMirrorY
;
538 aGeometryItem
.SetPropertyValue( aPropVal
);
539 SetMergedItem( aGeometryItem
);
542 double SdrObjCustomShape::GetObjectRotation() const
544 return fObjectRotation
;
547 bool SdrObjCustomShape::IsPostRotate() const
549 const com::sun::star::uno::Any
* pAny
;
550 bool bPostRotate
= false;
551 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
552 pAny
= rGeometryItem
.GetPropertyValueByName( "IsPostRotateAngle" );
554 *pAny
>>= bPostRotate
;
558 double SdrObjCustomShape::GetExtraTextRotation( const bool bPreRotation
) const
560 const com::sun::star::uno::Any
* pAny
;
561 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
562 const OUString
sTextRotateAngle( "TextRotateAngle" );
563 const OUString
sTextPreRotateAngle( "TextPreRotateAngle" );
564 pAny
= rGeometryItem
.GetPropertyValueByName( bPreRotation
? sTextPreRotateAngle
: sTextRotateAngle
);
565 double fExtraTextRotateAngle
= 0.0;
567 *pAny
>>= fExtraTextRotateAngle
;
568 return fExtraTextRotateAngle
;
571 sal_Bool
SdrObjCustomShape::GetTextBounds( Rectangle
& rTextBound
) const
573 sal_Bool bRet
= sal_False
;
575 Reference
< XCustomShapeEngine
> xCustomShapeEngine( GetCustomShapeEngine() );
576 if ( xCustomShapeEngine
.is() )
578 awt::Rectangle
aR( xCustomShapeEngine
->getTextBounds() );
579 if ( aR
.Width
> 1 && aR
.Height
> 1 )
581 rTextBound
= Rectangle( Point( aR
.X
, aR
.Y
), Size( aR
.Width
, aR
.Height
) );
587 basegfx::B2DPolyPolygon
SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape
* pCustomShape
, const sal_Bool bBezierAllowed
)
589 basegfx::B2DPolyPolygon aRetval
;
590 Reference
< XCustomShapeEngine
> xCustomShapeEngine( pCustomShape
->GetCustomShapeEngine() );
591 if ( xCustomShapeEngine
.is() )
593 com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords
= xCustomShapeEngine
->getLineGeometry();
596 aRetval
= basegfx::unotools::polyPolygonBezierToB2DPolyPolygon( aBezierCoords
);
597 if ( !bBezierAllowed
&& aRetval
.areControlPointsUsed())
599 aRetval
= basegfx::tools::adaptiveSubdivideByAngle(aRetval
);
602 catch ( const com::sun::star::lang::IllegalArgumentException
& )
609 std::vector
< SdrCustomShapeInteraction
> SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape
* pCustomShape
) const
611 std::vector
< SdrCustomShapeInteraction
> xRet
;
614 Reference
< XCustomShapeEngine
> xCustomShapeEngine( pCustomShape
->GetCustomShapeEngine() );
615 if ( xCustomShapeEngine
.is() )
618 Sequence
< Reference
< XCustomShapeHandle
> > xInteractionHandles( xCustomShapeEngine
->getInteraction() );
619 for ( i
= 0; i
< xInteractionHandles
.getLength(); i
++ )
621 if ( xInteractionHandles
[ i
].is() )
623 SdrCustomShapeInteraction aSdrCustomShapeInteraction
;
624 aSdrCustomShapeInteraction
.xInteraction
= xInteractionHandles
[ i
];
625 aSdrCustomShapeInteraction
.aPosition
= xInteractionHandles
[ i
]->getPosition();
628 switch( ImpGetCustomShapeType( *this ) )
630 case mso_sptAccentBorderCallout90
: // 2 ortho
633 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
635 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
| CUSTOMSHAPE_HANDLE_ORTHO4
;
639 case mso_sptWedgeRectCallout
:
640 case mso_sptWedgeRRectCallout
:
641 case mso_sptCloudCallout
:
642 case mso_sptWedgeEllipseCallout
:
645 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
;
649 case mso_sptBorderCallout1
: // 2 diag
652 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
654 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
;
657 case mso_sptBorderCallout2
: // 3
660 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
662 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
| CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
| CUSTOMSHAPE_HANDLE_MOVE_SHAPE
;
665 case mso_sptCallout90
:
666 case mso_sptAccentCallout90
:
667 case mso_sptBorderCallout90
:
668 case mso_sptCallout1
:
669 case mso_sptCallout2
:
670 case mso_sptCallout3
:
671 case mso_sptAccentCallout1
:
672 case mso_sptAccentCallout2
:
673 case mso_sptAccentCallout3
:
674 case mso_sptBorderCallout3
:
675 case mso_sptAccentBorderCallout1
:
676 case mso_sptAccentBorderCallout2
:
677 case mso_sptAccentBorderCallout3
:
680 nMode
|= CUSTOMSHAPE_HANDLE_RESIZE_FIXED
| CUSTOMSHAPE_HANDLE_CREATE_FIXED
;
685 aSdrCustomShapeInteraction
.nMode
= nMode
;
686 xRet
.push_back( aSdrCustomShapeInteraction
);
691 catch( const uno::RuntimeException
& )
697 //////////////////////////////////////////////////////////////////////////////
698 // BaseProperties section
699 #define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000)
700 #define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff)
702 static sal_Int32
GetNumberOfProperties ( const SvxMSDffHandle
* pData
)
704 sal_Int32 nPropertiesNeeded
=1; // position is always needed
705 sal_Int32 nFlags
= pData
->nFlags
;
707 if ( nFlags
& MSDFF_HANDLE_FLAGS_MIRRORED_X
)
709 if ( nFlags
& MSDFF_HANDLE_FLAGS_MIRRORED_Y
)
711 if ( nFlags
& MSDFF_HANDLE_FLAGS_SWITCHED
)
713 if ( nFlags
& MSDFF_HANDLE_FLAGS_POLAR
)
716 if ( nFlags
& MSDFF_HANDLE_FLAGS_RADIUS_RANGE
)
718 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
720 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
724 else if ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE
)
726 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
728 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
730 if ( pData
->nRangeYMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
732 if ( pData
->nRangeYMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
736 return nPropertiesNeeded
;
739 static void lcl_ShapePropertiesFromDFF( const SvxMSDffHandle
* pData
, com::sun::star::beans::PropertyValues
& rPropValues
)
741 sal_Int32 nFlags
= pData
->nFlags
, n
=0;
745 const OUString
sPosition( "Position" );
746 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition
;
747 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition
.First
, pData
->nPositionX
, true, true );
748 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition
.Second
, pData
->nPositionY
, true, false );
749 rPropValues
[ n
].Name
= sPosition
;
750 rPropValues
[ n
++ ].Value
<<= aPosition
;
752 if ( nFlags
& MSDFF_HANDLE_FLAGS_MIRRORED_X
)
754 const OUString
sMirroredX( "MirroredX" );
755 sal_Bool bMirroredX
= sal_True
;
756 rPropValues
[ n
].Name
= sMirroredX
;
757 rPropValues
[ n
++ ].Value
<<= bMirroredX
;
759 if ( nFlags
& MSDFF_HANDLE_FLAGS_MIRRORED_Y
)
761 const OUString
sMirroredY( "MirroredY" );
762 sal_Bool bMirroredY
= sal_True
;
763 rPropValues
[ n
].Name
= sMirroredY
;
764 rPropValues
[ n
++ ].Value
<<= bMirroredY
;
766 if ( nFlags
& MSDFF_HANDLE_FLAGS_SWITCHED
)
768 const OUString
sSwitched( "Switched" );
769 sal_Bool bSwitched
= sal_True
;
770 rPropValues
[ n
].Name
= sSwitched
;
771 rPropValues
[ n
++ ].Value
<<= bSwitched
;
773 if ( nFlags
& MSDFF_HANDLE_FLAGS_POLAR
)
775 const OUString
sPolar( "Polar" );
776 ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter
;
777 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter
.First
, pData
->nCenterX
,
778 ( nFlags
& MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL
) != 0, true );
779 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter
.Second
, pData
->nCenterY
,
780 ( nFlags
& MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL
) != 0, false );
781 rPropValues
[ n
].Name
= sPolar
;
782 rPropValues
[ n
++ ].Value
<<= aCenter
;
783 if ( nFlags
& MSDFF_HANDLE_FLAGS_RADIUS_RANGE
)
785 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
787 const OUString
sRadiusRangeMinimum( "RadiusRangeMinimum" );
788 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum
;
789 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum
, pData
->nRangeXMin
,
790 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL
) != 0, true );
791 rPropValues
[ n
].Name
= sRadiusRangeMinimum
;
792 rPropValues
[ n
++ ].Value
<<= aRadiusRangeMinimum
;
794 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
796 const OUString
sRadiusRangeMaximum( "RadiusRangeMaximum" );
797 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum
;
798 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum
, pData
->nRangeXMax
,
799 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL
) != 0, false );
800 rPropValues
[ n
].Name
= sRadiusRangeMaximum
;
801 rPropValues
[ n
++ ].Value
<<= aRadiusRangeMaximum
;
805 else if ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE
)
807 if ( pData
->nRangeXMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
809 const OUString
sRangeXMinimum( "RangeXMinimum" );
810 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum
;
811 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum
, pData
->nRangeXMin
,
812 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL
) != 0, true );
813 rPropValues
[ n
].Name
= sRangeXMinimum
;
814 rPropValues
[ n
++ ].Value
<<= aRangeXMinimum
;
816 if ( pData
->nRangeXMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
818 const OUString
sRangeXMaximum( "RangeXMaximum" );
819 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum
;
820 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum
, pData
->nRangeXMax
,
821 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL
) != 0, false );
822 rPropValues
[ n
].Name
= sRangeXMaximum
;
823 rPropValues
[ n
++ ].Value
<<= aRangeXMaximum
;
825 if ( pData
->nRangeYMin
!= DEFAULT_MINIMUM_SIGNED_COMPARE
)
827 const OUString
sRangeYMinimum( "RangeYMinimum" );
828 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum
;
829 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum
, pData
->nRangeYMin
,
830 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL
) != 0, true );
831 rPropValues
[ n
].Name
= sRangeYMinimum
;
832 rPropValues
[ n
++ ].Value
<<= aRangeYMinimum
;
834 if ( pData
->nRangeYMax
!= DEFAULT_MAXIMUM_SIGNED_COMPARE
)
836 const OUString
sRangeYMaximum( "RangeYMaximum" );
837 ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum
;
838 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum
, pData
->nRangeYMax
,
839 ( nFlags
& MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL
) != 0, false );
840 rPropValues
[ n
].Name
= sRangeYMaximum
;
841 rPropValues
[ n
++ ].Value
<<= aRangeYMaximum
;
847 sdr::properties::BaseProperties
* SdrObjCustomShape::CreateObjectSpecificProperties()
849 return new sdr::properties::CustomShapeProperties(*this);
852 TYPEINIT1(SdrObjCustomShape
,SdrTextObj
);
853 SdrObjCustomShape::SdrObjCustomShape() :
855 fObjectRotation( 0.0 ),
856 mpLastShadowGeometry(0L)
858 bTextFrame
= sal_True
;
861 SdrObjCustomShape::~SdrObjCustomShape()
863 // delete buffered display geometry
864 InvalidateRenderGeometry();
867 void SdrObjCustomShape::MergeDefaultAttributes( const OUString
* pType
)
869 PropertyValue aPropVal
;
871 const OUString
sType( "Type" );
872 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
873 if ( pType
&& !pType
->isEmpty() )
875 sal_Int32 nType
= pType
->toInt32();
877 sShapeType
= EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT
>( nType
) );
881 aPropVal
.Name
= sType
;
882 aPropVal
.Value
<<= sShapeType
;
883 aGeometryItem
.SetPropertyValue( aPropVal
);
887 Any
*pAny
= aGeometryItem
.GetPropertyValueByName( sType
);
889 *pAny
>>= sShapeType
;
891 MSO_SPT eSpType
= EnhancedCustomShapeTypeNames::Get( sShapeType
);
893 const sal_Int32
* pDefData
= NULL
;
894 const mso_CustomShape
* pDefCustomShape
= GetCustomShapeContent( eSpType
);
895 if ( pDefCustomShape
)
896 pDefData
= pDefCustomShape
->pDefData
;
898 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue
> seqAdjustmentValues
;
900 //////////////////////
901 // AdjustmentValues //
902 //////////////////////
903 const OUString
sAdjustmentValues( "AdjustmentValues" );
904 const Any
* pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sAdjustmentValues
);
906 *pAny
>>= seqAdjustmentValues
;
907 if ( pDefCustomShape
&& pDefData
) // now check if we have to default some adjustment values
909 // first check if there are adjustment values are to be appended
910 sal_Int32 i
, nAdjustmentValues
= seqAdjustmentValues
.getLength();
911 sal_Int32 nAdjustmentDefaults
= *pDefData
++;
912 if ( nAdjustmentDefaults
> nAdjustmentValues
)
914 seqAdjustmentValues
.realloc( nAdjustmentDefaults
);
915 for ( i
= nAdjustmentValues
; i
< nAdjustmentDefaults
; i
++ )
917 seqAdjustmentValues
[ i
].Value
<<= pDefData
[ i
];
918 seqAdjustmentValues
[ i
].State
= com::sun::star::beans::PropertyState_DIRECT_VALUE
;
921 // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
922 sal_Int32 nCount
= nAdjustmentValues
> nAdjustmentDefaults
? nAdjustmentDefaults
: nAdjustmentValues
;
923 for ( i
= 0; i
< nCount
; i
++ )
925 if ( seqAdjustmentValues
[ i
].State
!= com::sun::star::beans::PropertyState_DIRECT_VALUE
)
927 seqAdjustmentValues
[ i
].Value
<<= pDefData
[ i
];
928 seqAdjustmentValues
[ i
].State
= com::sun::star::beans::PropertyState_DIRECT_VALUE
;
932 aPropVal
.Name
= sAdjustmentValues
;
933 aPropVal
.Value
<<= seqAdjustmentValues
;
934 aGeometryItem
.SetPropertyValue( aPropVal
);
939 const OUString
sViewBox( "ViewBox" );
940 const Any
* pViewBox
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sViewBox
);
941 com::sun::star::awt::Rectangle aViewBox
;
942 if ( !pViewBox
|| !(*pViewBox
>>= aViewBox
) )
944 if ( pDefCustomShape
)
948 aViewBox
.Width
= pDefCustomShape
->nCoordWidth
;
949 aViewBox
.Height
= pDefCustomShape
->nCoordHeight
;
950 aPropVal
.Name
= sViewBox
;
951 aPropVal
.Value
<<= aViewBox
;
952 aGeometryItem
.SetPropertyValue( aPropVal
);
956 const OUString
sPath( "Path" );
958 //////////////////////
959 // Path/Coordinates //
960 //////////////////////
961 const OUString
sCoordinates( "Coordinates" );
962 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sCoordinates
);
963 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nVertices
&& pDefCustomShape
->pVertices
)
965 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> seqCoordinates
;
967 sal_Int32 i
, nCount
= pDefCustomShape
->nVertices
;
968 seqCoordinates
.realloc( nCount
);
969 for ( i
= 0; i
< nCount
; i
++ )
971 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates
[ i
].First
, pDefCustomShape
->pVertices
[ i
].nValA
);
972 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates
[ i
].Second
, pDefCustomShape
->pVertices
[ i
].nValB
);
974 aPropVal
.Name
= sCoordinates
;
975 aPropVal
.Value
<<= seqCoordinates
;
976 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
979 // Path/GluePoints //
980 const OUString
sGluePoints( "GluePoints" );
981 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sGluePoints
);
982 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nGluePoints
&& pDefCustomShape
->pGluePoints
)
984 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> seqGluePoints
;
985 sal_Int32 i
, nCount
= pDefCustomShape
->nGluePoints
;
986 seqGluePoints
.realloc( nCount
);
987 for ( i
= 0; i
< nCount
; i
++ )
989 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints
[ i
].First
, pDefCustomShape
->pGluePoints
[ i
].nValA
);
990 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints
[ i
].Second
, pDefCustomShape
->pGluePoints
[ i
].nValB
);
992 aPropVal
.Name
= sGluePoints
;
993 aPropVal
.Value
<<= seqGluePoints
;
994 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
998 const OUString
sSegments( "Segments" );
999 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sSegments
);
1000 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nElements
&& pDefCustomShape
->pElements
)
1002 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeSegment
> seqSegments
;
1004 sal_Int32 i
, nCount
= pDefCustomShape
->nElements
;
1005 seqSegments
.realloc( nCount
);
1006 for ( i
= 0; i
< nCount
; i
++ )
1008 EnhancedCustomShapeSegment
& rSegInfo
= seqSegments
[ i
];
1009 sal_uInt16 nSDat
= pDefCustomShape
->pElements
[ i
];
1010 lcl_ShapeSegmentFromBinary( rSegInfo
, nSDat
);
1012 aPropVal
.Name
= sSegments
;
1013 aPropVal
.Value
<<= seqSegments
;
1014 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
1018 const OUString
sStretchX( "StretchX" );
1019 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sStretchX
);
1020 if ( !pAny
&& pDefCustomShape
)
1022 sal_Int32 nXRef
= pDefCustomShape
->nXRef
;
1023 if ( ( nXRef
!= DEFAULT_MINIMUM_SIGNED_COMPARE
) )
1025 aPropVal
.Name
= sStretchX
;
1026 aPropVal
.Value
<<= nXRef
;
1027 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
1032 const OUString
sStretchY( "StretchY" );
1033 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sStretchY
);
1034 if ( !pAny
&& pDefCustomShape
)
1036 sal_Int32 nYRef
= pDefCustomShape
->nYRef
;
1037 if ( ( nYRef
!= DEFAULT_MINIMUM_SIGNED_COMPARE
) )
1039 aPropVal
.Name
= sStretchY
;
1040 aPropVal
.Value
<<= nYRef
;
1041 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
1045 // Path/TextFrames //
1046 const OUString
sTextFrames( "TextFrames" );
1047 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sTextFrames
);
1048 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nTextRect
&& pDefCustomShape
->pTextRect
)
1050 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeTextFrame
> seqTextFrames
;
1052 sal_Int32 i
, nCount
= pDefCustomShape
->nTextRect
;
1053 seqTextFrames
.realloc( nCount
);
1054 const SvxMSDffTextRectangles
* pRectangles
= pDefCustomShape
->pTextRect
;
1055 for ( i
= 0; i
< nCount
; i
++, pRectangles
++ )
1057 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames
[ i
].TopLeft
.First
, pRectangles
->nPairA
.nValA
);
1058 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames
[ i
].TopLeft
.Second
, pRectangles
->nPairA
.nValB
);
1059 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames
[ i
].BottomRight
.First
, pRectangles
->nPairB
.nValA
);
1060 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames
[ i
].BottomRight
.Second
, pRectangles
->nPairB
.nValB
);
1062 aPropVal
.Name
= sTextFrames
;
1063 aPropVal
.Value
<<= seqTextFrames
;
1064 aGeometryItem
.SetPropertyValue( sPath
, aPropVal
);
1068 const OUString
sEquations( "Equations" );
1069 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sEquations
);
1070 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nCalculation
&& pDefCustomShape
->pCalculation
)
1072 com::sun::star::uno::Sequence
< OUString
> seqEquations
;
1074 sal_Int32 i
, nCount
= pDefCustomShape
->nCalculation
;
1075 seqEquations
.realloc( nCount
);
1076 const SvxMSDffCalculationData
* pData
= pDefCustomShape
->pCalculation
;
1077 for ( i
= 0; i
< nCount
; i
++, pData
++ )
1078 seqEquations
[ i
] = EnhancedCustomShape2d::GetEquation( pData
->nFlags
, pData
->nVal
[ 0 ], pData
->nVal
[ 1 ], pData
->nVal
[ 2 ] );
1079 aPropVal
.Name
= sEquations
;
1080 aPropVal
.Value
<<= seqEquations
;
1081 aGeometryItem
.SetPropertyValue( aPropVal
);
1085 const OUString
sHandles( "Handles" );
1086 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sHandles
);
1087 if ( !pAny
&& pDefCustomShape
&& pDefCustomShape
->nHandles
&& pDefCustomShape
->pHandles
)
1089 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValues
> seqHandles
;
1091 sal_Int32 i
, nCount
= pDefCustomShape
->nHandles
;
1092 const SvxMSDffHandle
* pData
= pDefCustomShape
->pHandles
;
1093 seqHandles
.realloc( nCount
);
1094 for ( i
= 0; i
< nCount
; i
++, pData
++ )
1096 sal_Int32 nPropertiesNeeded
;
1097 com::sun::star::beans::PropertyValues
& rPropValues
= seqHandles
[ i
];
1098 nPropertiesNeeded
= GetNumberOfProperties( pData
);
1099 rPropValues
.realloc( nPropertiesNeeded
);
1100 lcl_ShapePropertiesFromDFF( pData
, rPropValues
);
1102 aPropVal
.Name
= sHandles
;
1103 aPropVal
.Value
<<= seqHandles
;
1104 aGeometryItem
.SetPropertyValue( aPropVal
);
1106 SetMergedItem( aGeometryItem
);
1109 sal_Bool
SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType
) const
1111 sal_Bool bIsDefaultGeometry
= sal_False
;
1113 PropertyValue aPropVal
;
1114 OUString sShapeType
;
1115 const OUString
sType( "Type" );
1116 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
1118 Any
*pAny
= aGeometryItem
.GetPropertyValueByName( sType
);
1120 *pAny
>>= sShapeType
;
1122 MSO_SPT eSpType
= EnhancedCustomShapeTypeNames::Get( sShapeType
);
1124 const mso_CustomShape
* pDefCustomShape
= GetCustomShapeContent( eSpType
);
1125 const OUString
sPath( "Path" );
1126 switch( eDefaultType
)
1128 case DEFAULT_VIEWBOX
:
1130 const OUString
sViewBox( "ViewBox" );
1131 const Any
* pViewBox
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sViewBox
);
1132 com::sun::star::awt::Rectangle aViewBox
;
1133 if ( pViewBox
&& ( *pViewBox
>>= aViewBox
) )
1135 if ( ( aViewBox
.Width
== pDefCustomShape
->nCoordWidth
)
1136 && ( aViewBox
.Height
== pDefCustomShape
->nCoordHeight
) )
1137 bIsDefaultGeometry
= sal_True
;
1144 const OUString
sCoordinates( "Coordinates" );
1145 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sCoordinates
);
1146 if ( pAny
&& pDefCustomShape
&& pDefCustomShape
->nVertices
&& pDefCustomShape
->pVertices
)
1148 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> seqCoordinates1
, seqCoordinates2
;
1149 if ( *pAny
>>= seqCoordinates1
)
1151 sal_Int32 i
, nCount
= pDefCustomShape
->nVertices
;
1152 seqCoordinates2
.realloc( nCount
);
1153 for ( i
= 0; i
< nCount
; i
++ )
1155 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2
[ i
].First
, pDefCustomShape
->pVertices
[ i
].nValA
);
1156 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2
[ i
].Second
, pDefCustomShape
->pVertices
[ i
].nValB
);
1158 if ( seqCoordinates1
== seqCoordinates2
)
1159 bIsDefaultGeometry
= sal_True
;
1162 else if ( pDefCustomShape
&& ( ( pDefCustomShape
->nVertices
== 0 ) || ( pDefCustomShape
->pVertices
== 0 ) ) )
1163 bIsDefaultGeometry
= sal_True
;
1167 case DEFAULT_GLUEPOINTS
:
1169 const OUString
sGluePoints( "GluePoints" );
1170 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sGluePoints
);
1171 if ( pAny
&& pDefCustomShape
&& pDefCustomShape
->nGluePoints
&& pDefCustomShape
->pGluePoints
)
1173 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeParameterPair
> seqGluePoints1
, seqGluePoints2
;
1174 if ( *pAny
>>= seqGluePoints1
)
1176 sal_Int32 i
, nCount
= pDefCustomShape
->nGluePoints
;
1177 seqGluePoints2
.realloc( nCount
);
1178 for ( i
= 0; i
< nCount
; i
++ )
1180 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2
[ i
].First
, pDefCustomShape
->pGluePoints
[ i
].nValA
);
1181 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2
[ i
].Second
, pDefCustomShape
->pGluePoints
[ i
].nValB
);
1183 if ( seqGluePoints1
== seqGluePoints2
)
1184 bIsDefaultGeometry
= sal_True
;
1187 else if ( pDefCustomShape
&& ( pDefCustomShape
->nGluePoints
== 0 ) )
1188 bIsDefaultGeometry
= sal_True
;
1192 case DEFAULT_SEGMENTS
:
1195 const OUString
sSegments( "Segments" );
1196 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sSegments
);
1199 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeSegment
> seqSegments1
, seqSegments2
;
1200 if ( *pAny
>>= seqSegments1
)
1202 if ( pDefCustomShape
&& pDefCustomShape
->nElements
&& pDefCustomShape
->pElements
)
1204 sal_Int32 i
, nCount
= pDefCustomShape
->nElements
;
1207 seqSegments2
.realloc( nCount
);
1208 for ( i
= 0; i
< nCount
; i
++ )
1210 EnhancedCustomShapeSegment
& rSegInfo
= seqSegments2
[ i
];
1211 sal_uInt16 nSDat
= pDefCustomShape
->pElements
[ i
];
1212 lcl_ShapeSegmentFromBinary( rSegInfo
, nSDat
);
1214 if ( seqSegments1
== seqSegments2
)
1215 bIsDefaultGeometry
= sal_True
;
1220 // check if its the default segment description ( M L Z N )
1221 if ( seqSegments1
.getLength() == 4 )
1223 if ( ( seqSegments1
[ 0 ].Command
== EnhancedCustomShapeSegmentCommand::MOVETO
)
1224 && ( seqSegments1
[ 1 ].Command
== EnhancedCustomShapeSegmentCommand::LINETO
)
1225 && ( seqSegments1
[ 2 ].Command
== EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
)
1226 && ( seqSegments1
[ 3 ].Command
== EnhancedCustomShapeSegmentCommand::ENDSUBPATH
) )
1227 bIsDefaultGeometry
= sal_True
;
1232 else if ( pDefCustomShape
&& ( ( pDefCustomShape
->nElements
== 0 ) || ( pDefCustomShape
->pElements
== 0 ) ) )
1233 bIsDefaultGeometry
= sal_True
;
1237 case DEFAULT_STRETCHX
:
1239 const OUString
sStretchX( "StretchX" );
1240 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sStretchX
);
1241 if ( pAny
&& pDefCustomShape
)
1243 sal_Int32 nStretchX
= 0;
1244 if ( *pAny
>>= nStretchX
)
1246 if ( pDefCustomShape
->nXRef
== nStretchX
)
1247 bIsDefaultGeometry
= sal_True
;
1250 else if ( pDefCustomShape
&& ( pDefCustomShape
->nXRef
== DEFAULT_MINIMUM_SIGNED_COMPARE
) )
1251 bIsDefaultGeometry
= sal_True
;
1255 case DEFAULT_STRETCHY
:
1257 const OUString
sStretchY( "StretchY" );
1258 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sStretchY
);
1259 if ( pAny
&& pDefCustomShape
)
1261 sal_Int32 nStretchY
= 0;
1262 if ( *pAny
>>= nStretchY
)
1264 if ( pDefCustomShape
->nYRef
== nStretchY
)
1265 bIsDefaultGeometry
= sal_True
;
1268 else if ( pDefCustomShape
&& ( pDefCustomShape
->nYRef
== DEFAULT_MINIMUM_SIGNED_COMPARE
) )
1269 bIsDefaultGeometry
= sal_True
;
1273 case DEFAULT_EQUATIONS
:
1275 const OUString
sEquations( "Equations" );
1276 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sEquations
);
1277 if ( pAny
&& pDefCustomShape
&& pDefCustomShape
->nCalculation
&& pDefCustomShape
->pCalculation
)
1279 com::sun::star::uno::Sequence
< OUString
> seqEquations1
, seqEquations2
;
1280 if ( *pAny
>>= seqEquations1
)
1282 sal_Int32 i
, nCount
= pDefCustomShape
->nCalculation
;
1283 seqEquations2
.realloc( nCount
);
1285 const SvxMSDffCalculationData
* pData
= pDefCustomShape
->pCalculation
;
1286 for ( i
= 0; i
< nCount
; i
++, pData
++ )
1287 seqEquations2
[ i
] = EnhancedCustomShape2d::GetEquation( pData
->nFlags
, pData
->nVal
[ 0 ], pData
->nVal
[ 1 ], pData
->nVal
[ 2 ] );
1289 if ( seqEquations1
== seqEquations2
)
1290 bIsDefaultGeometry
= sal_True
;
1293 else if ( pDefCustomShape
&& ( ( pDefCustomShape
->nCalculation
== 0 ) || ( pDefCustomShape
->pCalculation
== 0 ) ) )
1294 bIsDefaultGeometry
= sal_True
;
1298 case DEFAULT_TEXTFRAMES
:
1300 const OUString
sTextFrames( "TextFrames" );
1301 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sPath
, sTextFrames
);
1302 if ( pAny
&& pDefCustomShape
&& pDefCustomShape
->nTextRect
&& pDefCustomShape
->pTextRect
)
1304 com::sun::star::uno::Sequence
< com::sun::star::drawing::EnhancedCustomShapeTextFrame
> seqTextFrames1
, seqTextFrames2
;
1305 if ( *pAny
>>= seqTextFrames1
)
1307 sal_Int32 i
, nCount
= pDefCustomShape
->nTextRect
;
1308 seqTextFrames2
.realloc( nCount
);
1309 const SvxMSDffTextRectangles
* pRectangles
= pDefCustomShape
->pTextRect
;
1310 for ( i
= 0; i
< nCount
; i
++, pRectangles
++ )
1312 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2
[ i
].TopLeft
.First
, pRectangles
->nPairA
.nValA
);
1313 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2
[ i
].TopLeft
.Second
, pRectangles
->nPairA
.nValB
);
1314 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2
[ i
].BottomRight
.First
, pRectangles
->nPairB
.nValA
);
1315 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2
[ i
].BottomRight
.Second
, pRectangles
->nPairB
.nValB
);
1317 if ( seqTextFrames1
== seqTextFrames2
)
1318 bIsDefaultGeometry
= sal_True
;
1321 else if ( pDefCustomShape
&& ( ( pDefCustomShape
->nTextRect
== 0 ) || ( pDefCustomShape
->pTextRect
== 0 ) ) )
1322 bIsDefaultGeometry
= sal_True
;
1326 case DEFAULT_HANDLES
:
1328 const OUString
sHandles( "Handles" );
1329 pAny
= ((SdrCustomShapeGeometryItem
&)aGeometryItem
).GetPropertyValueByName( sHandles
);
1330 if ( pAny
&& pDefCustomShape
&& pDefCustomShape
->nHandles
&& pDefCustomShape
->pHandles
)
1332 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValues
> seqHandles1
, seqHandles2
;
1333 if ( *pAny
>>= seqHandles1
)
1335 sal_Int32 i
, nCount
= pDefCustomShape
->nHandles
;
1336 const SvxMSDffHandle
* pData
= pDefCustomShape
->pHandles
;
1337 seqHandles2
.realloc( nCount
);
1338 for ( i
= 0; i
< nCount
; i
++, pData
++ )
1340 sal_Int32 nPropertiesNeeded
;
1341 com::sun::star::beans::PropertyValues
& rPropValues
= seqHandles2
[ i
];
1342 nPropertiesNeeded
= GetNumberOfProperties( pData
);
1343 rPropValues
.realloc( nPropertiesNeeded
);
1344 lcl_ShapePropertiesFromDFF( pData
, rPropValues
);
1346 if ( seqHandles1
== seqHandles2
)
1347 bIsDefaultGeometry
= sal_True
;
1350 else if ( pDefCustomShape
&& ( ( pDefCustomShape
->nHandles
== 0 ) || ( pDefCustomShape
->pHandles
== 0 ) ) )
1351 bIsDefaultGeometry
= sal_True
;
1355 return bIsDefaultGeometry
;
1358 void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
1360 rInfo
.bResizeFreeAllowed
=fObjectRotation
== 0.0;
1361 rInfo
.bResizePropAllowed
=sal_True
;
1362 rInfo
.bRotateFreeAllowed
=sal_True
;
1363 rInfo
.bRotate90Allowed
=sal_True
;
1364 rInfo
.bMirrorFreeAllowed
=sal_True
;
1365 rInfo
.bMirror45Allowed
=sal_True
;
1366 rInfo
.bMirror90Allowed
=sal_True
;
1367 rInfo
.bTransparenceAllowed
= sal_False
;
1368 rInfo
.bGradientAllowed
= sal_False
;
1369 rInfo
.bShearAllowed
=sal_True
;
1370 rInfo
.bEdgeRadiusAllowed
=sal_False
;
1371 rInfo
.bNoContortion
=sal_True
;
1374 if ( mXRenderedCustomShape
.is() )
1376 const SdrObject
* pRenderedCustomShape
= GetSdrObjectFromXShape( mXRenderedCustomShape
);
1377 if ( pRenderedCustomShape
)
1380 // Iterate self over the contained objects, since there are combinations of
1381 // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1382 // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1383 SdrObjListIter
aIterator(*pRenderedCustomShape
);
1384 while(aIterator
.IsMore())
1386 SdrObject
* pCandidate
= aIterator
.Next();
1387 SdrObjTransformInfoRec aInfo
;
1388 pCandidate
->TakeObjInfo(aInfo
);
1390 // set path and poly conversion if one is possible since
1391 // this object will first be broken
1392 const bool bCanConvToPathOrPoly(aInfo
.bCanConvToPath
|| aInfo
.bCanConvToPoly
);
1393 if(rInfo
.bCanConvToPath
!= bCanConvToPathOrPoly
)
1395 rInfo
.bCanConvToPath
= bCanConvToPathOrPoly
;
1398 if(rInfo
.bCanConvToPoly
!= bCanConvToPathOrPoly
)
1400 rInfo
.bCanConvToPoly
= bCanConvToPathOrPoly
;
1403 if(rInfo
.bCanConvToContour
!= aInfo
.bCanConvToContour
)
1405 rInfo
.bCanConvToContour
= aInfo
.bCanConvToContour
;
1408 if(rInfo
.bShearAllowed
!= aInfo
.bShearAllowed
)
1410 rInfo
.bShearAllowed
= aInfo
.bShearAllowed
;
1417 void SdrObjCustomShape::SetModel(SdrModel
* pNewModel
)
1419 SdrTextObj::SetModel(pNewModel
);
1420 mXRenderedCustomShape
.clear();
1423 sal_uInt16
SdrObjCustomShape::GetObjIdentifier() const
1425 return sal_uInt16(OBJ_CUSTOMSHAPE
);
1428 ////////////////////////////////////////////////////////////////////////////////////////////////////
1430 void SdrObjCustomShape::RecalcSnapRect()
1432 SdrTextObj::RecalcSnapRect();
1434 const Rectangle
& SdrObjCustomShape::GetSnapRect() const
1436 return SdrTextObj::GetSnapRect();
1438 const Rectangle
& SdrObjCustomShape::GetCurrentBoundRect() const
1440 return SdrTextObj::GetCurrentBoundRect();
1442 const Rectangle
& SdrObjCustomShape::GetLogicRect() const
1444 return SdrTextObj::GetLogicRect();
1446 void SdrObjCustomShape::NbcSetSnapRect( const Rectangle
& rRect
)
1449 ImpJustifyRect(aRect
);
1450 InvalidateRenderGeometry();
1451 Rectangle
aTextBound( aRect
);
1452 if ( GetTextBounds( aTextBound
) )
1454 if ( pModel
==NULL
|| !pModel
->IsPasteResize() )
1456 long nHDist
=GetTextLeftDistance()+GetTextRightDistance();
1457 long nVDist
=GetTextUpperDistance()+GetTextLowerDistance();
1458 long nTWdt
=aTextBound
.GetWidth ()-1-nHDist
; if (nTWdt
<0) nTWdt
=0;
1459 long nTHgt
=aTextBound
.GetHeight()-1-nVDist
; if (nTHgt
<0) nTHgt
=0;
1460 if ( IsAutoGrowWidth() )
1461 NbcSetMinTextFrameWidth( nTWdt
);
1462 if ( IsAutoGrowHeight() )
1463 NbcSetMinTextFrameHeight( nTHgt
);
1464 NbcAdjustTextFrameWidthAndHeight();
1471 void SdrObjCustomShape::SetSnapRect( const Rectangle
& rRect
)
1473 Rectangle aBoundRect0
;
1475 aBoundRect0
= GetLastBoundRect();
1476 NbcSetSnapRect( rRect
);
1477 BroadcastObjectChange();
1478 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
1480 void SdrObjCustomShape::NbcSetLogicRect( const Rectangle
& rRect
)
1483 ImpJustifyRect( aRect
);
1484 InvalidateRenderGeometry();
1485 Rectangle
aTextBound( aRect
);
1486 if ( GetTextBounds( aTextBound
) )
1488 long nHDist
=GetTextLeftDistance()+GetTextRightDistance();
1489 long nVDist
=GetTextUpperDistance()+GetTextLowerDistance();
1491 long nTWdt
=aTextBound
.GetWidth()-1-nHDist
; if (nTWdt
<0) nTWdt
=0;
1492 long nTHgt
=aTextBound
.GetHeight()-1-nVDist
; if (nTHgt
<0) nTHgt
=0;
1493 if ( IsAutoGrowWidth() )
1494 NbcSetMinTextFrameWidth( nTWdt
);
1495 if ( IsAutoGrowHeight() )
1496 NbcSetMinTextFrameHeight( nTHgt
);
1497 NbcAdjustTextFrameWidthAndHeight();
1502 void SdrObjCustomShape::SetLogicRect( const Rectangle
& rRect
)
1504 Rectangle aBoundRect0
;
1506 aBoundRect0
= GetLastBoundRect();
1507 NbcSetLogicRect(rRect
);
1508 BroadcastObjectChange();
1509 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
1511 void SdrObjCustomShape::Move( const Size
& rSiz
)
1513 if ( rSiz
.Width() || rSiz
.Height() )
1515 Rectangle aBoundRect0
;
1517 aBoundRect0
= GetLastBoundRect();
1520 BroadcastObjectChange();
1521 SendUserCall(SDRUSERCALL_MOVEONLY
,aBoundRect0
);
1524 void SdrObjCustomShape::NbcMove( const Size
& rSiz
)
1526 SdrTextObj::NbcMove( rSiz
);
1527 if ( mXRenderedCustomShape
.is() )
1529 SdrObject
* pRenderedCustomShape
= GetSdrObjectFromXShape( mXRenderedCustomShape
);
1530 if ( pRenderedCustomShape
)
1532 // #i97149# the visualisation shape needs to be informed
1533 // about change, too
1534 pRenderedCustomShape
->ActionChanged();
1535 pRenderedCustomShape
->NbcMove( rSiz
);
1539 // #i37011# adapt geometry shadow
1540 if(mpLastShadowGeometry
)
1542 mpLastShadowGeometry
->NbcMove( rSiz
);
1545 void SdrObjCustomShape::Resize( const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bUnsetRelative
)
1547 SdrTextObj::Resize( rRef
, xFact
, yFact
, bUnsetRelative
);
1550 void SdrObjCustomShape::NbcResize( const Point
& rRef
, const Fraction
& rxFact
, const Fraction
& ryFact
)
1552 Fraction
xFact( rxFact
);
1553 Fraction
yFact( ryFact
);
1555 // taking care of handles that should not been changed
1556 Rectangle
aOld( aRect
);
1557 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
1559 SdrTextObj::NbcResize( rRef
, xFact
, yFact
);
1561 if ( ( xFact
.GetNumerator() != xFact
.GetDenominator() )
1562 || ( yFact
.GetNumerator()!= yFact
.GetDenominator() ) )
1564 if ( ( ( xFact
.GetNumerator() < 0 ) && ( xFact
.GetDenominator() > 0 ) ) ||
1565 ( ( xFact
.GetNumerator() > 0 ) && ( xFact
.GetDenominator() < 0 ) ) )
1567 SetMirroredX( IsMirroredX() == sal_False
);
1569 if ( ( ( yFact
.GetNumerator() < 0 ) && ( yFact
.GetDenominator() > 0 ) ) ||
1570 ( ( yFact
.GetNumerator() > 0 ) && ( yFact
.GetDenominator() < 0 ) ) )
1572 SetMirroredY( IsMirroredY() == sal_False
);
1576 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd( aInteractionHandles
.end() );
1577 aIter
!= aEnd
; ++aIter
)
1581 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_FIXED
)
1582 aIter
->xInteraction
->setControllerPosition( aIter
->aPosition
);
1583 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
)
1585 sal_Int32 nX
= ( aIter
->aPosition
.X
- aOld
.Left() ) + aRect
.Left();
1586 aIter
->xInteraction
->setControllerPosition( com::sun::star::awt::Point( nX
, aIter
->xInteraction
->getPosition().Y
) );
1588 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
)
1590 sal_Int32 nY
= ( aIter
->aPosition
.Y
- aOld
.Top() ) + aRect
.Top();
1591 aIter
->xInteraction
->setControllerPosition( com::sun::star::awt::Point( aIter
->xInteraction
->getPosition().X
, nY
) );
1594 catch ( const uno::RuntimeException
& )
1598 InvalidateRenderGeometry();
1600 void SdrObjCustomShape::NbcRotate( const Point
& rRef
, long nWink
, double sn
, double cs
)
1602 sal_Bool bMirroredX
= IsMirroredX();
1603 sal_Bool bMirroredY
= IsMirroredY();
1605 fObjectRotation
= fmod( fObjectRotation
, 360.0 );
1606 if ( fObjectRotation
< 0 )
1607 fObjectRotation
= 360 + fObjectRotation
;
1609 // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1610 // has to be applied to the text object (which is internally using aGeo.nWink).
1611 SdrTextObj::NbcRotate( aRect
.TopLeft(), -aGeo
.nDrehWink
, // retrieving the unrotated text object
1612 sin( (-aGeo
.nDrehWink
) * F_PI18000
),
1613 cos( (-aGeo
.nDrehWink
) * F_PI18000
) );
1614 aGeo
.nDrehWink
= 0; // resetting aGeo data
1615 aGeo
.RecalcSinCos();
1617 long nW
= (long)( fObjectRotation
* 100 ); // applying our object rotation
1625 SdrTextObj::NbcRotate( aRect
.TopLeft(), nW
, // applying text rotation
1626 sin( nW
* F_PI18000
),
1627 cos( nW
* F_PI18000
) );
1635 double fWink
= nWink
; // updating to our new object rotation
1637 fObjectRotation
= fmod( nSwap
? fObjectRotation
- fWink
: fObjectRotation
+ fWink
, 360.0 );
1638 if ( fObjectRotation
< 0 )
1639 fObjectRotation
= 360 + fObjectRotation
;
1641 SdrTextObj::NbcRotate( rRef
, nWink
, sn
, cs
); // applying text rotation
1642 InvalidateRenderGeometry();
1645 void SdrObjCustomShape::NbcMirror( const Point
& rRef1
, const Point
& rRef2
)
1647 // storing horizontal and vertical flipping without modifying the rotate angle
1648 sal_Bool bHorz
= sal_False
;
1649 sal_Bool bVert
= sal_False
;
1650 if ( rRef1
.X() == rRef2
.X() )
1652 if ( rRef1
.Y() == rRef2
.Y() )
1654 if ( !bHorz
&& !bVert
)
1655 bHorz
= bVert
= sal_True
;
1657 if ( bHorz
|| bVert
)
1659 SdrCustomShapeGeometryItem
aGeometryItem( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) );
1664 const OUString
sMirroredX( "MirroredX" );
1665 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredX
);
1668 sal_Bool bFlip
= sal_Bool();
1669 if ( *pAny
>>= bFlip
)
1675 PropertyValue aPropVal
;
1676 aPropVal
.Name
= sMirroredX
;
1677 aPropVal
.Value
<<= bHorz
;
1678 aGeometryItem
.SetPropertyValue( aPropVal
);
1684 const OUString
sMirroredY( "MirroredY" );
1685 com::sun::star::uno::Any
* pAny
= aGeometryItem
.GetPropertyValueByName( sMirroredY
);
1688 sal_Bool bFlip
= sal_Bool();
1689 if ( *pAny
>>= bFlip
)
1695 PropertyValue aPropVal
;
1696 aPropVal
.Name
= sMirroredY
;
1697 aPropVal
.Value
<<= bVert
;
1698 aGeometryItem
.SetPropertyValue( aPropVal
);
1700 SetMergedItem( aGeometryItem
);
1702 SdrTextObj::NbcMirror( rRef1
, rRef2
);
1703 InvalidateRenderGeometry();
1706 void SdrObjCustomShape::Shear( const Point
& rRef
, long nWink
, double tn
, bool bVShear
)
1708 SdrTextObj::Shear( rRef
, nWink
, tn
, bVShear
);
1709 InvalidateRenderGeometry();
1711 void SdrObjCustomShape::NbcShear( const Point
& rRef
, long nWink
, double tn
, bool bVShear
)
1713 long nDrehWink
= aGeo
.nDrehWink
;
1716 aGeo
.nDrehWink
= -nDrehWink
;
1717 aGeo
.RecalcSinCos();
1718 NbcRotate( rRef
, aGeo
.nDrehWink
, aGeo
.nSin
, aGeo
.nCos
);
1720 SdrTextObj::NbcShear(rRef
,nWink
,tn
,bVShear
);
1723 aGeo
.nDrehWink
= nDrehWink
;
1724 aGeo
.RecalcSinCos();
1725 Rotate( rRef
, aGeo
.nDrehWink
, aGeo
.nSin
, aGeo
.nCos
);
1727 InvalidateRenderGeometry();
1730 ////////////////////////////////////////////////////////////////////////////////////////////////////
1732 SdrGluePoint
SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum
) const
1734 sal_Int32 nWdt
= ImpGetLineWdt(); // #i25616#
1737 if(!LineIsOutsideGeometry())
1745 case 0: aPt
=aRect
.TopCenter(); aPt
.Y()-=nWdt
; break;
1746 case 1: aPt
=aRect
.RightCenter(); aPt
.X()+=nWdt
; break;
1747 case 2: aPt
=aRect
.BottomCenter(); aPt
.Y()+=nWdt
; break;
1748 case 3: aPt
=aRect
.LeftCenter(); aPt
.X()-=nWdt
; break;
1750 if (aGeo
.nShearWink
!=0) ShearPoint(aPt
,aRect
.TopLeft(),aGeo
.nTan
);
1751 if (aGeo
.nDrehWink
!=0) RotatePoint(aPt
,aRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
1752 aPt
-=GetSnapRect().Center();
1753 SdrGluePoint
aGP(aPt
);
1754 aGP
.SetPercent(sal_False
);
1758 ////////////////////////////////////////////////////////////////////////////////////////////////////
1761 void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
1763 const SdrObject
* pSdrObject
= GetSdrObjectFromCustomShape();
1767 const SdrGluePointList
* pSource
= pSdrObject
->GetGluePointList();
1769 if(pSource
&& pSource
->GetCount())
1771 if(!SdrTextObj::GetGluePointList())
1773 SdrTextObj::ForceGluePointList();
1776 const SdrGluePointList
* pList
= SdrTextObj::GetGluePointList();
1780 SdrGluePointList aNewList
;
1783 for(a
= 0; a
< pSource
->GetCount(); a
++)
1785 SdrGluePoint
aCopy((*pSource
)[a
]);
1786 aCopy
.SetUserDefined(sal_False
);
1787 aNewList
.Insert(aCopy
);
1790 sal_Bool bMirroredX
= IsMirroredX();
1791 sal_Bool bMirroredY
= IsMirroredY();
1793 long nShearWink
= aGeo
.nShearWink
;
1794 double fTan
= aGeo
.nTan
;
1796 if ( aGeo
.nDrehWink
|| nShearWink
|| bMirroredX
|| bMirroredY
)
1798 Polygon
aPoly( aRect
);
1801 sal_uInt16 nPointCount
=aPoly
.GetSize();
1802 for (sal_uInt16 i
=0; i
<nPointCount
; i
++)
1803 ShearPoint(aPoly
[i
],aRect
.Center(), fTan
, sal_False
);
1805 if ( aGeo
.nDrehWink
)
1806 aPoly
.Rotate( aRect
.Center(), aGeo
.nDrehWink
/ 10 );
1808 Rectangle
aBoundRect( aPoly
.GetBoundRect() );
1809 sal_Int32 nXDiff
= aBoundRect
.Left() - aRect
.Left();
1810 sal_Int32 nYDiff
= aBoundRect
.Top() - aRect
.Top();
1812 if (nShearWink
&&((bMirroredX
&&!bMirroredY
)||(bMirroredY
&&!bMirroredX
)))
1814 nShearWink
= -nShearWink
;
1818 Point
aRef( aRect
.GetWidth() / 2, aRect
.GetHeight() / 2 );
1819 for ( a
= 0; a
< aNewList
.GetCount(); a
++ )
1821 SdrGluePoint
& rPoint
= aNewList
[ a
];
1822 Point
aGlue( rPoint
.GetPos() );
1824 ShearPoint( aGlue
, aRef
, fTan
);
1826 RotatePoint( aGlue
, aRef
, sin( fObjectRotation
* F_PI180
), cos( fObjectRotation
* F_PI180
) );
1828 aGlue
.X() = aRect
.GetWidth() - aGlue
.X();
1830 aGlue
.Y() = aRect
.GetHeight() - aGlue
.Y();
1831 aGlue
.X() -= nXDiff
;
1832 aGlue
.Y() -= nYDiff
;
1833 rPoint
.SetPos( aGlue
);
1837 for(a
= 0; a
< pList
->GetCount(); a
++)
1839 const SdrGluePoint
& rCandidate
= (*pList
)[a
];
1841 if(rCandidate
.IsUserDefined())
1843 aNewList
.Insert(rCandidate
);
1847 // copy new list to local. This is NOT very convenient behavior, the local
1848 // GluePointList should not be set, but we delivered by using GetGluePointList(),
1849 // maybe on demand. Since the local object is changed here, this is assumed to
1850 // be a result of GetGluePointList and thus the list is copied
1853 pPlusData
->SetGluePoints(aNewList
);
1861 const SdrGluePointList
* SdrObjCustomShape::GetGluePointList() const
1863 ((SdrObjCustomShape
*)this)->ImpCheckCustomGluePointsAreAdded();
1864 return SdrTextObj::GetGluePointList();
1868 SdrGluePointList
* SdrObjCustomShape::ForceGluePointList()
1870 if(SdrTextObj::ForceGluePointList())
1872 ImpCheckCustomGluePointsAreAdded();
1873 return SdrTextObj::ForceGluePointList();
1881 ////////////////////////////////////////////////////////////////////////////////////////////////////
1883 sal_uInt32
SdrObjCustomShape::GetHdlCount() const
1885 const sal_uInt32
nBasicHdlCount(SdrTextObj::GetHdlCount());
1886 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
1887 return ( aInteractionHandles
.size() + nBasicHdlCount
);
1890 SdrHdl
* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum
) const
1893 const sal_uInt32
nBasicHdlCount(SdrTextObj::GetHdlCount());
1895 if ( nHdlNum
< nBasicHdlCount
)
1896 pH
= SdrTextObj::GetHdl( nHdlNum
);
1899 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
1900 const sal_uInt32
nCustomShapeHdlNum(nHdlNum
- nBasicHdlCount
);
1902 if ( nCustomShapeHdlNum
< aInteractionHandles
.size() )
1904 if ( aInteractionHandles
[ nCustomShapeHdlNum
].xInteraction
.is() )
1908 com::sun::star::awt::Point
aPosition( aInteractionHandles
[ nCustomShapeHdlNum
].xInteraction
->getPosition() );
1909 pH
= new SdrHdl( Point( aPosition
.X
, aPosition
.Y
), HDL_CUSTOMSHAPE1
);
1910 pH
->SetPointNum( nCustomShapeHdlNum
);
1911 pH
->SetObj( (SdrObject
*)this );
1913 catch ( const uno::RuntimeException
& )
1922 ////////////////////////////////////////////////////////////////////////////////////////////////////
1924 bool SdrObjCustomShape::hasSpecialDrag() const
1929 bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat
& rDrag
) const
1931 const SdrHdl
* pHdl
= rDrag
.GetHdl();
1933 if(pHdl
&& HDL_CUSTOMSHAPE1
== pHdl
->GetKind())
1935 rDrag
.SetEndDragChangesAttributes(true);
1936 rDrag
.SetNoSnap(true);
1940 const SdrHdl
* pHdl2
= rDrag
.GetHdl();
1941 const SdrHdlKind
eHdl((pHdl2
== NULL
) ? HDL_MOVE
: pHdl2
->GetKind());
1967 void SdrObjCustomShape::DragResizeCustomShape( const Rectangle
& rNewRect
, SdrObjCustomShape
* pObj
) const
1969 Rectangle
aOld( pObj
->aRect
);
1970 sal_Bool
bOldMirroredX( pObj
->IsMirroredX() );
1971 sal_Bool
bOldMirroredY( pObj
->IsMirroredY() );
1973 Rectangle
aNewRect( rNewRect
);
1976 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( pObj
) );
1978 GeoStat
aGeoStat( pObj
->GetGeoStat() );
1979 if ( aNewRect
.TopLeft()!= pObj
->aRect
.TopLeft() &&
1980 ( pObj
->aGeo
.nDrehWink
|| pObj
->aGeo
.nShearWink
) )
1982 Point
aNewPos( aNewRect
.TopLeft() );
1983 if ( pObj
->aGeo
.nShearWink
) ShearPoint( aNewPos
, aOld
.TopLeft(), aGeoStat
.nTan
);
1984 if ( pObj
->aGeo
.nDrehWink
) RotatePoint(aNewPos
, aOld
.TopLeft(), aGeoStat
.nSin
, aGeoStat
.nCos
);
1985 aNewRect
.SetPos( aNewPos
);
1987 if ( aNewRect
!= pObj
->aRect
)
1989 pObj
->SetLogicRect( aNewRect
);
1990 pObj
->InvalidateRenderGeometry();
1992 if ( rNewRect
.Left() > rNewRect
.Right() )
1994 Point
aTop( ( pObj
->GetSnapRect().Left() + pObj
->GetSnapRect().Right() ) >> 1, pObj
->GetSnapRect().Top() );
1995 Point
aBottom( aTop
.X(), aTop
.Y() + 1000 );
1996 pObj
->NbcMirror( aTop
, aBottom
);
1998 if ( rNewRect
.Top() > rNewRect
.Bottom() )
2000 Point
aLeft( pObj
->GetSnapRect().Left(), ( pObj
->GetSnapRect().Top() + pObj
->GetSnapRect().Bottom() ) >> 1 );
2001 Point
aRight( aLeft
.X() + 1000, aLeft
.Y() );
2002 pObj
->NbcMirror( aLeft
, aRight
);
2005 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd( aInteractionHandles
.end() );
2006 aIter
!= aEnd
; ++aIter
)
2010 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_FIXED
)
2011 aIter
->xInteraction
->setControllerPosition( aIter
->aPosition
);
2012 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X
)
2015 if ( bOldMirroredX
)
2017 nX
= ( aIter
->aPosition
.X
- aOld
.Right() );
2018 if ( rNewRect
.Left() > rNewRect
.Right() )
2019 nX
= pObj
->aRect
.Left() - nX
;
2021 nX
+= pObj
->aRect
.Right();
2025 nX
= ( aIter
->aPosition
.X
- aOld
.Left() );
2026 if ( rNewRect
.Left() > rNewRect
.Right() )
2027 nX
= pObj
->aRect
.Right() - nX
;
2029 nX
+= pObj
->aRect
.Left();
2031 aIter
->xInteraction
->setControllerPosition( com::sun::star::awt::Point( nX
, aIter
->xInteraction
->getPosition().Y
) );
2033 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y
)
2036 if ( bOldMirroredY
)
2038 nY
= ( aIter
->aPosition
.Y
- aOld
.Bottom() );
2039 if ( rNewRect
.Top() > rNewRect
.Bottom() )
2040 nY
= pObj
->aRect
.Top() - nY
;
2042 nY
+= pObj
->aRect
.Bottom();
2046 nY
= ( aIter
->aPosition
.Y
- aOld
.Top() );
2047 if ( rNewRect
.Top() > rNewRect
.Bottom() )
2048 nY
= pObj
->aRect
.Bottom() - nY
;
2050 nY
+= pObj
->aRect
.Top();
2052 aIter
->xInteraction
->setControllerPosition( com::sun::star::awt::Point( aIter
->xInteraction
->getPosition().X
, nY
) );
2055 catch ( const uno::RuntimeException
& )
2062 void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination
, const sal_uInt16 nCustomShapeHdlNum
, SdrObjCustomShape
* pObj
) const
2064 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( pObj
) );
2065 if ( nCustomShapeHdlNum
< aInteractionHandles
.size() )
2067 SdrCustomShapeInteraction
aInteractionHandle( aInteractionHandles
[ nCustomShapeHdlNum
] );
2068 if ( aInteractionHandle
.xInteraction
.is() )
2072 com::sun::star::awt::Point
aPt( aDestination
.X(), aDestination
.Y() );
2073 if ( aInteractionHandle
.nMode
& CUSTOMSHAPE_HANDLE_MOVE_SHAPE
)
2075 sal_Int32 nXDiff
= aPt
.X
- aInteractionHandle
.aPosition
.X
;
2076 sal_Int32 nYDiff
= aPt
.Y
- aInteractionHandle
.aPosition
.Y
;
2078 pObj
->aRect
.Move( nXDiff
, nYDiff
);
2079 pObj
->aOutRect
.Move( nXDiff
, nYDiff
);
2080 pObj
->maSnapRect
.Move( nXDiff
, nYDiff
);
2081 pObj
->SetRectsDirty(sal_True
);
2082 pObj
->InvalidateRenderGeometry();
2084 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd( aInteractionHandles
.end() ) ;
2085 aIter
!= aEnd
; ++aIter
)
2087 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_FIXED
)
2089 if ( aIter
->xInteraction
.is() )
2090 aIter
->xInteraction
->setControllerPosition( aIter
->aPosition
);
2094 aInteractionHandle
.xInteraction
->setControllerPosition( aPt
);
2096 catch ( const uno::RuntimeException
& )
2103 bool SdrObjCustomShape::applySpecialDrag(SdrDragStat
& rDrag
)
2105 const SdrHdl
* pHdl
= rDrag
.GetHdl();
2106 const SdrHdlKind
eHdl((pHdl
== NULL
) ? HDL_MOVE
: pHdl
->GetKind());
2110 case HDL_CUSTOMSHAPE1
:
2112 rDrag
.SetEndDragChangesGeoAndAttributes(true);
2113 DragMoveCustomShapeHdl( rDrag
.GetNow(), (sal_uInt16
)pHdl
->GetPointNum(), this );
2115 InvalidateRenderGeometry();
2129 DragResizeCustomShape(ImpDragCalcRect(rDrag
), this);
2134 Move(Size(rDrag
.GetDX(), rDrag
.GetDY()));
2143 ////////////////////////////////////////////////////////////////////////////////////////////////////
2145 void SdrObjCustomShape::DragCreateObject( SdrDragStat
& rStat
)
2148 rStat
.TakeCreateRect( aRect1
);
2150 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
2152 sal_uInt32 nDefaultObjectSizeWidth
= 3000; // default width from SDOptions ?
2153 sal_uInt32 nDefaultObjectSizeHeight
= 3000;
2155 if ( ImpVerticalSwitch( *this ) )
2157 SetMirroredX( aRect1
.Left() > aRect1
.Right() );
2159 aRect1
= Rectangle( rStat
.GetNow(), Size( nDefaultObjectSizeWidth
, nDefaultObjectSizeHeight
) );
2160 // subtracting the horizontal difference of the latest handle from shape position
2161 if ( !aInteractionHandles
.empty() )
2163 sal_Int32 nHandlePos
= aInteractionHandles
[ aInteractionHandles
.size() - 1 ].xInteraction
->getPosition().X
;
2164 aRect1
.Move( aRect
.Left() - nHandlePos
, 0 );
2167 ImpJustifyRect( aRect1
);
2168 rStat
.SetActionRect( aRect1
);
2172 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd( aInteractionHandles
.end() );
2173 aIter
!= aEnd
; ++aIter
)
2177 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_CREATE_FIXED
)
2178 aIter
->xInteraction
->setControllerPosition( awt::Point( rStat
.GetStart().X(), rStat
.GetStart().Y() ) );
2180 catch ( const uno::RuntimeException
& )
2185 SetBoundRectDirty();
2186 bSnapRectDirty
=sal_True
;
2189 bool SdrObjCustomShape::BegCreate( SdrDragStat
& rDrag
)
2191 return SdrTextObj::BegCreate( rDrag
);
2194 bool SdrObjCustomShape::MovCreate(SdrDragStat
& rStat
)
2196 SdrView
* pView
= rStat
.GetView(); // #i37448#
2197 if( pView
&& pView
->IsSolidDragging() )
2199 InvalidateRenderGeometry();
2201 DragCreateObject( rStat
);
2206 bool SdrObjCustomShape::EndCreate( SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
2208 DragCreateObject( rStat
);
2212 if ( IsAutoGrowHeight() )
2215 long nHgt
=aRect
.GetHeight()-1;
2216 if (nHgt
==1) nHgt
=0;
2217 NbcSetMinTextFrameHeight( nHgt
);
2219 if ( IsAutoGrowWidth() )
2222 long nWdt
=aRect
.GetWidth()-1;
2223 if (nWdt
==1) nWdt
=0;
2224 NbcSetMinTextFrameWidth( nWdt
);
2226 // re-calculate text frame
2227 NbcAdjustTextFrameWidthAndHeight();
2230 return ( eCmd
== SDRCREATE_FORCEEND
|| rStat
.GetPointAnz() >= 2 );
2233 basegfx::B2DPolyPolygon
SdrObjCustomShape::TakeCreatePoly(const SdrDragStat
& /*rDrag*/) const
2235 return GetLineGeometry( this, sal_False
);
2238 ////////////////////////////////////////////////////////////////////////////////////////////////////
2240 // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2241 // the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
2242 bool SdrObjCustomShape::IsAutoGrowHeight() const
2244 const SfxItemSet
& rSet
= GetMergedItemSet();
2245 bool bIsAutoGrowHeight
= ((SdrTextAutoGrowHeightItem
&)(rSet
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
))).GetValue();
2246 if ( bIsAutoGrowHeight
&& IsVerticalWriting() )
2247 bIsAutoGrowHeight
= ((SdrTextWordWrapItem
&)(rSet
.Get(SDRATTR_TEXT_WORDWRAP
))).GetValue() == sal_False
;
2248 return bIsAutoGrowHeight
;
2250 bool SdrObjCustomShape::IsAutoGrowWidth() const
2252 const SfxItemSet
& rSet
= GetMergedItemSet();
2253 bool bIsAutoGrowWidth
= ((SdrTextAutoGrowHeightItem
&)(rSet
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
))).GetValue();
2254 if ( bIsAutoGrowWidth
&& !IsVerticalWriting() )
2255 bIsAutoGrowWidth
= ((SdrTextWordWrapItem
&)(rSet
.Get(SDRATTR_TEXT_WORDWRAP
))).GetValue() == sal_False
;
2256 return bIsAutoGrowWidth
;
2259 /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2260 is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2261 mode has been changed */
2263 void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical
)
2265 ForceOutlinerParaObject();
2267 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
2269 DBG_ASSERT( pOutlinerParaObject
, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2271 if( pOutlinerParaObject
)
2273 if(pOutlinerParaObject
->IsVertical() != (bool)bVertical
)
2275 // get item settings
2276 const SfxItemSet
& rSet
= GetObjectItemSet();
2278 // Also exchange horizontal and vertical adjust items
2279 SdrTextHorzAdjust eHorz
= ((SdrTextHorzAdjustItem
&)(rSet
.Get(SDRATTR_TEXT_HORZADJUST
))).GetValue();
2280 SdrTextVertAdjust eVert
= ((SdrTextVertAdjustItem
&)(rSet
.Get(SDRATTR_TEXT_VERTADJUST
))).GetValue();
2282 // rescue object size
2283 Rectangle aObjectRect
= GetSnapRect();
2285 // prepare ItemSet to set exchanged width and height items
2286 SfxItemSet
aNewSet(*rSet
.GetPool(),
2287 SDRATTR_TEXT_AUTOGROWHEIGHT
, SDRATTR_TEXT_AUTOGROWHEIGHT
,
2288 // Expanded item ranges to also support horizontal and vertical adjust.
2289 SDRATTR_TEXT_VERTADJUST
, SDRATTR_TEXT_VERTADJUST
,
2290 SDRATTR_TEXT_AUTOGROWWIDTH
, SDRATTR_TEXT_HORZADJUST
,
2295 // Exchange horizontal and vertical adjusts
2298 case SDRTEXTVERTADJUST_TOP
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT
)); break;
2299 case SDRTEXTVERTADJUST_CENTER
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER
)); break;
2300 case SDRTEXTVERTADJUST_BOTTOM
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT
)); break;
2301 case SDRTEXTVERTADJUST_BLOCK
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK
)); break;
2305 case SDRTEXTHORZADJUST_LEFT
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM
)); break;
2306 case SDRTEXTHORZADJUST_CENTER
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER
)); break;
2307 case SDRTEXTHORZADJUST_RIGHT
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP
)); break;
2308 case SDRTEXTHORZADJUST_BLOCK
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK
)); break;
2311 SetObjectItemSet( aNewSet
);
2312 pOutlinerParaObject
= GetOutlinerParaObject();
2313 if ( pOutlinerParaObject
)
2314 pOutlinerParaObject
->SetVertical(bVertical
);
2316 // restore object size
2317 SetSnapRect(aObjectRect
);
2321 bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle
& rR
, bool bHgt
, bool bWdt
) const
2323 if ( pModel
&& HasText() && !rR
.IsEmpty() )
2325 bool bWdtGrow
=bWdt
&& IsAutoGrowWidth();
2326 bool bHgtGrow
=bHgt
&& IsAutoGrowHeight();
2327 if ( bWdtGrow
|| bHgtGrow
)
2330 long nHgt
=0,nMinHgt
=0,nMaxHgt
=0;
2331 long nWdt
=0,nMinWdt
=0,nMaxWdt
=0;
2332 Size
aSiz(rR
.GetSize()); aSiz
.Width()--; aSiz
.Height()--;
2333 Size
aMaxSiz(100000,100000);
2334 Size
aTmpSiz(pModel
->GetMaxObjSize());
2335 if (aTmpSiz
.Width()!=0) aMaxSiz
.Width()=aTmpSiz
.Width();
2336 if (aTmpSiz
.Height()!=0) aMaxSiz
.Height()=aTmpSiz
.Height();
2339 nMinWdt
=GetMinTextFrameWidth();
2340 nMaxWdt
=GetMaxTextFrameWidth();
2341 if (nMaxWdt
==0 || nMaxWdt
>aMaxSiz
.Width()) nMaxWdt
=aMaxSiz
.Width();
2342 if (nMinWdt
<=0) nMinWdt
=1;
2343 aSiz
.Width()=nMaxWdt
;
2347 nMinHgt
=GetMinTextFrameHeight();
2348 nMaxHgt
=GetMaxTextFrameHeight();
2349 if (nMaxHgt
==0 || nMaxHgt
>aMaxSiz
.Height()) nMaxHgt
=aMaxSiz
.Height();
2350 if (nMinHgt
<=0) nMinHgt
=1;
2351 aSiz
.Height()=nMaxHgt
;
2353 long nHDist
=GetTextLeftDistance()+GetTextRightDistance();
2354 long nVDist
=GetTextUpperDistance()+GetTextLowerDistance();
2355 aSiz
.Width()-=nHDist
;
2356 aSiz
.Height()-=nVDist
;
2357 if ( aSiz
.Width() < 2 )
2358 aSiz
.Width() = 2; // minimum size=2
2359 if ( aSiz
.Height() < 2 )
2360 aSiz
.Height() = 2; // minimum size=2
2364 pEdtOutl
->SetMaxAutoPaperSize( aSiz
);
2367 Size
aSiz2(pEdtOutl
->CalcTextSize());
2368 nWdt
=aSiz2
.Width()+1; // a little more tolerance
2369 if (bHgtGrow
) nHgt
=aSiz2
.Height()+1; // a little more tolerance
2372 nHgt
=pEdtOutl
->GetTextHeight()+1; // a little more tolerance
2377 Outliner
& rOutliner
=ImpGetDrawOutliner();
2378 rOutliner
.SetPaperSize(aSiz
);
2379 rOutliner
.SetUpdateMode(sal_True
);
2380 // TODO: add the optimization with bPortionInfoChecked again.
2381 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
2382 if( pOutlinerParaObject
!= NULL
)
2384 rOutliner
.SetText(*pOutlinerParaObject
);
2385 rOutliner
.SetFixedCellHeight(((const SdrTextFixedCellHeightItem
&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
)).GetValue());
2389 Size
aSiz2(rOutliner
.CalcTextSize());
2390 nWdt
=aSiz2
.Width()+1; // a little more tolerance
2392 nHgt
=aSiz2
.Height()+1; // a little more tolerance
2395 nHgt
= rOutliner
.GetTextHeight()+1; // a little more tolerance
2398 if ( nWdt
< nMinWdt
)
2400 if ( nWdt
> nMaxWdt
)
2404 nWdt
= 1; // nHDist may also be negative
2405 if ( nHgt
< nMinHgt
)
2407 if ( nHgt
> nMaxHgt
)
2411 nHgt
= 1; // nVDist may also be negative
2412 long nWdtGrow
= nWdt
-(rR
.Right()-rR
.Left());
2413 long nHgtGrow
= nHgt
-(rR
.Bottom()-rR
.Top());
2414 if ( nWdtGrow
== 0 )
2415 bWdtGrow
= sal_False
;
2416 if ( nHgtGrow
== 0 )
2418 if ( bWdtGrow
|| bHgtGrow
)
2422 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
2423 if ( eHAdj
== SDRTEXTHORZADJUST_LEFT
)
2424 rR
.Right()+=nWdtGrow
;
2425 else if ( eHAdj
== SDRTEXTHORZADJUST_RIGHT
)
2426 rR
.Left()-=nWdtGrow
;
2429 long nWdtGrow2
=nWdtGrow
/2;
2430 rR
.Left()-=nWdtGrow2
;
2431 rR
.Right()=rR
.Left()+nWdt
;
2436 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
2437 if ( eVAdj
== SDRTEXTVERTADJUST_TOP
)
2438 rR
.Bottom()+=nHgtGrow
;
2439 else if ( eVAdj
== SDRTEXTVERTADJUST_BOTTOM
)
2443 long nHgtGrow2
=nHgtGrow
/2;
2444 rR
.Top()-=nHgtGrow2
;
2445 rR
.Bottom()=rR
.Top()+nHgt
;
2448 if ( aGeo
.nDrehWink
)
2450 Point
aD1(rR
.TopLeft());
2453 RotatePoint(aD2
,Point(),aGeo
.nSin
,aGeo
.nCos
);
2455 rR
.Move(aD2
.X(),aD2
.Y());
2464 Rectangle
SdrObjCustomShape::ImpCalculateTextFrame( const bool bHgt
, const bool bWdt
)
2466 Rectangle aReturnValue
;
2468 Rectangle
aOldTextRect( aRect
); // <- initial text rectangle
2470 Rectangle
aNewTextRect( aRect
); // <- new text rectangle returned from the custom shape renderer,
2471 GetTextBounds( aNewTextRect
); // it depends to the current logical shape size
2473 Rectangle
aAdjustedTextRect( aNewTextRect
); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2474 if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect
, bHgt
, bWdt
) ) // that the new text rectangle is matching the current text size from the outliner
2476 if ( ( aAdjustedTextRect
!= aNewTextRect
) && ( aOldTextRect
!= aAdjustedTextRect
) )
2478 aReturnValue
= aRect
;
2479 double fXScale
= (double)aOldTextRect
.GetWidth() / (double)aNewTextRect
.GetWidth();
2480 double fYScale
= (double)aOldTextRect
.GetHeight() / (double)aNewTextRect
.GetHeight();
2481 double fRightDiff
= (double)( aAdjustedTextRect
.Right() - aNewTextRect
.Right() ) * fXScale
;
2482 double fLeftDiff
= (double)( aAdjustedTextRect
.Left() - aNewTextRect
.Left() ) * fXScale
;
2483 double fTopDiff
= (double)( aAdjustedTextRect
.Top() - aNewTextRect
.Top() ) * fYScale
;
2484 double fBottomDiff
= (double)( aAdjustedTextRect
.Bottom()- aNewTextRect
.Bottom()) * fYScale
;
2485 aReturnValue
.Left() += (sal_Int32
)fLeftDiff
;
2486 aReturnValue
.Right() += (sal_Int32
)fRightDiff
;
2487 aReturnValue
.Top() += (sal_Int32
)fTopDiff
;
2488 aReturnValue
.Bottom() += (sal_Int32
)fBottomDiff
;
2491 return aReturnValue
;
2494 bool SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(bool bHgt
, bool bWdt
)
2496 Rectangle aNewTextRect
= ImpCalculateTextFrame( bHgt
, bWdt
);
2497 bool bRet
= !aNewTextRect
.IsEmpty() && ( aNewTextRect
!= aRect
);
2500 // taking care of handles that should not been changed
2501 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
2503 aRect
= aNewTextRect
;
2507 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd ( aInteractionHandles
.end() );
2508 aIter
!= aEnd
; ++aIter
)
2512 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_FIXED
)
2513 aIter
->xInteraction
->setControllerPosition( aIter
->aPosition
);
2515 catch ( const uno::RuntimeException
& )
2519 InvalidateRenderGeometry();
2523 bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(bool bHgt
, bool bWdt
)
2525 Rectangle aNewTextRect
= ImpCalculateTextFrame( bHgt
, bWdt
);
2526 bool bRet
= !aNewTextRect
.IsEmpty() && ( aNewTextRect
!= aRect
);
2529 Rectangle aBoundRect0
;
2531 aBoundRect0
= GetCurrentBoundRect();
2533 // taking care of handles that should not been changed
2534 std::vector
< SdrCustomShapeInteraction
> aInteractionHandles( GetInteractionHandles( this ) );
2536 aRect
= aNewTextRect
;
2539 for (std::vector
< SdrCustomShapeInteraction
>::const_iterator
aIter( aInteractionHandles
.begin() ), aEnd( aInteractionHandles
.end() ) ;
2540 aIter
!= aEnd
; ++aIter
)
2544 if ( aIter
->nMode
& CUSTOMSHAPE_HANDLE_RESIZE_FIXED
)
2545 aIter
->xInteraction
->setControllerPosition( aIter
->aPosition
);
2547 catch ( const uno::RuntimeException
& )
2552 InvalidateRenderGeometry();
2554 BroadcastObjectChange();
2555 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
2559 sal_Bool
SdrObjCustomShape::BegTextEdit( SdrOutliner
& rOutl
)
2561 return SdrTextObj::BegTextEdit( rOutl
);
2563 void SdrObjCustomShape::TakeTextEditArea(Size
* pPaperMin
, Size
* pPaperMax
, Rectangle
* pViewInit
, Rectangle
* pViewMin
) const
2565 Size aPaperMin
,aPaperMax
;
2566 Rectangle aViewInit
;
2567 TakeTextAnchorRect( aViewInit
);
2568 if ( aGeo
.nDrehWink
)
2570 Point
aCenter(aViewInit
.Center());
2571 aCenter
-=aViewInit
.TopLeft();
2572 Point
aCenter0(aCenter
);
2573 RotatePoint(aCenter
,Point(),aGeo
.nSin
,aGeo
.nCos
);
2575 aViewInit
.Move(aCenter
.X(),aCenter
.Y());
2577 Size
aAnkSiz(aViewInit
.GetSize());
2578 aAnkSiz
.Width()--; aAnkSiz
.Height()--; // because GetSize() adds 1
2579 Size
aMaxSiz(1000000,1000000);
2581 Size
aTmpSiz(pModel
->GetMaxObjSize());
2582 if (aTmpSiz
.Width()!=0) aMaxSiz
.Width()=aTmpSiz
.Width();
2583 if (aTmpSiz
.Height()!=0) aMaxSiz
.Height()=aTmpSiz
.Height();
2585 SdrTextHorzAdjust
eHAdj(GetTextHorizontalAdjust());
2586 SdrTextVertAdjust
eVAdj(GetTextVerticalAdjust());
2588 long nMinWdt
= GetMinTextFrameWidth();
2589 long nMinHgt
= GetMinTextFrameHeight();
2590 long nMaxWdt
= GetMaxTextFrameWidth();
2591 long nMaxHgt
= GetMaxTextFrameHeight();
2592 if (nMinWdt
<1) nMinWdt
=1;
2593 if (nMinHgt
<1) nMinHgt
=1;
2594 if ( nMaxWdt
== 0 || nMaxWdt
> aMaxSiz
.Width() )
2595 nMaxWdt
= aMaxSiz
.Width();
2596 if ( nMaxHgt
== 0 || nMaxHgt
> aMaxSiz
.Height() )
2597 nMaxHgt
=aMaxSiz
.Height();
2599 if (((SdrTextWordWrapItem
&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP
))).GetValue())
2601 if ( IsVerticalWriting() )
2603 nMaxHgt
= aAnkSiz
.Height();
2608 nMaxWdt
= aAnkSiz
.Width();
2612 aPaperMax
.Width()=nMaxWdt
;
2613 aPaperMax
.Height()=nMaxHgt
;
2615 aPaperMin
.Width()=nMinWdt
;
2616 aPaperMin
.Height()=nMinHgt
;
2620 *pViewMin
= aViewInit
;
2622 long nXFree
= aAnkSiz
.Width() - aPaperMin
.Width();
2623 if ( eHAdj
== SDRTEXTHORZADJUST_LEFT
)
2624 pViewMin
->Right() -= nXFree
;
2625 else if ( eHAdj
== SDRTEXTHORZADJUST_RIGHT
)
2626 pViewMin
->Left() += nXFree
;
2627 else { pViewMin
->Left() += nXFree
/ 2; pViewMin
->Right() = pViewMin
->Left() + aPaperMin
.Width(); }
2629 long nYFree
= aAnkSiz
.Height() - aPaperMin
.Height();
2630 if ( eVAdj
== SDRTEXTVERTADJUST_TOP
)
2631 pViewMin
->Bottom() -= nYFree
;
2632 else if ( eVAdj
== SDRTEXTVERTADJUST_BOTTOM
)
2633 pViewMin
->Top() += nYFree
;
2634 else { pViewMin
->Top() += nYFree
/ 2; pViewMin
->Bottom() = pViewMin
->Top() + aPaperMin
.Height(); }
2637 if( IsVerticalWriting() )
2638 aPaperMin
.Width() = 0;
2640 aPaperMin
.Height() = 0;
2642 if( eHAdj
!= SDRTEXTHORZADJUST_BLOCK
)
2643 aPaperMin
.Width()=0;
2645 // For complete vertical adjust support, set paper min height to 0, here.
2646 if(SDRTEXTVERTADJUST_BLOCK
!= eVAdj
)
2647 aPaperMin
.Height() = 0;
2649 if (pPaperMin
!=NULL
) *pPaperMin
=aPaperMin
;
2650 if (pPaperMax
!=NULL
) *pPaperMax
=aPaperMax
;
2651 if (pViewInit
!=NULL
) *pViewInit
=aViewInit
;
2653 void SdrObjCustomShape::EndTextEdit( SdrOutliner
& rOutl
)
2655 SdrTextObj::EndTextEdit( rOutl
);
2656 InvalidateRenderGeometry();
2658 void SdrObjCustomShape::TakeTextAnchorRect( Rectangle
& rAnchorRect
) const
2660 if ( GetTextBounds( rAnchorRect
) )
2662 Point
aRotateRef( maSnapRect
.Center() );
2663 rAnchorRect
.Left() += GetTextLeftDistance();
2664 rAnchorRect
.Top() += GetTextUpperDistance();
2665 rAnchorRect
.Right() -= GetTextRightDistance();
2666 rAnchorRect
.Bottom() -= GetTextLowerDistance();
2667 ImpJustifyRect( rAnchorRect
);
2669 if ( rAnchorRect
.GetWidth() < 2 )
2670 rAnchorRect
.Right() = rAnchorRect
.Left() + 1; // minimal width is 2
2671 if ( rAnchorRect
.GetHeight() < 2 )
2672 rAnchorRect
.Bottom() = rAnchorRect
.Top() + 1; // minimal height is 2
2673 if ( aGeo
.nDrehWink
)
2675 Point
aP( rAnchorRect
.TopLeft() );
2676 RotatePoint( aP
, aRotateRef
, aGeo
.nSin
, aGeo
. nCos
);
2677 rAnchorRect
.SetPos( aP
);
2681 SdrTextObj::TakeTextAnchorRect( rAnchorRect
);
2683 void SdrObjCustomShape::TakeTextRect( SdrOutliner
& rOutliner
, Rectangle
& rTextRect
, bool bNoEditText
,
2684 Rectangle
* pAnchorRect
, bool /*bLineWidth*/) const
2686 Rectangle aAnkRect
; // Rect in which we anchor
2687 TakeTextAnchorRect(aAnkRect
);
2688 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
2689 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
2690 sal_uIntPtr nStat0
=rOutliner
.GetControlWord();
2693 rOutliner
.SetControlWord(nStat0
|EE_CNTRL_AUTOPAGESIZE
);
2694 rOutliner
.SetMinAutoPaperSize(aNullSize
);
2695 sal_Int32 nMaxAutoPaperWidth
= 1000000;
2696 sal_Int32 nMaxAutoPaperHeight
= 1000000;
2698 long nAnkWdt
=aAnkRect
.GetWidth();
2699 long nAnkHgt
=aAnkRect
.GetHeight();
2701 if (((SdrTextWordWrapItem
&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP
))).GetValue())
2703 if ( IsVerticalWriting() )
2704 nMaxAutoPaperHeight
= nAnkHgt
;
2706 nMaxAutoPaperWidth
= nAnkWdt
;
2708 if(SDRTEXTHORZADJUST_BLOCK
== eHAdj
&& !IsVerticalWriting())
2710 rOutliner
.SetMinAutoPaperSize(Size(nAnkWdt
, 0));
2713 if(SDRTEXTVERTADJUST_BLOCK
== eVAdj
&& IsVerticalWriting())
2715 rOutliner
.SetMinAutoPaperSize(Size(0, nAnkHgt
));
2717 rOutliner
.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth
, nMaxAutoPaperHeight
) );
2718 rOutliner
.SetPaperSize( aNullSize
);
2720 // put text into the Outliner - if necessary the use the text from the EditOutliner
2721 OutlinerParaObject
* pPara
= GetOutlinerParaObject();
2722 if (pEdtOutl
&& !bNoEditText
)
2723 pPara
=pEdtOutl
->CreateParaObject();
2727 bool bHitTest
= false;
2729 bHitTest
= &pModel
->GetHitTestOutliner() == &rOutliner
;
2731 const SdrTextObj
* pTestObj
= rOutliner
.GetTextObj();
2732 if( !pTestObj
|| !bHitTest
|| pTestObj
!= this ||
2733 pTestObj
->GetOutlinerParaObject() != GetOutlinerParaObject() )
2736 rOutliner
.SetTextObj( this );
2738 rOutliner
.SetUpdateMode(sal_True
);
2739 rOutliner
.SetText(*pPara
);
2744 rOutliner
.SetTextObj( NULL
);
2746 if (pEdtOutl
&& !bNoEditText
&& pPara
)
2749 rOutliner
.SetUpdateMode(sal_True
);
2750 rOutliner
.SetControlWord(nStat0
);
2752 SdrText
* pText
= getActiveText();
2754 pText
->CheckPortionInfo( rOutliner
);
2756 Point
aTextPos(aAnkRect
.TopLeft());
2757 Size
aTextSiz(rOutliner
.GetPaperSize()); // GetPaperSize() has a little added tolerance, no?
2759 // For draw objects containing text correct horizontal/vertical alignment if text is bigger
2760 // than the object itself. Without that correction, the text would always be
2761 // formatted to the left edge (or top edge when vertical) of the draw object.
2763 if( !IsTextFrame() )
2765 if(aAnkRect
.GetWidth() < aTextSiz
.Width() && !IsVerticalWriting())
2767 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
2768 // else the alignment is wanted.
2769 if(SDRTEXTHORZADJUST_BLOCK
== eHAdj
)
2771 eHAdj
= SDRTEXTHORZADJUST_CENTER
;
2775 if(aAnkRect
.GetHeight() < aTextSiz
.Height() && IsVerticalWriting())
2777 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
2778 // else the alignment is wanted.
2779 if(SDRTEXTVERTADJUST_BLOCK
== eVAdj
)
2781 eVAdj
= SDRTEXTVERTADJUST_CENTER
;
2786 if (eHAdj
==SDRTEXTHORZADJUST_CENTER
|| eHAdj
==SDRTEXTHORZADJUST_RIGHT
)
2788 long nFreeWdt
=aAnkRect
.GetWidth()-aTextSiz
.Width();
2789 if (eHAdj
==SDRTEXTHORZADJUST_CENTER
)
2790 aTextPos
.X()+=nFreeWdt
/2;
2791 if (eHAdj
==SDRTEXTHORZADJUST_RIGHT
)
2792 aTextPos
.X()+=nFreeWdt
;
2794 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
|| eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
2796 long nFreeHgt
=aAnkRect
.GetHeight()-aTextSiz
.Height();
2797 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
)
2798 aTextPos
.Y()+=nFreeHgt
/2;
2799 if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
2800 aTextPos
.Y()+=nFreeHgt
;
2802 if (aGeo
.nDrehWink
!=0)
2803 RotatePoint(aTextPos
,aAnkRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
2806 *pAnchorRect
=aAnkRect
;
2808 // using rTextRect together with ContourFrame doesn't always work correctly
2809 rTextRect
=Rectangle(aTextPos
,aTextSiz
);
2812 void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject
* pTextObject
)
2814 SdrTextObj::NbcSetOutlinerParaObject( pTextObject
);
2815 SetBoundRectDirty();
2816 SetRectsDirty(sal_True
);
2817 InvalidateRenderGeometry();
2820 SdrObjCustomShape
* SdrObjCustomShape::Clone() const
2822 return CloneHelper
< SdrObjCustomShape
>();
2825 SdrObjCustomShape
& SdrObjCustomShape::operator=(const SdrObjCustomShape
& rObj
)
2829 SdrTextObj::operator=( rObj
);
2831 fObjectRotation
= rObj
.fObjectRotation
;
2832 InvalidateRenderGeometry();
2837 void SdrObjCustomShape::TakeObjNameSingul(XubString
& rName
) const
2839 rName
= ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE
);
2840 String
aNm( GetName() );
2843 rName
+= sal_Unicode(' ');
2844 rName
+= sal_Unicode('\'');
2846 rName
+= sal_Unicode('\'');
2850 void SdrObjCustomShape::TakeObjNamePlural(XubString
& rName
) const
2852 rName
=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE
);
2855 basegfx::B2DPolyPolygon
SdrObjCustomShape::TakeXorPoly() const
2857 return GetLineGeometry( (SdrObjCustomShape
*)this, sal_False
);
2860 basegfx::B2DPolyPolygon
SdrObjCustomShape::TakeContour() const
2862 const SdrObject
* pSdrObject
= GetSdrObjectFromCustomShape();
2864 return pSdrObject
->TakeContour();
2865 return basegfx::B2DPolyPolygon();
2868 SdrObject
* SdrObjCustomShape::DoConvertToPolyObj(sal_Bool bBezier
, bool bAddText
) const
2871 SdrObject
* pRetval
= 0L;
2872 SdrObject
* pRenderedCustomShape
= 0L;
2874 if ( !mXRenderedCustomShape
.is() )
2876 // force CustomShape
2877 ((SdrObjCustomShape
*)this)->GetSdrObjectFromCustomShape();
2880 if ( mXRenderedCustomShape
.is() )
2882 pRenderedCustomShape
= GetSdrObjectFromXShape( mXRenderedCustomShape
);
2885 if ( pRenderedCustomShape
)
2887 SdrObject
* pCandidate
= pRenderedCustomShape
->Clone();
2888 DBG_ASSERT(pCandidate
, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
2889 pCandidate
->SetModel(GetModel());
2890 pRetval
= pCandidate
->DoConvertToPolyObj(bBezier
, bAddText
);
2891 SdrObject::Free( pCandidate
);
2895 const sal_Bool
bShadow(((SdrShadowItem
&)GetMergedItem(SDRATTR_SHADOW
)).GetValue());
2898 pRetval
->SetMergedItem(SdrShadowItem(sal_True
));
2902 if(bAddText
&& HasText() && !IsTextPath())
2904 pRetval
= ImpConvertAddText(pRetval
, bBezier
);
2911 void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet
* pNewStyleSheet
, sal_Bool bDontRemoveHardAttr
)
2914 InvalidateRenderGeometry();
2915 SdrObject::NbcSetStyleSheet( pNewStyleSheet
, bDontRemoveHardAttr
);
2918 void SdrObjCustomShape::SetPage( SdrPage
* pNewPage
)
2920 SdrTextObj::SetPage( pNewPage
);
2924 // invalidating rectangles by SetRectsDirty is not sufficient,
2925 // AdjustTextFrameWidthAndHeight() also has to be made, both
2926 // actions are done by NbcSetSnapRect
2927 Rectangle
aTmp( aRect
); //creating temporary rectangle #i61108#
2928 NbcSetSnapRect( aTmp
);
2932 SdrObjGeoData
* SdrObjCustomShape::NewGeoData() const
2934 return new SdrAShapeObjGeoData
;
2937 void SdrObjCustomShape::SaveGeoData(SdrObjGeoData
& rGeo
) const
2939 SdrTextObj::SaveGeoData( rGeo
);
2940 SdrAShapeObjGeoData
& rAGeo
=(SdrAShapeObjGeoData
&)rGeo
;
2941 rAGeo
.fObjectRotation
= fObjectRotation
;
2942 rAGeo
.bMirroredX
= IsMirroredX();
2943 rAGeo
.bMirroredY
= IsMirroredY();
2945 const OUString
sAdjustmentValues( "AdjustmentValues" );
2946 Any
* pAny( ( (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
) ).GetPropertyValueByName( sAdjustmentValues
) );
2948 *pAny
>>= rAGeo
.aAdjustmentSeq
;
2951 void SdrObjCustomShape::RestGeoData(const SdrObjGeoData
& rGeo
)
2953 SdrTextObj::RestGeoData( rGeo
);
2954 SdrAShapeObjGeoData
& rAGeo
=(SdrAShapeObjGeoData
&)rGeo
;
2955 fObjectRotation
= rAGeo
.fObjectRotation
;
2956 SetMirroredX( rAGeo
.bMirroredX
);
2957 SetMirroredY( rAGeo
.bMirroredY
);
2959 SdrCustomShapeGeometryItem rGeometryItem
= (SdrCustomShapeGeometryItem
&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
2960 const OUString
sAdjustmentValues( "AdjustmentValues" );
2961 PropertyValue aPropVal
;
2962 aPropVal
.Name
= sAdjustmentValues
;
2963 aPropVal
.Value
<<= rAGeo
.aAdjustmentSeq
;
2964 rGeometryItem
.SetPropertyValue( aPropVal
);
2965 SetMergedItem( rGeometryItem
);
2967 InvalidateRenderGeometry();
2970 void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& /*rPolyPolygon*/)
2973 basegfx::B2DTuple aScale
;
2974 basegfx::B2DTuple aTranslate
;
2975 double fRotate
, fShearX
;
2976 rMatrix
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
2978 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
2979 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
2980 if(basegfx::fTools::less(aScale
.getX(), 0.0) && basegfx::fTools::less(aScale
.getY(), 0.0))
2982 aScale
.setX(fabs(aScale
.getX()));
2983 aScale
.setY(fabs(aScale
.getY()));
2984 fRotate
= fmod(fRotate
+ F_PI
, F_2PI
);
2987 // reset object shear and rotations
2989 aGeo
.RecalcSinCos();
2990 aGeo
.nShearWink
= 0;
2993 // force metric to pool metric
2994 const SfxMapUnit
eMapUnit(GetObjectMapUnit());
2995 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
2999 case SFX_MAPUNIT_TWIP
:
3002 aTranslate
.setX(ImplMMToTwips(aTranslate
.getX()));
3003 aTranslate
.setY(ImplMMToTwips(aTranslate
.getY()));
3006 aScale
.setX(ImplMMToTwips(aScale
.getX()));
3007 aScale
.setY(ImplMMToTwips(aScale
.getY()));
3013 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3018 // if anchor is used, make position relative to it
3019 if( pModel
&& pModel
->IsWriter() )
3021 if(GetAnchorPos().X() || GetAnchorPos().Y())
3023 aTranslate
+= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3027 // build and set BaseRect (use scale)
3028 Point aPoint
= Point();
3029 Size
aSize(FRound(aScale
.getX()), FRound(aScale
.getY()));
3030 // fdo#47434 We need a valid rectangle here
3031 if( !aSize
.Height() ) aSize
.setHeight( 1 );
3032 if( !aSize
.Width() ) aSize
.setWidth( 1 );
3034 Rectangle
aBaseRect(aPoint
, aSize
);
3035 SetSnapRect(aBaseRect
);
3038 if(!basegfx::fTools::equalZero(fShearX
))
3041 aGeoStat
.nShearWink
= FRound((atan(fShearX
) / F_PI180
) * 100.0);
3042 aGeoStat
.RecalcTan();
3043 Shear(Point(), aGeoStat
.nShearWink
, aGeoStat
.nTan
, sal_False
);
3047 if(!basegfx::fTools::equalZero(fRotate
))
3052 // fRotate is mathematically correct, but aGeoStat.nDrehWink is
3053 // mirrored -> mirror value here
3054 aGeoStat
.nDrehWink
= NormAngle360(FRound(-fRotate
/ F_PI18000
));
3055 aGeoStat
.RecalcSinCos();
3056 Rotate(Point(), aGeoStat
.nDrehWink
, aGeoStat
.nSin
, aGeoStat
.nCos
);
3060 if(!aTranslate
.equalZero())
3062 Move(Size(FRound(aTranslate
.getX()), FRound(aTranslate
.getY())));
3066 // taking fObjectRotation instead of aGeo.nWink
3067 sal_Bool
SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix
& rMatrix
, basegfx::B2DPolyPolygon
& /*rPolyPolygon*/) const
3069 // get turn and shear
3070 double fRotate
= fObjectRotation
* F_PI180
;
3071 double fShearX
= (aGeo
.nShearWink
/ 100.0) * F_PI180
;
3073 // get aRect, this is the unrotated snaprect
3074 Rectangle
aRectangle(aRect
);
3076 sal_Bool bMirroredX
= IsMirroredX();
3077 sal_Bool bMirroredY
= IsMirroredY();
3078 if ( bMirroredX
|| bMirroredY
)
3079 { // we have to retrieve the unmirrored rect
3081 GeoStat
aNewGeo( aGeo
);
3085 Polygon
aPol( Rect2Poly( aRect
, aNewGeo
) );
3086 Rectangle
aBoundRect( aPol
.GetBoundRect() );
3088 Point
aRef1( ( aBoundRect
.Left() + aBoundRect
.Right() ) >> 1, aBoundRect
.Top() );
3089 Point
aRef2( aRef1
.X(), aRef1
.Y() + 1000 );
3091 sal_uInt16 nPntAnz
=aPol
.GetSize();
3092 for (i
=0; i
<nPntAnz
; i
++)
3094 MirrorPoint(aPol
[i
],aRef1
,aRef2
);
3096 // mirror polygon and move it a bit
3097 Polygon
aPol0(aPol
);
3103 Poly2Rect(aPol
,aRectangle
,aNewGeo
);
3107 Polygon
aPol( Rect2Poly( aRectangle
, aNewGeo
) );
3108 Rectangle
aBoundRect( aPol
.GetBoundRect() );
3110 Point
aRef1( aBoundRect
.Left(), ( aBoundRect
.Top() + aBoundRect
.Bottom() ) >> 1 );
3111 Point
aRef2( aRef1
.X() + 1000, aRef1
.Y() );
3113 sal_uInt16 nPntAnz
=aPol
.GetSize();
3114 for (i
=0; i
<nPntAnz
; i
++)
3116 MirrorPoint(aPol
[i
],aRef1
,aRef2
);
3118 // mirror polygon and move it a bit
3119 Polygon
aPol0(aPol
);
3125 Poly2Rect(aPol
,aRectangle
,aNewGeo
);
3129 // fill other values
3130 basegfx::B2DTuple
aScale(aRectangle
.GetWidth(), aRectangle
.GetHeight());
3131 basegfx::B2DTuple
aTranslate(aRectangle
.Left(), aRectangle
.Top());
3133 // position may be relative to anchorpos, convert
3134 if( pModel
&& pModel
->IsWriter() )
3136 if(GetAnchorPos().X() || GetAnchorPos().Y())
3138 aTranslate
-= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3142 // force MapUnit to 100th mm
3143 const SfxMapUnit
eMapUnit(GetObjectMapUnit());
3144 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
3148 case SFX_MAPUNIT_TWIP
:
3151 aTranslate
.setX(ImplTwipsToMM(aTranslate
.getX()));
3152 aTranslate
.setY(ImplTwipsToMM(aTranslate
.getY()));
3155 aScale
.setX(ImplTwipsToMM(aScale
.getX()));
3156 aScale
.setY(ImplTwipsToMM(aScale
.getY()));
3162 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3168 rMatrix
= basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
3170 basegfx::fTools::equalZero(fShearX
) ? 0.0 : tan(fShearX
),
3171 basegfx::fTools::equalZero(fRotate
) ? 0.0 : -fRotate
,
3177 sdr::contact::ViewContact
* SdrObjCustomShape::CreateObjectSpecificViewContact()
3179 return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
3183 bool SdrObjCustomShape::doConstructOrthogonal(const OUString
& rName
)
3185 bool bRetval(false);
3186 static OUString
Imps_sNameASOrtho_quadrat( "quadrat" );
3187 static OUString
Imps_sNameASOrtho_round_quadrat( "round-quadrat" );
3188 static OUString
Imps_sNameASOrtho_circle( "circle" );
3189 static OUString
Imps_sNameASOrtho_circle_pie( "circle-pie" );
3190 static OUString
Imps_sNameASOrtho_ring( "ring" );
3192 if(Imps_sNameASOrtho_quadrat
.equalsIgnoreAsciiCase(rName
))
3196 else if(Imps_sNameASOrtho_round_quadrat
.equalsIgnoreAsciiCase(rName
))
3200 else if(Imps_sNameASOrtho_circle
.equalsIgnoreAsciiCase(rName
))
3204 else if(Imps_sNameASOrtho_circle_pie
.equalsIgnoreAsciiCase(rName
))
3208 else if(Imps_sNameASOrtho_ring
.equalsIgnoreAsciiCase(rName
))
3216 // #i37011# centralize throw-away of render geometry
3217 void SdrObjCustomShape::InvalidateRenderGeometry()
3219 mXRenderedCustomShape
= 0L;
3220 SdrObject::Free( mpLastShadowGeometry
);
3221 mpLastShadowGeometry
= 0L;
3224 void SdrObjCustomShape::impl_setUnoShape(const uno::Reference
<uno::XInterface
>& rxUnoShape
)
3226 SdrTextObj::impl_setUnoShape(rxUnoShape
);
3228 // The shape engine is created with _current_ shape. This means we
3229 // _must_ reset it when the shape changes.
3230 mxCustomShapeEngine
.set(0);
3233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */