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