| /************************************************************** |
| * |
| * 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 <svx/svdoashp.hxx> |
| #include "svx/unoapi.hxx" |
| #include <svx/unoshape.hxx> |
| #include <ucbhelper/content.hxx> |
| #include <ucbhelper/contentbroker.hxx> |
| #include <unotools/datetime.hxx> |
| #include <sfx2/lnkbase.hxx> |
| #include <tools/urlobj.hxx> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/drawing/XShape.hpp> |
| #include <com/sun/star/drawing/XCustomShapeEngine.hpp> |
| #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/awt/Rectangle.hpp> |
| #include "unopolyhelper.hxx" |
| #include <comphelper/processfactory.hxx> |
| #include <svl/urihelper.hxx> |
| #include <com/sun/star/uno/Sequence.h> |
| #include <svx/svdogrp.hxx> |
| #include <vcl/salbtype.hxx> // FRound |
| #include <svx/svddrag.hxx> |
| #include <svx/xpool.hxx> |
| #include <svx/xpoly.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/svdpage.hxx> |
| #include "svx/svditer.hxx" |
| #include <svx/svdobj.hxx> |
| #include <svx/svdtrans.hxx> |
| #include <svx/svdetc.hxx> |
| #include <svx/svdattrx.hxx> // NotPersistItems |
| #include <svx/svdoedge.hxx> // #32383# Die Verbinder nach Move nochmal anbroadcasten |
| #include "svx/svdglob.hxx" // StringCache |
| #include "svx/svdstr.hrc" // Objektname |
| #include <editeng/eeitem.hxx> |
| #include "editeng/editstat.hxx" |
| #include <svx/svdoutl.hxx> |
| #include <editeng/outlobj.hxx> |
| #include <svx/sdtfchim.hxx> |
| #include "../svx/EnhancedCustomShapeGeometry.hxx" |
| #include "../svx/EnhancedCustomShapeTypeNames.hxx" |
| #include "../svx/EnhancedCustomShape2d.hxx" |
| #include <com/sun/star/beans/PropertyValues.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> |
| #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> |
| #include <editeng/writingmodeitem.hxx> |
| #include <svx/xlnclit.hxx> |
| #include <svx/svxids.hrc> |
| #include <svl/whiter.hxx> |
| #include <svx/sdr/properties/customshapeproperties.hxx> |
| #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx> |
| #include <svx/xlnclit.hxx> |
| #include <svx/xlntrit.hxx> |
| #include <svx/xfltrit.hxx> |
| #include <svx/xflclit.hxx> |
| #include <svx/xflgrit.hxx> |
| #include <svx/xflhtit.hxx> |
| #include <svx/xbtmpit.hxx> |
| #include <vcl/bmpacc.hxx> |
| #include <svx/svdview.hxx> |
| #include <basegfx/polygon/b2dpolypolygontools.hxx> |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <basegfx/matrix/b2dhommatrixtools.hxx> |
| |
| // #104018# replace macros above with type-safe methods |
| inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); } |
| inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); } |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::drawing; |
| |
| static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape ) |
| { |
| MSO_SPT eRetValue = mso_sptNil; |
| |
| rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() ); |
| if ( !aEngine.getLength() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) |
| { |
| rtl::OUString sShapeType; |
| const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); |
| SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| Any* pAny = rGeometryItem.GetPropertyValueByName( sType ); |
| if ( pAny && ( *pAny >>= sShapeType ) ) |
| eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType ); |
| } |
| return eRetValue; |
| }; |
| |
| static sal_Bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape ) |
| { |
| sal_Bool bRet = sal_False; |
| MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) ); |
| switch( eShapeType ) |
| { |
| case mso_sptAccentBorderCallout90 : // 2 ortho |
| case mso_sptBorderCallout1 : // 2 diag |
| case mso_sptBorderCallout2 : // 3 |
| { |
| bRet = sal_True; |
| } |
| break; |
| /* |
| case mso_sptCallout1 : |
| case mso_sptAccentCallout1 : |
| case mso_sptAccentBorderCallout1 : |
| case mso_sptBorderCallout90 : |
| case mso_sptCallout90 : |
| case mso_sptAccentCallout90 : |
| case mso_sptCallout2 : |
| case mso_sptCallout3 : |
| case mso_sptAccentCallout2 : |
| case mso_sptAccentCallout3 : |
| case mso_sptBorderCallout3 : |
| case mso_sptAccentBorderCallout2 : |
| case mso_sptAccentBorderCallout3 : |
| */ |
| default: break; |
| } |
| return bRet; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // #i37011# create a clone with all attributes changed to shadow attributes |
| // and translation executed, too. |
| SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet) |
| { |
| SdrObject* pRetval = 0L; |
| const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue()); |
| |
| if(bShadow) |
| { |
| // create a shadow representing object |
| const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue()); |
| const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); |
| const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue()); |
| const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); |
| pRetval = rOriginal.Clone(); |
| DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)"); |
| |
| // look for used stuff |
| SdrObjListIter aIterator(rOriginal); |
| sal_Bool bLineUsed(sal_False); |
| sal_Bool bAllFillUsed(sal_False); |
| sal_Bool bSolidFillUsed(sal_False); |
| sal_Bool bGradientFillUsed(sal_False); |
| sal_Bool bHatchFillUsed(sal_False); |
| sal_Bool bBitmapFillUsed(sal_False); |
| |
| while(aIterator.IsMore()) |
| { |
| SdrObject* pObj = aIterator.Next(); |
| XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue(); |
| |
| if(!bLineUsed) |
| { |
| XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue(); |
| |
| if(XLINE_NONE != eLineStyle) |
| { |
| bLineUsed = sal_True; |
| } |
| } |
| |
| if(!bAllFillUsed) |
| { |
| if(!bSolidFillUsed && XFILL_SOLID == eFillStyle) |
| { |
| bSolidFillUsed = sal_True; |
| bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed); |
| } |
| if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle) |
| { |
| bGradientFillUsed = sal_True; |
| bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed); |
| } |
| if(!bHatchFillUsed && XFILL_HATCH == eFillStyle) |
| { |
| bHatchFillUsed = sal_True; |
| bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed); |
| } |
| if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle) |
| { |
| bBitmapFillUsed = sal_True; |
| bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed); |
| } |
| } |
| } |
| |
| // translate to shadow coordinates |
| pRetval->NbcMove(Size(nXDist, nYDist)); |
| |
| // set items as needed |
| SfxItemSet aTempSet(rOriginalSet); |
| |
| // SJ: #40108# :-( if a SvxWritingModeItem (Top->Bottom) is set the text object |
| // is creating a paraobject, but paraobjects can not be created without model. So |
| // we are preventing the crash by setting the writing mode always left to right, |
| // this is not bad since our shadow geometry does not contain text. |
| aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) ); |
| |
| // no shadow |
| aTempSet.Put(SdrShadowItem(sal_False)); |
| aTempSet.Put(SdrShadowXDistItem(0L)); |
| aTempSet.Put(SdrShadowYDistItem(0L)); |
| |
| // line color and transparence like shadow |
| if(bLineUsed) |
| { |
| aTempSet.Put(XLineColorItem(String(), aShadowColor)); |
| aTempSet.Put(XLineTransparenceItem(nShadowTransparence)); |
| } |
| |
| // fill color and transparence like shadow |
| if(bSolidFillUsed) |
| { |
| aTempSet.Put(XFillColorItem(String(), aShadowColor)); |
| aTempSet.Put(XFillTransparenceItem(nShadowTransparence)); |
| } |
| |
| // gradient and transparence like shadow |
| if(bGradientFillUsed) |
| { |
| XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue()); |
| sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance()); |
| sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance()); |
| |
| if(aGradient.GetStartIntens() != 100) |
| { |
| nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0)); |
| } |
| |
| if(aGradient.GetEndIntens() != 100) |
| { |
| nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0)); |
| } |
| |
| ::Color aStartColor( |
| (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256), |
| (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256), |
| (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256)); |
| |
| ::Color aEndColor( |
| (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256), |
| (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256), |
| (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256)); |
| |
| aGradient.SetStartColor(aStartColor); |
| aGradient.SetEndColor(aEndColor); |
| aTempSet.Put(XFillGradientItem(aTempSet.GetPool(), aGradient)); |
| aTempSet.Put(XFillTransparenceItem(nShadowTransparence)); |
| } |
| |
| // hatch and transparence like shadow |
| if(bHatchFillUsed) |
| { |
| XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue()); |
| aHatch.SetColor(aShadowColor); |
| aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch)); |
| aTempSet.Put(XFillTransparenceItem(nShadowTransparence)); |
| } |
| |
| // bitmap and transparence like shadow |
| if(bBitmapFillUsed) |
| { |
| GraphicObject aGraphicObject(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetGraphicObject()); |
| const BitmapEx aBitmapEx(aGraphicObject.GetGraphic().GetBitmapEx()); |
| Bitmap aBitmap(aBitmapEx.GetBitmap()); |
| |
| if(!aBitmap.IsEmpty()) |
| { |
| BitmapReadAccess* pReadAccess = aBitmap.AcquireReadAccess(); |
| |
| if(pReadAccess) |
| { |
| Bitmap aDestBitmap(aBitmap.GetSizePixel(), 24L); |
| BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess(); |
| |
| if(pWriteAccess) |
| { |
| for(sal_Int32 y(0L); y < pReadAccess->Height(); y++) |
| { |
| for(sal_Int32 x(0L); x < pReadAccess->Width(); x++) |
| { |
| sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1); |
| const BitmapColor aDestColor( |
| (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L), |
| (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L), |
| (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L)); |
| pWriteAccess->SetPixel(y, x, aDestColor); |
| } |
| } |
| |
| aDestBitmap.ReleaseAccess(pWriteAccess); |
| } |
| |
| aBitmap.ReleaseAccess(pReadAccess); |
| |
| if(aBitmapEx.IsTransparent()) |
| { |
| if(aBitmapEx.IsAlpha()) |
| { |
| aGraphicObject.SetGraphic(Graphic(BitmapEx(aDestBitmap, aBitmapEx.GetAlpha()))); |
| } |
| else |
| { |
| aGraphicObject.SetGraphic(Graphic(BitmapEx(aDestBitmap, aBitmapEx.GetMask()))); |
| } |
| } |
| else |
| { |
| aGraphicObject.SetGraphic(Graphic(aDestBitmap)); |
| } |
| } |
| } |
| |
| aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aGraphicObject)); |
| aTempSet.Put(XFillTransparenceItem(nShadowTransparence)); |
| } |
| |
| // set attributes and paint shadow object |
| pRetval->SetMergedItemSet( aTempSet ); |
| } |
| return pRetval; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine( const SdrObjCustomShape* pCustomShape ) |
| { |
| Reference< XCustomShapeEngine > xCustomShapeEngine; |
| String aEngine(((SdrCustomShapeEngineItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue()); |
| if ( !aEngine.Len() ) |
| aEngine = String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ); |
| |
| Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); |
| |
| Reference< XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape ); |
| if ( aXShape.is() ) |
| { |
| if ( aEngine.Len() && xFactory.is() ) |
| { |
| Sequence< Any > aArgument( 1 ); |
| Sequence< PropertyValue > aPropValues( 1 ); |
| aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" ); |
| aPropValues[ 0 ].Value <<= aXShape; |
| aArgument[ 0 ] <<= aPropValues; |
| Reference< XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) ); |
| if ( xInterface.is() ) |
| xCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY ); |
| } |
| } |
| return xCustomShapeEngine; |
| } |
| const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const |
| { |
| if ( !mXRenderedCustomShape.is() ) |
| { |
| Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); |
| if ( xCustomShapeEngine.is() ) |
| ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render(); |
| } |
| SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is() |
| ? GetSdrObjectFromXShape( mXRenderedCustomShape ) |
| : NULL; |
| return pRenderedCustomShape; |
| } |
| |
| // #i37011# Shadow geometry creation |
| const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const |
| { |
| if(!mpLastShadowGeometry) |
| { |
| const SdrObject* pSdrObject = GetSdrObjectFromCustomShape(); |
| if(pSdrObject) |
| { |
| const SfxItemSet& rOriginalSet = GetObjectItemSet(); |
| const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue()); |
| |
| if(bShadow) |
| { |
| // create a clone with all attributes changed to shadow attributes |
| // and translation executed, too. |
| ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet); |
| } |
| } |
| } |
| |
| return mpLastShadowGeometry; |
| } |
| |
| sal_Bool SdrObjCustomShape::IsTextPath() const |
| { |
| const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); |
| sal_Bool bTextPathOn = sal_False; |
| SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); |
| Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath ); |
| if ( pAny ) |
| *pAny >>= bTextPathOn; |
| return bTextPathOn; |
| } |
| |
| sal_Bool SdrObjCustomShape::UseNoFillStyle() const |
| { |
| sal_Bool bRet = sal_False; |
| rtl::OUString sShapeType; |
| const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); |
| SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| Any* pAny = rGeometryItem.GetPropertyValueByName( sType ); |
| if ( pAny ) |
| *pAny >>= sShapeType; |
| bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == 0; |
| |
| return bRet; |
| } |
| |
| sal_Bool SdrObjCustomShape::IsMirroredX() const |
| { |
| sal_Bool bMirroredX = sal_False; |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); |
| com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX ); |
| if ( pAny ) |
| *pAny >>= bMirroredX; |
| return bMirroredX; |
| } |
| sal_Bool SdrObjCustomShape::IsMirroredY() const |
| { |
| sal_Bool bMirroredY = sal_False; |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); |
| com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY ); |
| if ( pAny ) |
| *pAny >>= bMirroredY; |
| return bMirroredY; |
| } |
| void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX ) |
| { |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); |
| //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX ); |
| PropertyValue aPropVal; |
| aPropVal.Name = sMirroredX; |
| aPropVal.Value <<= bMirrorX; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| SetMergedItem( aGeometryItem ); |
| } |
| void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY ) |
| { |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); |
| //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY ); |
| PropertyValue aPropVal; |
| aPropVal.Name = sMirroredY; |
| aPropVal.Value <<= bMirrorY; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| SetMergedItem( aGeometryItem ); |
| } |
| |
| double SdrObjCustomShape::GetObjectRotation() const |
| { |
| return fObjectRotation; |
| } |
| |
| double SdrObjCustomShape::GetExtraTextRotation() const |
| { |
| const com::sun::star::uno::Any* pAny; |
| SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); |
| const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) ); |
| pAny = rGeometryItem.GetPropertyValueByName( sTextRotateAngle ); |
| double fExtraTextRotateAngle = 0.0; |
| if ( pAny ) |
| *pAny >>= fExtraTextRotateAngle; |
| return fExtraTextRotateAngle; |
| } |
| sal_Bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const |
| { |
| sal_Bool bRet = sal_False; |
| Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); // a candidate for being cached |
| if ( xCustomShapeEngine.is() ) |
| { |
| awt::Rectangle aR( xCustomShapeEngine->getTextBounds() ); |
| if ( aR.Width || aR.Height ) |
| { |
| rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) ); |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const sal_Bool bBezierAllowed ) |
| { |
| basegfx::B2DPolyPolygon aRetval; |
| sal_Bool bRet = sal_False; |
| Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) ); |
| if ( xCustomShapeEngine.is() ) |
| { |
| com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry(); |
| try |
| { |
| aRetval = SvxConvertPolyPolygonBezierToB2DPolyPolygon( &aBezierCoords ); |
| if ( !bBezierAllowed && aRetval.areControlPointsUsed()) |
| { |
| aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval); |
| } |
| bRet = sal_True; |
| } |
| catch ( const com::sun::star::lang::IllegalArgumentException ) |
| { |
| } |
| } |
| return aRetval; |
| } |
| |
| std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const |
| { |
| std::vector< SdrCustomShapeInteraction > xRet; |
| try |
| { |
| Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) ); |
| if ( xCustomShapeEngine.is() ) |
| { |
| int i; |
| Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() ); |
| for ( i = 0; i < xInteractionHandles.getLength(); i++ ) |
| { |
| if ( xInteractionHandles[ i ].is() ) |
| { |
| SdrCustomShapeInteraction aSdrCustomShapeInteraction; |
| aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ]; |
| aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition(); |
| |
| sal_Int32 nMode = 0; |
| switch( ImpGetCustomShapeType( *this ) ) |
| { |
| case mso_sptAccentBorderCallout90 : // 2 ortho |
| { |
| if ( !i ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED; |
| else if ( i == 1) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4; |
| } |
| break; |
| |
| case mso_sptWedgeRectCallout : |
| case mso_sptWedgeRRectCallout : |
| case mso_sptCloudCallout : |
| case mso_sptWedgeEllipseCallout : |
| { |
| if ( !i ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED; |
| } |
| break; |
| |
| case mso_sptBorderCallout1 : // 2 diag |
| { |
| if ( !i ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED; |
| else if ( i == 1 ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE; |
| } |
| break; |
| case mso_sptBorderCallout2 : // 3 |
| { |
| if ( !i ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED; |
| else if ( i == 2 ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE; |
| } |
| break; |
| case mso_sptCallout90 : |
| case mso_sptAccentCallout90 : |
| case mso_sptBorderCallout90 : |
| case mso_sptCallout1 : |
| case mso_sptCallout2 : |
| case mso_sptCallout3 : |
| case mso_sptAccentCallout1 : |
| case mso_sptAccentCallout2 : |
| case mso_sptAccentCallout3 : |
| case mso_sptBorderCallout3 : |
| case mso_sptAccentBorderCallout1 : |
| case mso_sptAccentBorderCallout2 : |
| case mso_sptAccentBorderCallout3 : |
| { |
| if ( !i ) |
| nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED; |
| } |
| break; |
| default: break; |
| } |
| aSdrCustomShapeInteraction.nMode = nMode; |
| xRet.push_back( aSdrCustomShapeInteraction ); |
| } |
| } |
| } |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| } |
| return xRet; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // BaseProperties section |
| #define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000) |
| #define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff) |
| |
| sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties() |
| { |
| return new sdr::properties::CustomShapeProperties(*this); |
| } |
| |
| TYPEINIT1(SdrObjCustomShape,SdrTextObj); |
| SdrObjCustomShape::SdrObjCustomShape() : |
| SdrTextObj(), |
| fObjectRotation( 0.0 ), |
| mpLastShadowGeometry(0L) |
| { |
| bClosedObj = true; // custom shapes may be filled |
| bTextFrame = sal_True; |
| } |
| |
| SdrObjCustomShape::~SdrObjCustomShape() |
| { |
| // delete buffered display geometry |
| InvalidateRenderGeometry(); |
| } |
| |
| void SdrObjCustomShape::MergeDefaultAttributes( const rtl::OUString* pType ) |
| { |
| PropertyValue aPropVal; |
| rtl::OUString sShapeType; |
| const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| if ( pType && pType->getLength() ) |
| { |
| sal_Int32 nType = pType->toInt32(); |
| if ( nType ) |
| sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) ); |
| else |
| sShapeType = *pType; |
| |
| aPropVal.Name = sType; |
| aPropVal.Value <<= sShapeType; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| } |
| else |
| { |
| Any *pAny = aGeometryItem.GetPropertyValueByName( sType ); |
| if ( pAny ) |
| *pAny >>= sShapeType; |
| } |
| MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType ); |
| |
| const sal_Int32* pDefData = NULL; |
| const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType ); |
| if ( pDefCustomShape ) |
| pDefData = pDefCustomShape->pDefData; |
| |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues; |
| |
| ////////////////////// |
| // AdjustmentValues // |
| ////////////////////// |
| const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); |
| const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues ); |
| if ( pAny ) |
| *pAny >>= seqAdjustmentValues; |
| if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values |
| { |
| // first check if there are adjustment values are to be appended |
| sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength(); |
| sal_Int32 nAdjustmentDefaults = *pDefData++; |
| if ( nAdjustmentDefaults > nAdjustmentValues ) |
| { |
| seqAdjustmentValues.realloc( nAdjustmentDefaults ); |
| for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ ) |
| { |
| seqAdjustmentValues[ i ].Value <<= pDefData[ i ]; |
| seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // com::sun::star::beans::PropertyState_DEFAULT_VALUE; |
| } |
| } |
| // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue) |
| sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues; |
| for ( i = 0; i < nCount; i++ ) |
| { |
| if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE ) |
| { |
| seqAdjustmentValues[ i ].Value <<= pDefData[ i ]; |
| seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; |
| } |
| } |
| } |
| aPropVal.Name = sAdjustmentValues; |
| aPropVal.Value <<= seqAdjustmentValues; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| |
| /////////////// |
| // Coordsize // |
| /////////////// |
| const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); |
| const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox ); |
| com::sun::star::awt::Rectangle aViewBox; |
| if ( !pViewBox || !(*pViewBox >>= aViewBox ) ) |
| { |
| if ( pDefCustomShape ) |
| { |
| aViewBox.X = 0; |
| aViewBox.Y = 0; |
| aViewBox.Width = pDefCustomShape->nCoordWidth; |
| aViewBox.Height= pDefCustomShape->nCoordHeight; |
| aPropVal.Name = sViewBox; |
| aPropVal.Value <<= aViewBox; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| } |
| } |
| |
| const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); |
| |
| ////////////////////// |
| // Path/Coordinates // |
| ////////////////////// |
| const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates; |
| |
| sal_Int32 i, nCount = pDefCustomShape->nVertices; |
| seqCoordinates.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB ); |
| } |
| aPropVal.Name = sCoordinates; |
| aPropVal.Value <<= seqCoordinates; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| |
| ///////////////////// |
| // Path/GluePoints // |
| ///////////////////// |
| const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints; |
| sal_Int32 i, nCount = pDefCustomShape->nGluePoints; |
| seqGluePoints.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB ); |
| } |
| aPropVal.Name = sGluePoints; |
| aPropVal.Value <<= seqGluePoints; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| |
| /////////////////// |
| // Path/Segments // |
| /////////////////// |
| const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments; |
| |
| sal_Int32 i, nCount = pDefCustomShape->nElements; |
| seqSegments.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ]; |
| sal_uInt16 nSDat = pDefCustomShape->pElements[ i ]; |
| switch( nSDat >> 8 ) |
| { |
| case 0x00 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x20 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x40 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x60 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0x80 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0xa1 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; |
| rSegInfo.Count = ( nSDat & 0xff ) / 3; |
| } |
| break; |
| case 0xa2 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; |
| rSegInfo.Count = ( nSDat & 0xff ) / 3; |
| } |
| break; |
| case 0xa3 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa4 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa5 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa6 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa7 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; |
| rSegInfo.Count = nSDat & 0xff; |
| } |
| break; |
| case 0xa8 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; |
| rSegInfo.Count = nSDat & 0xff; |
| } |
| break; |
| case 0xaa : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0xab : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE; |
| rSegInfo.Count = 0; |
| } |
| break; |
| default: |
| case 0xf8 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN; |
| rSegInfo.Count = nSDat; |
| } |
| break; |
| } |
| } |
| aPropVal.Name = sSegments; |
| aPropVal.Value <<= seqSegments; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| |
| /////////////////// |
| // Path/StretchX // |
| /////////////////// |
| const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX ); |
| if ( !pAny && pDefCustomShape ) |
| { |
| sal_Int32 nXRef = pDefCustomShape->nXRef; |
| if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) ) |
| { |
| aPropVal.Name = sStretchX; |
| aPropVal.Value <<= nXRef; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| } |
| |
| /////////////////// |
| // Path/StretchY // |
| /////////////////// |
| const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY ); |
| if ( !pAny && pDefCustomShape ) |
| { |
| sal_Int32 nYRef = pDefCustomShape->nYRef; |
| if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) ) |
| { |
| aPropVal.Name = sStretchY; |
| aPropVal.Value <<= nYRef; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| } |
| |
| ///////////////////// |
| // Path/TextFrames // |
| ///////////////////// |
| const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames; |
| |
| sal_Int32 i, nCount = pDefCustomShape->nTextRect; |
| seqTextFrames.realloc( nCount ); |
| const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect; |
| for ( i = 0; i < nCount; i++, pRectangles++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB ); |
| } |
| aPropVal.Name = sTextFrames; |
| aPropVal.Value <<= seqTextFrames; |
| aGeometryItem.SetPropertyValue( sPath, aPropVal ); |
| } |
| |
| /////////////// |
| // Equations // |
| /////////////// |
| const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation ) |
| { |
| com::sun::star::uno::Sequence< rtl::OUString > seqEquations; |
| |
| sal_Int32 i, nCount = pDefCustomShape->nCalculation; |
| seqEquations.realloc( nCount ); |
| const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation; |
| for ( i = 0; i < nCount; i++, pData++ ) |
| seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] ); |
| aPropVal.Name = sEquations; |
| aPropVal.Value <<= seqEquations; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| } |
| |
| ///////////// |
| // Handles // |
| ///////////// |
| const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles ); |
| if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles; |
| |
| sal_Int32 i, n, nCount = pDefCustomShape->nHandles; |
| const SvxMSDffHandle* pData = pDefCustomShape->pHandles; |
| seqHandles.realloc( nCount ); |
| for ( i = 0; i < nCount; i++, pData++ ) |
| { |
| sal_Int32 nPropertiesNeeded = 1; // position is always needed |
| sal_Int32 nFlags = pData->nFlags; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR ) |
| { |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| } |
| } |
| else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| } |
| |
| n = 0; |
| com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ]; |
| rPropValues.realloc( nPropertiesNeeded ); |
| |
| // POSITION |
| { |
| const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False ); |
| rPropValues[ n ].Name = sPosition; |
| rPropValues[ n++ ].Value <<= aPosition; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X ) |
| { |
| const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); |
| sal_Bool bMirroredX = sal_True; |
| rPropValues[ n ].Name = sMirroredX; |
| rPropValues[ n++ ].Value <<= bMirroredX; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y ) |
| { |
| const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); |
| sal_Bool bMirroredY = sal_True; |
| rPropValues[ n ].Name = sMirroredY; |
| rPropValues[ n++ ].Value <<= bMirroredY; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED ) |
| { |
| const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) ); |
| sal_Bool bSwitched = sal_True; |
| rPropValues[ n ].Name = sSwitched; |
| rPropValues[ n++ ].Value <<= bSwitched; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR ) |
| { |
| const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX, |
| ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY, |
| ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sPolar; |
| rPropValues[ n++ ].Value <<= aCenter; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRadiusRangeMinimum; |
| rPropValues[ n++ ].Value <<= aRadiusRangeMinimum; |
| } |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRadiusRangeMaximum; |
| rPropValues[ n++ ].Value <<= aRadiusRangeMaximum; |
| } |
| } |
| } |
| else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRangeXMinimum; |
| rPropValues[ n++ ].Value <<= aRangeXMinimum; |
| } |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRangeXMaximum; |
| rPropValues[ n++ ].Value <<= aRangeXMaximum; |
| } |
| if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRangeYMinimum; |
| rPropValues[ n++ ].Value <<= aRangeYMinimum; |
| } |
| if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRangeYMaximum; |
| rPropValues[ n++ ].Value <<= aRangeYMaximum; |
| } |
| } |
| } |
| aPropVal.Name = sHandles; |
| aPropVal.Value <<= seqHandles; |
| aGeometryItem.SetPropertyValue( aPropVal ); |
| } |
| SetMergedItem( aGeometryItem ); |
| } |
| |
| sal_Bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const |
| { |
| sal_Bool bIsDefaultGeometry = sal_False; |
| |
| PropertyValue aPropVal; |
| rtl::OUString sShapeType; |
| const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); |
| SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| |
| Any *pAny = aGeometryItem.GetPropertyValueByName( sType ); |
| if ( pAny ) |
| *pAny >>= sShapeType; |
| |
| MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType ); |
| |
| const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType ); |
| const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); |
| switch( eDefaultType ) |
| { |
| case DEFAULT_VIEWBOX : |
| { |
| const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); |
| const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox ); |
| com::sun::star::awt::Rectangle aViewBox; |
| if ( pViewBox && ( *pViewBox >>= aViewBox ) ) |
| { |
| if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth ) |
| && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| break; |
| |
| case DEFAULT_PATH : |
| { |
| const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates ); |
| if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2; |
| if ( *pAny >>= seqCoordinates1 ) |
| { |
| sal_Int32 i, nCount = pDefCustomShape->nVertices; |
| seqCoordinates2.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB ); |
| } |
| if ( seqCoordinates1 == seqCoordinates2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_GLUEPOINTS : |
| { |
| const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints ); |
| if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2; |
| if ( *pAny >>= seqGluePoints1 ) |
| { |
| sal_Int32 i, nCount = pDefCustomShape->nGluePoints; |
| seqGluePoints2.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB ); |
| } |
| if ( seqGluePoints1 == seqGluePoints2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_SEGMENTS : |
| { |
| /////////////////// |
| // Path/Segments // |
| /////////////////// |
| const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments ); |
| if ( pAny ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2; |
| if ( *pAny >>= seqSegments1 ) |
| { |
| if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements ) |
| { |
| sal_Int32 i, nCount = pDefCustomShape->nElements; |
| if ( nCount ) |
| { |
| seqSegments2.realloc( nCount ); |
| for ( i = 0; i < nCount; i++ ) |
| { |
| EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ]; |
| sal_uInt16 nSDat = pDefCustomShape->pElements[ i ]; |
| switch( nSDat >> 8 ) |
| { |
| case 0x00 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x20 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x40 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO; |
| rSegInfo.Count = nSDat & 0xff; |
| if ( !rSegInfo.Count ) |
| rSegInfo.Count = 1; |
| } |
| break; |
| case 0x60 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0x80 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0xa1 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; |
| rSegInfo.Count = ( nSDat & 0xff ) / 3; |
| } |
| break; |
| case 0xa2 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; |
| rSegInfo.Count = ( nSDat & 0xff ) / 3; |
| } |
| break; |
| case 0xa3 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa4 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa5 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa6 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; |
| rSegInfo.Count = ( nSDat & 0xff ) >> 2; |
| } |
| break; |
| case 0xa7 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; |
| rSegInfo.Count = nSDat & 0xff; |
| } |
| break; |
| case 0xa8 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; |
| rSegInfo.Count = nSDat & 0xff; |
| } |
| break; |
| case 0xaa : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL; |
| rSegInfo.Count = 0; |
| } |
| break; |
| case 0xab : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE; |
| rSegInfo.Count = 0; |
| } |
| break; |
| default: |
| case 0xf8 : |
| { |
| rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN; |
| rSegInfo.Count = nSDat; |
| } |
| break; |
| } |
| } |
| if ( seqSegments1 == seqSegments2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else |
| { |
| // check if its the default segment description ( M L Z N ) |
| if ( seqSegments1.getLength() == 4 ) |
| { |
| if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO ) |
| && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO ) |
| && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH ) |
| && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| } |
| } |
| else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_STRETCHX : |
| { |
| const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX ); |
| if ( pAny && pDefCustomShape ) |
| { |
| sal_Int32 nStretchX = 0; |
| if ( *pAny >>= nStretchX ) |
| { |
| if ( pDefCustomShape->nXRef == nStretchX ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_STRETCHY : |
| { |
| const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY ); |
| if ( pAny && pDefCustomShape ) |
| { |
| sal_Int32 nStretchY = 0; |
| if ( *pAny >>= nStretchY ) |
| { |
| if ( pDefCustomShape->nYRef == nStretchY ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_EQUATIONS : |
| { |
| const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations ); |
| if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation ) |
| { |
| com::sun::star::uno::Sequence< rtl::OUString > seqEquations1, seqEquations2; |
| if ( *pAny >>= seqEquations1 ) |
| { |
| sal_Int32 i, nCount = pDefCustomShape->nCalculation; |
| seqEquations2.realloc( nCount ); |
| |
| const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation; |
| for ( i = 0; i < nCount; i++, pData++ ) |
| seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] ); |
| |
| if ( seqEquations1 == seqEquations2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_TEXTFRAMES : |
| { |
| const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames ); |
| if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2; |
| if ( *pAny >>= seqTextFrames1 ) |
| { |
| sal_Int32 i, nCount = pDefCustomShape->nTextRect; |
| seqTextFrames2.realloc( nCount ); |
| const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect; |
| for ( i = 0; i < nCount; i++, pRectangles++ ) |
| { |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB ); |
| } |
| if ( seqTextFrames1 == seqTextFrames2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| |
| case DEFAULT_HANDLES : |
| { |
| const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) ); |
| pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles ); |
| if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles ) |
| { |
| com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2; |
| if ( *pAny >>= seqHandles1 ) |
| { |
| sal_Int32 i, n, nCount = pDefCustomShape->nHandles; |
| const SvxMSDffHandle* pData = pDefCustomShape->pHandles; |
| seqHandles2.realloc( nCount ); |
| for ( i = 0; i < nCount; i++, pData++ ) |
| { |
| sal_Int32 nPropertiesNeeded = 1; // position is always needed |
| sal_Int32 nFlags = pData->nFlags; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED ) |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR ) |
| { |
| nPropertiesNeeded++; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| } |
| } |
| else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| nPropertiesNeeded++; |
| } |
| |
| n = 0; |
| com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ]; |
| rPropValues.realloc( nPropertiesNeeded ); |
| |
| // POSITION |
| { |
| const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False ); |
| rPropValues[ n ].Name = sPosition; |
| rPropValues[ n++ ].Value <<= aPosition; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X ) |
| { |
| const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); |
| sal_Bool bMirroredX = sal_True; |
| rPropValues[ n ].Name = sMirroredX; |
| rPropValues[ n++ ].Value <<= bMirroredX; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y ) |
| { |
| const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); |
| sal_Bool bMirroredY = sal_True; |
| rPropValues[ n ].Name = sMirroredY; |
| rPropValues[ n++ ].Value <<= bMirroredY; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED ) |
| { |
| const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) ); |
| sal_Bool bSwitched = sal_True; |
| rPropValues[ n ].Name = sSwitched; |
| rPropValues[ n++ ].Value <<= bSwitched; |
| } |
| if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR ) |
| { |
| const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX, |
| ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True ); |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY, |
| ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sPolar; |
| rPropValues[ n++ ].Value <<= aCenter; |
| if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRadiusRangeMinimum; |
| rPropValues[ n++ ].Value <<= aRadiusRangeMinimum; |
| } |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRadiusRangeMaximum; |
| rPropValues[ n++ ].Value <<= aRadiusRangeMaximum; |
| } |
| } |
| } |
| else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE ) |
| { |
| if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRangeXMinimum; |
| rPropValues[ n++ ].Value <<= aRangeXMinimum; |
| } |
| if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRangeXMaximum; |
| rPropValues[ n++ ].Value <<= aRangeXMaximum; |
| } |
| if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True ); |
| rPropValues[ n ].Name = sRangeYMinimum; |
| rPropValues[ n++ ].Value <<= aRangeYMinimum; |
| } |
| if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE ) |
| { |
| const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) ); |
| ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum; |
| EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax, |
| ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False ); |
| rPropValues[ n ].Name = sRangeYMaximum; |
| rPropValues[ n++ ].Value <<= aRangeYMaximum; |
| } |
| } |
| } |
| if ( seqHandles1 == seqHandles2 ) |
| bIsDefaultGeometry = sal_True; |
| } |
| } |
| else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) ) |
| bIsDefaultGeometry = sal_True; |
| } |
| break; |
| } |
| return bIsDefaultGeometry; |
| } |
| |
| void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const |
| { |
| rInfo.bResizeFreeAllowed=fObjectRotation == 0.0; |
| rInfo.bResizePropAllowed=sal_True; |
| rInfo.bRotateFreeAllowed=sal_True; |
| rInfo.bRotate90Allowed =sal_True; |
| rInfo.bMirrorFreeAllowed=sal_True; |
| rInfo.bMirror45Allowed =sal_True; |
| rInfo.bMirror90Allowed =sal_True; |
| rInfo.bTransparenceAllowed = sal_False; |
| rInfo.bGradientAllowed = sal_False; |
| rInfo.bShearAllowed =sal_True; |
| rInfo.bEdgeRadiusAllowed=sal_False; |
| rInfo.bNoContortion =sal_True; |
| |
| // #i37011# |
| if ( mXRenderedCustomShape.is() ) |
| { |
| const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape ); |
| if ( pRenderedCustomShape ) |
| { |
| // #i37262# |
| // Iterate self over the contained objects, since there are combinations of |
| // polygon and curve objects. In that case, aInfo.bCanConvToPath and |
| // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and. |
| SdrObjListIter aIterator(*pRenderedCustomShape); |
| while(aIterator.IsMore()) |
| { |
| SdrObject* pCandidate = aIterator.Next(); |
| SdrObjTransformInfoRec aInfo; |
| pCandidate->TakeObjInfo(aInfo); |
| |
| // set path and poly conversion if one is possible since |
| // this object will first be broken |
| const sal_Bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly); |
| if(rInfo.bCanConvToPath != bCanConvToPathOrPoly) |
| { |
| rInfo.bCanConvToPath = bCanConvToPathOrPoly; |
| } |
| |
| if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly) |
| { |
| rInfo.bCanConvToPoly = bCanConvToPathOrPoly; |
| } |
| |
| if(rInfo.bCanConvToContour != aInfo.bCanConvToContour) |
| { |
| rInfo.bCanConvToContour = aInfo.bCanConvToContour; |
| } |
| } |
| } |
| } |
| } |
| |
| void SdrObjCustomShape::SetModel(SdrModel* pNewModel) |
| { |
| SdrTextObj::SetModel(pNewModel); |
| mXRenderedCustomShape.clear(); |
| } |
| |
| sal_uInt16 SdrObjCustomShape::GetObjIdentifier() const |
| { |
| return sal_uInt16(OBJ_CUSTOMSHAPE); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| void SdrObjCustomShape::RecalcSnapRect() |
| { |
| SdrTextObj::RecalcSnapRect(); |
| } |
| const Rectangle& SdrObjCustomShape::GetSnapRect() const |
| { |
| return SdrTextObj::GetSnapRect(); |
| } |
| const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const |
| { |
| return SdrTextObj::GetCurrentBoundRect(); |
| } |
| const Rectangle& SdrObjCustomShape::GetLogicRect() const |
| { |
| return SdrTextObj::GetLogicRect(); |
| } |
| |
| // #115391# This implementation is based on the TextFrame size of the CustomShape and the |
| // state of the ResizeShapeToFitText flag to correctly set TextMinFrameWidth/Height |
| void SdrObjCustomShape::AdaptTextMinSize() |
| { |
| if(!pModel || !pModel->IsPasteResize()) |
| { |
| const bool bResizeShapeToFitText(0 != static_cast< const SdrTextAutoGrowHeightItem& >(GetObjectItem(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue()); |
| SfxItemSet aSet(GetObjectItemSet()); |
| bool bChanged(false); |
| |
| if(bResizeShapeToFitText) |
| { |
| // always reset MinWidthHeight to zero to only rely on text size and frame size |
| // to allow resizing being completely dependent on text size only |
| aSet.Put(SdrTextMinFrameWidthItem(0)); |
| aSet.Put(SdrTextMinFrameHeightItem(0)); |
| bChanged = true; |
| } |
| else |
| { |
| // recreate from CustomShape-specific TextBounds |
| Rectangle aTextBound(aRect); |
| |
| if(GetTextBounds(aTextBound)) |
| { |
| const long nHDist(GetTextLeftDistance() + GetTextRightDistance()); |
| const long nVDist(GetTextUpperDistance() + GetTextLowerDistance()); |
| const long nTWdt(std::max(long(0), (long)(aTextBound.GetWidth() - 1 - nHDist))); |
| const long nTHgt(std::max(long(0), (long)(aTextBound.GetHeight() - 1 - nVDist))); |
| SfxItemSet aSet(GetObjectItemSet()); |
| |
| aSet.Put(SdrTextMinFrameWidthItem(nTWdt)); |
| aSet.Put(SdrTextMinFrameHeightItem(nTHgt)); |
| bChanged = true; |
| } |
| } |
| |
| if(bChanged) |
| { |
| SetObjectItemSet(aSet); |
| NbcAdjustTextFrameWidthAndHeight(); |
| } |
| } |
| } |
| |
| void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect ) |
| { |
| aRect=rRect; |
| ImpJustifyRect(aRect); |
| InvalidateRenderGeometry(); |
| |
| // #115391# |
| AdaptTextMinSize(); |
| |
| ImpCheckShear(); |
| SetRectsDirty(); |
| SetChanged(); |
| } |
| void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect ) |
| { |
| Rectangle aBoundRect0; |
| if ( pUserCall ) |
| aBoundRect0 = GetLastBoundRect(); |
| NbcSetSnapRect( rRect ); |
| BroadcastObjectChange(); |
| SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); |
| } |
| void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect ) |
| { |
| aRect = rRect; |
| ImpJustifyRect( aRect ); |
| InvalidateRenderGeometry(); |
| |
| // #115391# |
| AdaptTextMinSize(); |
| |
| SetRectsDirty(); |
| SetChanged(); |
| } |
| void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect ) |
| { |
| Rectangle aBoundRect0; |
| if ( pUserCall ) |
| aBoundRect0 = GetLastBoundRect(); |
| NbcSetLogicRect(rRect); |
| BroadcastObjectChange(); |
| SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); |
| } |
| void SdrObjCustomShape::Move( const Size& rSiz ) |
| { |
| if ( rSiz.Width() || rSiz.Height() ) |
| { |
| Rectangle aBoundRect0; |
| if ( pUserCall ) |
| aBoundRect0 = GetLastBoundRect(); |
| // #110094#-14 SendRepaintBroadcast(); |
| NbcMove(rSiz); |
| SetChanged(); |
| BroadcastObjectChange(); |
| SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0); |
| } |
| } |
| void SdrObjCustomShape::NbcMove( const Size& rSiz ) |
| { |
| SdrTextObj::NbcMove( rSiz ); |
| if ( mXRenderedCustomShape.is() ) |
| { |
| SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape ); |
| if ( pRenderedCustomShape ) |
| { |
| // #i97149# the visualisation shape needs to be informed |
| // about change, too |
| pRenderedCustomShape->ActionChanged(); |
| pRenderedCustomShape->NbcMove( rSiz ); |
| } |
| } |
| |
| // #i37011# adapt geometry shadow |
| if(mpLastShadowGeometry) |
| { |
| mpLastShadowGeometry->NbcMove( rSiz ); |
| } |
| } |
| void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact ) |
| { |
| SdrTextObj::Resize( rRef, xFact, yFact ); |
| } |
| |
| void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact ) |
| { |
| Fraction xFact( rxFact ); |
| Fraction yFact( ryFact ); |
| |
| // taking care of handles that should not been changed |
| Rectangle aOld( aRect ); |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| |
| SdrTextObj::NbcResize( rRef, xFact, yFact ); |
| |
| if ( ( xFact.GetNumerator() != xFact.GetDenominator() ) |
| || ( yFact.GetNumerator()!= yFact.GetDenominator() ) ) |
| { |
| if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) || |
| ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) ) |
| { |
| SetMirroredX( IsMirroredX() == sal_False ); |
| } |
| if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) || |
| ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) ) |
| { |
| SetMirroredY( IsMirroredY() == sal_False ); |
| } |
| } |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| try |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED ) |
| aIter->xInteraction->setControllerPosition( aIter->aPosition ); |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X ) |
| { |
| sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left(); |
| aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) ); |
| } |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y ) |
| { |
| sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top(); |
| aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) ); |
| } |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| aIter++; |
| } |
| InvalidateRenderGeometry(); |
| } |
| void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs ) |
| { |
| sal_Bool bMirroredX = IsMirroredX(); |
| sal_Bool bMirroredY = IsMirroredY(); |
| |
| fObjectRotation = fmod( fObjectRotation, 360.0 ); |
| if ( fObjectRotation < 0 ) |
| fObjectRotation = 360 + fObjectRotation; |
| |
| // the rotation angle for ashapes is stored in fObjectRotation, this rotation |
| // has to be applied to the text object (which is internally using aGeo.nWink). |
| SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink, // retrieving the unrotated text object |
| sin( (-aGeo.nDrehWink) * F_PI18000 ), |
| cos( (-aGeo.nDrehWink) * F_PI18000 ) ); |
| aGeo.nDrehWink = 0; // resetting aGeo data |
| aGeo.RecalcSinCos(); |
| |
| long nW = (long)( fObjectRotation * 100 ); // applying our object rotation |
| if ( bMirroredX ) |
| nW = 36000 - nW; |
| if ( bMirroredY ) |
| nW = 18000 - nW; |
| nW = nW % 36000; |
| if ( nW < 0 ) |
| nW = 36000 + nW; |
| SdrTextObj::NbcRotate( aRect.TopLeft(), nW, // applying text rotation |
| sin( nW * F_PI18000 ), |
| cos( nW * F_PI18000 ) ); |
| |
| int nSwap = 0; |
| if ( bMirroredX ) |
| nSwap ^= 1; |
| if ( bMirroredY ) |
| nSwap ^= 1; |
| |
| double fWink = nWink; // updating to our new object rotation |
| fWink /= 100.0; |
| fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 ); |
| if ( fObjectRotation < 0 ) |
| fObjectRotation = 360 + fObjectRotation; |
| |
| SdrTextObj::NbcRotate( rRef, nWink, sn, cs ); // applying text rotation |
| InvalidateRenderGeometry(); |
| } |
| |
| void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 ) |
| { |
| // TTTT: Fix for old mirroring, can be removed again in aw080 |
| // storing horizontal and vertical flipping without modifying the rotate angle |
| // decompose other flipping to rotation and MirrorX. |
| long ndx = rRef2.X()-rRef1.X(); |
| long ndy = rRef2.Y()-rRef1.Y(); |
| |
| if(!ndx) // MirroredX |
| { |
| SetMirroredX(!IsMirroredX()); |
| SdrTextObj::NbcMirror( rRef1, rRef2 ); |
| } |
| else |
| { |
| if(!ndy) // MirroredY |
| { |
| SetMirroredY(!IsMirroredY()); |
| SdrTextObj::NbcMirror( rRef1, rRef2 ); |
| } |
| else // neither horizontal nor vertical |
| { |
| SetMirroredX(!IsMirroredX()); |
| |
| // call parent |
| SdrTextObj::NbcMirror( rRef1, rRef2 ); |
| |
| // update fObjectRotation |
| long nTextObjRotation = aGeo.nDrehWink; |
| double fWink = nTextObjRotation; |
| |
| fWink /= 100.0; |
| |
| bool bSingleFlip = (IsMirroredX()!= IsMirroredY()); |
| |
| fObjectRotation = fmod( bSingleFlip ? -fWink : fWink, 360.0 ); |
| |
| if ( fObjectRotation < 0 ) |
| { |
| fObjectRotation = 360.0 + fObjectRotation; |
| } |
| } |
| } |
| |
| InvalidateRenderGeometry(); |
| } |
| |
| void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear ) |
| { |
| SdrTextObj::Shear( rRef, nWink, tn, bVShear ); |
| InvalidateRenderGeometry(); |
| } |
| void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear ) |
| { |
| // TTTT: Fix for old mirroring, can be removed again in aw080 |
| SdrTextObj::NbcShear(rRef,nWink,tn,bVShear); |
| |
| // updating fObjectRotation |
| long nTextObjRotation = aGeo.nDrehWink; |
| double fWink = nTextObjRotation; |
| |
| fWink /= 100.0; |
| |
| bool bSingleFlip = (IsMirroredX()!= IsMirroredY()); |
| |
| fObjectRotation = fmod( bSingleFlip ? -fWink : fWink, 360.0 ); |
| |
| if ( fObjectRotation < 0 ) |
| { |
| fObjectRotation = 360.0 + fObjectRotation; |
| } |
| |
| InvalidateRenderGeometry(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum) const |
| { |
| sal_Int32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue(); |
| |
| // #i25616# |
| if(!LineIsOutsideGeometry()) |
| { |
| nWdt++; |
| nWdt /= 2; |
| } |
| |
| Point aPt; |
| switch (nPosNum) { |
| case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break; |
| case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break; |
| case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break; |
| case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break; |
| } |
| if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan); |
| if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos); |
| aPt-=GetSnapRect().Center(); |
| SdrGluePoint aGP(aPt); |
| aGP.SetPercent(sal_False); |
| return aGP; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| // #i38892# |
| void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded() |
| { |
| const SdrObject* pSdrObject = GetSdrObjectFromCustomShape(); |
| |
| if(pSdrObject) |
| { |
| const SdrGluePointList* pSource = pSdrObject->GetGluePointList(); |
| |
| if(pSource && pSource->GetCount()) |
| { |
| if(!SdrTextObj::GetGluePointList()) |
| { |
| SdrTextObj::ForceGluePointList(); |
| } |
| |
| const SdrGluePointList* pList = SdrTextObj::GetGluePointList(); |
| |
| if(pList) |
| { |
| SdrGluePointList aNewList; |
| sal_uInt16 a; |
| |
| for(a = 0; a < pSource->GetCount(); a++) |
| { |
| SdrGluePoint aCopy((*pSource)[a]); |
| aCopy.SetUserDefined(sal_False); |
| aNewList.Insert(aCopy); |
| } |
| |
| sal_Bool bMirroredX = IsMirroredX(); |
| sal_Bool bMirroredY = IsMirroredY(); |
| |
| long nShearWink = aGeo.nShearWink; |
| double fTan = aGeo.nTan; |
| |
| if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY ) |
| { |
| Polygon aPoly( aRect ); |
| if( nShearWink ) |
| { |
| sal_uInt16 nPointCount=aPoly.GetSize(); |
| for (sal_uInt16 i=0; i<nPointCount; i++) |
| ShearPoint(aPoly[i],aRect.Center(), fTan, sal_False ); |
| } |
| if ( aGeo.nDrehWink ) |
| aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 ); |
| |
| Rectangle aBoundRect( aPoly.GetBoundRect() ); |
| sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left(); |
| sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top(); |
| |
| if (nShearWink&&((bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX))) |
| { |
| nShearWink = -nShearWink; |
| fTan = -fTan; |
| } |
| |
| Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 ); |
| for ( a = 0; a < aNewList.GetCount(); a++ ) |
| { |
| SdrGluePoint& rPoint = aNewList[ a ]; |
| Point aGlue( rPoint.GetPos() ); |
| if ( nShearWink ) |
| ShearPoint( aGlue, aRef, fTan ); |
| |
| RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) ); |
| if ( bMirroredX ) |
| aGlue.X() = aRect.GetWidth() - aGlue.X(); |
| if ( bMirroredY ) |
| aGlue.Y() = aRect.GetHeight() - aGlue.Y(); |
| aGlue.X() -= nXDiff; |
| aGlue.Y() -= nYDiff; |
| rPoint.SetPos( aGlue ); |
| } |
| } |
| |
| for(a = 0; a < pList->GetCount(); a++) |
| { |
| const SdrGluePoint& rCandidate = (*pList)[a]; |
| |
| if(rCandidate.IsUserDefined()) |
| { |
| aNewList.Insert(rCandidate); |
| } |
| } |
| |
| // copy new list to local. This is NOT very convenient behaviour, the local |
| // GluePointList should not be set, but be delivered by using GetGluePointList(), |
| // maybe on demand. Since the local object is changed here, this is assumed to |
| // be a result of GetGluePointList and thus the list is copied |
| if(pPlusData) |
| { |
| *pPlusData->pGluePoints = aNewList; |
| } |
| } |
| } |
| } |
| } |
| |
| // #i38892# |
| const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const |
| { |
| ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded(); |
| return SdrTextObj::GetGluePointList(); |
| } |
| |
| // #i38892# |
| //SdrGluePointList* SdrObjCustomShape::GetGluePointList() |
| //{ |
| // ImpCheckCustomGluePointsAreAdded(); |
| // return SdrTextObj::GetGluePointList(); |
| //} |
| |
| // #i38892# |
| SdrGluePointList* SdrObjCustomShape::ForceGluePointList() |
| { |
| if(SdrTextObj::ForceGluePointList()) |
| { |
| ImpCheckCustomGluePointsAreAdded(); |
| return SdrTextObj::ForceGluePointList(); |
| } |
| else |
| { |
| return 0L; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| sal_uInt32 SdrObjCustomShape::GetHdlCount() const |
| { |
| const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount()); |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| return ( aInteractionHandles.size() + nBasicHdlCount ); |
| } |
| |
| SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const |
| { |
| SdrHdl* pH = NULL; |
| const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount()); |
| |
| if ( nHdlNum < nBasicHdlCount ) |
| pH = SdrTextObj::GetHdl( nHdlNum ); |
| else |
| { |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount); |
| |
| if ( nCustomShapeHdlNum < aInteractionHandles.size() ) |
| { |
| if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() ) |
| { |
| try |
| { |
| com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() ); |
| pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 ); |
| pH->SetPointNum( nCustomShapeHdlNum ); |
| pH->SetObj( (SdrObject*)this ); |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| } |
| } |
| } |
| return pH; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| bool SdrObjCustomShape::hasSpecialDrag() const |
| { |
| return true; |
| } |
| |
| bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const |
| { |
| const SdrHdl* pHdl = rDrag.GetHdl(); |
| |
| if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind()) |
| { |
| rDrag.SetEndDragChangesAttributes(true); |
| rDrag.SetNoSnap(true); |
| } |
| else |
| { |
| const SdrHdl* pHdl2 = rDrag.GetHdl(); |
| const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind()); |
| |
| switch( eHdl ) |
| { |
| case HDL_UPLFT : |
| case HDL_UPPER : |
| case HDL_UPRGT : |
| case HDL_LEFT : |
| case HDL_RIGHT : |
| case HDL_LWLFT : |
| case HDL_LOWER : |
| case HDL_LWRGT : |
| case HDL_MOVE : |
| { |
| break; |
| } |
| default: |
| { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const |
| { |
| Rectangle aOld( pObj->aRect ); |
| sal_Bool bOldMirroredX( pObj->IsMirroredX() ); |
| sal_Bool bOldMirroredY( pObj->IsMirroredY() ); |
| |
| Rectangle aNewRect( rNewRect ); |
| aNewRect.Justify(); |
| |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) ); |
| |
| GeoStat aGeoStat( pObj->GetGeoStat() ); |
| if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() && |
| ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) ) |
| { |
| Point aNewPos( aNewRect.TopLeft() ); |
| if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan ); |
| if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos ); |
| aNewRect.SetPos( aNewPos ); |
| } |
| if ( aNewRect != pObj->aRect ) |
| { |
| pObj->SetLogicRect( aNewRect ); |
| pObj->InvalidateRenderGeometry(); |
| |
| if ( rNewRect.Left() > rNewRect.Right() ) |
| { |
| Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() ); |
| Point aBottom( aTop.X(), aTop.Y() + 1000 ); |
| pObj->NbcMirror( aTop, aBottom ); |
| } |
| if ( rNewRect.Top() > rNewRect.Bottom() ) |
| { |
| Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 ); |
| Point aRight( aLeft.X() + 1000, aLeft.Y() ); |
| pObj->NbcMirror( aLeft, aRight ); |
| } |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| try |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED ) |
| aIter->xInteraction->setControllerPosition( aIter->aPosition ); |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X ) |
| { |
| sal_Int32 nX; |
| if ( bOldMirroredX ) |
| { |
| nX = ( aIter->aPosition.X - aOld.Right() ); |
| if ( rNewRect.Left() > rNewRect.Right() ) |
| nX = pObj->aRect.Left() - nX; |
| else |
| nX += pObj->aRect.Right(); |
| } |
| else |
| { |
| nX = ( aIter->aPosition.X - aOld.Left() ); |
| if ( rNewRect.Left() > rNewRect.Right() ) |
| nX = pObj->aRect.Right() - nX; |
| else |
| nX += pObj->aRect.Left(); |
| } |
| aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) ); |
| } |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y ) |
| { |
| sal_Int32 nY; |
| if ( bOldMirroredY ) |
| { |
| nY = ( aIter->aPosition.Y - aOld.Bottom() ); |
| if ( rNewRect.Top() > rNewRect.Bottom() ) |
| nY = pObj->aRect.Top() - nY; |
| else |
| nY += pObj->aRect.Bottom(); |
| } |
| else |
| { |
| nY = ( aIter->aPosition.Y - aOld.Top() ); |
| if ( rNewRect.Top() > rNewRect.Bottom() ) |
| nY = pObj->aRect.Bottom() - nY; |
| else |
| nY += pObj->aRect.Top(); |
| } |
| aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) ); |
| } |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| aIter++; |
| } |
| } |
| } |
| |
| void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const |
| { |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) ); |
| if ( nCustomShapeHdlNum < aInteractionHandles.size() ) |
| { |
| SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] ); |
| if ( aInteractionHandle.xInteraction.is() ) |
| { |
| try |
| { |
| com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() ); |
| if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE ) |
| { |
| sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X; |
| sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y; |
| |
| pObj->aRect.Move( nXDiff, nYDiff ); |
| pObj->aOutRect.Move( nXDiff, nYDiff ); |
| pObj->maSnapRect.Move( nXDiff, nYDiff ); |
| pObj->SetRectsDirty(sal_True); |
| pObj->InvalidateRenderGeometry(); |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED ) |
| { |
| if ( aIter->xInteraction.is() ) |
| aIter->xInteraction->setControllerPosition( aIter->aPosition ); |
| } |
| aIter++; |
| } |
| } |
| aInteractionHandle.xInteraction->setControllerPosition( aPt ); |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| } |
| } |
| } |
| |
| bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag) |
| { |
| const SdrHdl* pHdl = rDrag.GetHdl(); |
| const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind()); |
| |
| switch(eHdl) |
| { |
| case HDL_CUSTOMSHAPE1 : |
| { |
| rDrag.SetEndDragChangesGeoAndAttributes(true); |
| DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this ); |
| SetRectsDirty(); |
| InvalidateRenderGeometry(); |
| SetChanged(); |
| break; |
| } |
| |
| case HDL_UPLFT : |
| case HDL_UPPER : |
| case HDL_UPRGT : |
| case HDL_LEFT : |
| case HDL_RIGHT : |
| case HDL_LWLFT : |
| case HDL_LOWER : |
| case HDL_LWRGT : |
| { |
| DragResizeCustomShape(ImpDragCalcRect(rDrag), this); |
| break; |
| } |
| case HDL_MOVE : |
| { |
| Move(Size(rDrag.GetDX(), rDrag.GetDY())); |
| break; |
| } |
| default: break; |
| } |
| |
| return true; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat ) |
| { |
| Rectangle aRect1; |
| rStat.TakeCreateRect( aRect1 ); |
| |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| |
| sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ? |
| sal_uInt32 nDefaultObjectSizeHeight= 3000; |
| |
| if ( ImpVerticalSwitch( *this ) ) |
| { |
| SetMirroredX( aRect1.Left() > aRect1.Right() ); |
| |
| aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) ); |
| // subtracting the horizontal difference of the latest handle from shape position |
| if ( !aInteractionHandles.empty() ) |
| { |
| sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X; |
| aRect1.Move( aRect.Left() - nHandlePos, 0 ); |
| } |
| } |
| ImpJustifyRect( aRect1 ); |
| rStat.SetActionRect( aRect1 ); |
| aRect = aRect1; |
| SetRectsDirty(); |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| try |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED ) |
| aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) ); |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| aIter++; |
| } |
| |
| SetBoundRectDirty(); |
| bSnapRectDirty=sal_True; |
| } |
| |
| FASTBOOL SdrObjCustomShape::BegCreate( SdrDragStat& rDrag ) |
| { |
| return SdrTextObj::BegCreate( rDrag ); |
| } |
| |
| FASTBOOL SdrObjCustomShape::MovCreate(SdrDragStat& rStat) |
| { |
| SdrView* pView = rStat.GetView(); // #i37448# |
| if( pView && pView->IsSolidDragging() ) |
| { |
| InvalidateRenderGeometry(); |
| } |
| DragCreateObject( rStat ); |
| SetRectsDirty(); |
| return sal_True; |
| } |
| |
| FASTBOOL SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd ) |
| { |
| DragCreateObject( rStat ); |
| |
| // #115391# |
| AdaptTextMinSize(); |
| |
| SetRectsDirty(); |
| return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 ); |
| } |
| |
| basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const |
| { |
| return GetLineGeometry( this, sal_False ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text, |
| // the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape |
| FASTBOOL SdrObjCustomShape::IsAutoGrowHeight() const |
| { |
| const SfxItemSet& rSet = GetMergedItemSet(); |
| FASTBOOL bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue(); |
| if ( bIsAutoGrowHeight && IsVerticalWriting() ) |
| bIsAutoGrowHeight = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False; |
| return bIsAutoGrowHeight; |
| } |
| FASTBOOL SdrObjCustomShape::IsAutoGrowWidth() const |
| { |
| const SfxItemSet& rSet = GetMergedItemSet(); |
| FASTBOOL bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue(); |
| if ( bIsAutoGrowWidth && !IsVerticalWriting() ) |
| bIsAutoGrowWidth = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == sal_False; |
| return bIsAutoGrowWidth; |
| } |
| |
| /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference |
| is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing |
| mode has been changed */ |
| |
| void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical ) |
| { |
| ForceOutlinerParaObject(); |
| |
| OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject(); |
| |
| DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" ); |
| |
| if( pOutlinerParaObject ) |
| { |
| if(pOutlinerParaObject->IsVertical() != (bool)bVertical) |
| { |
| // get item settings |
| const SfxItemSet& rSet = GetObjectItemSet(); |
| |
| // #103516# Also exchange hor/ver adjust items |
| SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue(); |
| SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue(); |
| |
| // rescue object size |
| Rectangle aObjectRect = GetSnapRect(); |
| |
| // prepare ItemSet to set exchanged width and height items |
| SfxItemSet aNewSet(*rSet.GetPool(), |
| SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT, |
| // #103516# Expanded item ranges to also support hor and ver adjust. |
| SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST, |
| SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST, |
| 0, 0); |
| |
| aNewSet.Put(rSet); |
| |
| // #103516# Exchange horz and vert adjusts |
| switch(eVert) |
| { |
| case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break; |
| case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break; |
| case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break; |
| case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break; |
| } |
| switch(eHorz) |
| { |
| case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break; |
| case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break; |
| case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break; |
| case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break; |
| } |
| |
| SetObjectItemSet( aNewSet ); |
| pOutlinerParaObject = GetOutlinerParaObject(); |
| if ( pOutlinerParaObject ) |
| pOutlinerParaObject->SetVertical(bVertical); |
| |
| // restore object size |
| SetSnapRect(aObjectRect); |
| } |
| } |
| } |
| FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const |
| { |
| if ( pModel && HasText() && !rR.IsEmpty() ) |
| { |
| FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth(); |
| FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight(); |
| if ( bWdtGrow || bHgtGrow ) |
| { |
| Rectangle aR0(rR); |
| long nHgt=0,nMinHgt=0,nMaxHgt=0; |
| long nWdt=0,nMinWdt=0,nMaxWdt=0; |
| Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--; |
| Size aMaxSiz(100000,100000); |
| Size aTmpSiz(pModel->GetMaxObjSize()); |
| if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width(); |
| if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height(); |
| if (bWdtGrow) |
| { |
| nMinWdt=GetMinTextFrameWidth(); |
| nMaxWdt=GetMaxTextFrameWidth(); |
| if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width(); |
| if (nMinWdt<=0) nMinWdt=1; |
| aSiz.Width()=nMaxWdt; |
| } |
| if (bHgtGrow) |
| { |
| nMinHgt=GetMinTextFrameHeight(); |
| nMaxHgt=GetMaxTextFrameHeight(); |
| if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height(); |
| if (nMinHgt<=0) nMinHgt=1; |
| aSiz.Height()=nMaxHgt; |
| } |
| long nHDist=GetTextLeftDistance()+GetTextRightDistance(); |
| long nVDist=GetTextUpperDistance()+GetTextLowerDistance(); |
| aSiz.Width()-=nHDist; |
| aSiz.Height()-=nVDist; |
| if ( aSiz.Width() < 2 ) |
| aSiz.Width() = 2; // Mindestgroesse 2 |
| if ( aSiz.Height() < 2 ) |
| aSiz.Height() = 2; // Mindestgroesse 2 |
| |
| if(pEdtOutl) |
| { |
| pEdtOutl->SetMaxAutoPaperSize( aSiz ); |
| if (bWdtGrow) |
| { |
| Size aSiz2(pEdtOutl->CalcTextSize()); |
| nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz |
| if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz |
| } else |
| { |
| nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz |
| } |
| } |
| else |
| { |
| Outliner& rOutliner=ImpGetDrawOutliner(); |
| rOutliner.SetPaperSize(aSiz); |
| rOutliner.SetUpdateMode(sal_True); |
| // !!! hier sollte ich wohl auch noch mal die Optimierung mit |
| // bPortionInfoChecked usw einbauen |
| OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject(); |
| if( pOutlinerParaObject != NULL ) |
| { |
| rOutliner.SetText(*pOutlinerParaObject); |
| rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue()); |
| } |
| if ( bWdtGrow ) |
| { |
| Size aSiz2(rOutliner.CalcTextSize()); |
| nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz |
| if ( bHgtGrow ) |
| nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz |
| } |
| else |
| nHgt = rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz |
| rOutliner.Clear(); |
| } |
| if ( nWdt < nMinWdt ) |
| nWdt = nMinWdt; |
| if ( nWdt > nMaxWdt ) |
| nWdt = nMaxWdt; |
| nWdt += nHDist; |
| if ( nWdt < 1 ) |
| nWdt = 1; // nHDist kann auch negativ sein |
| if ( nHgt < nMinHgt ) |
| nHgt = nMinHgt; |
| if ( nHgt > nMaxHgt ) |
| nHgt = nMaxHgt; |
| nHgt+=nVDist; |
| if ( nHgt < 1 ) |
| nHgt = 1; // nVDist kann auch negativ sein |
| long nWdtGrow = nWdt-(rR.Right()-rR.Left()); |
| long nHgtGrow = nHgt-(rR.Bottom()-rR.Top()); |
| if ( nWdtGrow == 0 ) |
| bWdtGrow = sal_False; |
| if ( nHgtGrow == 0 ) |
| bHgtGrow=sal_False; |
| if ( bWdtGrow || bHgtGrow ) |
| { |
| if ( bWdtGrow ) |
| { |
| SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust(); |
| if ( eHAdj == SDRTEXTHORZADJUST_LEFT ) |
| rR.Right()+=nWdtGrow; |
| else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT ) |
| rR.Left()-=nWdtGrow; |
| else |
| { |
| long nWdtGrow2=nWdtGrow/2; |
| rR.Left()-=nWdtGrow2; |
| rR.Right()=rR.Left()+nWdt; |
| } |
| } |
| if ( bHgtGrow ) |
| { |
| SdrTextVertAdjust eVAdj=GetTextVerticalAdjust(); |
| if ( eVAdj == SDRTEXTVERTADJUST_TOP ) |
| rR.Bottom()+=nHgtGrow; |
| else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM ) |
| rR.Top()-=nHgtGrow; |
| else |
| { |
| long nHgtGrow2=nHgtGrow/2; |
| rR.Top()-=nHgtGrow2; |
| rR.Bottom()=rR.Top()+nHgt; |
| } |
| } |
| if ( aGeo.nDrehWink ) |
| { |
| Point aD1(rR.TopLeft()); |
| aD1-=aR0.TopLeft(); |
| Point aD2(aD1); |
| RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos); |
| aD2-=aD1; |
| rR.Move(aD2.X(),aD2.Y()); |
| } |
| return sal_True; |
| } |
| } |
| } |
| return sal_False; |
| } |
| |
| Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const FASTBOOL bHgt, const FASTBOOL bWdt ) |
| { |
| Rectangle aReturnValue; |
| |
| Rectangle aOldTextRect( aRect ); // <- initial text rectangle |
| |
| Rectangle aNewTextRect( aRect ); // <- new text rectangle returned from the custom shape renderer, |
| GetTextBounds( aNewTextRect ); // it depends to the current logical shape size |
| |
| Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure |
| if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner |
| { |
| if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) ) |
| { |
| aReturnValue = aRect; |
| double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth(); |
| double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight(); |
| double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale; |
| double fLeftDiff = (double)( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale; |
| double fTopDiff = (double)( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale; |
| double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale; |
| aReturnValue.Left() += (sal_Int32)fLeftDiff; |
| aReturnValue.Right() += (sal_Int32)fRightDiff; |
| aReturnValue.Top() += (sal_Int32)fTopDiff; |
| aReturnValue.Bottom() += (sal_Int32)fBottomDiff; |
| } |
| } |
| return aReturnValue; |
| } |
| |
| FASTBOOL SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt) |
| { |
| Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt ); |
| sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect ); |
| if ( bRet ) |
| { |
| // taking care of handles that should not been changed |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| |
| aRect = aNewTextRect; |
| SetRectsDirty(); |
| SetChanged(); |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| try |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED ) |
| aIter->xInteraction->setControllerPosition( aIter->aPosition ); |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| aIter++; |
| } |
| InvalidateRenderGeometry(); |
| } |
| return bRet; |
| } |
| FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt) |
| { |
| Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt ); |
| sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect ); |
| if ( bRet ) |
| { |
| Rectangle aBoundRect0; |
| if ( pUserCall ) |
| aBoundRect0 = GetCurrentBoundRect(); |
| |
| // taking care of handles that should not been changed |
| std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) ); |
| |
| // SendRepaintBroadcast(); |
| aRect = aNewTextRect; |
| SetRectsDirty(); |
| |
| std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); |
| while ( aIter != aInteractionHandles.end() ) |
| { |
| try |
| { |
| if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED ) |
| aIter->xInteraction->setControllerPosition( aIter->aPosition ); |
| } |
| catch ( const uno::RuntimeException& ) |
| { |
| } |
| aIter++; |
| } |
| |
| InvalidateRenderGeometry(); |
| SetChanged(); |
| // SendRepaintBroadcast(); |
| BroadcastObjectChange(); |
| SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0); |
| } |
| return bRet; |
| } |
| sal_Bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl ) |
| { |
| return SdrTextObj::BegTextEdit( rOutl ); |
| } |
| void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const |
| { |
| Size aPaperMin,aPaperMax; |
| Rectangle aViewInit; |
| TakeTextAnchorRect( aViewInit ); |
| if ( aGeo.nDrehWink ) |
| { |
| Point aCenter(aViewInit.Center()); |
| aCenter-=aViewInit.TopLeft(); |
| Point aCenter0(aCenter); |
| RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos); |
| aCenter-=aCenter0; |
| aViewInit.Move(aCenter.X(),aCenter.Y()); |
| } |
| Size aAnkSiz(aViewInit.GetSize()); |
| aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert |
| Size aMaxSiz(1000000,1000000); |
| if (pModel!=NULL) { |
| Size aTmpSiz(pModel->GetMaxObjSize()); |
| if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width(); |
| if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height(); |
| } |
| SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust()); |
| SdrTextVertAdjust eVAdj(GetTextVerticalAdjust()); |
| |
| long nMinWdt = GetMinTextFrameWidth(); |
| long nMinHgt = GetMinTextFrameHeight(); |
| long nMaxWdt = GetMaxTextFrameWidth(); |
| long nMaxHgt = GetMaxTextFrameHeight(); |
| if (nMinWdt<1) nMinWdt=1; |
| if (nMinHgt<1) nMinHgt=1; |
| if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() ) |
| nMaxWdt = aMaxSiz.Width(); |
| if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() ) |
| nMaxHgt=aMaxSiz.Height(); |
| |
| if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue()) |
| { |
| if ( IsVerticalWriting() ) |
| { |
| nMaxHgt = aAnkSiz.Height(); |
| nMinHgt = nMaxHgt; |
| } |
| else |
| { |
| nMaxWdt = aAnkSiz.Width(); |
| nMinWdt = nMaxWdt; |
| } |
| } |
| aPaperMax.Width()=nMaxWdt; |
| aPaperMax.Height()=nMaxHgt; |
| |
| aPaperMin.Width()=nMinWdt; |
| aPaperMin.Height()=nMinHgt; |
| |
| if ( pViewMin ) |
| { |
| *pViewMin = aViewInit; |
| |
| long nXFree = aAnkSiz.Width() - aPaperMin.Width(); |
| if ( eHAdj == SDRTEXTHORZADJUST_LEFT ) |
| pViewMin->Right() -= nXFree; |
| else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT ) |
| pViewMin->Left() += nXFree; |
| else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); } |
| |
| long nYFree = aAnkSiz.Height() - aPaperMin.Height(); |
| if ( eVAdj == SDRTEXTVERTADJUST_TOP ) |
| pViewMin->Bottom() -= nYFree; |
| else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM ) |
| pViewMin->Top() += nYFree; |
| else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); } |
| } |
| |
| if( IsVerticalWriting() ) |
| aPaperMin.Width() = 0; |
| else |
| aPaperMin.Height() = 0; // #33102# |
| |
| if( eHAdj != SDRTEXTHORZADJUST_BLOCK ) |
| aPaperMin.Width()=0; |
| |
| // #103516# For complete ver adjust support, set paper min height to 0, here. |
| if(SDRTEXTVERTADJUST_BLOCK != eVAdj ) |
| aPaperMin.Height() = 0; |
| |
| if (pPaperMin!=NULL) *pPaperMin=aPaperMin; |
| if (pPaperMax!=NULL) *pPaperMax=aPaperMax; |
| if (pViewInit!=NULL) *pViewInit=aViewInit; |
| } |
| void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl ) |
| { |
| SdrTextObj::EndTextEdit( rOutl ); |
| InvalidateRenderGeometry(); |
| } |
| void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const |
| { |
| if ( GetTextBounds( rAnchorRect ) ) |
| { |
| Point aRotateRef( maSnapRect.Center() ); |
| rAnchorRect.Left() += GetTextLeftDistance(); |
| rAnchorRect.Top() += GetTextUpperDistance(); |
| rAnchorRect.Right() -= GetTextRightDistance(); |
| rAnchorRect.Bottom() -= GetTextLowerDistance(); |
| ImpJustifyRect( rAnchorRect ); |
| |
| if ( rAnchorRect.GetWidth() < 2 ) |
| rAnchorRect.Right() = rAnchorRect.Left() + 1; // minimal width is 2 |
| if ( rAnchorRect.GetHeight() < 2 ) |
| rAnchorRect.Bottom() = rAnchorRect.Top() + 1; // minimal height is 2 |
| if ( aGeo.nDrehWink ) |
| { |
| Point aP( rAnchorRect.TopLeft() ); |
| RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos ); |
| rAnchorRect.SetPos( aP ); |
| } |
| } |
| else |
| SdrTextObj::TakeTextAnchorRect( rAnchorRect ); |
| } |
| void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, |
| Rectangle* pAnchorRect, sal_Bool /*bLineWidth*/) const |
| { |
| Rectangle aAnkRect; // Rect innerhalb dem geankert wird |
| TakeTextAnchorRect(aAnkRect); |
| SdrTextVertAdjust eVAdj=GetTextVerticalAdjust(); |
| SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust(); |
| sal_uIntPtr nStat0=rOutliner.GetControlWord(); |
| Size aNullSize; |
| |
| rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE); |
| rOutliner.SetMinAutoPaperSize(aNullSize); |
| sal_Int32 nMaxAutoPaperWidth = 1000000; |
| sal_Int32 nMaxAutoPaperHeight= 1000000; |
| |
| long nAnkWdt=aAnkRect.GetWidth(); |
| long nAnkHgt=aAnkRect.GetHeight(); |
| |
| if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue()) |
| { |
| if ( IsVerticalWriting() ) |
| nMaxAutoPaperHeight = nAnkHgt; |
| else |
| nMaxAutoPaperWidth = nAnkWdt; |
| } |
| if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting()) |
| { |
| rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0)); |
| } |
| |
| if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()) |
| { |
| rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt)); |
| } |
| rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) ); |
| rOutliner.SetPaperSize( aNullSize ); |
| |
| // Text in den Outliner stecken - ggf. den aus dem EditOutliner |
| OutlinerParaObject* pPara= GetOutlinerParaObject(); |
| if (pEdtOutl && !bNoEditText) |
| pPara=pEdtOutl->CreateParaObject(); |
| |
| if (pPara) |
| { |
| sal_Bool bHitTest = sal_False; |
| if( pModel ) |
| bHitTest = &pModel->GetHitTestOutliner() == &rOutliner; |
| |
| const SdrTextObj* pTestObj = rOutliner.GetTextObj(); |
| if( !pTestObj || !bHitTest || pTestObj != this || |
| pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() ) |
| { |
| if( bHitTest ) |
| rOutliner.SetTextObj( this ); |
| |
| rOutliner.SetUpdateMode(sal_True); |
| rOutliner.SetText(*pPara); |
| } |
| } |
| else |
| { |
| rOutliner.SetTextObj( NULL ); |
| } |
| if (pEdtOutl && !bNoEditText && pPara) |
| delete pPara; |
| |
| rOutliner.SetUpdateMode(sal_True); |
| rOutliner.SetControlWord(nStat0); |
| |
| SdrText* pText = getActiveText(); |
| if( pText ) |
| pText->CheckPortionInfo( rOutliner ); |
| |
| Point aTextPos(aAnkRect.TopLeft()); |
| Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder? |
| |
| // #106653# |
| // For draw objects containing text correct hor/ver alignment if text is bigger |
| // than the object itself. Without that correction, the text would always be |
| // formatted to the left edge (or top edge when vertical) of the draw object. |
| |
| if( !IsTextFrame() ) |
| { |
| if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting()) |
| { |
| // #110129# |
| // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK, |
| // else the alignment is wanted. |
| if(SDRTEXTHORZADJUST_BLOCK == eHAdj) |
| { |
| eHAdj = SDRTEXTHORZADJUST_CENTER; |
| } |
| } |
| |
| if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting()) |
| { |
| // #110129# |
| // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK, |
| // else the alignment is wanted. |
| if(SDRTEXTVERTADJUST_BLOCK == eVAdj) |
| { |
| eVAdj = SDRTEXTVERTADJUST_CENTER; |
| } |
| } |
| } |
| |
| if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT) |
| { |
| long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width(); |
| if (eHAdj==SDRTEXTHORZADJUST_CENTER) |
| aTextPos.X()+=nFreeWdt/2; |
| if (eHAdj==SDRTEXTHORZADJUST_RIGHT) |
| aTextPos.X()+=nFreeWdt; |
| } |
| if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM) |
| { |
| long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height(); |
| if (eVAdj==SDRTEXTVERTADJUST_CENTER) |
| aTextPos.Y()+=nFreeHgt/2; |
| if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) |
| aTextPos.Y()+=nFreeHgt; |
| } |
| if (aGeo.nDrehWink!=0) |
| RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos); |
| |
| if (pAnchorRect) |
| *pAnchorRect=aAnkRect; |
| |
| // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt |
| rTextRect=Rectangle(aTextPos,aTextSiz); |
| } |
| |
| void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject) |
| { |
| SdrTextObj::NbcSetOutlinerParaObject( pTextObject ); |
| SetBoundRectDirty(); |
| SetRectsDirty(sal_True); |
| InvalidateRenderGeometry(); |
| } |
| |
| void SdrObjCustomShape::operator=(const SdrObject& rObj) |
| { |
| SdrTextObj::operator=( rObj ); |
| aName =((SdrObjCustomShape&)rObj).aName; |
| fObjectRotation = ((SdrObjCustomShape&)rObj).fObjectRotation; |
| InvalidateRenderGeometry(); |
| } |
| |
| |
| void SdrObjCustomShape::TakeObjNameSingul(XubString& rName) const |
| { |
| rName = ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE); |
| String aNm( GetName() ); |
| if( aNm.Len() ) |
| { |
| rName += sal_Unicode(' '); |
| rName += sal_Unicode('\''); |
| rName += aNm; |
| rName += sal_Unicode('\''); |
| } |
| } |
| |
| void SdrObjCustomShape::TakeObjNamePlural(XubString& rName) const |
| { |
| rName=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE); |
| } |
| |
| basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const |
| { |
| return GetLineGeometry( (SdrObjCustomShape*)this, sal_False ); |
| } |
| |
| basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const |
| { |
| const SdrObject* pSdrObject = GetSdrObjectFromCustomShape(); |
| if ( pSdrObject ) |
| return pSdrObject->TakeContour(); |
| return basegfx::B2DPolyPolygon(); |
| } |
| |
| SdrObject* SdrObjCustomShape::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const |
| { |
| // #i37011# |
| SdrObject* pRetval = 0L; |
| SdrObject* pRenderedCustomShape = 0L; |
| |
| if ( !mXRenderedCustomShape.is() ) |
| { |
| // force CustomShape |
| ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape(); |
| } |
| |
| if ( mXRenderedCustomShape.is() ) |
| { |
| pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape ); |
| } |
| |
| if ( pRenderedCustomShape ) |
| { |
| SdrObject* pCandidate = pRenderedCustomShape->Clone(); |
| DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)"); |
| pCandidate->SetModel(GetModel()); |
| pRetval = pCandidate->DoConvertToPolyObj(bBezier, bAddText); |
| SdrObject::Free( pCandidate ); |
| |
| if(pRetval) |
| { |
| const sal_Bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue()); |
| if(bShadow) |
| { |
| pRetval->SetMergedItem(SdrShadowItem(sal_True)); |
| } |
| } |
| |
| if(bAddText && HasText() && !IsTextPath()) |
| { |
| pRetval = ImpConvertAddText(pRetval, bBezier); |
| } |
| } |
| |
| return pRetval; |
| } |
| |
| void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr ) |
| { |
| // #i40944# |
| InvalidateRenderGeometry(); |
| SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr ); |
| } |
| |
| void SdrObjCustomShape::SetPage( SdrPage* pNewPage ) |
| { |
| SdrTextObj::SetPage( pNewPage ); |
| |
| if( pNewPage ) |
| { |
| // invalidating rectangles by SetRectsDirty is not sufficient, |
| // AdjustTextFrameWidthAndHeight() also has to be made, both |
| // actions are done by NbcSetSnapRect |
| Rectangle aTmp( aRect ); //creating temporary rectangle #i61108# |
| NbcSetSnapRect( aTmp ); |
| } |
| } |
| |
| SdrObjGeoData* SdrObjCustomShape::NewGeoData() const |
| { |
| return new SdrAShapeObjGeoData; |
| } |
| |
| void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const |
| { |
| SdrTextObj::SaveGeoData( rGeo ); |
| SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo; |
| rAGeo.fObjectRotation = fObjectRotation; |
| rAGeo.bMirroredX = IsMirroredX(); |
| rAGeo.bMirroredY = IsMirroredY(); |
| |
| const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); |
| Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) ); |
| if ( pAny ) |
| *pAny >>= rAGeo.aAdjustmentSeq; |
| } |
| |
| void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo) |
| { |
| SdrTextObj::RestGeoData( rGeo ); |
| SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo; |
| fObjectRotation = rAGeo.fObjectRotation; |
| SetMirroredX( rAGeo.bMirroredX ); |
| SetMirroredY( rAGeo.bMirroredY ); |
| |
| SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); |
| const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); |
| PropertyValue aPropVal; |
| aPropVal.Name = sAdjustmentValues; |
| aPropVal.Value <<= rAGeo.aAdjustmentSeq; |
| rGeometryItem.SetPropertyValue( aPropVal ); |
| SetMergedItem( rGeometryItem ); |
| |
| InvalidateRenderGeometry(); |
| } |
| |
| void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/) |
| { |
| // break up matrix |
| basegfx::B2DTuple aScale; |
| basegfx::B2DTuple aTranslate; |
| double fRotate, fShearX; |
| rMatrix.decompose(aScale, aTranslate, fRotate, fShearX); |
| |
| // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings |
| // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly |
| const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0)); |
| const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0)); |
| |
| if(bMirrorX && bMirrorY) |
| { |
| aScale.setX(fabs(aScale.getX())); |
| aScale.setY(fabs(aScale.getY())); |
| fRotate = fmod(fRotate + F_PI, F_2PI); |
| } |
| else if(bMirrorX || bMirrorY) |
| { |
| basegfx::B2DHomMatrix aNew; |
| |
| // create pre-multiplied matrix without mirroring |
| aNew.translate(-0.5, -0.5); |
| aNew.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0); |
| aNew.translate(0.5, 0.5); |
| aNew = rMatrix * aNew; |
| |
| // decompose to get corrected, mirror-free values |
| aNew.decompose(aScale, aTranslate, fRotate, fShearX); |
| |
| // apply mirroring to CustomShapeGeometry |
| if((bool)IsMirroredX() != bMirrorX) |
| { |
| SetMirroredX(bMirrorX); |
| } |
| |
| if((bool)IsMirroredY() != bMirrorY) |
| { |
| SetMirroredY(bMirrorY); |
| } |
| } |
| |
| // reset object shear and rotations |
| aGeo.nDrehWink = 0; |
| aGeo.RecalcSinCos(); |
| aGeo.nShearWink = 0; |
| aGeo.RecalcTan(); |
| |
| // force metric to pool metric |
| const SfxMapUnit eMapUnit(GetObjectMapUnit()); |
| if(eMapUnit != SFX_MAPUNIT_100TH_MM) |
| { |
| switch(eMapUnit) |
| { |
| case SFX_MAPUNIT_TWIP : |
| { |
| // position |
| aTranslate.setX(ImplMMToTwips(aTranslate.getX())); |
| aTranslate.setY(ImplMMToTwips(aTranslate.getY())); |
| |
| // size |
| aScale.setX(ImplMMToTwips(aScale.getX())); |
| aScale.setY(ImplMMToTwips(aScale.getY())); |
| |
| break; |
| } |
| default: |
| { |
| DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!"); |
| } |
| } |
| } |
| |
| // if anchor is used, make position relative to it |
| if( pModel && pModel->IsWriter() ) |
| { |
| if(GetAnchorPos().X() || GetAnchorPos().Y()) |
| { |
| aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y()); |
| } |
| } |
| |
| // build and set BaseRect (use scale) |
| Point aPoint = Point(); |
| Size aSize(FRound(aScale.getX()), FRound(aScale.getY())); |
| Rectangle aBaseRect(aPoint, aSize); |
| SetSnapRect(aBaseRect); |
| |
| // shear? |
| if(!basegfx::fTools::equalZero(fShearX)) |
| { |
| GeoStat aGeoStat; |
| // #123181# The fix for #121932# here was wrong, the trunk version does not correct the |
| // mirrored shear values, neither at the object level, nor on the API or XML level. Taking |
| // back the mirroring of the shear angle |
| aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0); |
| aGeoStat.RecalcTan(); |
| Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False); |
| } |
| |
| // rotation? |
| if(!basegfx::fTools::equalZero(fRotate)) |
| { |
| GeoStat aGeoStat; |
| |
| // #i78696# |
| // fRotate is mathematically correct, but aGeoStat.nDrehWink is |
| // mirrored -> mirror value here |
| aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000)); |
| aGeoStat.RecalcSinCos(); |
| Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos); |
| } |
| |
| // translate? |
| if(!aTranslate.equalZero()) |
| { |
| Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY()))); |
| } |
| } |
| |
| // taking fObjectRotation instead of aGeo.nWink |
| sal_Bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const |
| { |
| // get turn and shear |
| // double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180; |
| double fRotate = fObjectRotation * F_PI180; |
| double fShearX = (aGeo.nShearWink / 100.0) * F_PI180; |
| |
| // get aRect, this is the unrotated snaprect |
| Rectangle aRectangle(aRect); |
| |
| sal_Bool bMirroredX = IsMirroredX(); |
| sal_Bool bMirroredY = IsMirroredY(); |
| if ( bMirroredX || bMirroredY ) |
| { // we have to retrieve the unmirrored rect |
| |
| GeoStat aNewGeo( aGeo ); |
| |
| if ( bMirroredX ) |
| { |
| Polygon aPol( Rect2Poly( aRect, aNewGeo ) ); |
| Rectangle aBoundRect( aPol.GetBoundRect() ); |
| |
| Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() ); |
| Point aRef2( aRef1.X(), aRef1.Y() + 1000 ); |
| sal_uInt16 i; |
| sal_uInt16 nPntAnz=aPol.GetSize(); |
| for (i=0; i<nPntAnz; i++) |
| { |
| MirrorPoint(aPol[i],aRef1,aRef2); |
| } |
| // Polygon wenden und etwas schieben |
| Polygon aPol0(aPol); |
| aPol[0]=aPol0[1]; |
| aPol[1]=aPol0[0]; |
| aPol[2]=aPol0[3]; |
| aPol[3]=aPol0[2]; |
| aPol[4]=aPol0[1]; |
| Poly2Rect(aPol,aRectangle,aNewGeo); |
| } |
| if ( bMirroredY ) |
| { |
| Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) ); |
| Rectangle aBoundRect( aPol.GetBoundRect() ); |
| |
| Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 ); |
| Point aRef2( aRef1.X() + 1000, aRef1.Y() ); |
| sal_uInt16 i; |
| sal_uInt16 nPntAnz=aPol.GetSize(); |
| for (i=0; i<nPntAnz; i++) |
| { |
| MirrorPoint(aPol[i],aRef1,aRef2); |
| } |
| // Polygon wenden und etwas schieben |
| Polygon aPol0(aPol); |
| aPol[0]=aPol0[1]; // This was WRONG for vertical (!) |
| aPol[1]=aPol0[0]; // #121932# Despite my own coment above |
| aPol[2]=aPol0[3]; // it was *not* wrong even when the reordering |
| aPol[3]=aPol0[2]; // *seems* to be specific for X-Mirrorings. Oh |
| aPol[4]=aPol0[1]; // will I be happy when this old stuff is |gone| with aw080 (!) |
| Poly2Rect(aPol,aRectangle,aNewGeo); |
| } |
| } |
| |
| // fill other values |
| basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight()); |
| basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top()); |
| |
| // position maybe relative to anchorpos, convert |
| if( pModel && pModel->IsWriter() ) |
| { |
| if(GetAnchorPos().X() || GetAnchorPos().Y()) |
| { |
| aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y()); |
| } |
| } |
| |
| // force MapUnit to 100th mm |
| const SfxMapUnit eMapUnit(GetObjectMapUnit()); |
| if(eMapUnit != SFX_MAPUNIT_100TH_MM) |
| { |
| switch(eMapUnit) |
| { |
| case SFX_MAPUNIT_TWIP : |
| { |
| // postion |
| aTranslate.setX(ImplTwipsToMM(aTranslate.getX())); |
| aTranslate.setY(ImplTwipsToMM(aTranslate.getY())); |
| |
| // size |
| aScale.setX(ImplTwipsToMM(aScale.getX())); |
| aScale.setY(ImplTwipsToMM(aScale.getY())); |
| |
| break; |
| } |
| default: |
| { |
| DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!"); |
| } |
| } |
| } |
| |
| // build matrix |
| rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( |
| aScale, |
| basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX), |
| basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate, |
| aTranslate); |
| |
| return sal_False; |
| } |
| |
| sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact() |
| { |
| return new sdr::contact::ViewContactOfSdrObjCustomShape(*this); |
| } |
| |
| // #i33136# |
| bool SdrObjCustomShape::doConstructOrthogonal(const ::rtl::OUString& rName) |
| { |
| bool bRetval(false); |
| static ::rtl::OUString Imps_sNameASOrtho_quadrat( RTL_CONSTASCII_USTRINGPARAM( "quadrat" ) ); |
| static ::rtl::OUString Imps_sNameASOrtho_round_quadrat( RTL_CONSTASCII_USTRINGPARAM( "round-quadrat" ) ); |
| static ::rtl::OUString Imps_sNameASOrtho_circle( RTL_CONSTASCII_USTRINGPARAM( "circle" ) ); |
| static ::rtl::OUString Imps_sNameASOrtho_circle_pie( RTL_CONSTASCII_USTRINGPARAM( "circle-pie" ) ); |
| static ::rtl::OUString Imps_sNameASOrtho_ring( RTL_CONSTASCII_USTRINGPARAM( "ring" ) ); |
| |
| if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName)) |
| { |
| bRetval = true; |
| } |
| else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName)) |
| { |
| bRetval = true; |
| } |
| else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName)) |
| { |
| bRetval = true; |
| } |
| else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName)) |
| { |
| bRetval = true; |
| } |
| else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName)) |
| { |
| bRetval = true; |
| } |
| |
| return bRetval; |
| } |
| |
| // #i37011# centralize throw-away of render geometry |
| void SdrObjCustomShape::InvalidateRenderGeometry() |
| { |
| mXRenderedCustomShape = 0L; |
| SdrObject::Free( mpLastShadowGeometry ); |
| mpLastShadowGeometry = 0L; |
| } |
| |
| //IAccessibility2 Implementation 2009----- |
| ::rtl::OUString SdrObjCustomShape::GetCustomShapeName() |
| { |
| rtl::OUString sShapeName; |
| rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)( *this ).GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() ); |
| if ( !aEngine.getLength() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) |
| { |
| rtl::OUString sShapeType; |
| const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); |
| SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)( *this ).GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); |
| Any* pAny = rGeometryItem.GetPropertyValueByName( sType ); |
| if ( pAny && ( *pAny >>= sShapeType ) ) |
| sShapeName = EnhancedCustomShapeTypeNames::GetAccName( sShapeType ); |
| } |
| return sShapeName; |
| } |
| //-----IAccessibility2 Implementation 2009 |
| // eof |