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