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