1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: EnhancedCustomShapeEngine.cxx,v $
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"
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" );
83 // -----------------------------------------------------------------------------
85 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const REF( NMSP_LANG::XMultiServiceFactory
)& 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
)
111 SEQ( NMSP_BEANS::PropertyValue
) aParameter
;
112 for ( i
= 0; i
< aArguments
.getLength(); i
++ )
114 if ( aArguments
[ i
] >>= aParameter
)
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
)
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 );
167 pRenderedShape
= pShadowGeometry
->Clone();
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());
178 OutlinerParaObject
* pParaObj
= pCustoObj
->GetOutlinerParaObject();
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
)
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
);
222 pRenderedShape
= pTextObj
;
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
)
245 SvxShape
* pShape
= SvxShape::getImplementation( xShape
);
247 pShape
->TakeSdrObjectOwnership();
249 ::com::sun::star::uno::Reference<
250 ::com::sun::star::drawing::XShapes > xShapes( xShape, ::com::sun::star::uno::UNO_QUERY );
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
);
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
)
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
;
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
;
321 pRenderedShape
->Shear( pSdrObjCustomShape
->GetSnapRect().Center(), nShearWink
, nTan
, FALSE
);
325 double a
= nRotateAngle
* F_PI18000
;
326 pRenderedShape
->NbcRotate( pSdrObjCustomShape
->GetSnapRect().Center(), nRotateAngle
, sin( a
), cos( a
) );
330 Point
aLeft( aRect
.Left(), ( aRect
.Top() + aRect
.Bottom() ) >> 1 );
331 Point
aRight( aLeft
.X() + 1000, aLeft
.Y() );
332 pRenderedShape
->NbcMirror( aLeft
, aRight
);
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
);
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();
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();
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
;
403 pObj
->Shear( aRect
.Center(), nShearWink
, nTan
, FALSE
);
405 sal_Int32 nRotateAngle
= aCustomShape2d
.GetRotateAngle();
408 double a
= nRotateAngle
* F_PI18000
;
409 pObj
->NbcRotate( aRect
.Center(), nRotateAngle
, sin( a
), cos( a
) );
413 Point
aTop( ( aRect
.Left() + aRect
.Right() ) >> 1, aRect
.Top() );
414 Point
aBottom( aTop
.X(), aTop
.Y() + 1000 );
415 pObj
->NbcMirror( aTop
, aBottom
);
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();
439 pNewObj
= pNext
->ConvertToPolyObj( FALSE
, FALSE
);
440 SdrPathObj
* pPath
= PTR_CAST( SdrPathObj
, pNewObj
);
442 aPP
= pPath
->GetPathPoly();
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
);