merge the formfield patch from ooo-build
[ooovba.git] / svx / source / customshapes / EnhancedCustomShapeEngine.cxx
blob2fad91e12ed2cfbd0b13431feaea85e15ba26936
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: EnhancedCustomShapeEngine.cxx,v $
10 * $Revision: 1.21 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include "EnhancedCustomShapeEngine.hxx"
34 #include "EnhancedCustomShape2d.hxx"
35 #include "EnhancedCustomShape3d.hxx"
36 #include "EnhancedCustomShapeFontWork.hxx"
37 #include "EnhancedCustomShapeHandle.hxx"
38 #include "EnhancedCustomShapeGeometry.hxx"
39 #include <svx/unoshape.hxx>
40 #ifndef _SVX_UNOPAGE_HXX
41 #include "svx/unopage.hxx"
42 #endif
43 #include "unoapi.hxx"
44 #include <svx/svdobj.hxx>
45 #include <svx/svdoashp.hxx>
46 #include <svx/svdogrp.hxx>
47 #include <svx/svdorect.hxx>
48 #include <svx/outlobj.hxx>
49 #include <svx/outliner.hxx>
50 #include <svx/svdoutl.hxx>
51 #include <svtools/itemset.hxx>
52 #include <svx/svdopath.hxx>
53 #include <svx/svdpage.hxx>
54 #include <svx/svdmodel.hxx>
55 #include "svditer.hxx"
56 #include "unopolyhelper.hxx"
57 #include <uno/mapping.hxx>
58 #include <basegfx/polygon/b2dpolypolygontools.hxx>
60 // ---------------------------
61 // - EnhancedCustomShapeEngine -
62 // ---------------------------
64 rtl::OUString EnhancedCustomShapeEngine_getImplementationName()
65 throw( NMSP_UNO::RuntimeException )
67 return B2UCONST( "com.sun.star.drawing.EnhancedCustomShapeEngine" );
69 sal_Bool SAL_CALL EnhancedCustomShapeEngine_supportsService( const rtl::OUString& ServiceName )
70 throw( NMSP_UNO::RuntimeException )
72 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShapeEngine" ) );
74 SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine_getSupportedServiceNames()
75 throw( NMSP_UNO::RuntimeException )
77 SEQ( rtl::OUString ) aRet(1);
78 rtl::OUString* pArray = aRet.getArray();
79 pArray[0] = B2UCONST( "com.sun.star.drawing.CustomShapeEngine" );
80 return aRet;
83 // -----------------------------------------------------------------------------
85 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
86 mxFact ( rxMgr ),
87 mbForceGroupWithText ( sal_False )
90 EnhancedCustomShapeEngine::~EnhancedCustomShapeEngine()
94 // XInterface -----------------------------------------------------------------
96 void SAL_CALL EnhancedCustomShapeEngine::acquire() throw()
98 OWeakObject::acquire();
100 void SAL_CALL EnhancedCustomShapeEngine::release() throw()
102 OWeakObject::release();
105 // XInitialization ------------------------------------------------------------
107 void SAL_CALL EnhancedCustomShapeEngine::initialize( const SEQ( NMSP_UNO::Any )& aArguments )
108 throw ( NMSP_UNO::Exception, NMSP_UNO::RuntimeException )
110 sal_Int32 i;
111 SEQ( NMSP_BEANS::PropertyValue ) aParameter;
112 for ( i = 0; i < aArguments.getLength(); i++ )
114 if ( aArguments[ i ] >>= aParameter )
115 break;
117 for ( i = 0; i < aParameter.getLength(); i++ )
119 const NMSP_BEANS::PropertyValue& rProp = aParameter[ i ];
120 if ( rProp.Name.equalsAscii( "CustomShape" ) )
121 rProp.Value >>= mxShape;
122 else if ( rProp.Name.equalsAscii( "ForceGroupWithText" ) )
123 rProp.Value >>= mbForceGroupWithText;
127 // XServiceInfo ---------------------------------------------------------------
129 rtl::OUString SAL_CALL EnhancedCustomShapeEngine::getImplementationName()
130 throw( NMSP_UNO::RuntimeException )
132 return EnhancedCustomShapeEngine_getImplementationName();
134 sal_Bool SAL_CALL EnhancedCustomShapeEngine::supportsService( const rtl::OUString& rServiceName )
135 throw( NMSP_UNO::RuntimeException )
137 return EnhancedCustomShapeEngine_supportsService( rServiceName );
139 SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceNames()
140 throw ( NMSP_UNO::RuntimeException )
142 return EnhancedCustomShapeEngine_getSupportedServiceNames();
145 // XCustomShapeEngine -----------------------------------------------------------
147 SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustomShape* pCustoObj, SdrObject* pRenderedShape )
149 bool bHasText = pCustoObj->HasText();
150 if ( pRenderedShape || bHasText )
152 // applying shadow
153 const SdrObject* pShadowGeometry = pCustoObj->GetSdrObjectShadowFromCustomShape();
154 if ( pShadowGeometry )
156 if ( pRenderedShape )
158 if ( !pRenderedShape->ISA( SdrObjGroup ) )
160 SdrObject* pTmp = pRenderedShape;
161 pRenderedShape = new SdrObjGroup();
162 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp );
164 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pShadowGeometry->Clone(), 0 );
166 else
167 pRenderedShape = pShadowGeometry->Clone();
170 // apply text
171 if ( bHasText )
173 // #i37011# also create a text object and add at rPos + 1
174 SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject(
175 pCustoObj->GetObjInventor(), OBJ_TEXT, 0L, pCustoObj->GetModel());
177 // Copy text content
178 OutlinerParaObject* pParaObj = pCustoObj->GetOutlinerParaObject();
179 if( pParaObj )
180 pTextObj->NbcSetOutlinerParaObject( new OutlinerParaObject(*pParaObj) );
182 // copy all attributes
183 SfxItemSet aTargetItemSet( pCustoObj->GetMergedItemSet() );
185 // clear fill and line style
186 aTargetItemSet.Put(XLineStyleItem(XLINE_NONE));
187 aTargetItemSet.Put(XFillStyleItem(XFILL_NONE));
189 // get the text bounds and set at text object
190 Rectangle aTextBounds = pCustoObj->GetSnapRect();
191 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
192 if ( pSdrObjCustomShape )
194 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
195 aTextBounds = aCustomShape2d.GetTextRect();
197 pTextObj->SetSnapRect( aTextBounds );
199 // if rotated, copy GeoStat, too.
200 const GeoStat& rSourceGeo = pCustoObj->GetGeoStat();
201 if ( rSourceGeo.nDrehWink )
203 pTextObj->NbcRotate(
204 pCustoObj->GetSnapRect().Center(), rSourceGeo.nDrehWink,
205 rSourceGeo.nSin, rSourceGeo.nCos);
208 // set modified ItemSet at text object
209 pTextObj->SetMergedItemSet(aTargetItemSet);
211 if ( pRenderedShape )
213 if ( !pRenderedShape->ISA( SdrObjGroup ) )
215 SdrObject* pTmp = pRenderedShape;
216 pRenderedShape = new SdrObjGroup();
217 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp );
219 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTextObj, LIST_APPEND );
221 else
222 pRenderedShape = pTextObj;
225 // force group
226 if ( pRenderedShape )
228 if ( !pRenderedShape->ISA( SdrObjGroup ) )
230 SdrObject* pTmp = pRenderedShape;
231 pRenderedShape = new SdrObjGroup();
232 ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp );
234 pRenderedShape->SetPage( pCustoObj->GetPage() );
235 pRenderedShape->SetModel( pCustoObj->GetModel() );
238 return pRenderedShape;
241 void SetTemporary( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape )
243 if ( xShape.is() )
245 SvxShape* pShape = SvxShape::getImplementation( xShape );
246 if ( pShape )
247 pShape->TakeSdrObjectOwnership();
249 ::com::sun::star::uno::Reference<
250 ::com::sun::star::drawing::XShapes > xShapes( xShape, ::com::sun::star::uno::UNO_QUERY );
251 if ( xShapes.is() )
253 sal_Int32 i;
254 for ( i = 0; i < xShapes->getCount(); i++ )
256 ::com::sun::star::uno::Any aAny( xShapes->getByIndex( i ) );
257 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
258 if ( aAny >>= xShape )
259 SetTemporary( xShape );
266 REF( com::sun::star::drawing::XShape ) SAL_CALL EnhancedCustomShapeEngine::render()
267 throw ( NMSP_UNO::RuntimeException )
269 REF( com::sun::star::drawing::XShape ) xShape;
270 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
271 if ( pSdrObjCustomShape )
273 // retrieving the TextPath property to check if feature is enabled
274 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)
275 pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
276 sal_Bool bTextPathOn = sal_False;
277 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
278 com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
279 if ( pAny )
280 *pAny >>= bTextPathOn;
282 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
283 sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle();
285 sal_Bool bFlipV = aCustomShape2d.IsFlipVert();
286 sal_Bool bFlipH = aCustomShape2d.IsFlipHorz();
287 sal_Bool bLineGeometryNeededOnly = bTextPathOn;
289 SdrObject* pRenderedShape = aCustomShape2d.CreateObject( bLineGeometryNeededOnly );
290 if ( pRenderedShape )
292 if ( bTextPathOn )
294 SdrObject* pRenderedFontWork = EnhancedCustomShapeFontWork::CreateFontWork( pRenderedShape, pSdrObjCustomShape );
295 if ( pRenderedFontWork )
297 SdrObject::Free( pRenderedShape );
298 pRenderedShape = pRenderedFontWork;
301 SdrObject* pRenderedShape3d = EnhancedCustomShape3d::Create3DObject( pRenderedShape, pSdrObjCustomShape );
302 if ( pRenderedShape3d )
304 bFlipV = bFlipH = sal_False;
305 nRotateAngle = 0;
306 SdrObject::Free( pRenderedShape );
307 pRenderedShape = pRenderedShape3d;
309 Rectangle aRect( pSdrObjCustomShape->GetSnapRect() );
311 const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat();
312 if ( rGeoStat.nShearWink )
314 long nShearWink = rGeoStat.nShearWink;
315 double nTan = rGeoStat.nTan;
316 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
318 nShearWink = -nShearWink;
319 nTan = -nTan;
321 pRenderedShape->Shear( pSdrObjCustomShape->GetSnapRect().Center(), nShearWink, nTan, FALSE);
323 if( nRotateAngle )
325 double a = nRotateAngle * F_PI18000;
326 pRenderedShape->NbcRotate( pSdrObjCustomShape->GetSnapRect().Center(), nRotateAngle, sin( a ), cos( a ) );
328 if ( bFlipV )
330 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
331 Point aRight( aLeft.X() + 1000, aLeft.Y() );
332 pRenderedShape->NbcMirror( aLeft, aRight );
334 if ( bFlipH )
336 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
337 Point aBottom( aTop.X(), aTop.Y() + 1000 );
338 pRenderedShape->NbcMirror( aTop, aBottom );
340 pRenderedShape->NbcSetStyleSheet( pSdrObjCustomShape->GetStyleSheet(), sal_True );
341 pRenderedShape->RecalcSnapRect();
344 if ( mbForceGroupWithText )
345 pRenderedShape = ImplForceGroupWithText( (SdrObjCustomShape*)pSdrObjCustomShape, pRenderedShape );
347 if ( pRenderedShape )
349 aCustomShape2d.ApplyGluePoints( pRenderedShape );
350 xShape = SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape->GetObjIdentifier(),
351 pRenderedShape->GetObjInventor(), pRenderedShape, NULL );
353 SetTemporary( xShape );
355 return xShape;
358 com::sun::star::awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds()
359 throw ( NMSP_UNO::RuntimeException )
361 com::sun::star::awt::Rectangle aTextRect;
362 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
363 if ( pSdrObjCustomShape && pSdrObjCustomShape->GetModel() && !pSdrObjCustomShape->GetModel()->isLocked() )
365 if ( pSdrObjCustomShape )
367 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
368 Rectangle aRect( aCustomShape2d.GetTextRect() );
369 aTextRect.X = aRect.Left();
370 aTextRect.Y = aRect.Top();
371 aTextRect.Width = aRect.GetWidth();
372 aTextRect.Height = aRect.GetHeight();
375 return aTextRect;
378 com::sun::star::drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeometry()
379 throw ( NMSP_UNO::RuntimeException )
381 com::sun::star::drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
382 SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
383 if ( pSdrObjCustomShape )
385 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
386 SdrObject* pObj = aCustomShape2d.CreateLineGeometry();
387 if ( pObj )
389 Rectangle aRect( pSdrObjCustomShape->GetSnapRect() );
390 sal_Bool bFlipV = aCustomShape2d.IsFlipVert();
391 sal_Bool bFlipH = aCustomShape2d.IsFlipHorz();
393 const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat();
394 if ( rGeoStat.nShearWink )
396 long nShearWink = rGeoStat.nShearWink;
397 double nTan = rGeoStat.nTan;
398 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
400 nShearWink = -nShearWink;
401 nTan = -nTan;
403 pObj->Shear( aRect.Center(), nShearWink, nTan, FALSE);
405 sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle();
406 if( nRotateAngle )
408 double a = nRotateAngle * F_PI18000;
409 pObj->NbcRotate( aRect.Center(), nRotateAngle, sin( a ), cos( a ) );
411 if ( bFlipH )
413 Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
414 Point aBottom( aTop.X(), aTop.Y() + 1000 );
415 pObj->NbcMirror( aTop, aBottom );
417 if ( bFlipV )
419 Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
420 Point aRight( aLeft.X() + 1000, aLeft.Y() );
421 pObj->NbcMirror( aLeft, aRight );
424 basegfx::B2DPolyPolygon aPolyPolygon;
425 SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
427 while ( aIter.IsMore() )
429 SdrObject* pNewObj = NULL;
430 basegfx::B2DPolyPolygon aPP;
431 const SdrObject* pNext = aIter.Next();
433 if ( pNext->ISA( SdrPathObj ) )
435 aPP = ((SdrPathObj*)pNext)->GetPathPoly();
437 else
439 pNewObj = pNext->ConvertToPolyObj( FALSE, FALSE );
440 SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj );
441 if ( pPath )
442 aPP = pPath->GetPathPoly();
445 if ( aPP.count() )
446 aPolyPolygon.append(aPP);
448 SdrObject::Free( pNewObj );
450 SdrObject::Free( pObj );
451 SvxConvertB2DPolyPolygonToPolyPolygonBezier( aPolyPolygon, aPolyPolygonBezierCoords );
455 return aPolyPolygonBezierCoords;
458 SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) SAL_CALL EnhancedCustomShapeEngine::getInteraction()
459 throw ( NMSP_UNO::RuntimeException )
461 sal_uInt32 i, nHdlCount = 0;
462 SdrObject* pSdrObjCustomShape = GetSdrObjectFromXShape( mxShape );
463 if ( pSdrObjCustomShape )
465 EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
466 nHdlCount = aCustomShape2d.GetHdlCount();
468 SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) aSeq( nHdlCount );
469 for ( i = 0; i < nHdlCount; i++ )
470 aSeq[ i ] = new EnhancedCustomShapeHandle( mxShape, i );
471 return aSeq;