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 "EnhancedCustomShapeEngine.hxx" 27 #include "svx/EnhancedCustomShape2d.hxx" 28 #include "EnhancedCustomShape3d.hxx" 29 #include "EnhancedCustomShapeFontWork.hxx" 30 #include "EnhancedCustomShapeHandle.hxx" 31 #include "svx/EnhancedCustomShapeGeometry.hxx" 32 #include <svx/unoshape.hxx> 33 #ifndef _SVX_UNOPAGE_HXX 34 #include "svx/unopage.hxx" 35 #endif 36 #include "svx/unoapi.hxx" 37 #include <svx/svdobj.hxx> 38 #include <svx/svdoashp.hxx> 39 #include <svx/svdogrp.hxx> 40 #include <svx/svdorect.hxx> 41 #include <editeng/outlobj.hxx> 42 #include <editeng/outliner.hxx> 43 #include <svx/svdoutl.hxx> 44 #include <svl/itemset.hxx> 45 #include <svx/svdopath.hxx> 46 #include <svx/svdpage.hxx> 47 #include <svx/svdmodel.hxx> 48 #include "svx/svditer.hxx" 49 #include "unopolyhelper.hxx" 50 #include <uno/mapping.hxx> 51 #include <basegfx/polygon/b2dpolypolygontools.hxx> 52 #include <com/sun/star/document/XActionLockable.hpp> 53 54 // --------------------------- 55 // - EnhancedCustomShapeEngine - 56 // --------------------------- 57 58 rtl::OUString EnhancedCustomShapeEngine_getImplementationName() 59 throw( NMSP_UNO::RuntimeException ) 60 { 61 return B2UCONST( "com.sun.star.drawing.EnhancedCustomShapeEngine" ); 62 } 63 sal_Bool SAL_CALL EnhancedCustomShapeEngine_supportsService( const rtl::OUString& ServiceName ) 64 throw( NMSP_UNO::RuntimeException ) 65 { 66 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShapeEngine" ) ); 67 } 68 SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine_getSupportedServiceNames() 69 throw( NMSP_UNO::RuntimeException ) 70 { 71 SEQ( rtl::OUString ) aRet(1); 72 rtl::OUString* pArray = aRet.getArray(); 73 pArray[0] = B2UCONST( "com.sun.star.drawing.CustomShapeEngine" ); 74 return aRet; 75 } 76 77 // ----------------------------------------------------------------------------- 78 79 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) : 80 mxFact ( rxMgr ), 81 mbForceGroupWithText ( sal_False ) 82 { 83 } 84 EnhancedCustomShapeEngine::~EnhancedCustomShapeEngine() 85 { 86 } 87 88 // XInterface ----------------------------------------------------------------- 89 90 void SAL_CALL EnhancedCustomShapeEngine::acquire() throw() 91 { 92 OWeakObject::acquire(); 93 } 94 void SAL_CALL EnhancedCustomShapeEngine::release() throw() 95 { 96 OWeakObject::release(); 97 } 98 99 // XInitialization ------------------------------------------------------------ 100 101 void SAL_CALL EnhancedCustomShapeEngine::initialize( const SEQ( NMSP_UNO::Any )& aArguments ) 102 throw ( NMSP_UNO::Exception, NMSP_UNO::RuntimeException ) 103 { 104 sal_Int32 i; 105 SEQ( NMSP_BEANS::PropertyValue ) aParameter; 106 for ( i = 0; i < aArguments.getLength(); i++ ) 107 { 108 if ( aArguments[ i ] >>= aParameter ) 109 break; 110 } 111 for ( i = 0; i < aParameter.getLength(); i++ ) 112 { 113 const NMSP_BEANS::PropertyValue& rProp = aParameter[ i ]; 114 if ( rProp.Name.equalsAscii( "CustomShape" ) ) 115 rProp.Value >>= mxShape; 116 else if ( rProp.Name.equalsAscii( "ForceGroupWithText" ) ) 117 rProp.Value >>= mbForceGroupWithText; 118 } 119 } 120 121 // XServiceInfo --------------------------------------------------------------- 122 123 rtl::OUString SAL_CALL EnhancedCustomShapeEngine::getImplementationName() 124 throw( NMSP_UNO::RuntimeException ) 125 { 126 return EnhancedCustomShapeEngine_getImplementationName(); 127 } 128 sal_Bool SAL_CALL EnhancedCustomShapeEngine::supportsService( const rtl::OUString& rServiceName ) 129 throw( NMSP_UNO::RuntimeException ) 130 { 131 return EnhancedCustomShapeEngine_supportsService( rServiceName ); 132 } 133 SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceNames() 134 throw ( NMSP_UNO::RuntimeException ) 135 { 136 return EnhancedCustomShapeEngine_getSupportedServiceNames(); 137 } 138 139 // XCustomShapeEngine ----------------------------------------------------------- 140 141 SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustomShape* pCustoObj, SdrObject* pRenderedShape ) 142 { 143 bool bHasText = pCustoObj->HasText(); 144 if ( pRenderedShape || bHasText ) 145 { 146 // applying shadow 147 const SdrObject* pShadowGeometry = pCustoObj->GetSdrObjectShadowFromCustomShape(); 148 if ( pShadowGeometry ) 149 { 150 if ( pRenderedShape ) 151 { 152 if ( !pRenderedShape->ISA( SdrObjGroup ) ) 153 { 154 SdrObject* pTmp = pRenderedShape; 155 pRenderedShape = new SdrObjGroup(); 156 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); 157 } 158 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pShadowGeometry->Clone(), 0 ); 159 } 160 else 161 pRenderedShape = pShadowGeometry->Clone(); 162 } 163 164 // apply text 165 if ( bHasText ) 166 { 167 // #i37011# also create a text object and add at rPos + 1 168 SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject( 169 pCustoObj->GetObjInventor(), OBJ_TEXT, 0L, pCustoObj->GetModel()); 170 171 // Copy text content 172 OutlinerParaObject* pParaObj = pCustoObj->GetOutlinerParaObject(); 173 if( pParaObj ) 174 pTextObj->NbcSetOutlinerParaObject( new OutlinerParaObject(*pParaObj) ); 175 176 // copy all attributes 177 SfxItemSet aTargetItemSet( pCustoObj->GetMergedItemSet() ); 178 179 // clear fill and line style 180 aTargetItemSet.Put(XLineStyleItem(XLINE_NONE)); 181 aTargetItemSet.Put(XFillStyleItem(XFILL_NONE)); 182 183 // get the text bounds and set at text object 184 Rectangle aTextBounds = pCustoObj->GetSnapRect(); 185 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); 186 if ( pSdrObjCustomShape ) 187 { 188 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); 189 aTextBounds = aCustomShape2d.GetTextRect(); 190 } 191 pTextObj->SetSnapRect( aTextBounds ); 192 193 // if rotated, copy GeoStat, too. 194 const GeoStat& rSourceGeo = pCustoObj->GetGeoStat(); 195 if ( rSourceGeo.nDrehWink ) 196 { 197 pTextObj->NbcRotate( 198 pCustoObj->GetSnapRect().Center(), rSourceGeo.nDrehWink, 199 rSourceGeo.nSin, rSourceGeo.nCos); 200 } 201 202 // set modified ItemSet at text object 203 pTextObj->SetMergedItemSet(aTargetItemSet); 204 205 if ( pRenderedShape ) 206 { 207 if ( !pRenderedShape->ISA( SdrObjGroup ) ) 208 { 209 SdrObject* pTmp = pRenderedShape; 210 pRenderedShape = new SdrObjGroup(); 211 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); 212 } 213 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTextObj, LIST_APPEND ); 214 } 215 else 216 pRenderedShape = pTextObj; 217 } 218 219 // force group 220 if ( pRenderedShape ) 221 { 222 if ( !pRenderedShape->ISA( SdrObjGroup ) ) 223 { 224 SdrObject* pTmp = pRenderedShape; 225 pRenderedShape = new SdrObjGroup(); 226 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); 227 } 228 pRenderedShape->SetPage( pCustoObj->GetPage() ); 229 pRenderedShape->SetModel( pCustoObj->GetModel() ); 230 } 231 } 232 return pRenderedShape; 233 } 234 235 void SetTemporary( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape ) 236 { 237 if ( xShape.is() ) 238 { 239 SvxShape* pShape = SvxShape::getImplementation( xShape ); 240 if ( pShape ) 241 pShape->TakeSdrObjectOwnership(); 242 /* 243 ::com::sun::star::uno::Reference< 244 ::com::sun::star::drawing::XShapes > xShapes( xShape, ::com::sun::star::uno::UNO_QUERY ); 245 if ( xShapes.is() ) 246 { 247 sal_Int32 i; 248 for ( i = 0; i < xShapes->getCount(); i++ ) 249 { 250 ::com::sun::star::uno::Any aAny( xShapes->getByIndex( i ) ); 251 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape; 252 if ( aAny >>= xShape ) 253 SetTemporary( xShape ); 254 } 255 } 256 */ 257 } 258 } 259 260 REF( com::sun::star::drawing::XShape ) SAL_CALL EnhancedCustomShapeEngine::render() 261 throw ( NMSP_UNO::RuntimeException ) 262 { 263 REF( com::sun::star::drawing::XShape ) xShape; 264 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); 265 if ( pSdrObjCustomShape ) 266 { 267 // retrieving the TextPath property to check if feature is enabled 268 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&) 269 pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 270 sal_Bool bTextPathOn = sal_False; 271 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); 272 com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath ); 273 if ( pAny ) 274 *pAny >>= bTextPathOn; 275 276 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); 277 sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle(); 278 279 sal_Bool bFlipV = aCustomShape2d.IsFlipVert(); 280 sal_Bool bFlipH = aCustomShape2d.IsFlipHorz(); 281 sal_Bool bLineGeometryNeededOnly = bTextPathOn; 282 283 SdrObject* pRenderedShape = aCustomShape2d.CreateObject( bLineGeometryNeededOnly ); 284 if ( pRenderedShape ) 285 { 286 if ( bTextPathOn ) 287 { 288 SdrObject* pRenderedFontWork = EnhancedCustomShapeFontWork::CreateFontWork( pRenderedShape, pSdrObjCustomShape ); 289 if ( pRenderedFontWork ) 290 { 291 SdrObject::Free( pRenderedShape ); 292 pRenderedShape = pRenderedFontWork; 293 } 294 } 295 SdrObject* pRenderedShape3d = EnhancedCustomShape3d::Create3DObject( pRenderedShape, pSdrObjCustomShape ); 296 if ( pRenderedShape3d ) 297 { 298 bFlipV = bFlipH = sal_False; 299 nRotateAngle = 0; 300 SdrObject::Free( pRenderedShape ); 301 pRenderedShape = pRenderedShape3d; 302 } 303 Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); 304 305 const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); 306 if ( rGeoStat.nShearWink ) 307 { 308 long nShearWink = rGeoStat.nShearWink; 309 double nTan = rGeoStat.nTan; 310 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) 311 { 312 nShearWink = -nShearWink; 313 nTan = -nTan; 314 } 315 pRenderedShape->Shear( pSdrObjCustomShape->GetSnapRect().Center(), nShearWink, nTan, sal_False); 316 } 317 if( nRotateAngle ) 318 { 319 double a = nRotateAngle * F_PI18000; 320 pRenderedShape->NbcRotate( pSdrObjCustomShape->GetSnapRect().Center(), nRotateAngle, sin( a ), cos( a ) ); 321 } 322 if ( bFlipV ) 323 { 324 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 ); 325 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 326 pRenderedShape->NbcMirror( aLeft, aRight ); 327 } 328 if ( bFlipH ) 329 { 330 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() ); 331 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 332 pRenderedShape->NbcMirror( aTop, aBottom ); 333 } 334 pRenderedShape->NbcSetStyleSheet( pSdrObjCustomShape->GetStyleSheet(), sal_True ); 335 pRenderedShape->RecalcSnapRect(); 336 } 337 338 if ( mbForceGroupWithText ) 339 pRenderedShape = ImplForceGroupWithText( (SdrObjCustomShape*)pSdrObjCustomShape, pRenderedShape ); 340 341 if ( pRenderedShape ) 342 { 343 aCustomShape2d.ApplyGluePoints( pRenderedShape ); 344 xShape = SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape->GetObjIdentifier(), 345 pRenderedShape->GetObjInventor(), pRenderedShape, NULL ); 346 } 347 SetTemporary( xShape ); 348 } 349 return xShape; 350 } 351 352 com::sun::star::awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds() 353 throw ( NMSP_UNO::RuntimeException ) 354 { 355 com::sun::star::awt::Rectangle aTextRect; 356 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); 357 ::com::sun::star::uno::Reference< ::com::sun::star::document::XActionLockable > xLockable( mxShape, ::com::sun::star::uno::UNO_QUERY ); 358 if ( pSdrObjCustomShape && pSdrObjCustomShape->GetModel() && xLockable.is() && !xLockable->isActionLocked() ) 359 { 360 if ( pSdrObjCustomShape ) 361 { 362 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); 363 Rectangle aRect( aCustomShape2d.GetTextRect() ); 364 aTextRect.X = aRect.Left(); 365 aTextRect.Y = aRect.Top(); 366 aTextRect.Width = aRect.GetWidth(); 367 aTextRect.Height = aRect.GetHeight(); 368 } 369 } 370 return aTextRect; 371 } 372 373 com::sun::star::drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeometry() 374 throw ( NMSP_UNO::RuntimeException ) 375 { 376 com::sun::star::drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords; 377 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); 378 if ( pSdrObjCustomShape ) 379 { 380 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); 381 SdrObject* pObj = aCustomShape2d.CreateLineGeometry(); 382 if ( pObj ) 383 { 384 Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); 385 sal_Bool bFlipV = aCustomShape2d.IsFlipVert(); 386 sal_Bool bFlipH = aCustomShape2d.IsFlipHorz(); 387 388 const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); 389 if ( rGeoStat.nShearWink ) 390 { 391 long nShearWink = rGeoStat.nShearWink; 392 double nTan = rGeoStat.nTan; 393 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) 394 { 395 nShearWink = -nShearWink; 396 nTan = -nTan; 397 } 398 pObj->Shear( aRect.Center(), nShearWink, nTan, sal_False); 399 } 400 sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle(); 401 if( nRotateAngle ) 402 { 403 double a = nRotateAngle * F_PI18000; 404 pObj->NbcRotate( aRect.Center(), nRotateAngle, sin( a ), cos( a ) ); 405 } 406 if ( bFlipH ) 407 { 408 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() ); 409 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 410 pObj->NbcMirror( aTop, aBottom ); 411 } 412 if ( bFlipV ) 413 { 414 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 ); 415 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 416 pObj->NbcMirror( aLeft, aRight ); 417 } 418 419 basegfx::B2DPolyPolygon aPolyPolygon; 420 SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS ); 421 422 while ( aIter.IsMore() ) 423 { 424 SdrObject* pNewObj = NULL; 425 basegfx::B2DPolyPolygon aPP; 426 const SdrObject* pNext = aIter.Next(); 427 428 if ( pNext->ISA( SdrPathObj ) ) 429 { 430 aPP = ((SdrPathObj*)pNext)->GetPathPoly(); 431 } 432 else 433 { 434 pNewObj = pNext->ConvertToPolyObj( sal_False, sal_False ); 435 SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj ); 436 if ( pPath ) 437 aPP = pPath->GetPathPoly(); 438 } 439 440 if ( aPP.count() ) 441 aPolyPolygon.append(aPP); 442 443 SdrObject::Free( pNewObj ); 444 } 445 SdrObject::Free( pObj ); 446 SvxConvertB2DPolyPolygonToPolyPolygonBezier( aPolyPolygon, aPolyPolygonBezierCoords ); 447 } 448 } 449 450 return aPolyPolygonBezierCoords; 451 } 452 453 SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) SAL_CALL EnhancedCustomShapeEngine::getInteraction() 454 throw ( NMSP_UNO::RuntimeException ) 455 { 456 sal_uInt32 i, nHdlCount = 0; 457 SdrObject* pSdrObjCustomShape = GetSdrObjectFromXShape( mxShape ); 458 if ( pSdrObjCustomShape ) 459 { 460 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); 461 nHdlCount = aCustomShape2d.GetHdlCount(); 462 } 463 SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) aSeq( nHdlCount ); 464 for ( i = 0; i < nHdlCount; i++ ) 465 aSeq[ i ] = new EnhancedCustomShapeHandle( mxShape, i ); 466 return aSeq; 467 } 468