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
EnhancedCustomShapeEngine_getImplementationName()58 rtl::OUString EnhancedCustomShapeEngine_getImplementationName()
59 throw( NMSP_UNO::RuntimeException )
60 {
61 return B2UCONST( "com.sun.star.drawing.EnhancedCustomShapeEngine" );
62 }
EnhancedCustomShapeEngine_supportsService(const rtl::OUString & ServiceName)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 }
SEQ(rtl::OUString)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
EnhancedCustomShapeEngine(const REF (NMSP_LANG::XMultiServiceFactory)& rxMgr)79 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) :
80 mxFact ( rxMgr ),
81 mbForceGroupWithText ( sal_False )
82 {
83 }
~EnhancedCustomShapeEngine()84 EnhancedCustomShapeEngine::~EnhancedCustomShapeEngine()
85 {
86 }
87
88 // XInterface -----------------------------------------------------------------
89
acquire()90 void SAL_CALL EnhancedCustomShapeEngine::acquire() throw()
91 {
92 OWeakObject::acquire();
93 }
release()94 void SAL_CALL EnhancedCustomShapeEngine::release() throw()
95 {
96 OWeakObject::release();
97 }
98
99 // XInitialization ------------------------------------------------------------
100
initialize(const SEQ (NMSP_UNO::Any)& aArguments)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
getImplementationName()123 rtl::OUString SAL_CALL EnhancedCustomShapeEngine::getImplementationName()
124 throw( NMSP_UNO::RuntimeException )
125 {
126 return EnhancedCustomShapeEngine_getImplementationName();
127 }
supportsService(const rtl::OUString & rServiceName)128 sal_Bool SAL_CALL EnhancedCustomShapeEngine::supportsService( const rtl::OUString& rServiceName )
129 throw( NMSP_UNO::RuntimeException )
130 {
131 return EnhancedCustomShapeEngine_supportsService( rServiceName );
132 }
SEQ(rtl::OUString)133 SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceNames()
134 throw ( NMSP_UNO::RuntimeException )
135 {
136 return EnhancedCustomShapeEngine_getSupportedServiceNames();
137 }
138
139 // XCustomShapeEngine -----------------------------------------------------------
140
ImplForceGroupWithText(const SdrObjCustomShape * pCustoObj,SdrObject * pRenderedShape)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
SetTemporary(::com::sun::star::uno::Reference<::com::sun::star::drawing::XShape> & xShape)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
REF(com::sun::star::drawing::XShape)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
getTextBounds()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
getLineGeometry()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
SEQ(REF (com::sun::star::drawing::XCustomShapeHandle))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