1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
47 using namespace css::uno
;
49 // ---------------------------
50 // - EnhancedCustomShapeEngine -
51 // ---------------------------
53 OUString
EnhancedCustomShapeEngine_getImplementationName()
54 throw( RuntimeException
)
56 return OUString( "com.sun.star.drawing.EnhancedCustomShapeEngine" );
58 sal_Bool SAL_CALL
EnhancedCustomShapeEngine_supportsService( const OUString
& ServiceName
)
59 throw( RuntimeException
)
61 return ServiceName
== "com.sun.star.drawing.CustomShapeEngine";
63 Sequence
< OUString
> SAL_CALL
EnhancedCustomShapeEngine_getSupportedServiceNames()
64 throw( RuntimeException
)
66 Sequence
< OUString
> aRet(1);
67 OUString
* pArray
= aRet
.getArray();
68 pArray
[0] = "com.sun.star.drawing.CustomShapeEngine";
72 // -----------------------------------------------------------------------------
74 EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const Reference
< lang::XMultiServiceFactory
>& rxMgr
) :
76 mbForceGroupWithText ( sal_False
)
79 EnhancedCustomShapeEngine::~EnhancedCustomShapeEngine()
83 // XInterface -----------------------------------------------------------------
85 void SAL_CALL
EnhancedCustomShapeEngine::acquire() throw()
87 OWeakObject::acquire();
89 void SAL_CALL
EnhancedCustomShapeEngine::release() throw()
91 OWeakObject::release();
94 // XInitialization ------------------------------------------------------------
96 void SAL_CALL
EnhancedCustomShapeEngine::initialize( const Sequence
< Any
>& aArguments
)
97 throw ( Exception
, RuntimeException
)
100 Sequence
< beans::PropertyValue
> aParameter
;
101 for ( i
= 0; i
< aArguments
.getLength(); i
++ )
103 if ( aArguments
[ i
] >>= aParameter
)
106 for ( i
= 0; i
< aParameter
.getLength(); i
++ )
108 const beans::PropertyValue
& rProp
= aParameter
[ i
];
109 if ( rProp
.Name
== "CustomShape" )
110 rProp
.Value
>>= mxShape
;
111 else if ( rProp
.Name
== "ForceGroupWithText" )
112 rProp
.Value
>>= mbForceGroupWithText
;
116 // XServiceInfo ---------------------------------------------------------------
118 OUString SAL_CALL
EnhancedCustomShapeEngine::getImplementationName()
119 throw( RuntimeException
)
121 return EnhancedCustomShapeEngine_getImplementationName();
123 sal_Bool SAL_CALL
EnhancedCustomShapeEngine::supportsService( const OUString
& rServiceName
)
124 throw( RuntimeException
)
126 return EnhancedCustomShapeEngine_supportsService( rServiceName
);
128 Sequence
< OUString
> SAL_CALL
EnhancedCustomShapeEngine::getSupportedServiceNames()
129 throw ( RuntimeException
)
131 return EnhancedCustomShapeEngine_getSupportedServiceNames();
134 // XCustomShapeEngine -----------------------------------------------------------
136 SdrObject
* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustomShape
* pCustoObj
, SdrObject
* pRenderedShape
)
138 bool bHasText
= pCustoObj
->HasText();
139 if ( pRenderedShape
|| bHasText
)
142 const SdrObject
* pShadowGeometry
= pCustoObj
->GetSdrObjectShadowFromCustomShape();
143 if ( pShadowGeometry
)
145 if ( pRenderedShape
)
147 if ( !pRenderedShape
->ISA( SdrObjGroup
) )
149 SdrObject
* pTmp
= pRenderedShape
;
150 pRenderedShape
= new SdrObjGroup();
151 ((SdrObjGroup
*)pRenderedShape
)->GetSubList()->NbcInsertObject( pTmp
);
153 ((SdrObjGroup
*)pRenderedShape
)->GetSubList()->NbcInsertObject( pShadowGeometry
->Clone(), 0 );
156 pRenderedShape
= pShadowGeometry
->Clone();
162 // #i37011# also create a text object and add at rPos + 1
163 SdrTextObj
* pTextObj
= (SdrTextObj
*)SdrObjFactory::MakeNewObject(
164 pCustoObj
->GetObjInventor(), OBJ_TEXT
, 0L, pCustoObj
->GetModel());
167 OutlinerParaObject
* pParaObj
= pCustoObj
->GetOutlinerParaObject();
169 pTextObj
->NbcSetOutlinerParaObject( new OutlinerParaObject(*pParaObj
) );
171 // copy all attributes
172 SfxItemSet
aTargetItemSet( pCustoObj
->GetMergedItemSet() );
174 // clear fill and line style
175 aTargetItemSet
.Put(XLineStyleItem(XLINE_NONE
));
176 aTargetItemSet
.Put(XFillStyleItem(XFILL_NONE
));
178 // get the text bounds and set at text object
179 Rectangle aTextBounds
= pCustoObj
->GetSnapRect();
180 SdrObject
* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape
) );
181 if ( pSdrObjCustomShape
)
183 EnhancedCustomShape2d
aCustomShape2d( pSdrObjCustomShape
);
184 aTextBounds
= aCustomShape2d
.GetTextRect();
186 pTextObj
->SetSnapRect( aTextBounds
);
188 // if rotated, copy GeoStat, too.
189 const GeoStat
& rSourceGeo
= pCustoObj
->GetGeoStat();
190 if ( rSourceGeo
.nDrehWink
)
193 pCustoObj
->GetSnapRect().Center(), rSourceGeo
.nDrehWink
,
194 rSourceGeo
.nSin
, rSourceGeo
.nCos
);
197 // set modified ItemSet at text object
198 pTextObj
->SetMergedItemSet(aTargetItemSet
);
200 if ( pRenderedShape
)
202 if ( !pRenderedShape
->ISA( SdrObjGroup
) )
204 SdrObject
* pTmp
= pRenderedShape
;
205 pRenderedShape
= new SdrObjGroup();
206 ((SdrObjGroup
*)pRenderedShape
)->GetSubList()->NbcInsertObject( pTmp
);
208 ((SdrObjGroup
*)pRenderedShape
)->GetSubList()->NbcInsertObject( pTextObj
, LIST_APPEND
);
211 pRenderedShape
= pTextObj
;
215 if ( pRenderedShape
)
217 if ( !pRenderedShape
->ISA( SdrObjGroup
) )
219 SdrObject
* pTmp
= pRenderedShape
;
220 pRenderedShape
= new SdrObjGroup();
221 ((SdrObjGroup
*)pRenderedShape
)->GetSubList()->NbcInsertObject( pTmp
);
223 pRenderedShape
->SetPage( pCustoObj
->GetPage() );
224 pRenderedShape
->SetModel( pCustoObj
->GetModel() );
227 return pRenderedShape
;
230 void SetTemporary( uno::Reference
< drawing::XShape
>& xShape
)
234 SvxShape
* pShape
= SvxShape::getImplementation( xShape
);
236 pShape
->TakeSdrObjectOwnership();
240 Reference
< drawing::XShape
> SAL_CALL
EnhancedCustomShapeEngine::render()
241 throw ( RuntimeException
)
243 Reference
< drawing::XShape
> xShape
;
244 SdrObject
* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape
) );
245 if ( pSdrObjCustomShape
)
247 // retrieving the TextPath property to check if feature is enabled
248 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)
249 pSdrObjCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
250 sal_Bool bTextPathOn
= sal_False
;
251 const OUString
sTextPath( "TextPath" );
252 uno::Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sTextPath
, sTextPath
);
254 *pAny
>>= bTextPathOn
;
256 EnhancedCustomShape2d
aCustomShape2d( pSdrObjCustomShape
);
257 sal_Int32 nRotateAngle
= aCustomShape2d
.GetRotateAngle();
258 bool bPostRotateAngle
= aCustomShape2d
.IsPostRotate();
260 sal_Bool bFlipV
= aCustomShape2d
.IsFlipVert();
261 sal_Bool bFlipH
= aCustomShape2d
.IsFlipHorz();
262 sal_Bool bLineGeometryNeededOnly
= bTextPathOn
;
264 SdrObject
* pRenderedShape
= aCustomShape2d
.CreateObject( bLineGeometryNeededOnly
);
265 if ( pRenderedShape
)
269 SdrObject
* pRenderedFontWork
= EnhancedCustomShapeFontWork::CreateFontWork( pRenderedShape
, pSdrObjCustomShape
);
270 if ( pRenderedFontWork
)
272 SdrObject::Free( pRenderedShape
);
273 pRenderedShape
= pRenderedFontWork
;
276 SdrObject
* pRenderedShape3d
= EnhancedCustomShape3d::Create3DObject( pRenderedShape
, pSdrObjCustomShape
);
277 if ( pRenderedShape3d
)
279 bFlipV
= bFlipH
= sal_False
;
281 SdrObject::Free( pRenderedShape
);
282 pRenderedShape
= pRenderedShape3d
;
284 Rectangle
aRect( pSdrObjCustomShape
->GetSnapRect() );
286 const GeoStat
& rGeoStat
= ((SdrObjCustomShape
*)pSdrObjCustomShape
)->GetGeoStat();
287 if ( rGeoStat
.nShearWink
)
289 long nShearWink
= rGeoStat
.nShearWink
;
290 double nTan
= rGeoStat
.nTan
;
291 if ((bFlipV
&&!bFlipH
)||(bFlipH
&&!bFlipV
))
293 nShearWink
= -nShearWink
;
296 pRenderedShape
->Shear( pSdrObjCustomShape
->GetSnapRect().Center(), nShearWink
, nTan
, sal_False
);
298 if( !bPostRotateAngle
&& nRotateAngle
)
300 double a
= nRotateAngle
* F_PI18000
;
301 pRenderedShape
->NbcRotate( pSdrObjCustomShape
->GetSnapRect().Center(), nRotateAngle
, sin( a
), cos( a
) );
305 Point
aLeft( aRect
.Left(), ( aRect
.Top() + aRect
.Bottom() ) >> 1 );
306 Point
aRight( aLeft
.X() + 1000, aLeft
.Y() );
307 pRenderedShape
->NbcMirror( aLeft
, aRight
);
311 Point
aTop( ( aRect
.Left() + aRect
.Right() ) >> 1, aRect
.Top() );
312 Point
aBottom( aTop
.X(), aTop
.Y() + 1000 );
313 pRenderedShape
->NbcMirror( aTop
, aBottom
);
315 // Specifically for pptx imports
316 if( bPostRotateAngle
&& nRotateAngle
)
318 double a
= nRotateAngle
* F_PI18000
;
319 pRenderedShape
->NbcRotate( pSdrObjCustomShape
->GetSnapRect().Center(), nRotateAngle
, sin( a
), cos( a
) );
321 pRenderedShape
->NbcSetStyleSheet( pSdrObjCustomShape
->GetStyleSheet(), sal_True
);
322 pRenderedShape
->RecalcSnapRect();
325 if ( mbForceGroupWithText
)
326 pRenderedShape
= ImplForceGroupWithText( (SdrObjCustomShape
*)pSdrObjCustomShape
, pRenderedShape
);
328 if ( pRenderedShape
)
330 aCustomShape2d
.ApplyGluePoints( pRenderedShape
);
331 xShape
= SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape
->GetObjIdentifier(),
332 pRenderedShape
->GetObjInventor(), pRenderedShape
, NULL
);
334 SetTemporary( xShape
);
339 awt::Rectangle SAL_CALL
EnhancedCustomShapeEngine::getTextBounds()
340 throw ( RuntimeException
)
342 awt::Rectangle aTextRect
;
343 SdrObject
* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape
) );
344 uno::Reference
< document::XActionLockable
> xLockable( mxShape
, uno::UNO_QUERY
);
345 if ( pSdrObjCustomShape
&& pSdrObjCustomShape
->GetModel() && xLockable
.is() && !xLockable
->isActionLocked() )
347 if ( pSdrObjCustomShape
)
349 EnhancedCustomShape2d
aCustomShape2d( pSdrObjCustomShape
);
350 Rectangle
aRect( aCustomShape2d
.GetTextRect() );
351 aTextRect
.X
= aRect
.Left();
352 aTextRect
.Y
= aRect
.Top();
353 aTextRect
.Width
= aRect
.GetWidth();
354 aTextRect
.Height
= aRect
.GetHeight();
360 drawing::PolyPolygonBezierCoords SAL_CALL
EnhancedCustomShapeEngine::getLineGeometry()
361 throw ( RuntimeException
)
363 drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords
;
364 SdrObject
* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape
) );
365 if ( pSdrObjCustomShape
)
367 EnhancedCustomShape2d
aCustomShape2d( pSdrObjCustomShape
);
368 SdrObject
* pObj
= aCustomShape2d
.CreateLineGeometry();
371 Rectangle
aRect( pSdrObjCustomShape
->GetSnapRect() );
372 sal_Bool bFlipV
= aCustomShape2d
.IsFlipVert();
373 sal_Bool bFlipH
= aCustomShape2d
.IsFlipHorz();
375 const GeoStat
& rGeoStat
= ((SdrObjCustomShape
*)pSdrObjCustomShape
)->GetGeoStat();
376 if ( rGeoStat
.nShearWink
)
378 long nShearWink
= rGeoStat
.nShearWink
;
379 double nTan
= rGeoStat
.nTan
;
380 if ((bFlipV
&&!bFlipH
)||(bFlipH
&&!bFlipV
))
382 nShearWink
= -nShearWink
;
385 pObj
->Shear( aRect
.Center(), nShearWink
, nTan
, sal_False
);
387 sal_Int32 nRotateAngle
= aCustomShape2d
.GetRotateAngle();
390 double a
= nRotateAngle
* F_PI18000
;
391 pObj
->NbcRotate( aRect
.Center(), nRotateAngle
, sin( a
), cos( a
) );
395 Point
aTop( ( aRect
.Left() + aRect
.Right() ) >> 1, aRect
.Top() );
396 Point
aBottom( aTop
.X(), aTop
.Y() + 1000 );
397 pObj
->NbcMirror( aTop
, aBottom
);
401 Point
aLeft( aRect
.Left(), ( aRect
.Top() + aRect
.Bottom() ) >> 1 );
402 Point
aRight( aLeft
.X() + 1000, aLeft
.Y() );
403 pObj
->NbcMirror( aLeft
, aRight
);
406 basegfx::B2DPolyPolygon aPolyPolygon
;
407 SdrObjListIter
aIter( *pObj
, IM_DEEPWITHGROUPS
);
409 while ( aIter
.IsMore() )
411 SdrObject
* pNewObj
= NULL
;
412 basegfx::B2DPolyPolygon aPP
;
413 const SdrObject
* pNext
= aIter
.Next();
415 if ( pNext
->ISA( SdrPathObj
) )
417 aPP
= ((SdrPathObj
*)pNext
)->GetPathPoly();
421 pNewObj
= pNext
->ConvertToPolyObj( sal_False
, sal_False
);
422 SdrPathObj
* pPath
= PTR_CAST( SdrPathObj
, pNewObj
);
424 aPP
= pPath
->GetPathPoly();
428 aPolyPolygon
.append(aPP
);
430 SdrObject::Free( pNewObj
);
432 SdrObject::Free( pObj
);
433 basegfx::unotools::b2DPolyPolygonToPolyPolygonBezier( aPolyPolygon
,
434 aPolyPolygonBezierCoords
);
438 return aPolyPolygonBezierCoords
;
441 Sequence
< Reference
< drawing::XCustomShapeHandle
> > SAL_CALL
EnhancedCustomShapeEngine::getInteraction()
442 throw ( RuntimeException
)
444 sal_uInt32 i
, nHdlCount
= 0;
445 SdrObject
* pSdrObjCustomShape
= GetSdrObjectFromXShape( mxShape
);
446 if ( pSdrObjCustomShape
)
448 EnhancedCustomShape2d
aCustomShape2d( pSdrObjCustomShape
);
449 nHdlCount
= aCustomShape2d
.GetHdlCount();
451 Sequence
< Reference
< drawing::XCustomShapeHandle
> > aSeq( nHdlCount
);
452 for ( i
= 0; i
< nHdlCount
; i
++ )
453 aSeq
[ i
] = new EnhancedCustomShapeHandle( mxShape
, i
);
457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */