| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| #include "EnhancedCustomShapeEngine.hxx" |
| #include "svx/EnhancedCustomShape2d.hxx" |
| #include "EnhancedCustomShape3d.hxx" |
| #include "EnhancedCustomShapeFontWork.hxx" |
| #include "EnhancedCustomShapeHandle.hxx" |
| #include "svx/EnhancedCustomShapeGeometry.hxx" |
| #include <svx/unoshape.hxx> |
| #ifndef _SVX_UNOPAGE_HXX |
| #include "svx/unopage.hxx" |
| #endif |
| #include "svx/unoapi.hxx" |
| #include <svx/svdobj.hxx> |
| #include <svx/svdoashp.hxx> |
| #include <svx/svdogrp.hxx> |
| #include <svx/svdorect.hxx> |
| #include <editeng/outlobj.hxx> |
| #include <editeng/outliner.hxx> |
| #include <svx/svdoutl.hxx> |
| #include <svl/itemset.hxx> |
| #include <svx/svdopath.hxx> |
| #include <svx/svdpage.hxx> |
| #include <svx/svdmodel.hxx> |
| #include "svx/svditer.hxx" |
| #include "unopolyhelper.hxx" |
| #include <uno/mapping.hxx> |
| #include <basegfx/polygon/b2dpolypolygontools.hxx> |
| #include <com/sun/star/document/XActionLockable.hpp> |
| |
| // --------------------------- |
| // - EnhancedCustomShapeEngine - |
| // --------------------------- |
| |
| rtl::OUString EnhancedCustomShapeEngine_getImplementationName() |
| throw( NMSP_UNO::RuntimeException ) |
| { |
| return B2UCONST( "com.sun.star.drawing.EnhancedCustomShapeEngine" ); |
| } |
| sal_Bool SAL_CALL EnhancedCustomShapeEngine_supportsService( const rtl::OUString& ServiceName ) |
| throw( NMSP_UNO::RuntimeException ) |
| { |
| return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShapeEngine" ) ); |
| } |
| SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine_getSupportedServiceNames() |
| throw( NMSP_UNO::RuntimeException ) |
| { |
| SEQ( rtl::OUString ) aRet(1); |
| rtl::OUString* pArray = aRet.getArray(); |
| pArray[0] = B2UCONST( "com.sun.star.drawing.CustomShapeEngine" ); |
| return aRet; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| EnhancedCustomShapeEngine::EnhancedCustomShapeEngine( const REF( NMSP_LANG::XMultiServiceFactory )& rxMgr ) : |
| mxFact ( rxMgr ), |
| mbForceGroupWithText ( sal_False ) |
| { |
| } |
| EnhancedCustomShapeEngine::~EnhancedCustomShapeEngine() |
| { |
| } |
| |
| // XInterface ----------------------------------------------------------------- |
| |
| void SAL_CALL EnhancedCustomShapeEngine::acquire() throw() |
| { |
| OWeakObject::acquire(); |
| } |
| void SAL_CALL EnhancedCustomShapeEngine::release() throw() |
| { |
| OWeakObject::release(); |
| } |
| |
| // XInitialization ------------------------------------------------------------ |
| |
| void SAL_CALL EnhancedCustomShapeEngine::initialize( const SEQ( NMSP_UNO::Any )& aArguments ) |
| throw ( NMSP_UNO::Exception, NMSP_UNO::RuntimeException ) |
| { |
| sal_Int32 i; |
| SEQ( NMSP_BEANS::PropertyValue ) aParameter; |
| for ( i = 0; i < aArguments.getLength(); i++ ) |
| { |
| if ( aArguments[ i ] >>= aParameter ) |
| break; |
| } |
| for ( i = 0; i < aParameter.getLength(); i++ ) |
| { |
| const NMSP_BEANS::PropertyValue& rProp = aParameter[ i ]; |
| if ( rProp.Name.equalsAscii( "CustomShape" ) ) |
| rProp.Value >>= mxShape; |
| else if ( rProp.Name.equalsAscii( "ForceGroupWithText" ) ) |
| rProp.Value >>= mbForceGroupWithText; |
| } |
| } |
| |
| // XServiceInfo --------------------------------------------------------------- |
| |
| rtl::OUString SAL_CALL EnhancedCustomShapeEngine::getImplementationName() |
| throw( NMSP_UNO::RuntimeException ) |
| { |
| return EnhancedCustomShapeEngine_getImplementationName(); |
| } |
| sal_Bool SAL_CALL EnhancedCustomShapeEngine::supportsService( const rtl::OUString& rServiceName ) |
| throw( NMSP_UNO::RuntimeException ) |
| { |
| return EnhancedCustomShapeEngine_supportsService( rServiceName ); |
| } |
| SEQ( rtl::OUString ) SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceNames() |
| throw ( NMSP_UNO::RuntimeException ) |
| { |
| return EnhancedCustomShapeEngine_getSupportedServiceNames(); |
| } |
| |
| // XCustomShapeEngine ----------------------------------------------------------- |
| |
| SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustomShape* pCustoObj, SdrObject* pRenderedShape ) |
| { |
| bool bHasText = pCustoObj->HasText(); |
| if ( pRenderedShape || bHasText ) |
| { |
| // applying shadow |
| const SdrObject* pShadowGeometry = pCustoObj->GetSdrObjectShadowFromCustomShape(); |
| if ( pShadowGeometry ) |
| { |
| if ( pRenderedShape ) |
| { |
| if ( !pRenderedShape->ISA( SdrObjGroup ) ) |
| { |
| SdrObject* pTmp = pRenderedShape; |
| pRenderedShape = new SdrObjGroup(); |
| ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); |
| } |
| ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pShadowGeometry->Clone(), 0 ); |
| } |
| else |
| pRenderedShape = pShadowGeometry->Clone(); |
| } |
| |
| // apply text |
| if ( bHasText ) |
| { |
| // #i37011# also create a text object and add at rPos + 1 |
| SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject( |
| pCustoObj->GetObjInventor(), OBJ_TEXT, 0L, pCustoObj->GetModel()); |
| |
| // Copy text content |
| OutlinerParaObject* pParaObj = pCustoObj->GetOutlinerParaObject(); |
| if( pParaObj ) |
| pTextObj->NbcSetOutlinerParaObject( new OutlinerParaObject(*pParaObj) ); |
| |
| // copy all attributes |
| SfxItemSet aTargetItemSet( pCustoObj->GetMergedItemSet() ); |
| |
| // clear fill and line style |
| aTargetItemSet.Put(XLineStyleItem(XLINE_NONE)); |
| aTargetItemSet.Put(XFillStyleItem(XFILL_NONE)); |
| |
| // get the text bounds and set at text object |
| Rectangle aTextBounds = pCustoObj->GetSnapRect(); |
| SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); |
| if ( pSdrObjCustomShape ) |
| { |
| EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); |
| aTextBounds = aCustomShape2d.GetTextRect(); |
| } |
| pTextObj->SetSnapRect( aTextBounds ); |
| |
| // if rotated, copy GeoStat, too. |
| const GeoStat& rSourceGeo = pCustoObj->GetGeoStat(); |
| if ( rSourceGeo.nDrehWink ) |
| { |
| pTextObj->NbcRotate( |
| pCustoObj->GetSnapRect().Center(), rSourceGeo.nDrehWink, |
| rSourceGeo.nSin, rSourceGeo.nCos); |
| } |
| |
| // set modified ItemSet at text object |
| pTextObj->SetMergedItemSet(aTargetItemSet); |
| |
| if ( pRenderedShape ) |
| { |
| if ( !pRenderedShape->ISA( SdrObjGroup ) ) |
| { |
| SdrObject* pTmp = pRenderedShape; |
| pRenderedShape = new SdrObjGroup(); |
| ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); |
| } |
| ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTextObj, LIST_APPEND ); |
| } |
| else |
| pRenderedShape = pTextObj; |
| } |
| |
| // force group |
| if ( pRenderedShape ) |
| { |
| if ( !pRenderedShape->ISA( SdrObjGroup ) ) |
| { |
| SdrObject* pTmp = pRenderedShape; |
| pRenderedShape = new SdrObjGroup(); |
| ((SdrObjGroup*)pRenderedShape)->GetSubList()->NbcInsertObject( pTmp ); |
| } |
| pRenderedShape->SetPage( pCustoObj->GetPage() ); |
| pRenderedShape->SetModel( pCustoObj->GetModel() ); |
| } |
| } |
| return pRenderedShape; |
| } |
| |
| void SetTemporary( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape ) |
| { |
| if ( xShape.is() ) |
| { |
| SvxShape* pShape = SvxShape::getImplementation( xShape ); |
| if ( pShape ) |
| pShape->TakeSdrObjectOwnership(); |
| /* |
| ::com::sun::star::uno::Reference< |
| ::com::sun::star::drawing::XShapes > xShapes( xShape, ::com::sun::star::uno::UNO_QUERY ); |
| if ( xShapes.is() ) |
| { |
| sal_Int32 i; |
| for ( i = 0; i < xShapes->getCount(); i++ ) |
| { |
| ::com::sun::star::uno::Any aAny( xShapes->getByIndex( i ) ); |
| ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape; |
| if ( aAny >>= xShape ) |
| SetTemporary( xShape ); |
| } |
| } |
| */ |
| } |
| } |
| |
| REF( com::sun::star::drawing::XShape ) SAL_CALL EnhancedCustomShapeEngine::render() |
| throw ( NMSP_UNO::RuntimeException ) |
| { |
| REF( com::sun::star::drawing::XShape ) xShape; |
| SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); |
| if ( pSdrObjCustomShape ) |
| { |
| // retrieving the TextPath property to check if feature is enabled |
| SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&) |
| pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); |
| sal_Bool bTextPathOn = sal_False; |
| const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); |
| com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath ); |
| if ( pAny ) |
| *pAny >>= bTextPathOn; |
| |
| EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); |
| sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle(); |
| |
| sal_Bool bFlipV = aCustomShape2d.IsFlipVert(); |
| sal_Bool bFlipH = aCustomShape2d.IsFlipHorz(); |
| sal_Bool bLineGeometryNeededOnly = bTextPathOn; |
| |
| SdrObject* pRenderedShape = aCustomShape2d.CreateObject( bLineGeometryNeededOnly ); |
| if ( pRenderedShape ) |
| { |
| if ( bTextPathOn ) |
| { |
| SdrObject* pRenderedFontWork = EnhancedCustomShapeFontWork::CreateFontWork( pRenderedShape, pSdrObjCustomShape ); |
| if ( pRenderedFontWork ) |
| { |
| SdrObject::Free( pRenderedShape ); |
| pRenderedShape = pRenderedFontWork; |
| } |
| } |
| SdrObject* pRenderedShape3d = EnhancedCustomShape3d::Create3DObject( pRenderedShape, pSdrObjCustomShape ); |
| if ( pRenderedShape3d ) |
| { |
| bFlipV = bFlipH = sal_False; |
| nRotateAngle = 0; |
| SdrObject::Free( pRenderedShape ); |
| pRenderedShape = pRenderedShape3d; |
| } |
| Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); |
| |
| const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); |
| if ( rGeoStat.nShearWink ) |
| { |
| long nShearWink = rGeoStat.nShearWink; |
| double nTan = rGeoStat.nTan; |
| if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) |
| { |
| nShearWink = -nShearWink; |
| nTan = -nTan; |
| } |
| pRenderedShape->Shear( pSdrObjCustomShape->GetSnapRect().Center(), nShearWink, nTan, sal_False); |
| } |
| if( nRotateAngle ) |
| { |
| double a = nRotateAngle * F_PI18000; |
| pRenderedShape->NbcRotate( pSdrObjCustomShape->GetSnapRect().Center(), nRotateAngle, sin( a ), cos( a ) ); |
| } |
| if ( bFlipV ) |
| { |
| Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 ); |
| Point aRight( aLeft.X() + 1000, aLeft.Y() ); |
| pRenderedShape->NbcMirror( aLeft, aRight ); |
| } |
| if ( bFlipH ) |
| { |
| Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() ); |
| Point aBottom( aTop.X(), aTop.Y() + 1000 ); |
| pRenderedShape->NbcMirror( aTop, aBottom ); |
| } |
| pRenderedShape->NbcSetStyleSheet( pSdrObjCustomShape->GetStyleSheet(), sal_True ); |
| pRenderedShape->RecalcSnapRect(); |
| } |
| |
| if ( mbForceGroupWithText ) |
| pRenderedShape = ImplForceGroupWithText( (SdrObjCustomShape*)pSdrObjCustomShape, pRenderedShape ); |
| |
| if ( pRenderedShape ) |
| { |
| aCustomShape2d.ApplyGluePoints( pRenderedShape ); |
| xShape = SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape->GetObjIdentifier(), |
| pRenderedShape->GetObjInventor(), pRenderedShape, NULL ); |
| } |
| SetTemporary( xShape ); |
| } |
| return xShape; |
| } |
| |
| com::sun::star::awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds() |
| throw ( NMSP_UNO::RuntimeException ) |
| { |
| com::sun::star::awt::Rectangle aTextRect; |
| SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); |
| ::com::sun::star::uno::Reference< ::com::sun::star::document::XActionLockable > xLockable( mxShape, ::com::sun::star::uno::UNO_QUERY ); |
| if ( pSdrObjCustomShape && pSdrObjCustomShape->GetModel() && xLockable.is() && !xLockable->isActionLocked() ) |
| { |
| if ( pSdrObjCustomShape ) |
| { |
| EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); |
| Rectangle aRect( aCustomShape2d.GetTextRect() ); |
| aTextRect.X = aRect.Left(); |
| aTextRect.Y = aRect.Top(); |
| aTextRect.Width = aRect.GetWidth(); |
| aTextRect.Height = aRect.GetHeight(); |
| } |
| } |
| return aTextRect; |
| } |
| |
| com::sun::star::drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeometry() |
| throw ( NMSP_UNO::RuntimeException ) |
| { |
| com::sun::star::drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords; |
| SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) ); |
| if ( pSdrObjCustomShape ) |
| { |
| EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); |
| SdrObject* pObj = aCustomShape2d.CreateLineGeometry(); |
| if ( pObj ) |
| { |
| Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); |
| sal_Bool bFlipV = aCustomShape2d.IsFlipVert(); |
| sal_Bool bFlipH = aCustomShape2d.IsFlipHorz(); |
| |
| const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); |
| if ( rGeoStat.nShearWink ) |
| { |
| long nShearWink = rGeoStat.nShearWink; |
| double nTan = rGeoStat.nTan; |
| if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) |
| { |
| nShearWink = -nShearWink; |
| nTan = -nTan; |
| } |
| pObj->Shear( aRect.Center(), nShearWink, nTan, sal_False); |
| } |
| sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle(); |
| if( nRotateAngle ) |
| { |
| double a = nRotateAngle * F_PI18000; |
| pObj->NbcRotate( aRect.Center(), nRotateAngle, sin( a ), cos( a ) ); |
| } |
| if ( bFlipH ) |
| { |
| Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() ); |
| Point aBottom( aTop.X(), aTop.Y() + 1000 ); |
| pObj->NbcMirror( aTop, aBottom ); |
| } |
| if ( bFlipV ) |
| { |
| Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 ); |
| Point aRight( aLeft.X() + 1000, aLeft.Y() ); |
| pObj->NbcMirror( aLeft, aRight ); |
| } |
| |
| basegfx::B2DPolyPolygon aPolyPolygon; |
| SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS ); |
| |
| while ( aIter.IsMore() ) |
| { |
| SdrObject* pNewObj = NULL; |
| basegfx::B2DPolyPolygon aPP; |
| const SdrObject* pNext = aIter.Next(); |
| |
| if ( pNext->ISA( SdrPathObj ) ) |
| { |
| aPP = ((SdrPathObj*)pNext)->GetPathPoly(); |
| } |
| else |
| { |
| pNewObj = pNext->ConvertToPolyObj( sal_False, sal_False ); |
| SdrPathObj* pPath = PTR_CAST( SdrPathObj, pNewObj ); |
| if ( pPath ) |
| aPP = pPath->GetPathPoly(); |
| } |
| |
| if ( aPP.count() ) |
| aPolyPolygon.append(aPP); |
| |
| SdrObject::Free( pNewObj ); |
| } |
| SdrObject::Free( pObj ); |
| SvxConvertB2DPolyPolygonToPolyPolygonBezier( aPolyPolygon, aPolyPolygonBezierCoords ); |
| } |
| } |
| |
| return aPolyPolygonBezierCoords; |
| } |
| |
| SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) SAL_CALL EnhancedCustomShapeEngine::getInteraction() |
| throw ( NMSP_UNO::RuntimeException ) |
| { |
| sal_uInt32 i, nHdlCount = 0; |
| SdrObject* pSdrObjCustomShape = GetSdrObjectFromXShape( mxShape ); |
| if ( pSdrObjCustomShape ) |
| { |
| EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape ); |
| nHdlCount = aCustomShape2d.GetHdlCount(); |
| } |
| SEQ( REF( com::sun::star::drawing::XCustomShapeHandle ) ) aSeq( nHdlCount ); |
| for ( i = 0; i < nHdlCount; i++ ) |
| aSeq[ i ] = new EnhancedCustomShapeHandle( mxShape, i ); |
| return aSeq; |
| } |