summaryrefslogtreecommitdiff
path: root/svx/source/customshapes/EnhancedCustomShape2d.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/customshapes/EnhancedCustomShape2d.cxx')
-rw-r--r--svx/source/customshapes/EnhancedCustomShape2d.cxx2187
1 files changed, 2187 insertions, 0 deletions
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
new file mode 100644
index 000000000000..200aa1e6b35e
--- /dev/null
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -0,0 +1,2187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include "EnhancedCustomShape2d.hxx"
+#include "EnhancedCustomShapeGeometry.hxx"
+#include "EnhancedCustomShapeTypeNames.hxx"
+#include <svx/svdoashp.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/sdasaitm.hxx>
+#include <svx/svdmodel.hxx>
+#include <rtl/crc.h>
+#include <rtl/math.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xbitmap.hxx>
+#include <svx/xhatch.hxx>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <boost/shared_ptr.hpp>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+// #i76201#
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#include <math.h>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand;
+
+void EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nValue )
+{
+ sal_uInt32 nDat = (sal_uInt32)nValue;
+ sal_Int32 nNewValue = nValue;
+
+ // check if this is a special point
+ if ( ( nDat >> 16 ) == 0x8000 )
+ {
+ nNewValue = (sal_uInt16)nDat;
+ rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ else
+ rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
+ rParameter.Value <<= nNewValue;
+}
+
+rtl::OUString EnhancedCustomShape2d::GetEquation( const sal_uInt16 nFlags, sal_Int16 nP1, sal_Int16 nP2, sal_Int16 nP3 )
+{
+ rtl::OUString aEquation;
+ sal_Bool b1Special = ( nFlags & 0x2000 ) != 0;
+ sal_Bool b2Special = ( nFlags & 0x4000 ) != 0;
+ sal_Bool b3Special = ( nFlags & 0x8000 ) != 0;
+ switch( nFlags & 0xff )
+ {
+ case 0 :
+ case 14 :
+ {
+ sal_Int32 nOptimize = 0;
+ if ( nP1 )
+ nOptimize |= 1;
+ if ( nP2 )
+ nOptimize |= 2;
+ if ( b1Special )
+ nOptimize |= 4;
+ if ( b2Special )
+ nOptimize |= 8;
+ switch( nOptimize )
+ {
+ case 0 :
+ break;
+ case 1 :
+ case 4 :
+ case 5 :
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ break;
+ case 2 :
+ case 8 :
+ case 10:
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ break;
+ default :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( (sal_Unicode)'+' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ }
+ break;
+ }
+ if ( b3Special || nP3 )
+ {
+ aEquation += rtl::OUString( (sal_Unicode)'-' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ }
+ }
+ break;
+ case 1 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ if ( b2Special || ( nP2 != 1 ) )
+ {
+ aEquation += rtl::OUString( (sal_Unicode)'*' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ }
+ if ( b3Special || ( ( nP3 != 1 ) && ( nP3 != 0 ) ) )
+ {
+ aEquation += rtl::OUString( (sal_Unicode)'/' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ }
+ }
+ break;
+ case 2 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/2" ) );
+ }
+ break;
+ case 3 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "abs(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ }
+ break;
+ case 4 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "min(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ }
+ break;
+ case 5 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "max(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ }
+ break;
+ case 6 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "if(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( (sal_Unicode)',' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( (sal_Unicode)',' );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( (sal_Unicode)')' );
+ }
+ break;
+ case 7 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( (sal_Unicode)')' );
+ }
+ break;
+ case 8 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "atan2(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/(pi/180)" ) );
+ }
+ break;
+ case 9 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sin(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) );
+ }
+ break;
+ case 10 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*cos(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) );
+ }
+ break;
+ case 11 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "cos(atan2(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
+ }
+ break;
+ case 12 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sin(atan2(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
+ }
+ break;
+ case 13 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ }
+ break;
+ case 15 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sqrt(1-(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
+ }
+ break;
+ case 16 :
+ {
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*tan(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
+ }
+ break;
+ case 0x80 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( (sal_Unicode)')' );
+ }
+ break;
+ case 0x81 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(cos(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)+sin(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) );
+ }
+ break;
+ case 0x82 :
+ {
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-(sin(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)-cos(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
+ EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
+ aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) );
+ }
+ break;
+ }
+ return aEquation;
+}
+
+void EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( rtl::OUString& rParameter, const sal_Int16 nPara, const sal_Bool bIsSpecialValue )
+{
+ if ( bIsSpecialValue )
+ {
+ if ( nPara & 0x400 )
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "?" ) );
+ rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara & 0xff ) );
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
+ }
+ else
+ {
+ switch( nPara )
+ {
+ case DFF_Prop_adjustValue :
+ case DFF_Prop_adjust2Value :
+ case DFF_Prop_adjust3Value :
+ case DFF_Prop_adjust4Value :
+ case DFF_Prop_adjust5Value :
+ case DFF_Prop_adjust6Value :
+ case DFF_Prop_adjust7Value :
+ case DFF_Prop_adjust8Value :
+ case DFF_Prop_adjust9Value :
+ case DFF_Prop_adjust10Value :
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "$" ) );
+ rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara - DFF_Prop_adjustValue ) );
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
+ }
+ break;
+ case DFF_Prop_geoLeft :
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "left" ) );
+ }
+ break;
+ case DFF_Prop_geoTop :
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "top" ) );
+ }
+ break;
+ case DFF_Prop_geoRight :
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "right" ) );
+ }
+ break;
+ case DFF_Prop_geoBottom :
+ {
+ rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "bottom" ) );
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara ) );
+ }
+}
+
+void EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nPara, const sal_Bool bIsSpecialValue, sal_Bool bHorz )
+{
+ sal_Int32 nValue = 0;
+ if ( bIsSpecialValue )
+ {
+ if ( ( nPara >= 0x100 ) && ( nPara <= 0x107 ) )
+ {
+ nValue = nPara & 0xff;
+ rParameter.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
+ }
+ else if ( ( nPara >= 3 ) && ( nPara <= 0x82 ) )
+ {
+ nValue = nPara - 3;
+ rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
+ }
+ else if ( nPara == 0 )
+ {
+ nValue = 0;
+ if ( bHorz )
+ rParameter.Type = EnhancedCustomShapeParameterType::LEFT;
+ else
+ rParameter.Type = EnhancedCustomShapeParameterType::TOP;
+ }
+ else if ( nPara == 1 )
+ {
+ nValue = 0;
+ if ( bHorz )
+ rParameter.Type = EnhancedCustomShapeParameterType::RIGHT;
+ else
+ rParameter.Type = EnhancedCustomShapeParameterType::BOTTOM;
+ }
+ else if ( nPara == 2 ) // means to be centered, but should not be
+ { // used in our implementation
+ nValue = 5600;
+ rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ else
+ {
+ nValue = nPara;
+ rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ }
+ else
+ {
+ nValue = nPara;
+ rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
+ }
+ rParameter.Value <<= nValue;
+}
+
+sal_Bool EnhancedCustomShape2d::ConvertSequenceToEnhancedCustomShape2dHandle(
+ const com::sun::star::beans::PropertyValues& rHandleProperties,
+ EnhancedCustomShape2d::Handle& rDestinationHandle )
+{
+ sal_Bool bRetValue = sal_False;
+ sal_uInt32 i, nProperties = rHandleProperties.getLength();
+ if ( nProperties )
+ {
+ rDestinationHandle.nFlags = 0;
+ for ( i = 0; i < nProperties; i++ )
+ {
+ const com::sun::star::beans::PropertyValue& rPropVal = rHandleProperties[ i ];
+
+ const rtl::OUString sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) );
+ const rtl::OUString sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) );
+ const rtl::OUString sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) );
+ const rtl::OUString sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) );
+ const rtl::OUString sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) );
+// const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) );
+ const rtl::OUString sRefX ( RTL_CONSTASCII_USTRINGPARAM( "RefX" ) );
+ const rtl::OUString sRefY ( RTL_CONSTASCII_USTRINGPARAM( "RefY" ) );
+ const rtl::OUString sRefAngle ( RTL_CONSTASCII_USTRINGPARAM( "RefAngle" ) );
+ const rtl::OUString sRefR ( RTL_CONSTASCII_USTRINGPARAM( "RefR" ) );
+ const rtl::OUString sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) );
+ const rtl::OUString sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) );
+ const rtl::OUString sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) );
+ const rtl::OUString sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) );
+ const rtl::OUString sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) );
+ const rtl::OUString sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) );
+
+ if ( rPropVal.Name.equals( sPosition ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aPosition )
+ bRetValue = sal_True;
+ }
+ else if ( rPropVal.Name.equals( sMirroredX ) )
+ {
+ sal_Bool bMirroredX = sal_Bool();
+ if ( rPropVal.Value >>= bMirroredX )
+ {
+ if ( bMirroredX )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_X;
+ }
+ }
+ else if ( rPropVal.Name.equals( sMirroredY ) )
+ {
+ sal_Bool bMirroredY = sal_Bool();
+ if ( rPropVal.Value >>= bMirroredY )
+ {
+ if ( bMirroredY )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_Y;
+ }
+ }
+ else if ( rPropVal.Name.equals( sSwitched ) )
+ {
+ sal_Bool bSwitched = sal_Bool();
+ if ( rPropVal.Value >>= bSwitched )
+ {
+ if ( bSwitched )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_SWITCHED;
+ }
+ }
+ else if ( rPropVal.Name.equals( sPolar ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aPolar )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_POLAR;
+ }
+/* seems not to be used.
+ else if ( rPropVal.Name.equals( sMap ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap;
+ if ( rPropVal.Value >>= aMap )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) )
+ rDestinationHandle.Flags |= 0x800;
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) )
+ rDestinationHandle.Flags |= 0x1000;
+ rDestinationHandle.Flags |= 0x10;
+ }
+ }
+*/
+ else if ( rPropVal.Name.equals( sRefX ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.nRefX )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_REFX;
+ }
+ else if ( rPropVal.Name.equals( sRefY ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.nRefY )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_REFY;
+ }
+ else if ( rPropVal.Name.equals( sRefAngle ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.nRefAngle )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_REFANGLE;
+ }
+ else if ( rPropVal.Name.equals( sRefR ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.nRefR )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_REFR;
+ }
+ else if ( rPropVal.Name.equals( sRadiusRangeMinimum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMinimum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MINIMUM;
+ }
+ else if ( rPropVal.Name.equals( sRadiusRangeMaximum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMaximum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM;
+ }
+ else if ( rPropVal.Name.equals( sRangeXMinimum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aXRangeMinimum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MINIMUM;
+ }
+ else if ( rPropVal.Name.equals( sRangeXMaximum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aXRangeMaximum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MAXIMUM;
+ }
+ else if ( rPropVal.Name.equals( sRangeYMinimum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aYRangeMinimum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MINIMUM;
+ }
+ else if ( rPropVal.Name.equals( sRangeYMaximum ) )
+ {
+ if ( rPropVal.Value >>= rDestinationHandle.aYRangeMaximum )
+ rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MAXIMUM;
+ }
+ }
+ }
+ return bRetValue;
+}
+
+const sal_Int32* EnhancedCustomShape2d::ApplyShapeAttributes( const SdrCustomShapeGeometryItem& rGeometryItem )
+{
+ const sal_Int32* pDefData = NULL;
+ const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
+ if ( pDefCustomShape )
+ pDefData = pDefCustomShape->pDefData;
+
+ //////////////////////
+ // AdjustmentValues //
+ //////////////////////
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ const Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sAdjustmentValues );
+ if ( pAny )
+ *pAny >>= seqAdjustmentValues;
+
+ ///////////////
+ // Coordsize //
+ ///////////////
+ const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
+ const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sViewBox );
+ com::sun::star::awt::Rectangle aViewBox;
+ if ( pViewBox && (*pViewBox >>= aViewBox ) )
+ {
+ nCoordLeft = aViewBox.X;
+ nCoordTop = aViewBox.Y;
+ nCoordWidth = labs( aViewBox.Width );
+ nCoordHeight= labs( aViewBox.Height);
+ }
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+
+ //////////////////////
+ // Path/Coordinates //
+ //////////////////////
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
+ if ( pAny )
+ *pAny >>= seqCoordinates;
+
+ /////////////////////
+ // Path/GluePoints //
+ /////////////////////
+ const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
+ if ( pAny )
+ *pAny >>= seqGluePoints;
+
+ ///////////////////
+ // Path/Segments //
+ ///////////////////
+ const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sSegments );
+ if ( pAny )
+ *pAny >>= seqSegments;
+
+ ///////////////////
+ // Path/StretchX //
+ ///////////////////
+ const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sStretchX );
+ if ( pAny )
+ {
+ sal_Int32 nStretchX = 0;
+ if ( *pAny >>= nStretchX )
+ nXRef = nStretchX;
+ }
+
+ ///////////////////
+ // Path/StretchY //
+ ///////////////////
+ const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sStretchY );
+ if ( pAny )
+ {
+ sal_Int32 nStretchY = 0;
+ if ( *pAny >>= nStretchY )
+ nYRef = nStretchY;
+ }
+
+ /////////////////////
+ // Path/TextFrames //
+ /////////////////////
+ const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
+ if ( pAny )
+ *pAny >>= seqTextFrames;
+
+ ///////////////
+ // Equations //
+ ///////////////
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sEquations );
+ if ( pAny )
+ *pAny >>= seqEquations;
+
+ /////////////
+ // Handles //
+ /////////////
+ const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sHandles );
+ if ( pAny )
+ *pAny >>= seqHandles;
+
+ return pDefData;
+}
+
+EnhancedCustomShape2d::~EnhancedCustomShape2d()
+{
+}
+
+EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
+ SfxItemSet ( pAObj->GetMergedItemSet() ),
+ pCustomShapeObj ( pAObj ),
+ eSpType ( mso_sptNil ),
+ nCoordLeft ( 0 ),
+ nCoordTop ( 0 ),
+ nCoordWidth ( 21600 ),
+ nCoordHeight ( 21600 ),
+ nXRef ( 0x80000000 ),
+ nYRef ( 0x80000000 ),
+ nFlags ( 0 ),
+ nColorData ( 0 ),
+ bTextFlow ( sal_False ),
+ bFilled ( ((const XFillStyleItem&)pAObj->GetMergedItem( XATTR_FILLSTYLE )).GetValue() != XFILL_NONE ),
+ bStroked ( ((const XLineStyleItem&)pAObj->GetMergedItem( XATTR_LINESTYLE )).GetValue() != XLINE_NONE ),
+ bFlipH ( sal_False ),
+ bFlipV ( sal_False )
+{
+ // bTextFlow needs to be set before clearing the TextDirection Item
+
+ ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
+
+ // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any
+ // of the constucted helper SdrObjects. This would lead to problems since the shadow
+ // of one helper object would fall on one helper object behind it (e.g. with the
+ // eyes of the smiley shape). This is not wanted; instead a single shadow 'behind'
+ // the AutoShape visualisation is wanted. This is done with primitive functionailty
+ // now in SdrCustomShapePrimitive2D::create2DDecomposition, but only for 2D objects
+ // (see there and in EnhancedCustomShape3d::Create3DObject to read more).
+ // This exception may be removed later when AutoShapes will create primitives directly.
+ // So, currently remove the ShadowAttribute from the ItemSet to not apply it to any
+ // 2D helper shape.
+ ClearItem(SDRATTR_SHADOW);
+
+ Point aP( pCustomShapeObj->GetSnapRect().Center() );
+ Size aS( pCustomShapeObj->GetLogicRect().GetSize() );
+ aP.X() -= aS.Width() / 2;
+ aP.Y() -= aS.Height() / 2;
+ aLogicRect = Rectangle( aP, aS );
+
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+
+ rtl::OUString sShapeType;
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny )
+ *pAny >>= sShapeType;
+ eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+
+ pAny = rGeometryItem.GetPropertyValueByName( sMirroredX );
+ if ( pAny )
+ *pAny >>= bFlipH;
+ pAny = rGeometryItem.GetPropertyValueByName( sMirroredY );
+ if ( pAny )
+ *pAny >>= bFlipV;
+
+ if ( pCustomShapeObj->ISA( SdrObjCustomShape ) ) // should always be a SdrObjCustomShape, but you don't know
+ nRotateAngle = (sal_Int32)(((SdrObjCustomShape*)pCustomShapeObj)->GetObjectRotation() * 100.0);
+ else
+ nRotateAngle = pCustomShapeObj->GetRotateAngle();
+
+ /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem );
+ switch( eSpType )
+ {
+ case mso_sptCan : nColorData = 0x20400000; break;
+ case mso_sptCube : nColorData = 0x302e0000; break;
+ case mso_sptActionButtonBlank : nColorData = 0x502ce400; break;
+ case mso_sptActionButtonHome : nColorData = 0x702ce4ce; break;
+ case mso_sptActionButtonHelp : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonInformation : nColorData = 0x702ce4c5; break;
+ case mso_sptActionButtonBackPrevious : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonForwardNext : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonBeginning : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonEnd : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonReturn : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonDocument : nColorData = 0x702ce4ec; break;
+ case mso_sptActionButtonSound : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonMovie : nColorData = 0x602ce4c0; break;
+ case mso_sptBevel : nColorData = 0x502ce400; break;
+ case mso_sptFoldedCorner : nColorData = 0x20e00000; break;
+ case mso_sptSmileyFace : nColorData = 0x20e00000; break;
+ case mso_sptNil :
+ {
+ if( sShapeType.getLength() > 4 &&
+ sShapeType.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "col-" )))
+ {
+ nColorData = sShapeType.copy( 4 ).toInt32( 16 );
+ }
+ }
+ break;
+ case mso_sptCurvedLeftArrow :
+ case mso_sptCurvedRightArrow :
+ case mso_sptCurvedUpArrow :
+ case mso_sptCurvedDownArrow : nColorData = 0x2d000000; break;
+ case mso_sptRibbon2 : nColorData = 0x30ee0000; break;
+ case mso_sptRibbon : nColorData = 0x30ee0000; break;
+
+ case mso_sptEllipseRibbon2 : nColorData = 0x30ee0000; break;
+ case mso_sptEllipseRibbon : nColorData = 0x30ee0000; break;
+
+ case mso_sptVerticalScroll : nColorData = 0x30ee0000; break;
+ case mso_sptHorizontalScroll : nColorData = 0x30ee0000; break;
+ default:
+ break;
+ }
+ fXScale = nCoordWidth == 0 ? 0.0 : (double)aLogicRect.GetWidth() / (double)nCoordWidth;
+ fYScale = nCoordHeight == 0 ? 0.0 : (double)aLogicRect.GetHeight() / (double)nCoordHeight;
+ if ( (sal_uInt32)nXRef != 0x80000000 && aLogicRect.GetHeight() )
+ {
+ fXRatio = (double)aLogicRect.GetWidth() / (double)aLogicRect.GetHeight();
+ if ( fXRatio > 1 )
+ fXScale /= fXRatio;
+ else
+ fXRatio = 1.0;
+ }
+ else
+ fXRatio = 1.0;
+ if ( (sal_uInt32)nYRef != 0x80000000 && aLogicRect.GetWidth() )
+ {
+ fYRatio = (double)aLogicRect.GetHeight() / (double)aLogicRect.GetWidth();
+ if ( fYRatio > 1 )
+ fYScale /= fYRatio;
+ else
+ fYRatio = 1.0;
+ }
+ else
+ fYRatio = 1.0;
+
+ sal_Int32 i, nLength = seqEquations.getLength();
+
+
+ if ( nLength )
+ {
+ vNodesSharedPtr.resize( nLength );
+ for ( i = 0; i < seqEquations.getLength(); i++ )
+ {
+ try
+ {
+ vNodesSharedPtr[ i ] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations[ i ], *this );
+ }
+ catch ( EnhancedCustomShape::ParseError& )
+ {
+ }
+ }
+ }
+}
+double EnhancedCustomShape2d::GetEnumFunc( const EnumFunc eFunc ) const
+{
+ double fRet = 0.0;
+ switch( eFunc )
+ {
+ case ENUM_FUNC_PI : fRet = F_PI; break;
+ case ENUM_FUNC_LEFT : fRet = 0.0; break;
+ case ENUM_FUNC_TOP : fRet = 0.0; break;
+ case ENUM_FUNC_RIGHT : fRet = (double)nCoordWidth * fXRatio; break;
+ case ENUM_FUNC_BOTTOM : fRet = (double)nCoordHeight * fYRatio; break;
+ case ENUM_FUNC_XSTRETCH : fRet = nXRef; break;
+ case ENUM_FUNC_YSTRETCH : fRet = nYRef; break;
+ case ENUM_FUNC_HASSTROKE : fRet = bStroked ? 1.0 : 0.0; break;
+ case ENUM_FUNC_HASFILL : fRet = bFilled ? 1.0 : 0.0; break;
+ case ENUM_FUNC_WIDTH : fRet = nCoordWidth; break;
+ case ENUM_FUNC_HEIGHT : fRet = nCoordHeight; break;
+ case ENUM_FUNC_LOGWIDTH : fRet = aLogicRect.GetWidth(); break;
+ case ENUM_FUNC_LOGHEIGHT : fRet = aLogicRect.GetHeight(); break;
+ }
+ return fRet;
+}
+double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex ) const
+{
+ double fNumber = 0.0;
+ if ( nIndex < seqAdjustmentValues.getLength() )
+ {
+ if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
+ seqAdjustmentValues[ nIndex ].Value >>= fNumber;
+ else
+ {
+ sal_Int32 nNumber = 0;
+ seqAdjustmentValues[ nIndex ].Value >>= nNumber;
+ fNumber = (double)nNumber;
+ }
+ }
+ return fNumber;
+}
+double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex ) const
+{
+ double fNumber = 0.0;
+ if ( nIndex < (sal_Int32)vNodesSharedPtr.size() )
+ {
+ if ( vNodesSharedPtr[ nIndex ].get() )
+ try
+ {
+ fNumber = (*vNodesSharedPtr[ nIndex ])();
+ if ( !rtl::math::isFinite( fNumber ) )
+ fNumber = 0.0;
+ }
+ catch ( ... )
+ {
+ /* sal_Bool bUps = sal_True; */
+ }
+ }
+ return fNumber;
+}
+sal_Int32 EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex, const sal_Int32 nDefault ) const
+{
+ sal_Int32 nNumber = nDefault;
+ if ( nIndex < seqAdjustmentValues.getLength() )
+ {
+ if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
+ {
+ double fNumber = 0;
+ seqAdjustmentValues[ nIndex ].Value >>= fNumber;
+ nNumber = (sal_Int32)fNumber;
+ }
+ else
+ seqAdjustmentValues[ nIndex ].Value >>= nNumber;
+ }
+ return nNumber;
+}
+sal_Bool EnhancedCustomShape2d::SetAdjustValueAsDouble( const double& rValue, const sal_Int32 nIndex )
+{
+ sal_Bool bRetValue = sal_False;
+ if ( nIndex < seqAdjustmentValues.getLength() )
+ {
+ // updating our local adjustment sequence
+ seqAdjustmentValues[ nIndex ].Value <<= rValue;
+ seqAdjustmentValues[ nIndex ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ bRetValue = sal_True;
+ }
+ return bRetValue;
+}
+
+Point EnhancedCustomShape2d::GetPoint( const com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPair,
+ const sal_Bool bScale, const sal_Bool bReplaceGeoSize ) const
+{
+ Point aRetValue;
+ sal_Bool bExchange = ( nFlags & DFF_CUSTOMSHAPE_EXCH ) != 0; // x <-> y
+ sal_uInt32 nPass = 0;
+ do
+ {
+ sal_uInt32 nIndex = nPass;
+
+ if ( bExchange )
+ nIndex ^= 1;
+
+ double fVal;
+ const EnhancedCustomShapeParameter& rParameter = nIndex ? rPair.Second : rPair.First;
+ if ( nPass ) // height
+ {
+ GetParameter( fVal, rParameter, sal_False, bReplaceGeoSize );
+ fVal -= nCoordTop;
+ if ( bScale )
+ {
+ fVal *= fYScale;
+
+ if ( nFlags & DFF_CUSTOMSHAPE_FLIP_V )
+ fVal = aLogicRect.GetHeight() - fVal;
+ }
+ aRetValue.Y() = (sal_Int32)fVal;
+ }
+ else // width
+ {
+ GetParameter( fVal, rParameter, bReplaceGeoSize, sal_False );
+ fVal -= nCoordLeft;
+ if ( bScale )
+ {
+ fVal *= fXScale;
+
+ if ( nFlags & DFF_CUSTOMSHAPE_FLIP_H )
+ fVal = aLogicRect.GetWidth() - fVal;
+ }
+ aRetValue.X() = (sal_Int32)fVal;
+ }
+ }
+ while ( ++nPass < 2 );
+ return aRetValue;
+}
+
+sal_Bool EnhancedCustomShape2d::GetParameter( double& rRetValue, const EnhancedCustomShapeParameter& rParameter,
+ const sal_Bool bReplaceGeoWidth, const sal_Bool bReplaceGeoHeight ) const
+{
+ rRetValue = 0.0;
+ sal_Bool bRetValue = sal_False;
+ switch ( rParameter.Type )
+ {
+ case EnhancedCustomShapeParameterType::ADJUSTMENT :
+ {
+ sal_Int32 nAdjustmentIndex = 0;
+ if ( rParameter.Value >>= nAdjustmentIndex )
+ {
+ rRetValue = GetAdjustValueAsDouble( nAdjustmentIndex );
+ bRetValue = sal_True;
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::EQUATION :
+ {
+ sal_Int32 nEquationIndex = 0;
+ if ( rParameter.Value >>= nEquationIndex )
+ {
+ rRetValue = GetEquationValueAsDouble( nEquationIndex );
+ bRetValue = sal_True;
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::NORMAL :
+ {
+ if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
+ {
+ double fValue;
+ if ( rParameter.Value >>= fValue )
+ {
+ rRetValue = fValue;
+ bRetValue = sal_True;
+ }
+ }
+ else
+ {
+ sal_Int32 nValue = 0;
+ if ( rParameter.Value >>= nValue )
+ {
+ rRetValue = nValue;
+ bRetValue = sal_True;
+ if ( bReplaceGeoWidth && ( nValue == nCoordWidth ) )
+ rRetValue *= fXRatio;
+ else if ( bReplaceGeoHeight && ( nValue == nCoordHeight ) )
+ rRetValue *= fYRatio;
+ }
+ }
+ }
+ break;
+ case EnhancedCustomShapeParameterType::LEFT :
+ {
+ rRetValue = 0.0;
+ bRetValue = sal_True;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::TOP :
+ {
+ rRetValue = 0.0;
+ bRetValue = sal_True;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::RIGHT :
+ {
+ rRetValue = nCoordWidth;
+ bRetValue = sal_True;
+ }
+ break;
+ case EnhancedCustomShapeParameterType::BOTTOM :
+ {
+ rRetValue = nCoordHeight;
+ bRetValue = sal_True;
+ }
+ break;
+ }
+ return bRetValue;
+}
+
+// nLumDat 28-31 = number of luminance entries in nLumDat
+// nLumDat 27-24 = nLumDatEntry 0
+// nLumDat 23-20 = nLumDatEntry 1 ...
+// each 4bit entry is to be interpreted as a 10 percent signed luminance changing
+sal_Int32 EnhancedCustomShape2d::GetLuminanceChange( sal_uInt32 nIndex ) const
+{
+ const sal_uInt32 nCount = nColorData >> 28;
+ if ( !nCount )
+ return 0;
+
+ if ( nIndex >= nCount )
+ nIndex = nCount - 1;
+
+ const sal_Int32 nLumDat = nColorData << ( ( 1 + nIndex ) << 2 );
+ return ( nLumDat >> 28 ) * 10;
+}
+
+Color EnhancedCustomShape2d::GetColorData( const Color& rFillColor, sal_uInt32 nIndex ) const
+{
+ const sal_Int32 nLuminance = GetLuminanceChange(nIndex);
+ if( !nLuminance )
+ return rFillColor;
+
+ basegfx::BColor aHSVColor=
+ basegfx::tools::rgb2hsv(
+ basegfx::BColor(rFillColor.GetRed()/255.0,
+ rFillColor.GetGreen()/255.0,
+ rFillColor.GetBlue()/255.0));
+ if( nLuminance > 0 )
+ {
+ aHSVColor.setGreen(
+ aHSVColor.getGreen() * (1.0-nLuminance/100.0));
+ aHSVColor.setBlue(
+ nLuminance/100.0 +
+ (1.0-nLuminance/100.0)*aHSVColor.getBlue());
+ }
+ else if( nLuminance < 0 )
+ {
+ aHSVColor.setBlue(
+ (1.0+nLuminance/100.0)*aHSVColor.getBlue());
+ }
+
+ aHSVColor = basegfx::tools::hsv2rgb(aHSVColor);
+ return Color( (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getRed(),0.0,1.0) * 255.0 + 0.5 ),
+ (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getGreen(),0.0,1.0) * 255.0 + 0.5 ),
+ (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getBlue(),0.0,1.0) * 255.0 + 0.5 ) );
+}
+
+Rectangle EnhancedCustomShape2d::GetTextRect() const
+{
+ sal_Int32 nIndex, nSize = seqTextFrames.getLength();
+ if ( !nSize )
+ return aLogicRect;
+ nIndex = 0;
+ if ( bTextFlow && ( nSize > 1 ) )
+ nIndex++;
+ Point aTopLeft( GetPoint( seqTextFrames[ nIndex ].TopLeft, sal_True, sal_True ) );
+ Point aBottomRight( GetPoint( seqTextFrames[ nIndex ].BottomRight, sal_True, sal_True ) );
+ if ( bFlipH )
+ {
+ aTopLeft.X() = aLogicRect.GetWidth() - aTopLeft.X();
+ aBottomRight.X() = aLogicRect.GetWidth() - aBottomRight.X();
+ }
+ if ( bFlipV )
+ {
+ aTopLeft.Y() = aLogicRect.GetHeight() - aTopLeft.Y();
+ aBottomRight.Y() = aLogicRect.GetHeight() - aBottomRight.Y();
+ }
+ Rectangle aRect( aTopLeft, aBottomRight );
+ aRect.Move( aLogicRect.Left(), aLogicRect.Top() );
+ aRect.Justify();
+ return aRect;
+}
+
+sal_uInt32 EnhancedCustomShape2d::GetHdlCount() const
+{
+ return seqHandles.getLength();
+}
+
+sal_Bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const
+{
+ sal_Bool bRetValue = sal_False;
+ if ( nIndex < GetHdlCount() )
+ {
+ Handle aHandle;
+ if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
+ {
+ if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
+ {
+ Point aReferencePoint( GetPoint( aHandle.aPolar, sal_True, sal_False ) );
+
+ double fAngle;
+ double fRadius;
+ GetParameter( fRadius, aHandle.aPosition.First, sal_False, sal_False );
+ GetParameter( fAngle, aHandle.aPosition.Second, sal_False, sal_False );
+
+ double a = ( 360.0 - fAngle ) * F_PI180;
+ double dx = fRadius * fXScale;
+ double fX = dx * cos( a );
+ double fY =-dx * sin( a );
+ rReturnPosition =
+ Point(
+ Round( fX + aReferencePoint.X() ),
+ basegfx::fTools::equalZero(fXScale) ? aReferencePoint.Y() :
+ Round( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) );
+ }
+ else
+ {
+ if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
+ {
+ if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameter aFirst = aHandle.aPosition.First;
+ com::sun::star::drawing::EnhancedCustomShapeParameter aSecond = aHandle.aPosition.Second;
+ aHandle.aPosition.First = aSecond;
+ aHandle.aPosition.Second = aFirst;
+ }
+ }
+ rReturnPosition = GetPoint( aHandle.aPosition, sal_True, sal_False );
+ }
+ const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() );
+ if ( aGeoStat.nShearWink )
+ {
+ double nTan = aGeoStat.nTan;
+ if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
+ nTan = -nTan;
+ ShearPoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
+ }
+ if ( nRotateAngle )
+ {
+ double a = nRotateAngle * F_PI18000;
+ RotatePoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
+ }
+ if ( bFlipH )
+ rReturnPosition.X() = aLogicRect.GetWidth() - rReturnPosition.X();
+ if ( bFlipV )
+ rReturnPosition.Y() = aLogicRect.GetHeight() - rReturnPosition.Y();
+ rReturnPosition.Move( aLogicRect.Left(), aLogicRect.Top() );
+ bRetValue = sal_True;
+ }
+ }
+ return bRetValue;
+}
+
+sal_Bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex, const com::sun::star::awt::Point& rPosition )
+{
+ sal_Bool bRetValue = sal_False;
+ if ( nIndex < GetHdlCount() )
+ {
+ Handle aHandle;
+ if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
+ {
+ Point aP( rPosition.X, rPosition.Y );
+ // apply the negative object rotation to the controller position
+
+ aP.Move( -aLogicRect.Left(), -aLogicRect.Top() );
+ if ( bFlipH )
+ aP.X() = aLogicRect.GetWidth() - aP.X();
+ if ( bFlipV )
+ aP.Y() = aLogicRect.GetHeight() - aP.Y();
+ if ( nRotateAngle )
+ {
+ double a = -nRotateAngle * F_PI18000;
+ RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
+ }
+ const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() );
+ if ( aGeoStat.nShearWink )
+ {
+ double nTan = -aGeoStat.nTan;
+ if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
+ nTan = -nTan;
+ ShearPoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
+ }
+
+ double fPos1 = aP.X(); //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X();
+ double fPos2 = aP.Y(); //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y();
+ fPos1 /= fXScale;
+ fPos2 /= fYScale;
+
+ if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
+ {
+ if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
+ {
+ double fX = fPos1;
+ double fY = fPos2;
+ fPos1 = fY;
+ fPos2 = fX;
+ }
+ }
+
+ sal_Int32 nFirstAdjustmentValue = -1, nSecondAdjustmentValue = -1;
+
+ if ( aHandle.aPosition.First.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
+ aHandle.aPosition.First.Value >>= nFirstAdjustmentValue;
+ if ( aHandle.aPosition.Second.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
+ aHandle.aPosition.Second.Value>>= nSecondAdjustmentValue;
+
+ if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
+ {
+ double fXRef, fYRef, fAngle;
+ GetParameter( fXRef, aHandle.aPolar.First, sal_False, sal_False );
+ GetParameter( fYRef, aHandle.aPolar.Second, sal_False, sal_False );
+ const double fDX = fPos1 - fXRef;
+ fAngle = -( atan2( -fPos2 + fYRef, ( ( fDX == 0.0L ) ? 0.000000001 : fDX ) ) / F_PI180 );
+ double fX = ( fPos1 - fXRef );
+ double fY = ( fPos2 - fYRef );
+ double fRadius = sqrt( fX * fX + fY * fY );
+ if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MINIMUM )
+ {
+ double fMin;
+ GetParameter( fMin, aHandle.aRadiusRangeMinimum, sal_False, sal_False );
+ if ( fRadius < fMin )
+ fRadius = fMin;
+ }
+ if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM )
+ {
+ double fMax;
+ GetParameter( fMax, aHandle.aRadiusRangeMaximum, sal_False, sal_False );
+ if ( fRadius > fMax )
+ fRadius = fMax;
+ }
+ if ( nFirstAdjustmentValue >= 0 )
+ SetAdjustValueAsDouble( fRadius, nFirstAdjustmentValue );
+ if ( nSecondAdjustmentValue >= 0 )
+ SetAdjustValueAsDouble( fAngle, nSecondAdjustmentValue );
+ }
+ else
+ {
+ if ( aHandle.nFlags & HANDLE_FLAGS_REFX )
+ {
+ nFirstAdjustmentValue = aHandle.nRefX;
+ fPos1 *= 100000.0;
+ fPos1 /= nCoordWidth;
+ }
+ if ( aHandle.nFlags & HANDLE_FLAGS_REFY )
+ {
+ nSecondAdjustmentValue = aHandle.nRefY;
+ fPos2 *= 100000.0;
+ fPos2 /= nCoordHeight;
+ }
+ if ( nFirstAdjustmentValue >= 0 )
+ {
+ if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MINIMUM ) // check if horizontal handle needs to be within a range
+ {
+ double fXMin;
+ GetParameter( fXMin, aHandle.aXRangeMinimum, sal_False, sal_False );
+ if ( fPos1 < fXMin )
+ fPos1 = fXMin;
+ }
+ if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MAXIMUM ) // check if horizontal handle needs to be within a range
+ {
+ double fXMax;
+ GetParameter( fXMax, aHandle.aXRangeMaximum, sal_False, sal_False );
+ if ( fPos1 > fXMax )
+ fPos1 = fXMax;
+ }
+ SetAdjustValueAsDouble( fPos1, nFirstAdjustmentValue );
+ }
+ if ( nSecondAdjustmentValue >= 0 )
+ {
+ if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MINIMUM ) // check if vertical handle needs to be within a range
+ {
+ double fYMin;
+ GetParameter( fYMin, aHandle.aYRangeMinimum, sal_False, sal_False );
+ if ( fPos2 < fYMin )
+ fPos2 = fYMin;
+ }
+ if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MAXIMUM ) // check if vertical handle needs to be within a range
+ {
+ double fYMax;
+ GetParameter( fYMax, aHandle.aYRangeMaximum, sal_False, sal_False );
+ if ( fPos2 > fYMax )
+ fPos2 = fYMax;
+ }
+ SetAdjustValueAsDouble( fPos2, nSecondAdjustmentValue );
+ }
+ }
+ // and writing them back into the GeometryItem
+ SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)
+ (const SdrCustomShapeGeometryItem&)pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ com::sun::star::beans::PropertyValue aPropVal;
+ aPropVal.Name = sAdjustmentValues;
+ aPropVal.Value <<= seqAdjustmentValues;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ pCustomShapeObj->SetMergedItem( aGeometryItem );
+ bRetValue = sal_True;
+ }
+ }
+ return bRetValue;
+}
+
+void EnhancedCustomShape2d::SwapStartAndEndArrow( SdrObject* pObj ) //#108274
+{
+ XLineStartItem aLineStart;
+ aLineStart.SetLineStartValue(((XLineStartItem&)pObj->GetMergedItem( XATTR_LINEEND )).GetLineStartValue());
+ XLineStartWidthItem aLineStartWidth(((XLineStartWidthItem&)pObj->GetMergedItem( XATTR_LINEENDWIDTH )).GetValue());
+ XLineStartCenterItem aLineStartCenter(((XLineStartCenterItem&)pObj->GetMergedItem( XATTR_LINEENDCENTER )).GetValue());
+
+ XLineEndItem aLineEnd;
+ aLineEnd.SetLineEndValue(((XLineEndItem&)pObj->GetMergedItem( XATTR_LINESTART )).GetLineEndValue());
+ XLineEndWidthItem aLineEndWidth(((XLineEndWidthItem&)pObj->GetMergedItem( XATTR_LINESTARTWIDTH )).GetValue());
+ XLineEndCenterItem aLineEndCenter(((XLineEndCenterItem&)pObj->GetMergedItem( XATTR_LINESTARTCENTER )).GetValue());
+
+ pObj->SetMergedItem( aLineStart );
+ pObj->SetMergedItem( aLineStartWidth );
+ pObj->SetMergedItem( aLineStartCenter );
+ pObj->SetMergedItem( aLineEnd );
+ pObj->SetMergedItem( aLineEndWidth );
+ pObj->SetMergedItem( aLineEndCenter );
+}
+
+basegfx::B2DPolygon CreateArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, const sal_Bool bClockwise )
+{
+ Rectangle aRect( rRect );
+ Point aStart( rStart );
+ Point aEnd( rEnd );
+
+ sal_Int32 bSwapStartEndAngle = 0;
+
+ if ( aRect.Left() > aRect.Right() )
+ bSwapStartEndAngle ^= 0x01;
+ if ( aRect.Top() > aRect.Bottom() )
+ bSwapStartEndAngle ^= 0x11;
+ if ( bSwapStartEndAngle )
+ {
+ aRect.Justify();
+ if ( bSwapStartEndAngle & 1 )
+ {
+ Point aTmp( aStart );
+ aStart = aEnd;
+ aEnd = aTmp;
+ }
+ }
+
+ Polygon aTempPoly( aRect, aStart, aEnd, POLY_ARC );
+ basegfx::B2DPolygon aRetval;
+
+ if ( bClockwise )
+ {
+ for ( sal_uInt16 j = aTempPoly.GetSize(); j--; )
+ {
+ aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
+ }
+ }
+ else
+ {
+ for ( sal_uInt16 j = 0; j < aTempPoly.GetSize(); j++ )
+ {
+ aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
+ }
+ }
+
+ return aRetval;
+}
+
+void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegmentInd, std::vector< SdrPathObj* >& rObjectList,
+ const sal_Bool bLineGeometryNeededOnly,
+ const sal_Bool bSortFilledObjectsToBack )
+{
+ sal_Bool bNoFill = sal_False;
+ sal_Bool bNoStroke = sal_False;
+
+ basegfx::B2DPolyPolygon aNewB2DPolyPolygon;
+ basegfx::B2DPolygon aNewB2DPolygon;
+
+ sal_Int32 nCoordSize = seqCoordinates.getLength();
+ sal_Int32 nSegInfoSize = seqSegments.getLength();
+ if ( !nSegInfoSize )
+ {
+ const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
+
+ for ( sal_Int32 nPtNum(0L); nPtNum < nCoordSize; nPtNum++ )
+ {
+ const Point aTempPoint(GetPoint( *pTmp++, sal_True, sal_True ));
+ aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
+ }
+
+ aNewB2DPolygon.setClosed(true);
+ }
+ else
+ {
+ for ( ;rSegmentInd < nSegInfoSize; )
+ {
+ sal_Int16 nCommand = seqSegments[ rSegmentInd ].Command;
+ sal_Int16 nPntCount= seqSegments[ rSegmentInd++ ].Count;
+
+ switch ( nCommand )
+ {
+ case NOFILL :
+ bNoFill = sal_True;
+ break;
+ case NOSTROKE :
+ bNoStroke = sal_True;
+ break;
+ case MOVETO :
+ {
+ if(aNewB2DPolygon.count() > 1L)
+ {
+ // #i76201# Add conversion to closed polygon when first and last points are equal
+ basegfx::tools::checkClosed(aNewB2DPolygon);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ aNewB2DPolygon.clear();
+
+ if ( rSrcPt < nCoordSize )
+ {
+ const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
+ }
+ }
+ break;
+ case ENDSUBPATH :
+ break;
+ case CLOSESUBPATH :
+ {
+ if(aNewB2DPolygon.count())
+ {
+ if(aNewB2DPolygon.count() > 1L)
+ {
+ aNewB2DPolygon.setClosed(true);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ aNewB2DPolygon.clear();
+ }
+ }
+ break;
+ case CURVETO :
+ {
+ for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
+ {
+ const Point aControlA(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ const Point aControlB(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+
+ DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding control point (!)");
+ aNewB2DPolygon.appendBezierSegment(
+ basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
+ basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
+ basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
+ }
+ }
+ break;
+
+ case ANGLEELLIPSE :
+ {
+ if(aNewB2DPolygon.count() > 1L)
+ {
+ // #i76201# Add conversion to closed polygon when first and last points are equal
+ basegfx::tools::checkClosed(aNewB2DPolygon);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ aNewB2DPolygon.clear();
+ }
+ case ANGLEELLIPSETO :
+ {
+ for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
+ {
+ // create a circle
+ Point _aCenter( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ) );
+ double fWidth, fHeight;
+ GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, sal_True, sal_False );
+ GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, sal_False, sal_True );
+ fWidth *= fXScale;
+ fHeight*= fYScale;
+ Point aP( (sal_Int32)( _aCenter.X() - fWidth ), (sal_Int32)( _aCenter.Y() - fHeight ) );
+ Size aS( (sal_Int32)( fWidth * 2.0 ), (sal_Int32)( fHeight * 2.0 ) );
+ Rectangle aRect( aP, aS );
+ if ( aRect.GetWidth() && aRect.GetHeight() )
+ {
+ double fStartAngle, fEndAngle;
+ GetParameter( fStartAngle, seqCoordinates[ rSrcPt + 2 ].First, sal_False, sal_False );
+ GetParameter( fEndAngle , seqCoordinates[ rSrcPt + 2 ].Second, sal_False, sal_False );
+
+ if ( ((sal_Int32)fStartAngle % 360) != ((sal_Int32)fEndAngle % 360) )
+ {
+ if ( (sal_Int32)fStartAngle & 0x7fff0000 ) // SJ: if the angle was imported from our escher import, then the
+ fStartAngle /= 65536.0; // value is shifted by 16. TODO: already change the fixed float to a
+ if ( (sal_Int32)fEndAngle & 0x7fff0000 ) // double in the import filter
+ {
+ fEndAngle /= 65536.0;
+ fEndAngle = fEndAngle + fStartAngle;
+ if ( fEndAngle < 0 )
+ { // in the binary filter the endangle is the amount
+ double fTemp = fStartAngle;
+ fStartAngle = fEndAngle;
+ fEndAngle = fTemp;
+ }
+ }
+ double fCenterX = aRect.Center().X();
+ double fCenterY = aRect.Center().Y();
+ double fx1 = ( cos( fStartAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
+ double fy1 = ( -sin( fStartAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
+ double fx2 = ( cos( fEndAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
+ double fy2 = ( -sin( fEndAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
+ aNewB2DPolygon.append(CreateArc( aRect, Point( (sal_Int32)fx1, (sal_Int32)fy1 ), Point( (sal_Int32)fx2, (sal_Int32)fy2 ), sal_False));
+ }
+ else
+ { /* SJ: TODO: this block should be replaced sometimes, because the current point
+ is not set correct, it also does not use the correct moveto
+ point if ANGLEELLIPSETO was used, but the method CreateArc
+ is at the moment not able to draw full circles (if startangle is 0
+ and endangle 360 nothing is painted :-( */
+ sal_Int32 nXControl = (sal_Int32)((double)aRect.GetWidth() * 0.2835 );
+ sal_Int32 nYControl = (sal_Int32)((double)aRect.GetHeight() * 0.2835 );
+ Point aCenter( aRect.Center() );
+
+ // append start point
+ aNewB2DPolygon.append(basegfx::B2DPoint(aCenter.X(), aRect.Top()));
+
+ // append four bezier segments
+ aNewB2DPolygon.appendBezierSegment(
+ basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Top()),
+ basegfx::B2DPoint(aRect.Right(), aCenter.Y() - nYControl),
+ basegfx::B2DPoint(aRect.Right(), aCenter.Y()));
+
+ aNewB2DPolygon.appendBezierSegment(
+ basegfx::B2DPoint(aRect.Right(), aCenter.Y() + nYControl),
+ basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Bottom()),
+ basegfx::B2DPoint(aCenter.X(), aRect.Bottom()));
+
+ aNewB2DPolygon.appendBezierSegment(
+ basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Bottom()),
+ basegfx::B2DPoint(aRect.Left(), aCenter.Y() + nYControl),
+ basegfx::B2DPoint(aRect.Left(), aCenter.Y()));
+
+ aNewB2DPolygon.appendBezierSegment(
+ basegfx::B2DPoint(aRect.Left(), aCenter.Y() - nYControl),
+ basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Top()),
+ basegfx::B2DPoint(aCenter.X(), aRect.Top()));
+
+ // close, rescue last controlpoint, remove double last point
+ basegfx::tools::closeWithGeometryChange(aNewB2DPolygon);
+ }
+ }
+ rSrcPt += 3;
+ }
+ }
+ break;
+
+ case LINETO :
+ {
+ for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
+ {
+ const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True ));
+ aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
+ }
+ }
+ break;
+
+ case ARC :
+ case CLOCKWISEARC :
+ {
+ if(aNewB2DPolygon.count() > 1L)
+ {
+ // #i76201# Add conversion to closed polygon when first and last points are equal
+ basegfx::tools::checkClosed(aNewB2DPolygon);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ aNewB2DPolygon.clear();
+ }
+ case ARCTO :
+ case CLOCKWISEARCTO :
+ {
+ sal_Bool bClockwise = ( nCommand == CLOCKWISEARC ) || ( nCommand == CLOCKWISEARCTO );
+ sal_uInt32 nXor = bClockwise ? 3 : 2;
+ for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 3 ) < nCoordSize ); i++ )
+ {
+ Rectangle aRect( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ), GetPoint( seqCoordinates[ rSrcPt + 1 ], sal_True, sal_True ) );
+ if ( aRect.GetWidth() && aRect.GetHeight() )
+ {
+ Point aCenter( aRect.Center() );
+ Point aStart( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + nXor ) ], sal_True, sal_True ) );
+ Point aEnd( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + ( nXor ^ 1 ) ) ], sal_True, sal_True ) );
+ double fRatio = (double)aRect.GetHeight() / (double)aRect.GetWidth();
+ aStart.X() = (sal_Int32)( ( (double)( aStart.X() - aCenter.X() ) ) * fRatio ) + aCenter.X();
+ aStart.Y() = (sal_Int32)( ( (double)( aStart.Y() - aCenter.Y() ) ) ) + aCenter.Y();
+ aEnd.X() = (sal_Int32)( ( (double)( aEnd.X() - aCenter.X() ) ) * fRatio ) + aCenter.X();
+ aEnd.Y() = (sal_Int32)( ( (double)( aEnd.Y() - aCenter.Y() ) ) ) + aCenter.Y();
+ aNewB2DPolygon.append(CreateArc( aRect, aStart, aEnd, bClockwise));
+ }
+ rSrcPt += 4;
+ }
+ }
+ break;
+
+ case ELLIPTICALQUADRANTX :
+ case ELLIPTICALQUADRANTY :
+ {
+ bool bFirstDirection(true);
+ basegfx::B2DPoint aControlPointA;
+ basegfx::B2DPoint aControlPointB;
+
+ for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
+ {
+ sal_uInt32 nModT = ( nCommand == ELLIPTICALQUADRANTX ) ? 1 : 0;
+ Point aCurrent( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ) );
+
+ if ( rSrcPt ) // we need a previous point
+ {
+ Point aPrev( GetPoint( seqCoordinates[ rSrcPt - 1 ], sal_True, sal_True ) );
+ sal_Int32 nX, nY;
+ nX = aCurrent.X() - aPrev.X();
+ nY = aCurrent.Y() - aPrev.Y();
+ if ( ( nY ^ nX ) & 0x80000000 )
+ {
+ if ( !i )
+ bFirstDirection = true;
+ else if ( !bFirstDirection )
+ nModT ^= 1;
+ }
+ else
+ {
+ if ( !i )
+ bFirstDirection = false;
+ else if ( bFirstDirection )
+ nModT ^= 1;
+ }
+ if ( nModT ) // get the right corner
+ {
+ nX = aCurrent.X();
+ nY = aPrev.Y();
+ }
+ else
+ {
+ nX = aPrev.X();
+ nY = aCurrent.Y();
+ }
+ sal_Int32 nXVec = ( nX - aPrev.X() ) >> 1;
+ sal_Int32 nYVec = ( nY - aPrev.Y() ) >> 1;
+ Point aControl1( aPrev.X() + nXVec, aPrev.Y() + nYVec );
+
+ aControlPointA = basegfx::B2DPoint(aControl1.X(), aControl1.Y());
+
+ nXVec = ( nX - aCurrent.X() ) >> 1;
+ nYVec = ( nY - aCurrent.Y() ) >> 1;
+ Point aControl2( aCurrent.X() + nXVec, aCurrent.Y() + nYVec );
+
+ aControlPointB = basegfx::B2DPoint(aControl2.X(), aControl2.Y());
+
+ aNewB2DPolygon.appendBezierSegment(
+ aControlPointA,
+ aControlPointB,
+ basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
+ }
+ else
+ {
+ aNewB2DPolygon.append(basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
+ }
+
+ rSrcPt++;
+ }
+ }
+ break;
+
+#ifdef DBG_CUSTOMSHAPE
+ case UNKNOWN :
+ default :
+ {
+ ByteString aString( "CustomShapes::unknown PolyFlagValue :" );
+ aString.Append( ByteString::CreateFromInt32( nCommand ) );
+ DBG_ERROR( aString.GetBuffer() );
+ }
+ break;
+#endif
+ }
+ if ( nCommand == ENDSUBPATH )
+ break;
+ }
+ }
+ if ( rSegmentInd == nSegInfoSize )
+ rSegmentInd++;
+
+ if(aNewB2DPolygon.count() > 1L)
+ {
+ // #i76201# Add conversion to closed polygon when first and last points are equal
+ basegfx::tools::checkClosed(aNewB2DPolygon);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ if(aNewB2DPolyPolygon.count())
+ {
+ if( !bLineGeometryNeededOnly )
+ {
+ // hack aNewB2DPolyPolygon to fill logic rect - this is
+ // needed to produce gradient fills that look like mso
+ aNewB2DPolygon.clear();
+ aNewB2DPolygon.append(basegfx::B2DPoint(0,0));
+ aNewB2DPolygon.setClosed(true);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+
+ aNewB2DPolygon.clear();
+ aNewB2DPolygon.append(basegfx::B2DPoint(aLogicRect.GetWidth(),
+ aLogicRect.GetHeight()));
+ aNewB2DPolygon.setClosed(true);
+ aNewB2DPolyPolygon.append(aNewB2DPolygon);
+ }
+
+ // #i37011#
+ bool bForceCreateTwoObjects(false);
+
+ if(!bSortFilledObjectsToBack && !aNewB2DPolyPolygon.isClosed() && !bNoStroke)
+ {
+ bForceCreateTwoObjects = true;
+ }
+
+ if(bLineGeometryNeededOnly)
+ {
+ bForceCreateTwoObjects = true;
+ bNoFill = true;
+ bNoStroke = false;
+ }
+
+ if(bForceCreateTwoObjects || bSortFilledObjectsToBack)
+ {
+ if(bFilled && !bNoFill)
+ {
+ basegfx::B2DPolyPolygon aClosedPolyPolygon(aNewB2DPolyPolygon);
+ aClosedPolyPolygon.setClosed(true);
+ SdrPathObj* pFill = new SdrPathObj(OBJ_POLY, aClosedPolyPolygon);
+ SfxItemSet aTempSet(*this);
+ aTempSet.Put(SdrShadowItem(sal_False));
+ aTempSet.Put(XLineStyleItem(XLINE_NONE));
+ pFill->SetMergedItemSet(aTempSet);
+ rObjectList.push_back(pFill);
+ }
+
+ if(!bNoStroke)
+ {
+ // there is no reason to use OBJ_PLIN here when the polygon is actually closed,
+ // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs
+ // to correct the polygon (here: open it) using the type, the last edge may get lost.
+ // Thus, use a type that fits the polygon
+ SdrPathObj* pStroke = new SdrPathObj(
+ aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
+ aNewB2DPolyPolygon);
+ SfxItemSet aTempSet(*this);
+ aTempSet.Put(SdrShadowItem(sal_False));
+ aTempSet.Put(XFillStyleItem(XFILL_NONE));
+ pStroke->SetMergedItemSet(aTempSet);
+ rObjectList.push_back(pStroke);
+ }
+ }
+ else
+ {
+ SdrPathObj* pObj = 0;
+ SfxItemSet aTempSet(*this);
+ aTempSet.Put(SdrShadowItem(sal_False));
+
+ if(bNoFill)
+ {
+ // see comment above about OBJ_PLIN
+ pObj = new SdrPathObj(
+ aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
+ aNewB2DPolyPolygon);
+ aTempSet.Put(XFillStyleItem(XFILL_NONE));
+ }
+ else
+ {
+ aNewB2DPolyPolygon.setClosed(true);
+ pObj = new SdrPathObj(OBJ_POLY, aNewB2DPolyPolygon);
+ }
+
+ if(bNoStroke)
+ {
+ aTempSet.Put(XLineStyleItem(XLINE_NONE));
+ }
+
+ if(pObj)
+ {
+ pObj->SetMergedItemSet(aTempSet);
+ rObjectList.push_back(pObj);
+ }
+ }
+ }
+}
+
+void CorrectCalloutArrows( MSO_SPT eSpType, sal_uInt32 nLineObjectCount, std::vector< SdrPathObj* >& vObjectList )
+{
+ sal_Bool bAccent = sal_False;
+ switch( eSpType )
+ {
+ case mso_sptCallout1 :
+ case mso_sptBorderCallout1 :
+ case mso_sptCallout90 :
+ case mso_sptBorderCallout90 :
+ default:
+ break;
+
+ case mso_sptAccentCallout1 :
+ case mso_sptAccentBorderCallout1 :
+ case mso_sptAccentCallout90 :
+ case mso_sptAccentBorderCallout90 :
+ {
+ sal_uInt32 i, nLine = 0;
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+ if(pObj->IsLine())
+ {
+ nLine++;
+ if ( nLine == nLineObjectCount )
+ {
+ pObj->ClearMergedItem( XATTR_LINESTART );
+ pObj->ClearMergedItem( XATTR_LINEEND );
+ }
+ }
+ }
+ }
+ break;
+
+ // switch start & end
+ case mso_sptAccentCallout2 :
+ case mso_sptAccentBorderCallout2 :
+ bAccent = sal_True;
+ case mso_sptCallout2 :
+ case mso_sptBorderCallout2 :
+ {
+ sal_uInt32 i, nLine = 0;
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+ if(pObj->IsLine())
+ {
+ nLine++;
+ if ( nLine == 1 )
+ pObj->ClearMergedItem( XATTR_LINEEND );
+ else if ( ( bAccent && ( nLine == nLineObjectCount - 1 ) ) || ( !bAccent && ( nLine == nLineObjectCount ) ) )
+ pObj->ClearMergedItem( XATTR_LINESTART );
+ else
+ {
+ pObj->ClearMergedItem( XATTR_LINESTART );
+ pObj->ClearMergedItem( XATTR_LINEEND );
+ }
+ }
+ }
+ }
+ break;
+
+ case mso_sptAccentCallout3 :
+ case mso_sptAccentBorderCallout3 :
+ bAccent = sal_False;
+ case mso_sptCallout3 :
+ case mso_sptBorderCallout3 :
+ {
+ sal_uInt32 i, nLine = 0;
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+ if(pObj->IsLine())
+ {
+ if ( nLine )
+ {
+ pObj->ClearMergedItem( XATTR_LINESTART );
+ pObj->ClearMergedItem( XATTR_LINEEND );
+ }
+ else
+ EnhancedCustomShape2d::SwapStartAndEndArrow( pObj );
+
+ nLine++;
+ }
+ }
+ }
+ break;
+ }
+}
+
+void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet,
+ sal_uInt32& nColorIndex, sal_uInt32 nColorCount)
+{
+ if ( !rObj.IsLine() )
+ {
+ const XFillStyle eFillStyle = ((const XFillStyleItem&)rObj.GetMergedItem(XATTR_FILLSTYLE)).GetValue();
+ switch( eFillStyle )
+ {
+ default:
+ case XFILL_SOLID:
+ {
+ Color aFillColor;
+ if ( nColorCount )
+ {
+ aFillColor = GetColorData(
+ ((XFillColorItem&)rCustomShapeSet.Get( XATTR_FILLCOLOR )).GetColorValue(),
+ std::min(nColorIndex, nColorCount-1) );
+ rObj.SetMergedItem( XFillColorItem( String(), aFillColor ) );
+ }
+ break;
+ }
+ case XFILL_GRADIENT:
+ {
+ XGradient aXGradient(((const XFillGradientItem&)rObj.GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue());
+ if ( nColorCount )
+ {
+ aXGradient.SetStartColor(
+ GetColorData(
+ aXGradient.GetStartColor(),
+ std::min(nColorIndex, nColorCount-1) ));
+ aXGradient.SetEndColor(
+ GetColorData(
+ aXGradient.GetEndColor(),
+ std::min(nColorIndex, nColorCount-1) ));
+ }
+
+ rObj.SetMergedItem( XFillGradientItem( String(), aXGradient ) );
+ break;
+ }
+ case XFILL_HATCH:
+ {
+ XHatch aXHatch(((const XFillHatchItem&)rObj.GetMergedItem(XATTR_FILLHATCH)).GetHatchValue());
+ if ( nColorCount )
+ {
+ aXHatch.SetColor(
+ GetColorData(
+ aXHatch.GetColor(),
+ std::min(nColorIndex, nColorCount-1) ));
+ }
+
+ rObj.SetMergedItem( XFillHatchItem( String(), aXHatch ) );
+ break;
+ }
+ case XFILL_BITMAP:
+ {
+ Bitmap aBitmap(((const XFillBitmapItem&)rObj.GetMergedItem(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap());
+ if ( nColorCount )
+ {
+ aBitmap.Adjust(
+ static_cast< short > ( GetLuminanceChange(
+ std::min(nColorIndex, nColorCount-1))));
+ }
+
+ rObj.SetMergedItem( XFillBitmapItem( String(), aBitmap ) );
+ break;
+ }
+ }
+
+ if ( nColorIndex < nColorCount )
+ nColorIndex++;
+ }
+}
+
+SdrObject* EnhancedCustomShape2d::CreatePathObj( sal_Bool bLineGeometryNeededOnly )
+{
+ sal_Int32 nCoordSize = seqCoordinates.getLength();
+ if ( !nCoordSize )
+ return NULL;
+
+ sal_uInt16 nSrcPt = 0;
+ sal_uInt16 nSegmentInd = 0;
+
+ std::vector< SdrPathObj* > vObjectList;
+ sal_Bool bSortFilledObjectsToBack = SortFilledObjectsToBackByDefault( eSpType );
+
+ while( nSegmentInd <= seqSegments.getLength() )
+ {
+ CreateSubPath( nSrcPt, nSegmentInd, vObjectList, bLineGeometryNeededOnly, bSortFilledObjectsToBack );
+ }
+
+ SdrObject* pRet = NULL;
+ sal_uInt32 i;
+
+ if ( vObjectList.size() )
+ {
+ const SfxItemSet& rCustomShapeSet = pCustomShapeObj->GetMergedItemSet();
+ Color aFillColor;
+ sal_uInt32 nColorCount = nColorData >> 28;
+ sal_uInt32 nColorIndex = 0;
+
+ // #i37011# remove invisible objects
+ if(vObjectList.size())
+ {
+ std::vector< SdrPathObj* > vTempList;
+
+ for(i = 0L; i < vObjectList.size(); i++)
+ {
+ SdrPathObj* pObj(vObjectList[i]);
+ const XLineStyle eLineStyle = ((const XLineStyleItem&)pObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
+ const XFillStyle eFillStyle = ((const XFillStyleItem&)pObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
+
+ //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter
+ if( !bLineGeometryNeededOnly && ( XLINE_NONE == eLineStyle ) && ( XFILL_NONE == eFillStyle ) )
+ delete pObj;
+ else
+ vTempList.push_back(pObj);
+ }
+
+ vObjectList = vTempList;
+ }
+
+ if(1L == vObjectList.size())
+ {
+ // a single object, correct some values
+ AdaptObjColor(*vObjectList[0L],rCustomShapeSet,nColorIndex,nColorCount);
+ }
+ else
+ {
+ sal_Int32 nLineObjectCount = 0;
+ sal_Int32 nAreaObjectCount = 0;
+
+ // correct some values and collect content data
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+
+ if(pObj->IsLine())
+ {
+ nLineObjectCount++;
+ }
+ else
+ {
+ nAreaObjectCount++;
+ AdaptObjColor(*pObj,rCustomShapeSet,nColorIndex,nColorCount);
+ }
+ }
+
+ // #i88870# correct line arrows for callouts
+ if ( nLineObjectCount )
+ CorrectCalloutArrows( eSpType, nLineObjectCount, vObjectList );
+
+ // sort objects so that filled ones are in front. Necessary
+ // for some strange objects
+ if ( bSortFilledObjectsToBack )
+ {
+ std::vector< SdrPathObj* > vTempList;
+
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+
+ if ( !pObj->IsLine() )
+ {
+ vTempList.push_back(pObj);
+ }
+ }
+
+ for ( i = 0; i < vObjectList.size(); i++ )
+ {
+ SdrPathObj* pObj( vObjectList[ i ] );
+
+ if ( pObj->IsLine() )
+ {
+ vTempList.push_back(pObj);
+ }
+ }
+
+ vObjectList = vTempList;
+ }
+ }
+ }
+
+ // #i37011#
+ if(vObjectList.size())
+ {
+ // copy remaining objects to pRet
+ if(vObjectList.size() > 1L)
+ {
+ pRet = new SdrObjGroup;
+
+ for (i = 0L; i < vObjectList.size(); i++)
+ {
+ SdrObject* pObj(vObjectList[i]);
+ pRet->GetSubList()->NbcInsertObject(pObj);
+ }
+ }
+ else if(1L == vObjectList.size())
+ {
+ pRet = vObjectList[0L];
+ }
+
+ if(pRet)
+ {
+ // move to target position
+ Rectangle aCurRect(pRet->GetSnapRect());
+ aCurRect.Move(aLogicRect.Left(), aLogicRect.Top());
+ pRet->NbcSetSnapRect(aCurRect);
+ }
+ }
+
+ return pRet;
+}
+
+SdrObject* EnhancedCustomShape2d::CreateObject( sal_Bool bLineGeometryNeededOnly )
+{
+ SdrObject* pRet = NULL;
+
+ if ( eSpType == mso_sptRectangle )
+ {
+ pRet = new SdrRectObj( aLogicRect );
+// SJ: not setting model, so we save a lot of broadcasting and the model is not modified any longer
+// pRet->SetModel( pCustomShapeObj->GetModel() );
+ pRet->SetMergedItemSet( *this );
+ }
+ if ( !pRet )
+ pRet = CreatePathObj( bLineGeometryNeededOnly );
+
+ return pRet;
+}
+
+void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj )
+{
+ if ( pObj && seqGluePoints.getLength() )
+ {
+ sal_uInt32 i, nCount = seqGluePoints.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ SdrGluePoint aGluePoint;
+
+ aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], sal_True, sal_True ) );
+ aGluePoint.SetPercent( sal_False );
+
+// const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True );
+// double fXRel = rPoint.X();
+// double fYRel = rPoint.Y();
+// fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000;
+// fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000;
+// aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
+// aGluePoint.SetPercent( sal_True );
+ aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
+ aGluePoint.SetEscDir( SDRESC_SMART );
+ SdrGluePointList* pList = pObj->ForceGluePointList();
+ if( pList )
+ /* sal_uInt16 nId = */ pList->Insert( aGluePoint );
+ }
+ }
+}
+
+SdrObject* EnhancedCustomShape2d::CreateLineGeometry()
+{
+ return CreateObject( sal_True );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */