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